diff options
-rw-r--r-- | common/spl/spl_fit.c | 65 |
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; } |