[PATCH v2] arm: init: add an option to use FDT from previous bootloader

Caleb Connolly caleb.connolly at linaro.org
Tue Oct 24 19:38:43 CEST 2023


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 <caleb.connolly at linaro.org>
---
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/20231024-b4-prevbl-fdt-v1-1-541f71dba802@linaro.org
---
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;
 



More information about the U-Boot mailing list