blob: 1a52d1dc52282716f867cb13f2bf9460ccaa619c [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Bin Meng2229c4c2015-05-07 21:34:08 +08002/*
3 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
Bin Meng2229c4c2015-05-07 21:34:08 +08004 */
5
6#include <common.h>
Simon Glass6980b6b2019-11-14 12:57:45 -07007#include <init.h>
Simon Glass3ba929a2020-10-30 21:38:53 -06008#include <asm/global_data.h>
Bin Meng2229c4c2015-05-07 21:34:08 +08009#include <asm/post.h>
10#include <asm/arch/qemu.h>
Simon Glassde1669f2023-07-30 21:02:04 -060011#include <linux/sizes.h>
Bin Meng2229c4c2015-05-07 21:34:08 +080012
13DECLARE_GLOBAL_DATA_PTR;
14
Bin Meng38502eb2019-08-29 02:53:04 -070015u32 qemu_get_low_memory_size(void)
Bin Meng2229c4c2015-05-07 21:34:08 +080016{
17 u32 ram;
18
19 outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT);
20 ram = ((u32)inb(CMOS_DATA_PORT)) << 14;
21 outb(LOW_RAM_ADDR, CMOS_ADDR_PORT);
22 ram |= ((u32)inb(CMOS_DATA_PORT)) << 6;
23 ram += 16 * 1024;
24
Bin Meng38502eb2019-08-29 02:53:04 -070025 return ram * 1024;
26}
27
Bin Mengfc7f57f2019-08-29 02:53:05 -070028u64 qemu_get_high_memory_size(void)
29{
30 u64 ram;
31
32 outb(HIGH_HIGHRAM_ADDR, CMOS_ADDR_PORT);
33 ram = ((u64)inb(CMOS_DATA_PORT)) << 22;
34 outb(MID_HIGHRAM_ADDR, CMOS_ADDR_PORT);
35 ram |= ((u64)inb(CMOS_DATA_PORT)) << 14;
36 outb(LOW_HIGHRAM_ADDR, CMOS_ADDR_PORT);
37 ram |= ((u64)inb(CMOS_DATA_PORT)) << 6;
38
39 return ram * 1024;
40}
41
Bin Meng38502eb2019-08-29 02:53:04 -070042int dram_init(void)
43{
44 gd->ram_size = qemu_get_low_memory_size();
Bin Mengfc7f57f2019-08-29 02:53:05 -070045 gd->ram_size += qemu_get_high_memory_size();
Bin Meng2229c4c2015-05-07 21:34:08 +080046 post_code(POST_DRAM);
47
48 return 0;
49}
50
Simon Glass2f949c32017-03-31 08:40:32 -060051int dram_init_banksize(void)
Bin Meng2229c4c2015-05-07 21:34:08 +080052{
Bin Mengfc7f57f2019-08-29 02:53:05 -070053 u64 high_mem_size;
54
Bin Meng2229c4c2015-05-07 21:34:08 +080055 gd->bd->bi_dram[0].start = 0;
Bin Mengfc7f57f2019-08-29 02:53:05 -070056 gd->bd->bi_dram[0].size = qemu_get_low_memory_size();
57
58 high_mem_size = qemu_get_high_memory_size();
59 if (high_mem_size) {
60 gd->bd->bi_dram[1].start = SZ_4G;
61 gd->bd->bi_dram[1].size = high_mem_size;
62 }
Simon Glass2f949c32017-03-31 08:40:32 -060063
64 return 0;
Bin Meng2229c4c2015-05-07 21:34:08 +080065}
66
67/*
68 * This function looks for the highest region of memory lower than 4GB which
69 * has enough space for U-Boot where U-Boot is aligned on a page boundary.
70 * It overrides the default implementation found elsewhere which simply
71 * picks the end of ram, wherever that may be. The location of the stack,
72 * the relocation address, and how far U-Boot is moved by relocation are
73 * set in the global data structure.
74 */
Pali Rohár4f4f5832022-09-09 17:32:40 +020075phys_size_t board_get_usable_ram_top(phys_size_t total_size)
Bin Meng2229c4c2015-05-07 21:34:08 +080076{
Bin Mengfc7f57f2019-08-29 02:53:05 -070077 return qemu_get_low_memory_size();
Bin Meng2229c4c2015-05-07 21:34:08 +080078}