
On Fri, Oct 26, 2018 at 11:27 AM Icenowy Zheng icenowy@aosc.io wrote:
于 2018年10月26日 GMT+08:00 下午1:54:44, Jagan Teki jagan@amarulasolutions.com 写到:
On Thu, Oct 25, 2018 at 2:53 PM Icenowy Zheng icenowy@aosc.io wrote:
From: Andre Przywara andre.przywara@arm.com
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:
- 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
Changes in v2:
- Restrict the DRAM size to the accessible range.
arch/arm/include/asm/arch-sunxi/spl.h | 3 ++- board/sunxi/board.c | 28
++++++++++++++++++++++++++-
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h
b/arch/arm/include/asm/arch-sunxi/spl.h
index 014184b638..4baba38b00 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -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 */
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index bdec82b065..65ae0c4219 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;
How about checking SPL_DRAM_HEADER_VERSION in valid header case?
get_spl_header() does the version check.
Applied to u-boot-sunxi/master