[Concept,15/32] boot: pxe: Split filename handling from label_process_fdt()

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

Separate the logic that determines the FDT filename into a new
label_get_fdt_path() function. This handles both the label->fdt case
and the label->fdtdir case where the filename is constructed from
environment variables.

The new function returns an allocated string that the caller must free.

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

 boot/pxe_utils.c | 148 +++++++++++++++++++++++++++--------------------
 1 file changed, 85 insertions(+), 63 deletions(-)
  

Patch

diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 55b738e5c45..0994e7e5196 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -428,6 +428,84 @@  const char *pxe_get_fdt_fallback(struct pxe_label *label, ulong kern_addr)
 	return conf_fdt_str;
 }
 
+/**
+ * label_get_fdt_path() - Get the FDT path for a label
+ *
+ * Determine the FDT filename from label->fdt or by constructing it from
+ * label->fdtdir and environment variables.
+ *
+ * @label: Label to get FDT path for
+ * @fdtfilep: Returns allocated FDT path, or NULL if none. Caller must free.
+ * Return: 0 on success, -ENOMEM on allocation failure
+ */
+static int label_get_fdt_path(struct pxe_label *label, char **fdtfilep)
+{
+	char *fdtfile = NULL;
+
+	if (label->fdt) {
+		if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
+			if (strcmp("-", label->fdt))
+				fdtfile = strdup(label->fdt);
+		} else {
+			fdtfile = strdup(label->fdt);
+		}
+	} else if (label->fdtdir) {
+		char *f1, *f2, *f3, *f4, *slash;
+		int len;
+
+		f1 = env_get("fdtfile");
+		if (f1) {
+			f2 = "";
+			f3 = "";
+			f4 = "";
+		} else {
+			/*
+			 * For complex cases where this code doesn't
+			 * generate the correct filename, the board
+			 * code should set $fdtfile during early boot,
+			 * or the boot scripts should set $fdtfile
+			 * before invoking "pxe" or "sysboot".
+			 */
+			f1 = env_get("soc");
+			f2 = "-";
+			f3 = env_get("board");
+			f4 = ".dtb";
+			if (!f1) {
+				f1 = "";
+				f2 = "";
+			}
+			if (!f3) {
+				f2 = "";
+				f3 = "";
+			}
+		}
+
+		len = strlen(label->fdtdir);
+		if (!len)
+			slash = "./";
+		else if (label->fdtdir[len - 1] != '/')
+			slash = "/";
+		else
+			slash = "";
+
+		len = strlen(label->fdtdir) + strlen(slash) +
+			strlen(f1) + strlen(f2) + strlen(f3) +
+			strlen(f4) + 1;
+		fdtfile = malloc(len);
+		if (!fdtfile) {
+			printf("malloc fail (FDT filename)\n");
+			return -ENOMEM;
+		}
+
+		snprintf(fdtfile, len, "%s%s%s%s%s%s",
+			 label->fdtdir, slash, f1, f2, f3, f4);
+	}
+
+	*fdtfilep = fdtfile;
+
+	return 0;
+}
+
 /*
  * label_process_fdt() - Process FDT for the label
  *
@@ -459,6 +537,9 @@  const char *pxe_get_fdt_fallback(struct pxe_label *label, ulong kern_addr)
 static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label,
 			     char *kernel_addr, 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,
@@ -469,68 +550,9 @@  static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label,
 		*fdt_argp = kernel_addr;
 	/* if fdt label is defined then get fdt from server */
 	} else if (*fdt_argp) {
-		char *fdtfile = NULL;
-		char *fdtfilefree = NULL;
-
-		if (label->fdt) {
-			if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
-				if (strcmp("-", label->fdt))
-					fdtfile = label->fdt;
-			} else {
-				fdtfile = label->fdt;
-			}
-		} else if (label->fdtdir) {
-			char *f1, *f2, *f3, *f4, *slash;
-			int len;
-
-			f1 = env_get("fdtfile");
-			if (f1) {
-				f2 = "";
-				f3 = "";
-				f4 = "";
-			} else {
-				/*
-				 * For complex cases where this code doesn't
-				 * generate the correct filename, the board
-				 * code should set $fdtfile during early boot,
-				 * or the boot scripts should set $fdtfile
-				 * before invoking "pxe" or "sysboot".
-				 */
-				f1 = env_get("soc");
-				f2 = "-";
-				f3 = env_get("board");
-				f4 = ".dtb";
-				if (!f1) {
-					f1 = "";
-					f2 = "";
-				}
-				if (!f3) {
-					f2 = "";
-					f3 = "";
-				}
-			}
-
-			len = strlen(label->fdtdir);
-			if (!len)
-				slash = "./";
-			else if (label->fdtdir[len - 1] != '/')
-				slash = "/";
-			else
-				slash = "";
-
-			len = strlen(label->fdtdir) + strlen(slash) +
-				strlen(f1) + strlen(f2) + strlen(f3) +
-				strlen(f4) + 1;
-			fdtfilefree = malloc(len);
-			if (!fdtfilefree) {
-				printf("malloc fail (FDT filename)\n");
-				return -ENOMEM;
-			}
-
-			snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
-				 label->fdtdir, slash, f1, f2, f3, f4);
-			fdtfile = fdtfilefree;
-		}
+		ret = label_get_fdt_path(label, &fdtfile);
+		if (ret)
+			return ret;
 
 		if (fdtfile) {
 			ulong addr;
@@ -541,7 +563,7 @@  static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label,
 					(enum bootflow_img_t)IH_TYPE_FLATDT,
 					&addr, NULL);
 
-			free(fdtfilefree);
+			free(fdtfile);
 			if (err < 0) {
 				*fdt_argp = NULL;