aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/spl/spl_fit.c95
1 files changed, 81 insertions, 14 deletions
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index c496f45..128af1b 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -2,7 +2,7 @@
* Copyright (C) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
@@ -16,22 +16,24 @@
#endif
/**
- * spl_fit_get_image_node(): By using the matching configuration subnode,
+ * spl_fit_get_image_name(): By using the matching configuration subnode,
* retrieve the name of an image, specified by a property name and an index
* into that.
* @fit: Pointer to the FDT blob.
* @images: Offset of the /images subnode.
* @type: Name of the property within the configuration subnode.
* @index: Index into the list of strings in this property.
+ * @outname: Name of the image
*
- * Return: the node offset of the respective image node or a negative
- * error number.
+ * Return: 0 on success, or a negative error number
*/
-static int spl_fit_get_image_node(const void *fit, int images,
- const char *type, int index)
+static int spl_fit_get_image_name(const void *fit, int images,
+ const char *type, int index,
+ char **outname)
{
const char *name, *str;
- int node, conf_node;
+ __maybe_unused int node;
+ int conf_node;
int len, i;
conf_node = fit_find_config_node(fit);
@@ -63,7 +65,35 @@ static int spl_fit_get_image_node(const void *fit, int images,
}
}
+ *outname = (char *)str;
+ return 0;
+}
+
+/**
+ * spl_fit_get_image_node(): By using the matching configuration subnode,
+ * retrieve the name of an image, specified by a property name and an index
+ * into that.
+ * @fit: Pointer to the FDT blob.
+ * @images: Offset of the /images subnode.
+ * @type: Name of the property within the configuration subnode.
+ * @index: Index into the list of strings in this property.
+ *
+ * Return: the node offset of the respective image node or a negative
+ * error number.
+ */
+static int spl_fit_get_image_node(const void *fit, int images,
+ const char *type, int index)
+{
+ char *str;
+ int err;
+ int node;
+
+ err = spl_fit_get_image_name(fit, images, type, index, &str);
+ if (err)
+ return err;
+
debug("%s: '%s'\n", type, str);
+
node = fdt_subnode_offset(fit, images, str);
if (node < 0) {
debug("cannot find image node '%s': %d\n", str, node);
@@ -116,15 +146,15 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
* @info: points to information about the device to load data from
* @sector: the start sector of the FIT image on the device
* @fit: points to the flattened device tree blob describing the FIT
- * image
+ * image
* @base_offset: the beginning of the data area containing the actual
* image data, relative to the beginning of the FIT
* @node: offset of the DT node describing the image to load (relative
- * to @fit)
+ * to @fit)
* @image_info: will be filled with information about the loaded image
- * If the FIT node does not contain a "load" (address) property,
- * the image gets loaded to the address pointed to by the
- * load_addr member in this struct.
+ * If the FIT node does not contain a "load" (address) property,
+ * the image gets loaded to the address pointed to by the
+ * load_addr member in this struct.
*
* Return: 0 on success or a negative error number.
*/
@@ -239,6 +269,35 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
image_info.load_addr = spl_image->load_addr + spl_image->size;
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
&image_info);
+
+ if (ret < 0)
+ return ret;
+
+ /* Make the load-address of the FDT available for the SPL framework */
+ spl_image->fdt_addr = (void *)image_info.load_addr;
+ /* Try to make space, so we can inject details on the loadables */
+ ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
+
+ return ret;
+}
+
+static int spl_fit_record_loadable(const void *fit, int images, int index,
+ void *blob, struct spl_image_info *image)
+{
+ char *name;
+ int node, ret;
+
+ ret = spl_fit_get_image_name(fit, images, "loadables",
+ index, &name);
+ if (ret < 0)
+ return ret;
+
+ node = spl_fit_get_image_node(fit, images, "loadables", index);
+
+ ret = fdt_record_loadable(blob, index, name, image->load_addr,
+ image->size, image->entry_point,
+ fdt_getprop(fit, node, "type", NULL),
+ fdt_getprop(fit, node, "os", NULL));
return ret;
}
@@ -364,9 +423,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
if (!fit_image_get_os(fit, node, &os_type))
debug("Loadable is %s\n", genimg_get_os_name(os_type));
- if (spl_image->os == IH_OS_U_BOOT)
- spl_fit_append_fdt(spl_image, info, sector,
+ if (os_type == IH_OS_U_BOOT) {
+ spl_fit_append_fdt(&image_info, info, sector,
fit, images, base_offset);
+ spl_image->fdt_addr = image_info.fdt_addr;
+ }
/*
* If the "firmware" image did not provide an entry point,
@@ -375,6 +436,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
if (spl_image->entry_point == FDT_ERROR &&
image_info.entry_point != FDT_ERROR)
spl_image->entry_point = image_info.entry_point;
+
+ /* Record our loadables into the FDT */
+ if (spl_image->fdt_addr)
+ spl_fit_record_loadable(fit, images, index,
+ spl_image->fdt_addr,
+ &image_info);
}
/*