[Concept,22/32] boot: pxe: Load FDT files in pxe_load_files()

Message ID 20260109231151.4056804-23-sjg@u-boot.org
State New
Headers
Series boot: pxe: Refactor into separate load/setup phases |

Commit Message

Simon Glass Jan. 9, 2026, 11:11 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Move the FDT file loading to pxe_load_files() so all file loading is in
one place. Add fdtfile parameter to pxe_load_files() and store the
loaded FDT address in ctx->fdt_addr

This simplifies label_process_fdt() to just do post-processing: setting
the working FDT address, handling kaslrseed, and applying overlays.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 boot/pxe_utils.c    | 76 ++++++++++++++++++++-------------------------
 include/pxe_utils.h |  2 ++
 2 files changed, 35 insertions(+), 43 deletions(-)
  

Patch

diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 4cb14783c77..2b1fe45c86d 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -495,49 +495,21 @@  static int label_get_fdt_path(struct pxe_label *label, char **fdtfilep)
 }
 
 /**
- * label_load_fdt() - Load FDT file for the label
+ * label_process_fdt() - Process FDT after loading
  *
- * If "fdt" or "fdtdir" is defined in the pxe file, retrieve the FDT blob
- * from the server.
- *
- * If retrieval fails and an exact FDT file is specified with "fdt", an
- * error is returned. If "fdtdir" is used and retrieval fails, this returns
- * success and allows the caller to use fallback options.
+ * Set the working FDT address, handle kaslrseed, and apply overlays.
+ * The FDT must already be loaded (ctx->fdt_addr set by pxe_load_files()).
  *
  * @ctx: PXE context
  * @label: Label to process
- * @fdtfile: FDT file path to load (freed by this function), or NULL
- * Return: 0 if OK, -ENOMEM if out of memory, -ENOENT if FDT file specified
- *	by "fdt" label could not be loaded
+ * Return: 0 if OK
  */
-static int label_load_fdt(struct pxe_context *ctx, struct pxe_label *label,
-			  char *fdtfile)
+static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label)
 {
-	ulong addr;
-	int ret;
-
-	if (!fdtfile)
+	if (!ctx->fdt_addr)
 		return 0;
 
-	ret = get_relfile_envaddr(ctx, fdtfile, "fdt_addr_r", SZ_4K,
-				  (enum bootflow_img_t)IH_TYPE_FLATDT,
-				  &addr, NULL);
-	free(fdtfile);
-	if (ret < 0) {
-		if (label->fdt) {
-			printf("Skipping %s for failure retrieving FDT\n",
-			       label->name);
-			return -ENOENT;
-		}
-
-		if (label->fdtdir) {
-			printf("Skipping fdtdir %s for failure retrieving dts\n",
-			       label->fdtdir);
-		}
-		return 0;
-	}
-
-	ctx->fdt = map_sysmem(addr, 0);
+	ctx->fdt = map_sysmem(ctx->fdt_addr, 0);
 
 	if (label->kaslrseed)
 		label_boot_kaslrseed(ctx);
@@ -654,7 +626,8 @@  static int generate_localboot(struct pxe_label *label)
 	return 0;
 }
 
-static int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label)
+static int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label,
+			  char *fdtfile)
 {
 	int ret;
 
@@ -686,6 +659,25 @@  static int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label)
 		}
 	}
 
+	if (fdtfile) {
+		ret = get_relfile_envaddr(ctx, fdtfile, "fdt_addr_r", SZ_4K,
+					  (enum bootflow_img_t)IH_TYPE_FLATDT,
+					  &ctx->fdt_addr, NULL);
+		free(fdtfile);
+		if (ret < 0) {
+			if (label->fdt) {
+				printf("Skipping %s for failure retrieving FDT\n",
+				       label->name);
+				return -ENOENT;
+			}
+
+			if (label->fdtdir) {
+				printf("Skipping fdtdir %s for failure retrieving dts\n",
+				       label->fdtdir);
+			}
+		}
+	}
+
 	return 0;
 }
 
@@ -722,11 +714,9 @@  int pxe_load_label(struct pxe_context *ctx, struct pxe_label *label)
 			return ret;
 	}
 
-	ret = pxe_load_files(ctx, label);
-	if (ret) {
-		free(fdtfile);
+	ret = pxe_load_files(ctx, label, fdtfile);
+	if (ret)
 		return ret;
-	}
 
 	/* for FIT, append the configuration identifier */
 	snprintf(fit_addr, sizeof(fit_addr), "%lx%s", ctx->kern_addr,
@@ -764,9 +754,9 @@  int pxe_load_label(struct pxe_context *ctx, struct pxe_label *label)
 	/* Scenario 1: FIT with embedded FDT */
 	if (is_fit) {
 		conf_fdt_str = fit_addr;
-	} else if (fdtfile) {
-		/* Scenario 2: load FDT file if fdt_addr_r is set */
-		ret = label_load_fdt(ctx, label, fdtfile);
+	} else if (ctx->fdt_addr) {
+		/* Scenario 2: FDT loaded by pxe_load_files(), do post-processing */
+		ret = label_process_fdt(ctx, label);
 		if (ret)
 			return ret;
 		conf_fdt_str = env_get("fdt_addr_r");
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index 9bca8d7868d..ec7f12cd7bf 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -150,6 +150,7 @@  typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path,
  * @initrd_addr: initaddr address (0 if none)
  * @initrd_size: initrd size (only used if @initrd_addr)
  * @initrd_str: initrd string to process (only used if @initrd_addr)
+ * @fdt_addr: FDT address from loaded file (0 if none)
  * @conf_fdt_str: FDT-address string
  * @conf_fdt: FDT address
  * @fdt: Working FDT pointer, for kaslrseed and overlay operations
@@ -189,6 +190,7 @@  struct pxe_context {
 	ulong initrd_addr;
 	ulong initrd_size;
 	char *initrd_str;
+	ulong fdt_addr;
 	char *conf_fdt_str;
 	ulong conf_fdt;
 	void *fdt;		/* working FDT pointer, for kaslrseed/overlays */