[PATCH 01/11] mach-snapdragon: refactor board_fdt_blob_setup()

Caleb Connolly caleb.connolly at linaro.org
Fri Aug 9 01:59:24 CEST 2024


If U-Boot has a DTB built in (appended to the image directly) then this
was likely intentional, we should prioritise it over one provided by ABL
(if there was one).

Make this behaviour explicit, and panic if no valid DTB could be found
anywhere. Returning an error is not useful in this case as U-Boot would
just crash later in a more confusing way.

Signed-off-by: Caleb Connolly <caleb.connolly at linaro.org>
---
 arch/arm/mach-snapdragon/board.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index b439a19ec7eb..2881de28a0a3 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -17,8 +17,9 @@
 #include <dm/uclass-internal.h>
 #include <dm/read.h>
 #include <power/regulator.h>
 #include <env.h>
+#include <fdt_support.h>
 #include <init.h>
 #include <linux/arm-smccc.h>
 #include <linux/bug.h>
 #include <linux/psci.h>
@@ -84,28 +85,37 @@ static void show_psci_version(void)
 	      PSCI_VERSION_MAJOR(res.a0),
 	      PSCI_VERSION_MINOR(res.a0));
 }
 
+/* We support booting U-Boot with an internal DT when running as a first-stage bootloader
+ * or for supporting quirky devices where it's easier to leave the downstream DT in place
+ * to improve ABL compatibility. Otherwise, we use the DT provided by ABL.
+ */
 void *board_fdt_blob_setup(int *err)
 {
-	phys_addr_t fdt;
-	/* Return DTB pointer passed by ABL */
+	struct fdt_header *fdt;
+	bool internal_valid, external_valid;
+
 	*err = 0;
-	fdt = get_prev_bl_fdt_addr();
+	fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
+	external_valid = fdt && !fdt_check_header(fdt);
+	internal_valid = !fdt_check_header(gd->fdt_blob);
 
 	/*
-	 * If we bail then the board will simply not boot, instead let's
-	 * try and use the FDT built into U-Boot if there is one...
-	 * This avoids having a hard dependency on the previous stage bootloader
+	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
+	 * Bail out while we can still print a useful error message.
 	 */
+	if (!internal_valid && !external_valid)
+		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
+		      (phys_addr_t)fdt);
 
-	if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, SZ_4K) ||
-					       fdt_check_header((void *)fdt))) {
-		debug("%s: Using built in FDT, bootloader gave us %#llx\n", __func__, fdt);
+	if (internal_valid) {
+		debug("Using built in FDT\n");
 		return (void *)gd->fdt_blob;
+	} else {
+		debug("Using external FDT\n");
+		return (void *)fdt;
 	}
-
-	return (void *)fdt;
 }
 
 void reset_cpu(void)
 {

-- 
2.46.0



More information about the U-Boot mailing list