]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
boot: pxe_utils: Add extension board devicetree overlay support
authorKory Maincent (TI.com) <kory.maincent@bootlin.com>
Thu, 30 Oct 2025 16:45:11 +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 PXE boot. After loading the main board devicetree,
the system now scans for available extension boards and applies their
overlays automatically.

This enables dynamic hardware configuration for systems with extension
boards during boot scenarios which are using pxe_utils.

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

index eb4d772348101f6b893b9ff3d35e30ef46bfa71d..038416203fc9b74e7a9ed5ac9f5fa00588c19a1a 100644 (file)
@@ -10,6 +10,7 @@
 #include <command.h>
 #include <dm.h>
 #include <env.h>
+#include <extension_board.h>
 #include <image.h>
 #include <log.h>
 #include <malloc.h>
@@ -432,6 +433,95 @@ skip_overlay:
 }
 #endif
 
+/*
+ * label_boot_extension - scan extension boards and load overlay associated
+ */
+
+static void label_boot_extension(struct pxe_context *ctx,
+                                struct pxe_label *label)
+{
+#if CONFIG_IS_ENABLED(SUPPORT_EXTENSION_SCAN)
+       const struct extension *extension;
+       struct fdt_header *working_fdt;
+       struct alist *extension_list;
+       int ret, dir_len, len;
+       char *overlay_dir;
+       const char *slash;
+       ulong fdt_addr;
+
+       ret = extension_scan();
+       if (ret < 0)
+               return;
+
+       extension_list = extension_get_list();
+       if (!extension_list)
+               return;
+
+       /* Get the main fdt and map it */
+       fdt_addr = env_get_hex("fdt_addr_r", 0);
+       working_fdt = map_sysmem(fdt_addr, 0);
+       if (fdt_check_header(working_fdt))
+               return;
+
+       /* Use fdtdir for now as the overlay devicetree directory */
+       if (label->fdtdir) {
+               len = strlen(label->fdtdir);
+               if (!len)
+                       slash = "./";
+               else if (label->fdtdir[len - 1] != '/')
+                       slash = "/";
+               else
+                       slash = "";
+
+               dir_len = strlen(label->fdtdir) + strlen(slash) + 1;
+               overlay_dir = calloc(1, len);
+               if (!overlay_dir)
+                       return;
+
+               snprintf(overlay_dir, dir_len, "%s%s", label->fdtdir,
+                        slash);
+       } else {
+               dir_len = 2;
+               snprintf(overlay_dir, dir_len, "/");
+       }
+
+       alist_for_each(extension, extension_list) {
+               char *overlay_file;
+               ulong size;
+
+               len = dir_len + strlen(extension->overlay);
+               overlay_file = calloc(1, len);
+               if (!overlay_file)
+                       goto cleanup;
+
+               snprintf(overlay_file, len, "%s%s", overlay_dir,
+                        extension->overlay);
+
+               /* Load extension overlay file */
+               ret = get_relfile_envaddr(ctx, overlay_file,
+                                         "extension_overlay_addr",
+                                         (enum bootflow_img_t)IH_TYPE_FLATDT,
+                                         &size);
+               if (ret < 0) {
+                       printf("Failed loading overlay %s\n", overlay_file);
+                       free(overlay_file);
+                       continue;
+               }
+
+               ret = extension_apply(working_fdt, size);
+               if (ret) {
+                       printf("Failed applying overlay %s\n", overlay_file);
+                       free(overlay_file);
+                       continue;
+               }
+               free(overlay_file);
+       }
+
+cleanup:
+       free(overlay_dir);
+#endif
+}
+
 /**
  * label_boot() - Boot according to the contents of a pxe_label
  *
@@ -685,6 +775,8 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
                        if (label->fdtoverlays)
                                label_boot_fdtoverlay(ctx, label);
 #endif
+                       label_boot_extension(ctx, label);
+
                } else {
                        bootm_argv[3] = NULL;
                }
index c2dc11f218d207164588cf9086a868969528e10d..18532f182d5c001dfb139201ef8ab2d87a3f0eb7 100644 (file)
@@ -103,6 +103,10 @@ Environment
         ``fdt_addr_r``. Required to use the ``fdtoverlays`` command in
         the PXE file.
 
+``extension_overlay_addr``
+       Location in RAM to temporarily store extension fdt overlay(s)
+       before applying them to the fdt blob stored at ``fdt_addr_r``.
+
 ``pxe_label_override``
         Override label to be used, if exists, instead of the default
         label. This will allow consumers to choose a pxe label at