[PATCHv2 5/5] memory: reserve from start_addr_sp to end_addr_sp

rs
2026-04-02T20:51:54Z

Add a new global data struct member called end_addr_sp. This stores the
original value of relocaddr, directly from setup_dest_addr. This is
specifically to avoid any adjustments made by other init functions.

Reserve the memory from gd->start_addr_sp - CONFIG_STACK_SIZE to
gd->end_addr_sp instead of gd->ram_top. This allows platform specific
relocation addresses to work without unnecessarily painting over a large
range.

Signed-off-by: Randolph Sapp <rs@ti.com>
---
common/board_f.c | 9 ++++++-
include/asm-generic/global_data.h | 6 +++++
lib/efi_loader/efi_memory.c | 4 +--
lib/lmb.c | 41 ++++++-------------------------
4 files changed, 23 insertions(+), 37 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index df2b0dc899b..85b1c3f3428 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -331,6 +331,8 @@ __weak int arch_setup_dest_addr(void)

static int setup_dest_addr(void)
{
+ int ret;
+
debug("Monitor len: %08x\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
@@ -357,7 +359,12 @@ static int setup_dest_addr(void)
gd->relocaddr = gd->ram_top;
debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);

- return arch_setup_dest_addr();
+ ret = arch_setup_dest_addr();
+ if (ret != 0)
+ return ret;
+
+ gd->end_addr_sp = gd->relocaddr;
+ return ret;
}

#ifdef CFG_PRAM
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 745d2c3a966..2f3ef26a17c 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -115,6 +115,12 @@ struct global_data {
* @start_addr_sp: initial stack pointer address
*/
unsigned long start_addr_sp;
+ /**
+ * @end_addr_sp: the end of memory currently in use by uboot,
+ * should be the original value of the relocaddr before
+ * any other allocations shift it
+ */
+ unsigned long end_addr_sp;
/**
* @reloc_off: relocation offset
*/
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 882366a9f8a..7968ae4b9ba 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -884,8 +884,8 @@ static void add_u_boot_and_runtime(void)
/* Add U-Boot */
uboot_start = ((uintptr_t)map_sysmem(gd->start_addr_sp, 0) -
uboot_stack_size) & ~EFI_PAGE_MASK;
- uboot_pages = ((uintptr_t)map_sysmem(gd->ram_top - 1, 0) -
- uboot_start + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+ uboot_pages = ((gd->end_addr_sp - uboot_start) + EFI_PAGE_MASK) >>
+ EFI_PAGE_SHIFT;
efi_update_memory_map(uboot_start, uboot_pages, EFI_BOOT_SERVICES_CODE,
false, false);
#if defined(__aarch64__)
diff --git a/lib/lmb.c b/lib/lmb.c
index 18703212afb..b38141275da 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -534,46 +534,19 @@ static long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags)

static void lmb_reserve_uboot_region(void)
{
- int bank;
- ulong end, bank_end;
+ ulong size;
phys_addr_t rsv_start;
- ulong pram = 0;

rsv_start = gd->start_addr_sp - CONFIG_STACK_SIZE;
- end = gd->ram_top;
+ size = gd->end_addr_sp - rsv_start;

- /*
- * Reserve memory from aligned address below the bottom of U-Boot stack
- * until end of RAM area to prevent LMB from overwriting that memory.
- */
- debug("## Current stack ends at 0x%08lx ", (ulong)rsv_start);
-
-#ifdef CFG_PRAM
- pram = env_get_ulong("pram", 10, CFG_PRAM);
- pram = pram << 10; /* size is in kB */
-#endif
+ debug("## Current stack ends at 0x%08lx\n", (ulong)rsv_start);

- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
- if (!gd->bd->bi_dram[bank].size ||
- rsv_start < gd->bd->bi_dram[bank].start)
- continue;
- /* Watch out for RAM at end of address space! */
- bank_end = gd->bd->bi_dram[bank].start +
- gd->bd->bi_dram[bank].size - 1;
- if (rsv_start > bank_end)
- continue;
- if (bank_end > end)
- bank_end = end - 1;
-
- lmb_reserve(rsv_start, bank_end - rsv_start - pram + 1,
+ if (gd->flags & GD_FLG_SKIP_RELOC)
+ lmb_reserve((phys_addr_t)(uintptr_t)_start, gd->mon_len,
LMB_NOOVERWRITE);
-
- if (gd->flags & GD_FLG_SKIP_RELOC)
- lmb_reserve((phys_addr_t)(uintptr_t)_start,
- gd->mon_len, LMB_NOOVERWRITE);
-
- break;
- }
+ else
+ lmb_reserve(rsv_start, size, LMB_NOOVERWRITE);
}

static void lmb_reserve_common(void *fdt_blob)
--
2.53.0