summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorIlias Apalodimas <[email protected]>2026-06-17 10:48:23 +0300
committerTom Rini <[email protected]>2026-06-24 18:13:24 -0600
commit55a34217698491cc0bb8d53d630644dc8756629c (patch)
treec3ee2c86e5dacb429866dcc5fb7ebd023d585aff /common
parentd19d9e1c064b6c782959d1da7bddf1e9da1c55d4 (diff)
common: Add an option to relocate on ram top
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. On certain platforms, it is currently not possible to relocate U-Boot above the 32bit boundary, due to various dependencies on content located below the 32bit boundary. One such example is ethernet, where the packet buffer built into U-Boot binary is placed below the 32bit boundary and allows loading of data via ethernet even above 32bit boundary due to memory copy from the packet buffer to the destination location. A previous patch moves the bi_dram[] info from bd to gd and make the memory bank information available early. So move the dram_init_banksize() INITCALL before the relocation address calculation and use it to derive the address. Also add a Kconfig option and allow the common code to relocate U-Boot to the top of the last discovered bank. It's worth noting that this patch changes when dram_init_banksize() is called. It's now called much earlier in the board init process. That is a significant ordering change for every board with a custom dram_init_banksize(), and it is unconditional (not gated on RELOC_ADDR_TOP). Reviewed-by: Marek Vasut <[email protected]> Reviewed-by: Simon Glass <[email protected]> Tested-by: Simon Glass <[email protected]> # Radxa ROCK 5B Signed-off-by: Ilias Apalodimas <[email protected]> Tested-by: Christophe Leroy (CS GROUP) <[email protected]>
Diffstat (limited to 'common')
-rw-r--r--common/board_f.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/common/board_f.c b/common/board_f.c
index b3e633418e1..85b888d4bb8 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -31,6 +31,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
+#include <memtop.h>
#include <os.h>
#include <post.h>
#include <relocate.h>
@@ -50,6 +51,7 @@
#include <dm/root.h>
#include <linux/errno.h>
#include <linux/log2.h>
+#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -308,6 +310,9 @@ __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)
{
+ if (CONFIG_IS_ENABLED(RELOC_ADDR_TOP))
+ return gd->ram_top;
+
#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
@@ -339,7 +344,23 @@ static int setup_ram_base(void)
static int setup_ram_config(void)
{
debug("Monitor len: %08x\n", gd->mon_len);
-#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
+
+ if (CONFIG_IS_ENABLED(RELOC_ADDR_TOP)) {
+ int i;
+ phys_addr_t top;
+
+ gd->ram_size = 0;
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ top = get_mem_top(gd->dram[i].start, gd->dram[i].size,
+ ALIGN(gd->mon_len, SZ_1M),
+ (void *)gd->fdt_blob);
+ gd->ram_top = max(top, gd->ram_top);
+ gd->ram_size += gd->dram[i].size;
+ }
+ } else {
+ gd->ram_top = gd->ram_base + get_effective_memsize();
+ }
+ gd->ram_top = board_get_usable_ram_top(gd->mon_len);
/*
* Subtract specified amount of memory to hide so that it won't
* get "touched" at all by U-Boot. By fixing up gd->ram_size
@@ -350,10 +371,10 @@ static int setup_ram_config(void)
* memory size from the SDRAM controller setup will have to
* get fixed.
*/
+#if CONFIG_VAL(SYS_MEM_TOP_HIDE)
+ gd->ram_top -= CONFIG_SYS_MEM_TOP_HIDE;
gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
#endif
- gd->ram_top = gd->ram_base + get_effective_memsize();
- gd->ram_top = board_get_usable_ram_top(gd->mon_len);
debug("Ram top: %08llx\n", (unsigned long long)gd->ram_top);
debug("Ram size: %08llx\n", (unsigned long long)gd->ram_size);
@@ -988,6 +1009,7 @@ static void initcall_run_f(void)
* - board info struct
*/
INITCALL(setup_ram_base);
+ INITCALL(dram_init_banksize);
INITCALL(setup_ram_config);
INITCALL(setup_dest_addr);
#if CONFIG_IS_ENABLED(OF_BOARD_FIXUP) && \
@@ -1016,7 +1038,6 @@ static void initcall_run_f(void)
INITCALL(reserve_bloblist);
INITCALL(reserve_arch);
INITCALL(reserve_stacks);
- INITCALL(dram_init_banksize);
INITCALL(show_dram_config);
WATCHDOG_RESET();
INITCALL(setup_bdinfo);