diff mbox series

[v2,5/6] spl: fit: Record loadables to spl_image->fdt_addr

Message ID 20260902-riscv-full-fit-support-v2-5-493e904a129e@maquefel.me
State Under Review
Delegated to: Tim Ouyang
Headers show
Series RISC-V SPL: fix OpenSBI FULL FIT loading | expand

Commit Message

Nikita Shubin Sept. 2, 2026, 6:31 a.m. UTC
Record loadables to FDT passed to next boot stage.

This is required for spl_invoke_opensbi(), for example, which requires
u-boot/kernel load or entry address to fill opensbi_info.next_addr
entry.

spl_load_simple_fit() does it, make spl_load_fit_image() also capable of
recording loadables into next stage.

One limitation remains: if the FIT image does not contain an FDT blob,
spl_load_fit_image() will not use gd->fdt_blob as a fallback,
unlike spl_load_simple_fit() which does.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 common/spl/spl_fit.c | 62 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 4d4a96d1c4c..a0aa91f0725 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -550,6 +550,17 @@  static int spl_fit_append_fdt(struct spl_image_info *spl_image,
 	return ret;
 }
 
+static int fit_record_loadable(const void *fit, int node, int idx, const char *name,
+			       ulong load_addr, ulong size, ulong entry_point,
+			       void *fdt_blob)
+{
+	return fdt_record_loadable(fdt_blob, idx, name, load_addr, size,
+				   entry_point,
+				   fdt_getprop(fit, node, FIT_TYPE_PROP, NULL),
+				   fdt_getprop(fit, node, FIT_OS_PROP, NULL),
+				   fdt_getprop(fit, node, FIT_ARCH_PROP, NULL));
+}
+
 static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
 				   void *blob, struct spl_image_info *image)
 {
@@ -563,13 +574,9 @@  static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
 
 	node = spl_fit_get_image_node(ctx, "loadables", index);
 
-	ret = fdt_record_loadable(blob, index, name, image->load_addr,
-			image->size, image->entry_point,
-			fdt_getprop(ctx->fit, node, FIT_TYPE_PROP, NULL),
-			fdt_getprop(ctx->fit, node, FIT_OS_PROP, NULL),
-			fdt_getprop(ctx->fit, node, FIT_ARCH_PROP, NULL));
-
-	return ret;
+	return fit_record_loadable(ctx->fit, node, index, name,
+				   image->load_addr, image->size,
+				   image->entry_point, blob);
 }
 
 static int spl_fit_image_is_fpga(const void *fit, int node)
@@ -991,7 +998,7 @@  int spl_load_fit_image(struct spl_image_info *spl_image,
 	const char *uname;
 	ulong fw_data = 0, dt_data = 0, img_data = 0;
 	ulong fw_len = 0, dt_len = 0, img_len = 0;
-	int idx, conf_noffset;
+	int idx, conf_noffset, noffset;
 	int ret;
 
 	images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE);
@@ -1040,6 +1047,13 @@  int spl_load_fit_image(struct spl_image_info *spl_image,
 		}
 	}
 
+	/* Try to make space, so we can inject details on the loadable */
+	if (spl_image->fdt_addr) {
+		ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
+		if (ret < 0)
+			log_debug("Failed to prepare FDT for loadables: %d\n", ret);
+	}
+
 	conf_noffset = fit_conf_get_node((const void *)header,
 					 fit_uname_config);
 	if (conf_noffset < 0)
@@ -1048,17 +1062,33 @@  int spl_load_fit_image(struct spl_image_info *spl_image,
 	for (idx = 0;
 	     uname = fdt_stringlist_get((const void *)header, conf_noffset,
 					FIT_LOADABLE_PROP, idx,
-				NULL), uname;
+					NULL), uname;
 	     idx++) {
 		images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE);
 
-		ret = fit_image_load(&images, virt_to_phys((void *)header),
-				     &uname, &fit_uname_config,
-				     IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
-				     FIT_LOAD_OPTIONAL_NON_ZERO,
-				     &img_data, &img_len);
-		if (ret < 0)
-			return ret;
+		noffset = fit_image_load(&images, virt_to_phys((void *)header),
+					 &uname, &fit_uname_config,
+					 IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
+					 FIT_LOAD_OPTIONAL_NON_ZERO,
+					 &img_data, &img_len);
+		if (noffset < 0)
+			return noffset;
+
+		/* Record our loadables into the FDT */
+		if (spl_image->fdt_addr) {
+			ulong entry_addr = FDT_ERROR;
+
+			fit_image_get_entry((const void *)header, noffset, &entry_addr);
+			log_debug("record_loadable: %s entry addr: 0x%lx\n",
+				  uname, entry_addr);
+
+			ret = fit_record_loadable((const void *)header, noffset,
+						  idx, uname, img_data, img_len,
+						  entry_addr, spl_image->fdt_addr);
+			if (ret < 0)
+				log_debug("record_loadable: couldn't "
+					  "record loadable: %s\n", uname);
+		}
 	}
 	spl_image->flags |= SPL_FIT_FOUND;