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

Reply via email to