@@ -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;
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(-)