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 <[email protected]> --- common/spl/spl_fit.c | 62 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 16 deletions(-) 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; -- 2.54.0
