[Concept,17/32] boot: pxe: Move FIT handling from label_process_fdt() to caller

Message ID 20260109231151.4056804-18-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>

The label_process_fdt() function handles both FIT images (where the FDT
is embedded in the FIT) and separate FDT files. Move the FIT detection
to pxe_load_label() to simplify label_process_fdt()

In the FIT case, the label's fdt field matches kernel_label, indicating
the FDT comes from the FIT image rather than a separate file. When this
is detected, use the fit_addr string (which includes the FIT
configuration) directly as conf_fdt_str

This allows label_process_fdt() to focus solely on loading separate FDT
files. Rename it to label_load_fdt() to reflect this.

Also move the log_debug() and scenario documentation to the caller where
more context is available.

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

 boot/pxe_utils.c | 83 ++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 38 deletions(-)
  

Patch

diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 93e00b6f97e..0e335cb2fdd 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -499,50 +499,31 @@  static int label_get_fdt_path(struct pxe_label *label, char **fdtfilep)
 	return 0;
 }
 
-/*
- * label_process_fdt() - Process FDT for the label
- *
- * @ctx: PXE context
- * @label: Label to process
- * @kernel_addr: String containing kernel address
- * @fdt_argp: bootm argument to fill in, for FDT
- * Return: 0 if OK, -ENOMEM if out of memory, -ENOENT if FDT file could not be
- *	loaded
- *
- * fdt usage is optional:
- * It handles the following scenarios.
- *
- * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
- * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
- * bootm, and adjust argc appropriately.
- *
- * If retrieve fails and no exact fdt blob is specified in pxe file with
- * "fdt" label, try Scenario 2.
+/**
+ * label_load_fdt() - Load FDT file for the label
  *
- * Scenario 2: If there is an fdt_addr specified, pass it along to
- * bootm, and adjust argc appropriately.
+ * If "fdt" or "fdtdir" is defined in the pxe file, retrieve the FDT blob
+ * from the server. This is only called when fdt_addr_r is set in the
+ * environment.
  *
- * Scenario 3: If there is an fdtcontroladdr specified, pass it along to
- * bootm, and adjust argc appropriately, unless the image type is fitImage.
+ * 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.
  *
- * Scenario 4: fdt blob is not available.
+ * @ctx: PXE context
+ * @label: Label to process
+ * @fdt_argp: Updated to NULL if FDT retrieval fails
+ * Return: 0 if OK, -ENOMEM if out of memory, -ENOENT if FDT file specified
+ *	by "fdt" label could not be loaded
  */
-static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label,
-			     char *kernel_addr, const char **fdt_argp)
+static int label_load_fdt(struct pxe_context *ctx, struct pxe_label *label,
+			  const char **fdt_argp)
 {
 	char *fdtfile;
 	int ret;
 
-	log_debug("label '%s' kernel_addr '%s' label->fdt '%s' fdtdir '%s' "
-		  "kernel_label '%s' fdt_argp '%s'\n",
-		  label->name, kernel_addr, label->fdt, label->fdtdir,
-		  label->kernel_label, *fdt_argp);
-
-	/* For FIT, the label can be identical to kernel one */
-	if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
-		*fdt_argp = kernel_addr;
 	/* if fdt label is defined then get fdt from server */
-	} else if (*fdt_argp) {
+	if (*fdt_argp) {
 		ret = label_get_fdt_path(label, &fdtfile);
 		if (ret)
 			return ret;
@@ -769,11 +750,37 @@  int pxe_load_label(struct pxe_context *ctx, struct pxe_label *label)
 			return -ENOSPC;
 	}
 
+	/*
+	 * FDT handling has several scenarios:
+	 *
+	 * 1. FIT image with embedded FDT: label->fdt matches kernel_label,
+	 *    use the FIT address so bootm extracts the FDT from the FIT
+	 *
+	 * 2. Separate FDT file: if fdt_addr_r is set and "fdt" or "fdtdir"
+	 *    is specified, load the FDT from the server
+	 *
+	 * 3. Fallback to fdt_addr env var if set
+	 *
+	 * 4. Fallback to fdtcontroladdr for non-FIT images
+	 *
+	 * 5. No FDT available
+	 */
 	conf_fdt_str = env_get("fdt_addr_r");
-	ret = label_process_fdt(ctx, label, fit_addr, &conf_fdt_str);
-	if (ret)
-		return ret;
+	log_debug("label '%s' kernel_addr '%s' label->fdt '%s' fdtdir '%s' kernel_label '%s' fdt_argp '%s'\n",
+		  label->name, fit_addr, label->fdt, label->fdtdir,
+		  label->kernel_label, conf_fdt_str);
+
+	/* Scenario 1: FIT with embedded FDT */
+	if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
+		conf_fdt_str = fit_addr;
+	} else {
+		/* Scenario 2: load FDT file if fdt_addr_r is set */
+		ret = label_load_fdt(ctx, label, &conf_fdt_str);
+		if (ret)
+			return ret;
+	}
 
+	/* Scenarios 3 and 4: fallback options */
 	if (!conf_fdt_str)
 		conf_fdt_str = pxe_get_fdt_fallback(label, ctx->kern_addr);
 	if (conf_fdt_str)