sunxi: store DRAM size in SPL header
authorAndre Przywara <andre.przywara@arm.com>
Thu, 25 Oct 2018 09:23:07 +0000 (17:23 +0800)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 29 Oct 2018 15:11:15 +0000 (20:41 +0530)
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>
arch/arm/include/asm/arch-sunxi/spl.h
board/sunxi/board.c

index 014184b638b3dc8d42613e744a8f714ada928ed4..4baba38b0045c4e327355c2a7d59f70fda748e50 100644 (file)
@@ -19,6 +19,7 @@
 
 #define SPL_ENV_HEADER_VERSION SPL_VERSION(0, 1)
 #define SPL_DT_HEADER_VERSION  SPL_VERSION(0, 2)
+#define SPL_DRAM_HEADER_VERSION        SPL_VERSION(0, 3)
 
 #define SPL_ADDR               CONFIG_SUNXI_SRAM_ADDRESS
 
@@ -70,7 +71,7 @@ struct boot_file_head {
         * to the users.
         */
        uint32_t dt_name_offset;        /* since v0.2, set by mksunxiboot */
-       uint32_t reserved1;
+       uint32_t dram_size;             /* in MiB, since v0.3, set by SPL */
        uint32_t boot_media;            /* written here by the boot ROM */
        /* A padding area (may be used for storing text strings) */
        uint32_t string_pool[13];       /* since v0.2, filled by mksunxiboot */
index b117de45550ce7f785b4260781de8551bff9ed1c..b196d48674c4078b9db5c3d94e7507f653fd6eb9 100644 (file)
@@ -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