From: Simon Glass <simon.glass@canonical.com> Use the new files list for handling the FDT overlays, using the type PFT_FDTOVERLAY. Add a helper function to check if any overlays exist in the list, to preserve the existing behaviour of only adding new overlays if not done already. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/pxe_parse.c | 33 ++++++++++++++++++++++++--------- boot/pxe_utils.c | 13 ++++++++----- include/pxe_utils.h | 2 -- test/boot/pxe.c | 26 +++++++++++++------------- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/boot/pxe_parse.c b/boot/pxe_parse.c index 29bee4d908c..b516da8f759 100644 --- a/boot/pxe_parse.c +++ b/boot/pxe_parse.c @@ -106,14 +106,14 @@ static struct pxe_label *label_create(void) if (!label) return NULL; memset(label, 0, sizeof(struct pxe_label)); - alist_init_struct(&label->fdtoverlays, struct pxe_file); + alist_init_struct(&label->files, struct pxe_file); return label; } void label_destroy(struct pxe_label *label) { - struct pxe_file *overlay; + struct pxe_file *file; free(label->name); free(label->menu); @@ -124,9 +124,9 @@ void label_destroy(struct pxe_label *label) free(label->initrd); free(label->fdt); free(label->fdtdir); - alist_for_each(overlay, &label->fdtoverlays) - free(overlay->path); - alist_uninit(&label->fdtoverlays); + alist_for_each(file, &label->files) + free(file->path); + alist_uninit(&label->files); free(label->say); free(label); } @@ -312,10 +312,25 @@ static int parse_sliteral(char **c, char **dst) return 1; } +/* + * Check if a files list contains any FDT overlays. + */ +static bool has_fdtoverlays(struct alist *files) +{ + struct pxe_file *file; + + alist_for_each(file, files) { + if (file->type == PFT_FDTOVERLAY) + return true; + } + + return false; +} + /* * Parse a space-separated list of overlay paths into an alist. */ -static int parse_fdtoverlays(char **c, struct alist *overlays) +static int parse_fdtoverlays(char **c, struct alist *files) { char *val, *start; int err; @@ -349,7 +364,7 @@ static int parse_fdtoverlays(char **c, struct alist *overlays) item.addr = 0; item.size = 0; - if (!item.path || !alist_add(overlays, item)) { + if (!item.path || !alist_add(files, item)) { free(item.path); free(start); return -ENOMEM; @@ -589,8 +604,8 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_sliteral(c, &label->fdtdir); break; case T_FDTOVERLAYS: - if (!label->fdtoverlays.count) - err = parse_fdtoverlays(c, &label->fdtoverlays); + if (!has_fdtoverlays(&label->files)) + err = parse_fdtoverlays(c, &label->files); break; case T_LOCALBOOT: label->localboot = 1; diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index b4bcba422b8..a2a2b986de1 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -327,11 +327,14 @@ static void label_load_fdtoverlays(struct pxe_context *ctx, use_lmb = true; } - alist_for_each(overlay, &label->fdtoverlays) { + alist_for_each(overlay, &label->files) { ulong addr = fdtoverlay_addr; ulong size; int err; + if (overlay->type != PFT_FDTOVERLAY) + continue; + err = get_relfile(ctx, overlay->path, &addr, SZ_4K, (enum bootflow_img_t)IH_TYPE_FLATDT, &size); if (err < 0) { @@ -368,8 +371,8 @@ static void label_apply_fdtoverlays(struct pxe_context *ctx, /* Resize main fdt to make room for overlays */ fdt_shrink_to_minimum(ctx->fdt, 8192); - alist_for_each(overlay, &label->fdtoverlays) { - if (!overlay->addr) + alist_for_each(overlay, &label->files) { + if (overlay->type != PFT_FDTOVERLAY || !overlay->addr) continue; blob = map_sysmem(overlay->addr, 0); @@ -515,7 +518,7 @@ static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label) if (label->kaslrseed) label_boot_kaslrseed(ctx); - if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->fdtoverlays.count) + if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->files.count) label_apply_fdtoverlays(ctx, label); return 0; @@ -679,7 +682,7 @@ int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label, } } - if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->fdtoverlays.count) + if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->files.count) label_load_fdtoverlays(ctx, label); return 0; diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 75437885dd3..266204b97ef 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -39,7 +39,6 @@ * @initrd: path to the initrd to use for this label. * @fdt: path to FDT to use * @fdtdir: path to FDT directory to use - * @fdtoverlays: list of FDT overlays to apply (alist of struct pxe_file) * @files: list of files to load (alist of struct pxe_file) * @say: message to print when this label is selected for booting * @ipappend: flags for appending IP address (0x1) and MAC address (0x3) @@ -60,7 +59,6 @@ struct pxe_label { char *initrd; char *fdt; char *fdtdir; - struct alist fdtoverlays; struct alist files; char *say; int ipappend; diff --git a/test/boot/pxe.c b/test/boot/pxe.c index 260fc918592..df7cf2a781a 100644 --- a/test/boot/pxe.c +++ b/test/boot/pxe.c @@ -190,11 +190,11 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_asserteq_str("/initrd.img", label->initrd); ut_asserteq_str("/dtb/board.dtb", label->fdt); ut_assertnull(label->fdtdir); - ut_asserteq(2, label->fdtoverlays.count); + ut_asserteq(2, label->files.count); ut_asserteq_str("/dtb/overlay1.dtbo", - alist_get(&label->fdtoverlays, 0, struct pxe_file)->path); + alist_get(&label->files, 0, struct pxe_file)->path); ut_asserteq_str("/dtb/overlay2.dtbo", - alist_get(&label->fdtoverlays, 1, struct pxe_file)->path); + alist_get(&label->files, 1, struct pxe_file)->path); ut_asserteq_str("Booting default Linux kernel", label->say); ut_asserteq(0, label->ipappend); ut_asserteq(0, label->attempted); @@ -214,7 +214,7 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_assertnull(label->initrd); ut_assertnull(label->fdt); ut_asserteq_str("/dtb/", label->fdtdir); - ut_asserteq(0, label->fdtoverlays.count); + ut_asserteq(0, label->files.count); ut_assertnull(label->say); ut_asserteq(3, label->ipappend); ut_asserteq(0, label->attempted); @@ -234,7 +234,7 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_assertnull(label->initrd); ut_assertnull(label->fdt); ut_assertnull(label->fdtdir); - ut_asserteq(0, label->fdtoverlays.count); + ut_asserteq(0, label->files.count); ut_assertnull(label->say); ut_asserteq(0, label->ipappend); ut_asserteq(0, label->attempted); @@ -254,7 +254,7 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_assertnull(label->initrd); ut_assertnull(label->fdt); ut_assertnull(label->fdtdir); - ut_asserteq(0, label->fdtoverlays.count); + ut_asserteq(0, label->files.count); ut_assertnull(label->say); ut_asserteq(0, label->ipappend); ut_asserteq(0, label->attempted); @@ -274,7 +274,7 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_assertnull(label->initrd); ut_assertnull(label->fdt); ut_assertnull(label->fdtdir); - ut_asserteq(0, label->fdtoverlays.count); + ut_asserteq(0, label->files.count); ut_assertnull(label->say); ut_asserteq(0, label->ipappend); ut_asserteq(0, label->attempted); @@ -296,7 +296,7 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) * environment, and verify overlay files can be loaded. */ label = list_first_entry(&cfg->labels, struct pxe_label, list); - ut_asserteq(2, label->fdtoverlays.count); + ut_asserteq(2, label->files.count); /* Set environment variables for file loading */ ut_assertok(env_set_hex("kernel_addr_r", PXE_KERNEL_ADDR)); @@ -316,14 +316,14 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_asserteq(PXE_FDT_ADDR, ctx.fdt_addr); /* Verify overlays were loaded to valid addresses */ - ut_assert(alist_get(&label->fdtoverlays, 0, + ut_assert(alist_get(&label->files, 0, struct pxe_file)->addr >= PXE_OVERLAY_ADDR); - ut_assert(alist_get(&label->fdtoverlays, 1, + ut_assert(alist_get(&label->files, 1, struct pxe_file)->addr >= PXE_OVERLAY_ADDR); /* Second overlay should be at a higher address than the first */ - ut_assert(alist_get(&label->fdtoverlays, 1, struct pxe_file)->addr > - alist_get(&label->fdtoverlays, 0, struct pxe_file)->addr); + ut_assert(alist_get(&label->files, 1, struct pxe_file)->addr > + alist_get(&label->files, 0, struct pxe_file)->addr); /* Verify no more console output */ ut_assert_console_end(); @@ -702,7 +702,7 @@ static int pxe_test_overlay_no_addr_norun(struct unit_test_state *uts) /* Get the first label (linux) which has fdtoverlays */ label = list_first_entry(&cfg->labels, struct pxe_label, list); ut_asserteq_str("linux", label->name); - ut_assert(label->fdtoverlays.count > 0); + ut_assert(label->files.count > 0); /* Enable output for loading phase */ ctx.quiet = false; -- 2.43.0