blob: 19d92f27d80c53a0edee11b0364e0f55075d03bd [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Bin Menga65b25d2015-05-07 21:34:08 +08002/*
3 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
Bin Menga65b25d2015-05-07 21:34:08 +08004 */
5
6#include <common.h>
Simon Glass67c4e9f2019-11-14 12:57:45 -07007#include <init.h>
Bin Menga65b25d2015-05-07 21:34:08 +08008#include <asm/post.h>
9#include <asm/arch/qemu.h>
10
11DECLARE_GLOBAL_DATA_PTR;
12
Bin Mengf4c00302019-08-29 02:53:04 -070013u32 qemu_get_low_memory_size(void)
Bin Menga65b25d2015-05-07 21:34:08 +080014{
15 u32 ram;
16
17 outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
18 ram = ((u32)inb(CMOS_DATA_PORT)) << 14;
19 outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
20 ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
21 ram += 16 * 1024;
22
Bin Mengf4c00302019-08-29 02:53:04 -070023 return ram * 1024;
24}
25
Bin Mengea67d542019-08-29 02:53:05 -070026u64 qemu_get_high_memory_size(void)
27{
28 u64 ram;
29
30 outb(HIGH_HIGHRAM_ADDR, CMOS_ADDR_PORT);
31 ram = ((u64)inb(CMOS_DATA_PORT)) << 22;
32 outb(MID_HIGHRAM_ADDR, CMOS_ADDR_PORT);
33 ram |= ((u64)inb(CMOS_DATA_PORT)) << 14;
34 outb(LOW_HIGHRAM_ADDR, CMOS_ADDR_PORT);
35 ram |= ((u64)inb(CMOS_DATA_PORT)) << 6;
36
37 return ram * 1024;
38}
39
Bin Mengf4c00302019-08-29 02:53:04 -070040int dram_init(void)
41{
42 gd->ram_size = qemu_get_low_memory_size();
Bin Mengea67d542019-08-29 02:53:05 -070043 gd->ram_size += qemu_get_high_memory_size();
Bin Menga65b25d2015-05-07 21:34:08 +080044 post_code(POST_DRAM);
45
46 return 0;
47}
48
Simon Glass76b00ac2017-03-31 08:40:32 -060049int dram_init_banksize(void)
Bin Menga65b25d2015-05-07 21:34:08 +080050{
Bin Mengea67d542019-08-29 02:53:05 -070051 u64 high_mem_size;
52
Bin Menga65b25d2015-05-07 21:34:08 +080053 gd->bd->bi_dram[0].start = 0;
Bin Mengea67d542019-08-29 02:53:05 -070054 gd->bd->bi_dram[0].size = qemu_get_low_memory_size();
55
56 high_mem_size = qemu_get_high_memory_size();
57 if (high_mem_size) {
58 gd->bd->bi_dram[1].start = SZ_4G;
59 gd->bd->bi_dram[1].size = high_mem_size;
60 }
Simon Glass76b00ac2017-03-31 08:40:32 -060061
62 return 0;
Bin Menga65b25d2015-05-07 21:34:08 +080063}
64
65/*
66 * This function looks for the highest region of memory lower than 4GB which
67 * has enough space for U-Boot where U-Boot is aligned on a page boundary.
68 * It overrides the default implementation found elsewhere which simply
69 * picks the end of ram, wherever that may be. The location of the stack,
70 * the relocation address, and how far U-Boot is moved by relocation are
71 * set in the global data structure.
72 */
73ulong board_get_usable_ram_top(ulong total_size)
74{
Bin Mengea67d542019-08-29 02:53:05 -070075 return qemu_get_low_memory_size();
Bin Menga65b25d2015-05-07 21:34:08 +080076}