]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
boot: bootmeth_efi: Add extension board devicetree overlay support
authorKory Maincent (TI.com) <kory.maincent@bootlin.com>
Thu, 30 Oct 2025 16:45:13 +0000 (17:45 +0100)
committerTom Rini <trini@konsulko.com>
Mon, 3 Nov 2025 16:02:39 +0000 (10:02 -0600)
Add support for scanning and applying extension board devicetree
overlays during EFI boot. After loading the main board devicetree,
the system now scans for available extension boards and applies their
overlays automatically.

Signed-off-by: Kory Maincent (TI.com) <kory.maincent@bootlin.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
boot/bootmeth_efi.c

index 64de5c08b7b700a03a9d0acbe41763541feed698..f592fec07f65dac140b49839ac3104059dd47abb 100644 (file)
@@ -16,6 +16,7 @@
 #include <efi.h>
 #include <efi_loader.h>
 #include <env.h>
+#include <extension_board.h>
 #include <fs.h>
 #include <malloc.h>
 #include <mapmem.h>
@@ -99,8 +100,11 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 static int distro_efi_try_bootflow_files(struct udevice *dev,
                                         struct bootflow *bflow)
 {
+       ulong fdt_addr, size, overlay_addr;
+       const struct extension *extension;
+       struct fdt_header *working_fdt;
        struct blk_desc *desc = NULL;
-       ulong fdt_addr, size;
+       struct alist *extension_list;
        char fname[256];
        int ret, seq;
 
@@ -157,16 +161,58 @@ static int distro_efi_try_bootflow_files(struct udevice *dev,
        bflow->fdt_size = size;
        bflow->fdt_addr = fdt_addr;
 
-       /*
-        * TODO: Apply extension overlay
-        *
-        * Here we need to load and apply the extension overlay. This is
-        * not implemented. See do_extension_apply(). The extension
-        * stuff needs an implementation in boot/extension.c so it is
-        * separate from the command code. Really the extension stuff
-        * should use the device tree and a uclass / driver interface
-        * rather than implementing its own list
-        */
+       if (!CONFIG_IS_ENABLED(SUPPORT_EXTENSION_SCAN))
+               return 0;
+
+       ret = extension_scan();
+       if (ret < 0)
+               return 0;
+
+       extension_list = extension_get_list();
+       if (!extension_list)
+               return 0;
+
+       working_fdt = map_sysmem(fdt_addr, 0);
+       if (fdt_check_header(working_fdt))
+               return 0;
+
+       overlay_addr = env_get_hex("extension_overlay_addr", 0);
+       if (!overlay_addr) {
+               log_debug("Environment extension_overlay_addr is missing\n");
+               return 0;
+       }
+
+       alist_for_each(extension, extension_list) {
+               char *overlay_file;
+               int len;
+
+               len = sizeof(EFI_DIRNAME) + strlen(extension->overlay);
+               overlay_file = calloc(1, len);
+               if (!overlay_file)
+                       return -ENOMEM;
+
+               snprintf(overlay_file, len, "%s%s", EFI_DIRNAME,
+                        extension->overlay);
+
+               ret = bootmeth_common_read_file(dev, bflow, overlay_file,
+                                               overlay_addr,
+                                               (enum bootflow_img_t)IH_TYPE_FLATDT,
+                                               &size);
+               if (ret) {
+                       log_debug("Failed loading overlay %s\n", overlay_file);
+                       free(overlay_file);
+                       continue;
+               }
+
+               ret = extension_apply(working_fdt, size);
+               if (ret) {
+                       log_debug("Failed applying overlay %s\n", overlay_file);
+                       free(overlay_file);
+                       continue;
+               }
+               bflow->fdt_size += size;
+               free(overlay_file);
+       }
 
        return 0;
 }