summaryrefslogtreecommitdiff
path: root/board/sunxi
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2018-10-25 17:23:07 +0800
committerJagan Teki <jagan@amarulasolutions.com>2018-10-29 20:41:15 +0530
commit5776610e9ef022e2d8a15793d4b9955c3f8076ed (patch)
tree04edf763dc3f6e3a0a6e2302a20597c88ab95c06 /board/sunxi
parentf8aa3f8d84af6e9ae0dce9c3577d342c6a013b14 (diff)
downloadu-boot-5776610e9ef022e2d8a15793d4b9955c3f8076ed.tar.gz
sunxi: store DRAM size in SPL header
At the moment we rely on the infamous get_ram_size() function to learn the actual DRAM size in U-Boot proper. This function has two issues: 1) It only works if the DRAM size is a power of two. We start to see boards which have 3GB of (usable) DRAM, so this does not fit anymore. 2) As U-Boot has no notion of reserved memory so far, it will happily ride through the DRAM, possibly stepping on secure-only memory. This could be a region of DRAM reserved for OP-TEE or some other secure payload, for instance. It will most likely crash in that case. As the SPL DRAM init routine has very accurate knowledge of the actual DRAM size, lets propagate this wisdom to U-Boot proper. We re-purpose a currently reserved word in our SPL header for that. The SPL itself stores the detected DRAM size there, and bumps the SPL header version number in that case. U-Boot proper checks for a valid SPL header and a high enough version number, then uses the DRAM size from there. If the SPL header field is not sufficient, we fall back to the old DRAM scanning routine. Part of the DRAM might be present and probed by SPL, but not accessible by the CPU. They're restricted in the main U-Boot binary, when accessing the DRAM size from SPL header. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> Reviewed-by: Jagan Teki <jagan@openedev.com>
Diffstat (limited to 'board/sunxi')
-rw-r--r--board/sunxi/board.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index b117de4555..b196d48674 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -281,7 +281,16 @@ static struct boot_file_head * get_spl_header(uint8_t req_version)
int dram_init(void)
{
- gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
+ struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
+
+ if (spl == INVALID_SPL_HEADER)
+ gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
+ PHYS_SDRAM_0_SIZE);
+ else
+ gd->ram_size = (phys_addr_t)spl->dram_size << 20;
+
+ if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
+ gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
return 0;
}
@@ -545,6 +554,21 @@ int board_mmc_init(bd_t *bis)
#endif
#ifdef CONFIG_SPL_BUILD
+
+static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
+{
+ struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
+
+ if (spl == INVALID_SPL_HEADER)
+ return;
+
+ /* Promote the header version for U-Boot proper, if needed. */
+ if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
+ spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
+
+ spl->dram_size = dram_size >> 20;
+}
+
void sunxi_board_init(void)
{
int power_failed = 0;
@@ -613,6 +637,8 @@ void sunxi_board_init(void)
if (!gd->ram_size)
hang();
+ sunxi_spl_store_dram_size(gd->ram_size);
+
/*
* Only clock up the CPU to full speed if we are reasonably
* assured it's being powered with suitable core voltage