Move SPL to start in the RAM region, using the relocating loader to copy
it there and run from there.

Add a simple test to make sure this works as expected.

Signed-off-by: Simon Glass <[email protected]>
---

 arch/arm/dts/qemu-arm64.dts      |  1 -
 board/emulation/qemu-arm/xpl.c   | 15 +++++++++++++++
 configs/qemu_arm64_tpl_defconfig |  3 ++-
 test/py/tests/test_reloc.py      | 21 +++++++++++++++++++++
 4 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 test/py/tests/test_reloc.py

diff --git a/arch/arm/dts/qemu-arm64.dts b/arch/arm/dts/qemu-arm64.dts
index de943642e76..098992f5da8 100644
--- a/arch/arm/dts/qemu-arm64.dts
+++ b/arch/arm/dts/qemu-arm64.dts
@@ -15,7 +15,6 @@
 
                u-boot-spl {
                        symbols-base = <0>;
-                       offset = <CONFIG_SPL_TEXT_BASE>;
                };
 
                u-boot {
diff --git a/board/emulation/qemu-arm/xpl.c b/board/emulation/qemu-arm/xpl.c
index ec59e0ff327..aa002ebcc90 100644
--- a/board/emulation/qemu-arm/xpl.c
+++ b/board/emulation/qemu-arm/xpl.c
@@ -20,12 +20,27 @@ static int binman_load_image(struct spl_image_info *img,
 {
        ulong base = spl_get_image_pos();
        ulong size = spl_get_image_size();
+       ulong spl_load_addr;
+       int ret;
 
        log_debug("Booting from address %lx size %lx\n", base, size);
        img->name = spl_phase_name(spl_next_phase());
        img->load_addr = base;
        img->entry_point = base;
 
+       if (CONFIG_IS_ENABLED(RELOC_LOADER)) {
+               img->size = size;
+               spl_set_fdt_size(img, 0);
+               ret = spl_reloc_prepare(img, &spl_load_addr);
+               if (ret)
+                       return log_msg_ret("rel", ret);
+               log_debug("Loading to %lx\n", spl_load_addr);
+               memcpy(map_sysmem(spl_load_addr, size),
+                      map_sysmem(base, size), size);
+               img->load_addr = CONFIG_SPL_TEXT_BASE;
+               img->entry_point = CONFIG_SPL_TEXT_BASE;
+       }
+
        return 0;
 }
 SPL_LOAD_IMAGE_METHOD("binman", 0, BOOT_DEVICE_BOARD, binman_load_image);
diff --git a/configs/qemu_arm64_tpl_defconfig b/configs/qemu_arm64_tpl_defconfig
index f09e357e5cc..5f506d2b553 100644
--- a/configs/qemu_arm64_tpl_defconfig
+++ b/configs/qemu_arm64_tpl_defconfig
@@ -9,7 +9,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40200000
 CONFIG_ENV_SIZE=0x40000
 CONFIG_ENV_SECT_SIZE=0x40000
 CONFIG_DEFAULT_DEVICE_TREE="qemu-arm64"
-CONFIG_SPL_TEXT_BASE=0x6000
+CONFIG_SPL_TEXT_BASE=0x40100000
 CONFIG_TARGET_QEMU_ARM_64BIT_TPL=y
 CONFIG_SPL_BSS_MAX_SIZE=0x10000
 CONFIG_DEBUG_UART_BASE=0x9000000
@@ -35,6 +35,7 @@ CONFIG_USE_PREBOOT=y
 CONFIG_PCI_INIT_R=y
 CONFIG_SPL_MAX_SIZE=0x10000
 # CONFIG_SPL_SEPARATE_BSS is not set
+CONFIG_TPL_RELOC_LOADER=y
 CONFIG_CMD_SMBIOS=y
 CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_BOOTEFI_SELFTEST=y
diff --git a/test/py/tests/test_reloc.py b/test/py/tests/test_reloc.py
new file mode 100644
index 00000000000..82913194fba
--- /dev/null
+++ b/test/py/tests/test_reloc.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2024 Google LLC
+# Written by Simon Glass <[email protected]>
+
+import pytest
+
[email protected]('target_qemu_arm_64bit_tpl')
+def test_reloc_loader(u_boot_console):
+    try:
+        cons = u_boot_console
+        # x = cons.restart_uboot()
+        output = cons.get_spawn_output().replace('\r', '')
+        assert 'spl_reloc TPL->SPL' in output
+        assert 'Loading to 40100200' in output
+
+        # Sanity check that it is picking up the correct environment
+        board_name = cons.run_command('print board_name')
+        assert board_name == 'board_name="qemu-arm64_tpl"'
+    finally:
+        # Restart afterward to get the normal U-Boot back
+        u_boot_console.restart_uboot()
-- 
2.43.0

Reply via email to