// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2016 Google, Inc */ #include #include #include #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; int sandbox_find_next_phase(char *fname, int maxlen, bool use_img) { const char *cur_prefix, *next_prefix; int ret; cur_prefix = spl_phase_prefix(spl_phase()); next_prefix = spl_phase_prefix(spl_next_phase()); ret = os_find_u_boot(fname, maxlen, use_img, cur_prefix, next_prefix); if (ret) return log_msg_ret("find", ret); return 0; } /* SPL / TPL / VPL init function */ void board_init_f(ulong flag) { struct sandbox_state *state = state_get_current(); int ret; gd->arch.ram_buf = state->ram_buf; gd->ram_size = state->ram_size; ret = spl_early_init(); if (ret) { debug("spl_early_init() failed: %d\n", ret); hang(); } preloader_console_init(); } void board_boot_order(u32 *spl_boot_list) { spl_boot_list[0] = BOOT_DEVICE_VBE; spl_boot_list[1] = BOOT_DEVICE_BOARD; } static int spl_board_load_file(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { char fname[256]; int ret; ret = sandbox_find_next_phase(fname, sizeof(fname), false); if (ret) { printf("(%s not found, error %d)\n", fname, ret); return ret; } /* * Set up spl_image to boot from jump_to_image_no_args(). Allocate this * outsdide the RAM buffer (i.e. don't use strdup()). */ spl_image->arg = os_malloc(strlen(fname) + 1); 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_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) { struct sandbox_state *state = state_get_current(); if (state->run_unittests) { struct unit_test *tests = UNIT_TEST_ALL_START(); const int count = UNIT_TEST_ALL_COUNT(); int ret; ret = ut_run_list("spl", NULL, tests, count, state->select_unittests, 1, false, NULL); /* continue execution into U-Boot */ } } void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { 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; 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(); } int handoff_arch_save(struct spl_handoff *ho) { ho->arch.magic = TEST_HANDOFF_MAGIC; return 0; }