Right now we only relocate u-boot to the top of the first memory bank unless the board specific code overwrites it. This is problematic when loading big binaries as it fragments the contiguous memory space for no apparent reason.
It's worth noting that there are cases where we must not relocate above the 4GiB boundary (64bit hardware with 32bit only capable DMA). E.g This will break platforms, if the ethernet controller cannot DMA above 4 GiB, and once U-Boot does get relocated above 4 GiB, the packet buffer which is built into the U-Boot binary is also relocated above 4 GiB. Add a Kconfig option and allow the common code to relocate U-Boot to the top of the last discovered bank. Signed-off-by: Ilias Apalodimas <[email protected]> --- Kconfig | 7 +++++++ common/board_f.c | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Kconfig b/Kconfig index ce25ea24a60f..3ebdee1b2794 100644 --- a/Kconfig +++ b/Kconfig @@ -474,6 +474,13 @@ config SKIP_RELOCATE Skips relocation of U-Boot allowing for systems that have extremely limited RAM to run U-Boot. +config RELOCATE_LAST_BANK + bool "Relocate to the topmost memory address" + help + When U-Boot relocates, it chooses the end of the first memory bank. + Enable this if you have multiple banks and want U-Boot to relocate + to the topmost memory address + endif # EXPERT config PHYS_64BIT diff --git a/common/board_f.c b/common/board_f.c index df2b0dc899bf..4270f368e653 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -309,6 +309,8 @@ __weak int mach_cpu_init(void) /* Get the top of usable RAM */ __weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size) { + int ret; + #if defined(CFG_SYS_SDRAM_BASE) && CFG_SYS_SDRAM_BASE > 0 /* * Detect whether we have so much RAM that it goes past the end of our @@ -321,6 +323,19 @@ __weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size) */ return 0; #endif + if (IS_ENABLED(CONFIG_RELOCATE_LAST_BANK)) { + phys_addr_t old_top = gd->ram_top; + + ret = fdtdec_setup_mem_ram_top(); + if (ret) + debug("failed to relocate to ram top"); + ret = fdtdec_setup_ram_size(); + if (ret) { + debug("failed to calculate RAM size"); + gd->ram_top = old_top; + } + } + return gd->ram_top; } -- 2.53.0

