diff options
Diffstat (limited to 'arch/sandbox/cpu')
-rw-r--r-- | arch/sandbox/cpu/spl.c | 84 | ||||
-rw-r--r-- | arch/sandbox/cpu/start.c | 30 | ||||
-rw-r--r-- | arch/sandbox/cpu/state.c | 2 |
3 files changed, 103 insertions, 13 deletions
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 1d49a9bd10..0faf34cc00 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -49,13 +49,14 @@ void board_init_f(ulong flag) preloader_console_init(); } -u32 spl_boot_device(void) +void board_boot_order(u32 *spl_boot_list) { - return BOOT_DEVICE_BOARD; + spl_boot_list[0] = BOOT_DEVICE_VBE; + spl_boot_list[1] = BOOT_DEVICE_BOARD; } -static int spl_board_load_image(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev) +static int spl_board_load_file(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev) { char fname[256]; int ret; @@ -74,10 +75,52 @@ static int spl_board_load_image(struct spl_image_info *spl_image, if (!spl_image->arg) return log_msg_ret("exec", -ENOMEM); strcpy(spl_image->arg, fname); + spl_image->flags = SPL_SANDBOXF_ARG_IS_FNAME; return 0; } -SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_image); +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) { @@ -89,20 +132,37 @@ void spl_board_init(void) int ret; ret = ut_run_list("spl", NULL, tests, count, - state->select_unittests, 1); + state->select_unittests, 1, false); /* continue execution into U-Boot */ } } void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { - const char *fname = spl_image->arg; + switch (spl_image->flags) { + case SPL_SANDBOXF_ARG_IS_FNAME: { + const char *fname = spl_image->arg; + + if (fname) { + os_fd_restore(); + os_spl_to_uboot(fname); + } else { + log_err("No filename provided for U-Boot\n"); + } + break; + } + case SPL_SANDBOXF_ARG_IS_BUF: { + int ret; - if (fname) { - os_fd_restore(); - os_spl_to_uboot(fname); - } else { - printf("No filename provided for U-Boot\n"); + 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; } hang(); } diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 642be164a3..622df41f54 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -244,6 +244,36 @@ static int sandbox_cmdline_cb_jump(struct sandbox_state *state, } SANDBOX_CMDLINE_OPT_SHORT(jump, 'j', 1, "Jumped from previous U-Boot"); +static int sandbox_cmdline_cb_program(struct sandbox_state *state, + const char *arg) +{ + /* + * Record the program name to use when jumping to future phases. This + * is the original executable which holds all the phases. We need to + * use this instead of argv[0] since each phase is started by + * extracting a particular binary from the full program, then running + * it. Therefore in that binary, argv[0] contains only the + * current-phase executable. + * + * For example, sandbox TPL may be started using image file: + * + * ./image.bin + * + * but then TPL needs to run VPL, which it does by extracting the VPL + * image from the image.bin file. + * + * ./temp-vpl + * + * When VPL runs it needs access to the original image.bin so it can + * extract the next phase (SPL). This works if we use '-f image.bin' + * when starting the original image.bin file. + */ + state->prog_fname = arg; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(program, 'p', 1, "U-Boot program name"); + static int sandbox_cmdline_cb_memory(struct sandbox_state *state, const char *arg) { diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index fcc4a337e5..a681e472ab 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -470,7 +470,7 @@ int state_uninit(void) int err; if (state->write_ram_buf || state->write_state) - log_info("Writing sandbox state\n"); + log_debug("Writing sandbox state\n"); state = &main_state; /* Finish the bloblist, so that it is correct before writing memory */ |