Add a new config option to allow u-boot to reuse the FDT provided by the
previous stage bootloader when available.

On some boards the previous stage bootloader can populate
platform-specific parts of the devicetree such as the memory node, this
allows us to avoid hardcoding it in u-boot and instead determine it
dynamically at runtime.

Signed-off-by: Caleb Connolly <[email protected]>
---
This patch will improve generic support for Qualcomm boards by enabling
us to configure the memory map at runtime rather than having hardcoded
maps on a per-device basis. I've gone for this approach initially to try
and avoid introducing board specific code where possible, but I'm happy
to rework this into mach-snapdragon if that's preferred.
---
Changes in v2:
- Replace pre-processor conditional with runtime IS_ENABLED()
- Link to v1: 
https://lore.kernel.org/r/[email protected]
---
base-commit: e65b5d35c9116485366bb08138043d51220551da

// Caleb (they/them)
---
 arch/arm/lib/save_prev_bl_data.c |  7 +++++++
 boot/Kconfig                     | 10 ++++++++++
 include/init.h                   | 11 +++++++++++
 lib/fdtdec.c                     |  8 +++++++-
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/save_prev_bl_data.c b/arch/arm/lib/save_prev_bl_data.c
index f7b23faf0d66..b0608502535e 100644
--- a/arch/arm/lib/save_prev_bl_data.c
+++ b/arch/arm/lib/save_prev_bl_data.c
@@ -45,6 +45,13 @@ bool is_addr_accessible(phys_addr_t addr)
        return false;
 }
 
+phys_addr_t get_prev_bl_fdt_addr(void)
+{
+       if (!is_addr_accessible((phys_addr_t)reg0))
+               return 0;
+       return reg0;
+}
+
 int save_prev_bl_data(void)
 {
        struct fdt_header *fdt_blob;
diff --git a/boot/Kconfig b/boot/Kconfig
index a01e6cb8aafe..c127ba254589 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -1599,6 +1599,16 @@ config SAVE_PREV_BL_INITRAMFS_START_ADDR
          If no initramfs was provided by previous bootloader, no env variables
          will be created.
 
+config USE_PREV_BL_FDT
+       depends on SAVE_PREV_BL_FDT_ADDR && !OF_BOARD
+       bool "Use the FDT provided by the previous stage bootloader"
+       help
+         When u-boot is chain-loaded from a previous bootloader, enable this 
option
+         to use the FDT provided by the previous bootloader instead of any 
built-in
+         to u-boot.
+
+         If no FDT was available, u-boot will fall back to its internal FDT.
+
 menu "Configuration editor"
 
 config CEDIT
diff --git a/include/init.h b/include/init.h
index 4e7fe26c2004..ca78ff9f08c4 100644
--- a/include/init.h
+++ b/include/init.h
@@ -168,6 +168,17 @@ defined(CONFIG_SAVE_PREV_BL_FDT_ADDR)
  * Return: 0 if ok; -ENODATA on error
  */
 int save_prev_bl_data(void);
+
+/**
+ * get_prev_bl_fdt_addr - When u-boot is chainloaded, get the address
+ * of the FDT passed by the previous bootloader.
+ *
+ * Return: the address of the FDT passed by the previous bootloader
+ * or 0 if not found.
+ */
+phys_addr_t get_prev_bl_fdt_addr(void);
+#else
+#define get_prev_bl_fdt_addr() 0LLU
 #endif
 
 /**
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 7a6916764835..b82baf08fc2f 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1222,7 +1222,7 @@ static int uncompress_blob(const void *src, ulong sz_src, 
void **dstp)
  */
 static void *fdt_find_separate(void)
 {
-       void *fdt_blob = NULL;
+       void *fdt_blob = NULL, *prevbl_fdt_blob;
 
        if (IS_ENABLED(CONFIG_SANDBOX))
                return NULL;
@@ -1234,6 +1234,12 @@ static void *fdt_find_separate(void)
        else
                fdt_blob = (ulong *)__bss_end;
 #else
+       if (IS_ENABLED(CONFIG_USE_PREV_BL_FDT)) {
+               prevbl_fdt_blob = (void *)get_prev_bl_fdt_addr();
+               if (prevbl_fdt_blob)
+                       return prevbl_fdt_blob;
+       }
+
        /* FDT is at end of image */
        fdt_blob = (ulong *)_end;
 

Reply via email to