summaryrefslogtreecommitdiff
path: root/common/spl/spl_fit.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2025-02-03 16:01:44 -0600
committerTom Rini <trini@konsulko.com>2025-02-03 16:01:44 -0600
commit3e69c75e86e1c32c8c0fd6153bcc10aa00fb3616 (patch)
tree676898552baf386cc0c4119ee4bf7edc1ba8aee0 /common/spl/spl_fit.c
parent752321b62530dcbd6e8b5872aff4cf761809d76b (diff)
parentf1eb367d76c9b28053b3adcb6bdeb865c6eda5fd (diff)
Merge patch series "vbe: Series part G"
Simon Glass <sjg@chromium.org> says: This includes the VBE ABrec (A/B/recovery) implementation as well as a number of patches needed to make it work: - marking some code as used by SPL_RELOC - selection of images from a FIT based on the boot phase - removal of unwanted hash code which increases code-size too much - a few Kconfig-related additions for VPL Note: The goal for the next series (part H) is to enable VBE on rk3399-generic, i.e. able to boot on multiple rk3399-based boards with only the TPL phase being different for each board. Link: https://lore.kernel.org/r/20250126184333.4058848-1-sjg@chromium.org/
Diffstat (limited to 'common/spl/spl_fit.c')
-rw-r--r--common/spl/spl_fit.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 64c4349b138..49b4df60560 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -199,7 +199,9 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
* the image gets loaded to the address pointed to by the
* load_addr member in this struct, if load_addr is not 0
*
- * Return: 0 on success or a negative error number.
+ * Return: 0 on success, -EPERM if this image is not the correct phase
+ * (for CONFIG_BOOTMETH_VBE_SIMPLE_FW), or another negative error number on
+ * other error.
*/
static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
const struct spl_fit_info *ctx, int node,
@@ -218,6 +220,25 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
const void *fit = ctx->fit;
bool external_data = false;
+ log_debug("starting\n");
+ if (CONFIG_IS_ENABLED(BOOTMETH_VBE) &&
+ xpl_get_phase(info) != IH_PHASE_NONE) {
+ enum image_phase_t phase;
+ int ret;
+
+ ret = fit_image_get_phase(fit, node, &phase);
+ /* if the image is for any phase, let's use it */
+ if (ret == -ENOENT || phase == xpl_get_phase(info)) {
+ log_debug("found\n");
+ } else if (ret < 0) {
+ log_debug("err=%d\n", ret);
+ return ret;
+ } else {
+ log_debug("- phase mismatch, skipping this image\n");
+ return -EPERM;
+ }
+ }
+
if (IS_ENABLED(CONFIG_SPL_FPGA) ||
(IS_ENABLED(CONFIG_SPL_OS_BOOT) && spl_decompression_enabled())) {
if (fit_image_get_type(fit, node, &type))
@@ -278,10 +299,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
log_debug("reading from offset %x / %lx size %lx to %p: ",
offset, read_offset, size, src_ptr);
- if (info->read(info,
- fit_offset +
- get_aligned_image_offset(info, offset), size,
- src_ptr) < length)
+ if (info->read(info, read_offset, size, src_ptr) < length)
return -EIO;
debug("External data: dst=%p, offset=%x, size=%lx\n",
@@ -456,7 +474,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
image_info.load_addr = (ulong)tmpbuffer;
ret = load_simple_fit(info, offset, ctx, node,
&image_info);
- if (ret < 0)
+ if (ret == -EPERM)
+ continue;
+ else if (ret < 0)
break;
/* Make room in FDT for changes from the overlay */
@@ -495,9 +515,6 @@ static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
const char *name;
int node;
- if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
- return 0;
-
ret = spl_fit_get_image_name(ctx, "loadables", index, &name);
if (ret < 0)
return ret;
@@ -817,7 +834,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
image_info.load_addr = 0;
ret = load_simple_fit(info, offset, &ctx, node, &image_info);
- if (ret < 0) {
+ if (ret < 0 && ret != -EPERM) {
printf("%s: can't load image loadables index %d (ret = %d)\n",
__func__, index, ret);
return ret;
@@ -843,7 +860,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
spl_image->entry_point = image_info.entry_point;
/* Record our loadables into the FDT */
- if (spl_image->fdt_addr)
+ if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) &&
+ xpl_get_fdt_update(info) && spl_image->fdt_addr)
spl_fit_record_loadable(&ctx, index,
spl_image->fdt_addr,
&image_info);