summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJean-Jacques Hiblot <jjhiblot@ti.com>2019-10-22 16:39:22 +0200
committerTom Rini <trini@konsulko.com>2020-01-07 11:13:25 -0500
commit152781d4641e0e4c37b3a32f699cf99aeec877c8 (patch)
tree4ad8fb97d0fa333e031ae43ac8d7cfd70da63b74 /common
parent557bc97fe8093506673985d3afcb66d64ee43c2c (diff)
spl: fit: Allow the board to tell if more images must be loaded from FIT
spl_fit_get_image_name() is used to get the names of the images that the SPL must load from the FIT. It relies on the content of a property present in the FIT. The list of images is thus statically defined in the FIT. With this scheme, it quickly becomes hard to manage combinations of more than a handful of images. To address this problem, give the board driver code the opportunity to add to the list of images. The images from the FIT property are loaded first, and then the board_get_fit_loadable() is called to get more image names. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/spl/spl_fit.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 9001731303..ac69d8312e 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <errno.h>
+#include <board.h>
#include <fpga.h>
#include <gzip.h>
#include <image.h>
@@ -32,6 +33,29 @@ __weak ulong board_spl_fit_size_align(ulong size)
return size;
}
+static int find_node_from_desc(const void *fit, int node, const char *str)
+{
+ int child;
+
+ if (node < 0)
+ return -EINVAL;
+
+ /* iterate the FIT nodes and find a matching description */
+ for (child = fdt_first_subnode(fit, node); child >= 0;
+ child = fdt_next_subnode(fit, child)) {
+ int len;
+ const char *desc = fdt_getprop(fit, child, "description", &len);
+
+ if (!desc)
+ continue;
+
+ if (!strcmp(desc, str))
+ return child;
+ }
+
+ return -ENOENT;
+}
+
/**
* 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
@@ -48,10 +72,12 @@ static int spl_fit_get_image_name(const void *fit, int images,
const char *type, int index,
const char **outname)
{
+ struct udevice *board;
const char *name, *str;
__maybe_unused int node;
int conf_node;
int len, i;
+ bool found = true;
conf_node = fit_find_config_node(fit);
if (conf_node < 0) {
@@ -77,12 +103,45 @@ static int spl_fit_get_image_name(const void *fit, int images,
for (i = 0; i < index; i++) {
str = strchr(str, '\0') + 1;
if (!str || (str - name >= len)) {
- debug("no string for index %d\n", index);
- return -E2BIG;
+ found = false;
+ break;
+ }
+ }
+
+ if (!found && !board_get(&board)) {
+ int rc;
+ /*
+ * no string in the property for this index. Check if the board
+ * level code can supply one.
+ */
+ rc = board_get_fit_loadable(board, index - i - 1, type, &str);
+ if (rc && rc != -ENOENT)
+ return rc;
+
+ if (!rc) {
+ /*
+ * The board provided a name for a loadable.
+ * Try to match it against the description properties
+ * first. If no matching node is found, use it as a
+ * node name.
+ */
+ int node;
+ int images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+
+ node = find_node_from_desc(fit, images, str);
+ if (node > 0)
+ str = fdt_get_name(fit, node, NULL);
+
+ found = true;
}
}
- *outname = (char *)str;
+ if (!found) {
+ debug("no string for index %d\n", index);
+ return -E2BIG;
+ }
+
+ *outname = str;
return 0;
}