static int do_vboot_twostop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t selection; int ro_firmware; bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP, "do_vboot_twostop"); /* * Empty keyboard buffer before boot. In case EC did not clear its * buffer between power cycles, this prevents vboot of current power * cycle being affected by keystrokes of previous power cycle. */ while (tstc()) getc(); if (cros_init()) { VBDEBUG("fail to init cros library\n"); goto on_error; } /* * TODO: We should clear screen later if we load graphics optionally. * In normal mode, we don't need to load graphics driver and clear * screen. */ display_clear(); /* * A processor reset jumps to the reset entry point (which is the * read-only firmware), otherwise we have entered U-Boot from a * software jump. * * Note: If a read-only firmware is loaded to memory not because of a * processor reset, this instance of read-only firmware should go to the * readwrite firmware code path. */ ro_firmware = is_processor_reset(); VBDEBUG("Starting %s firmware\n", ro_firmware ? "read-only" : "read-write"); if (ro_firmware) selection = twostop_boot(0); else selection = twostop_readwrite_main_firmware(); VBDEBUG("selection of main firmware: %s\n", str_selection(selection)); if (selection == TWOSTOP_SELECT_COMMAND_LINE) return 0; if (selection == TWOSTOP_SELECT_POWER_OFF) power_off(); assert(selection == TWOSTOP_SELECT_ERROR); on_error: cold_reboot(); return 0; }
static void enable_graphics(void) { if (!CONFIG_OPROM_MATTERS) return; int oprom_loaded = flag_fetch(FLAG_OPROM); // Manipulating vboot's internal data and calling its internal // functions is NOT NICE and will give you athlete's foot and make // you unpopular at parties. Right now it's the only way to ensure // graphics are enabled, though, so it's a necessary evil. if (!oprom_loaded) { printf("Enabling graphics.\n"); VbNvContext context; VbExNvStorageRead(context.raw); VbNvSetup(&context); VbNvSet(&context, VBNV_OPROM_NEEDED, 1); VbNvTeardown(&context); VbExNvStorageWrite(context.raw); printf("Rebooting.\n"); if (cold_reboot()) halt(); } }
/* * support more than 64 bytes command on ep4 */ void usb_reg_out_patch(void) { uint16_t usbfifolen; uint16_t ii; uint32_t ep4_data; static volatile uint32_t *regaddr; static uint16_t cmd_len; static VBUF *buf; BOOLEAN cmd_is_last = FALSE; static BOOLEAN cmd_is_new = TRUE; /* get the size of this transcation */ usbfifolen = USB_BYTE_REG_READ(ZM_EP4_BYTE_COUNT_LOW_OFFSET); if (usbfifolen > USB_EP4_MAX_PKT_SIZE) { A_PRINTF("EP4 FIFO Bug? Buffer is too big: %x\n", usbfifolen); cold_reboot(); } /* check is command is new */ if(cmd_is_new) { buf = usbFifoConf.get_command_buf(); cmd_len = 0; if(!buf) { A_PRINTF("%s: Filed to get new buffer.\n", __func__); goto err; } /* copy free, assignment buffer of the address */ regaddr = (uint32_t *)buf->desc_list->buf_addr; cmd_is_new = FALSE; } /* just in case, suppose should not happen */ if(!buf) goto err; /* if size is smaller, this is the last command! * zero-length supposed should be set through 0x27/bit7->0x19/bit4, not here */ if(usbfifolen < USB_EP4_MAX_PKT_SIZE) cmd_is_last = TRUE; /* accumulate the size */ cmd_len += usbfifolen; if (cmd_len > buf->desc_list->buf_size) { A_PRINTF("%s: Data length on EP4 FIFO is bigger as " "allocated buffer data! Drop it!\n", __func__); goto err; } /* round it to alignment */ if(usbfifolen % 4) usbfifolen = (usbfifolen >> 2) + 1; else
static int do_vboot_load_oprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t selection; struct vboot_flag_details oprom; if (cros_init()) { VBDEBUG("fail to init cros library\n"); return -1; } /* We should be in RO now. */ if (!is_processor_reset()) { VBDEBUG("This command should only be executed in RO.\n"); return -1; } if (!cros_fdtdec_config_has_prop(gd->fdt_blob, "oprom-matters")) { VBDEBUG("FDT doesn't say oprom-matters.\n"); return -1; } if (vboot_flag_fetch(VBOOT_FLAG_OPROM_LOADED, &oprom)) { VBDEBUG("Failed to fetch OPROM gpio\n"); return -1; } vboot_flag_dump(VBOOT_FLAG_OPROM_LOADED, &oprom); if (oprom.value) { VBDEBUG("OPROM already loaded\n"); return 0; } /* * Initialize necessary data and stop at firmware selection. If * OPROM is not loaded and is needed, we should get an error here. */ selection = twostop_boot(1); if (selection == TWOSTOP_SELECT_ERROR) { cold_reboot(); return 0; } else { VBDEBUG("Vboot doesn't say we need OPROM.\n"); return -1; } }
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; }
static void system_abort(void) { /* Wait for 3 seconds to let users see error messages and reboot. */ VbExSleepMs(3000); cold_reboot(); }
/* Append underscore to prevent name conflict with abort() in * cpu/arm_cortexa9/tegra2/board.c (which is empty) */ void _abort(void) { cold_reboot(); }