void __attribute__((noreturn)) load_app(int signed_firmware) { // zero out SRAM memset_reg(_ram_start, _ram_end, 0); jump_to_firmware((const vector_table_t *) FLASH_PTR(FLASH_APP_START), signed_firmware); }
int do_cros_bootstub(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int status = LOAD_FIRMWARE_RECOVERY; firmware_storage_t file; VbNvContext nvcxt; uint64_t boot_flags = 0; uint32_t recovery_request = 0; uint32_t reason = VBNV_RECOVERY_NOT_REQUESTED; uint8_t *firmware_data; if (firmware_storage_init(&file)) { /* FIXME(clchiou) Bring up a sad face as boot has failed */ VBDEBUG(PREFIX "init_firmware_storage fail\n"); while (1); } if (is_firmware_write_protect_gpio_asserted()) WARN_ON_FAILURE(file.lock_device(file.context)); clear_kernel_shared_data(); /* Fill in the RO firmware ID */ KernelSharedDataType *sd = get_kernel_shared_data(); if (firmware_storage_read(&file, (off_t)CONFIG_OFFSET_RO_FRID, (size_t)CONFIG_LENGTH_RO_FRID, sd->frid)) { VBDEBUG(PREFIX "fail to read fwid\n"); reason = VBNV_RECOVERY_US_UNSPECIFIED; goto RECOVERY; } if (read_nvcontext(&nvcxt) || VbNvGet(&nvcxt, VBNV_RECOVERY_REQUEST, &recovery_request)) { VBDEBUG(PREFIX "fail to read nvcontext\n"); reason = VBNV_RECOVERY_US_UNSPECIFIED; goto RECOVERY; } /* clear VBNV_DEBUG_RESET_MODE after read */ if (VbNvSet(&nvcxt, VBNV_DEBUG_RESET_MODE, 0)) { VBDEBUG(PREFIX "fail to write nvcontext\n"); reason = VBNV_RECOVERY_US_UNSPECIFIED; goto RECOVERY; } if (recovery_request != VBNV_RECOVERY_NOT_REQUESTED) { VBDEBUG(PREFIX "boot recovery cookie set\n"); reason = recovery_request; goto RECOVERY; } if (is_recovery_mode_gpio_asserted()) { VBDEBUG(PREFIX "recovery button pressed\n"); reason = VBNV_RECOVERY_RO_MANUAL; goto RECOVERY; } if (is_developer_mode_gpio_asserted()) boot_flags |= BOOT_FLAG_DEVELOPER; status = load_firmware_wrapper(&file, boot_flags, &nvcxt, NULL, &firmware_data); if (nvcxt.raw_changed && write_nvcontext(&nvcxt)) { VBDEBUG(PREFIX "fail to write nvcontext\n"); reason = VBNV_RECOVERY_US_UNSPECIFIED; goto RECOVERY; } if (status == LOAD_FIRMWARE_SUCCESS) { jump_to_firmware((void (*)(void)) firmware_data); } else if (status == LOAD_FIRMWARE_REBOOT) { cold_reboot(); } /* assert(status == LOAD_FIRMWARE_RECOVERY) */ RECOVERY: VBDEBUG(PREFIX "write to recovery cookie\n"); /* * Although writing back VbNvContext cookies may fail, we boot * recovery firmware anyway. In this way, the recovery reason * would be incorrect, but this is much better than not booting * anything. */ if (reason != VBNV_RECOVERY_NOT_REQUESTED && VbNvSet(&nvcxt, VBNV_RECOVERY_REQUEST, reason)) { /* FIXME: bring up a sad face? */ VBDEBUG(PREFIX "error: cannot write recovery reason\n"); } if (VbNvTeardown(&nvcxt)) { /* FIXME: bring up a sad face? */ VBDEBUG(PREFIX "error: cannot tear down cookie\n"); } if (nvcxt.raw_changed && write_nvcontext(&nvcxt)) { /* FIXME: bring up a sad face? */ VBDEBUG(PREFIX "error: cannot write recovery cookie\n"); } VBDEBUG(PREFIX "jump to recovery firmware and never return\n"); firmware_data = malloc(CONFIG_LENGTH_RECOVERY); WARN_ON_FAILURE(load_recovery_firmware(&file, firmware_data)); jump_to_firmware((void (*)(void)) firmware_data); /* never reach here */ return 1; }