From 82efffc38f8f834393ab06375d4e8bd38dec024a Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 9 Aug 2024 01:59:24 +0200 Subject: [PATCH] mach-snapdragon: refactor board_fdt_blob_setup() 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. Reviewed-by: Neil Armstrong Signed-off-by: Caleb Connolly --- 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 22a7d2a637..92492c3a03 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -85,26 +86,35 @@ static void show_psci_version(void) 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.39.5