Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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;
}