summaryrefslogtreecommitdiff
path: root/boot/image-fit.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-10-31 14:43:04 -0400
committerTom Rini <trini@konsulko.com>2022-10-31 14:43:04 -0400
commita90afc6730e6c67ad37f4c98a02891a93b4ff971 (patch)
tree724c085433631e142a56c052d667139cba29b4a6 /boot/image-fit.c
parent6f38d91158e7e4199753b79e0a25c1a65175aba4 (diff)
parent77bec9e3d8bd2dc307447b92a3d5cefd693a62ad (diff)
Merge branch '2022-10-31-vbe-implement-the-full-firmware-flow'
To quote Simon: This series provides an implementation of VBE from TPL through to U-Boot proper, using VBE to load the relevant firmware stages. It buils a single image.bin file containing all the phases: TPL - initial phase, loads VPL using binman symbols VPL - main firmware phase, loads SPL using VBE parameters SPL - loads U-Boot proper using VBE parameters U-Boot - final firmware phase, where OS booting is processed This series does not include the OS-booting phase. That will be the subject of a future series. The implementation is entirely handled by sandbox. It should be possible to enable this on a real board without much effort, but that is also the subject of a future series.
Diffstat (limited to 'boot/image-fit.c')
-rw-r--r--boot/image-fit.c126
1 files changed, 73 insertions, 53 deletions
diff --git a/boot/image-fit.c b/boot/image-fit.c
index 6e503f827dd..3cc556b727f 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -802,6 +802,40 @@ int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
return 0;
}
+/**
+ * fit_image_get_phase() - get the phase for a configuration node
+ * @fit: pointer to the FIT format image header
+ * @offset: configuration-node offset
+ * @phasep: returns the phase
+ *
+ * Finds the phase property in a given configuration node. If the property is
+ * found, its (string) value is translated to the numeric id which is returned
+ * to the caller.
+ *
+ * Returns: 0 on success, -ENOENT if missing, -EINVAL for invalid value
+ */
+int fit_image_get_phase(const void *fit, int offset, enum image_phase_t *phasep)
+{
+ const void *data;
+ int len, ret;
+
+ /* Get phase name from property data */
+ data = fdt_getprop(fit, offset, FIT_PHASE_PROP, &len);
+ if (!data) {
+ fit_get_debug(fit, offset, FIT_PHASE_PROP, len);
+ *phasep = 0;
+ return -ENOENT;
+ }
+
+ /* Translate phase name to id */
+ ret = genimg_get_phase_id(data);
+ if (ret < 0)
+ return ret;
+ *phasep = ret;
+
+ return 0;
+}
+
static int fit_image_get_address(const void *fit, int noffset, char *name,
ulong *load)
{
@@ -1686,49 +1720,6 @@ int fit_check_format(const void *fit, ulong size)
return 0;
}
-/**
- * fit_conf_find_compat
- * @fit: pointer to the FIT format image header
- * @fdt: pointer to the device tree to compare against
- *
- * fit_conf_find_compat() attempts to find the configuration whose fdt is the
- * most compatible with the passed in device tree.
- *
- * Example:
- *
- * / o image-tree
- * |-o images
- * | |-o fdt-1
- * | |-o fdt-2
- * |
- * |-o configurations
- * |-o config-1
- * | |-fdt = fdt-1
- * |
- * |-o config-2
- * |-fdt = fdt-2
- *
- * / o U-Boot fdt
- * |-compatible = "foo,bar", "bim,bam"
- *
- * / o kernel fdt1
- * |-compatible = "foo,bar",
- *
- * / o kernel fdt2
- * |-compatible = "bim,bam", "baz,biz"
- *
- * Configuration 1 would be picked because the first string in U-Boot's
- * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
- * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
- *
- * As an optimization, the compatible property from the FDT's root node can be
- * copied into the configuration node in the FIT image. This is required to
- * match configurations with compressed FDTs.
- *
- * returns:
- * offset to the configuration to use if one was found
- * -1 otherwise
- */
int fit_conf_find_compat(const void *fit, const void *fdt)
{
int ndepth = 0;
@@ -1910,10 +1901,37 @@ int fit_conf_get_prop_node_index(const void *fit, int noffset,
return fit_image_get_node(fit, uname);
}
-int fit_conf_get_prop_node(const void *fit, int noffset,
- const char *prop_name)
+int fit_conf_get_prop_node(const void *fit, int noffset, const char *prop_name,
+ enum image_phase_t sel_phase)
{
- return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
+ int i, count;
+
+ if (sel_phase == IH_PHASE_NONE)
+ return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
+
+ count = fit_conf_get_prop_node_count(fit, noffset, prop_name);
+ if (count < 0)
+ return count;
+
+ /* check each image in the list */
+ for (i = 0; i < count; i++) {
+ enum image_phase_t phase;
+ int ret, node;
+
+ node = fit_conf_get_prop_node_index(fit, noffset, prop_name, i);
+ ret = fit_image_get_phase(fit, node, &phase);
+
+ /* if the image is for any phase, let's use it */
+ if (ret == -ENOENT)
+ return node;
+ else if (ret < 0)
+ return ret;
+
+ if (phase == sel_phase)
+ return node;
+ }
+
+ return -ENOENT;
}
static int fit_get_data_tail(const void *fit, int noffset,
@@ -1949,7 +1967,8 @@ int fit_get_data_conf_prop(const void *fit, const char *prop_name,
{
int noffset = fit_conf_get_node(fit, NULL);
- noffset = fit_conf_get_prop_node(fit, noffset, prop_name);
+ noffset = fit_conf_get_prop_node(fit, noffset, prop_name,
+ IH_PHASE_NONE);
return fit_get_data_tail(fit, noffset, data, size);
}
@@ -1987,7 +2006,8 @@ int fit_get_node_from_config(struct bootm_headers *images,
return -EINVAL;
}
- noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
+ noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name,
+ IH_PHASE_NONE);
if (noffset < 0) {
debug("* %s: no '%s' in config\n", prop_name, prop_name);
return -ENOENT;
@@ -2033,9 +2053,10 @@ static const char *fit_get_image_type_property(int type)
int fit_image_load(struct bootm_headers *images, ulong addr,
const char **fit_unamep, const char **fit_uname_configp,
- int arch, int image_type, int bootstage_id,
+ int arch, int ph_type, int bootstage_id,
enum fit_load_op load_op, ulong *datap, ulong *lenp)
{
+ int image_type = image_ph_type(ph_type);
int cfg_noffset, noffset;
const char *fit_uname;
const char *fit_uname_config;
@@ -2081,8 +2102,7 @@ int fit_image_load(struct bootm_headers *images, ulong addr,
if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
} else {
- cfg_noffset = fit_conf_get_node(fit,
- fit_uname_config);
+ cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
}
if (cfg_noffset < 0) {
puts("Could not find configuration node\n");
@@ -2110,8 +2130,8 @@ int fit_image_load(struct bootm_headers *images, ulong addr,
bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
- noffset = fit_conf_get_prop_node(fit, cfg_noffset,
- prop_name);
+ noffset = fit_conf_get_prop_node(fit, cfg_noffset, prop_name,
+ image_ph_phase(ph_type));
fit_uname = fit_get_name(fit, noffset, NULL);
}
if (noffset < 0) {