diff options
author | Simon Glass <sjg@chromium.org> | 2022-10-20 18:23:08 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-10-31 11:03:18 -0400 |
commit | f1459c365795a72fff94e249b0eb5cb61ead340e (patch) | |
tree | 5f375e56f815ea70a09786183b049399dbae97d7 | |
parent | 5a61bf17d893c269b9cec383ebdd7c1d5348a853 (diff) | |
download | u-boot-f1459c365795a72fff94e249b0eb5cb61ead340e.tar.gz u-boot-f1459c365795a72fff94e249b0eb5cb61ead340e.tar.bz2 u-boot-f1459c365795a72fff94e249b0eb5cb61ead340e.zip |
sandbox: Support obtaining the next phase from an image
At present sandbox runs the next phase from discrete executables, so for
example u-boot-tpl runs u-boot-vpl to get to the next phase.
In some cases the phases are all built into a single firmware image, as is
done for real boards. Add support for this to sandbox.
Make it higher priority so that it takes precedence over the existing
method.
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | arch/sandbox/cpu/spl.c | 52 | ||||
-rw-r--r-- | include/spl.h | 3 |
2 files changed, 54 insertions, 1 deletions
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 2678370481..75f4601fdf 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -78,7 +78,48 @@ static int spl_board_load_file(struct spl_image_info *spl_image, return 0; } -SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_file); +SPL_LOAD_IMAGE_METHOD("sandbox_file", 9, BOOT_DEVICE_BOARD, + spl_board_load_file); + +static int load_from_image(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev) +{ + struct sandbox_state *state = state_get_current(); + enum u_boot_phase next_phase; + const char *fname; + ulong pos, size; + int full_size; + void *buf; + int ret; + + if (!IS_ENABLED(CONFIG_SANDBOX_VPL)) + return -ENOENT; + + next_phase = spl_next_phase(); + pos = spl_get_image_pos(); + size = spl_get_image_size(); + if (pos == BINMAN_SYM_MISSING || size == BINMAN_SYM_MISSING) { + log_debug("No image found\n"); + return -ENOENT; + } + log_info("Reading from pos %lx size %lx\n", pos, size); + + /* + * Set up spl_image to boot from jump_to_image_no_args(). Allocate this + * outside the RAM buffer (i.e. don't use strdup()). + */ + fname = state->prog_fname ? state->prog_fname : state->argv[0]; + ret = os_read_file(fname, &buf, &full_size); + if (ret) + return log_msg_ret("rd", -ENOMEM); + spl_image->flags = SPL_SANDBOXF_ARG_IS_BUF; + spl_image->arg = buf; + spl_image->offset = pos; + spl_image->size = size; + + return 0; +} +SPL_LOAD_IMAGE_METHOD("sandbox_image", 7, BOOT_DEVICE_BOARD, load_from_image); void spl_board_init(void) { @@ -109,6 +150,15 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) } break; } + case SPL_SANDBOXF_ARG_IS_BUF: { + int ret; + + ret = os_jump_to_image(spl_image->arg + spl_image->offset, + spl_image->size); + if (ret) + log_err("Failed to load image\n"); + break; + } default: log_err("Invalid flags\n"); break; diff --git a/include/spl.h b/include/spl.h index c2c1f969a5..7286f4b5ca 100644 --- a/include/spl.h +++ b/include/spl.h @@ -232,9 +232,12 @@ static inline const char *spl_phase_prefix(enum u_boot_phase phase) * enum spl_sandbox_flags - flags for sandbox's use of spl_image_info->flags * * @SPL_SANDBOXF_ARG_IS_FNAME: arg is the filename to jump to (default) + * @SPL_SANDBOXF_ARG_IS_BUF: arg is the containing image to jump to, @offset is + * the start offset within the image, @size is the size of the image */ enum spl_sandbox_flags { SPL_SANDBOXF_ARG_IS_FNAME = 0, + SPL_SANDBOXF_ARG_IS_BUF, }; struct spl_image_info { |