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;
}
Exemplo n.º 2
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;
	}
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
static void system_abort(void)
{
	/* Wait for 3 seconds to let users see error messages and reboot. */
	VbExSleepMs(3000);
	cold_reboot();
}
Exemplo n.º 7
0
/* Append underscore to prevent name conflict with abort() in
 * cpu/arm_cortexa9/tegra2/board.c (which is empty)
 */
void _abort(void)
{
	cold_reboot();
}