1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
4  */
5 
6 #include <common.h>
7 #include <init.h>
8 #include <asm/global_data.h>
9 #include <asm/post.h>
10 #include <asm/arch/qemu.h>
11 
12 DECLARE_GLOBAL_DATA_PTR;
13 
qemu_get_low_memory_size(void)14 u32 qemu_get_low_memory_size(void)
15 {
16 	u32 ram;
17 
18 	outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
19 	ram = ((u32)inb(CMOS_DATA_PORT)) << 14;
20 	outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
21 	ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
22 	ram += 16 * 1024;
23 
24 	return ram * 1024;
25 }
26 
qemu_get_high_memory_size(void)27 u64 qemu_get_high_memory_size(void)
28 {
29 	u64 ram;
30 
31 	outb(HIGH_HIGHRAM_ADDR, CMOS_ADDR_PORT);
32 	ram = ((u64)inb(CMOS_DATA_PORT)) << 22;
33 	outb(MID_HIGHRAM_ADDR, CMOS_ADDR_PORT);
34 	ram |= ((u64)inb(CMOS_DATA_PORT)) << 14;
35 	outb(LOW_HIGHRAM_ADDR, CMOS_ADDR_PORT);
36 	ram |= ((u64)inb(CMOS_DATA_PORT)) << 6;
37 
38 	return ram * 1024;
39 }
40 
dram_init(void)41 int dram_init(void)
42 {
43 	gd->ram_size = qemu_get_low_memory_size();
44 	gd->ram_size += qemu_get_high_memory_size();
45 	post_code(POST_DRAM);
46 
47 	return 0;
48 }
49 
dram_init_banksize(void)50 int dram_init_banksize(void)
51 {
52 	u64 high_mem_size;
53 
54 	gd->bd->bi_dram[0].start = 0;
55 	gd->bd->bi_dram[0].size = qemu_get_low_memory_size();
56 
57 	high_mem_size = qemu_get_high_memory_size();
58 	if (high_mem_size) {
59 		gd->bd->bi_dram[1].start = SZ_4G;
60 		gd->bd->bi_dram[1].size = high_mem_size;
61 	}
62 
63 	return 0;
64 }
65 
66 /*
67  * This function looks for the highest region of memory lower than 4GB which
68  * has enough space for U-Boot where U-Boot is aligned on a page boundary.
69  * It overrides the default implementation found elsewhere which simply
70  * picks the end of ram, wherever that may be. The location of the stack,
71  * the relocation address, and how far U-Boot is moved by relocation are
72  * set in the global data structure.
73  */
board_get_usable_ram_top(ulong total_size)74 ulong board_get_usable_ram_top(ulong total_size)
75 {
76 	return qemu_get_low_memory_size();
77 }
78