/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * High-level firmware wrapper API - entry points for init, firmware selection
 */

#include "sysincludes.h"

#include "region.h"
#include "gbb_access.h"
#include "gbb_header.h"
#include "load_firmware_fw.h"
#include "rollback_index.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_nvstorage.h"

VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	GoogleBinaryBlockHeader gbb;
	VbNvContext vnc;
	VbError_t retval = VBERROR_SUCCESS;
	uint32_t recovery = VBNV_RECOVERY_NOT_REQUESTED;
	int is_s3_resume = 0;
	uint32_t s3_debug_boot = 0;
	uint32_t require_official_os = 0;
	uint32_t tpm_version = 0;
	uint32_t tpm_status = 0;
	int has_virt_dev_switch = 0;
	int is_hw_dev = 0;
	int is_virt_dev = 0;
	uint32_t disable_dev_request = 0;
	uint32_t clear_tpm_owner_request = 0;
	int is_dev = 0;

	/* Initialize output flags */
	iparams->out_flags = 0;

	retval = VbGbbReadHeader_static(cparams, &gbb);
	if (retval)
		return retval;

	VBDEBUG(("VbInit() input flags 0x%x gbb flags 0x%x\n", iparams->flags,
		gbb.flags));

	/* Set up NV storage */
	VbExNvStorageRead(vnc.raw);
	VbNvSetup(&vnc);

	/* Initialize shared data structure */
	if (0 != VbSharedDataInit(shared, cparams->shared_data_size)) {
		VBDEBUG(("Shared data init error\n"));
		return VBERROR_INIT_SHARED_DATA;
	}

	shared->timer_vb_init_enter = VbExGetTimer();

	/* Copy some boot switch flags */
	/* TODO: in next refactor, just save in/out flags in VbSharedData */
	shared->flags = 0;
	if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED)
		shared->flags |= VBSD_BOOT_REC_SWITCH_ON;
	if (iparams->flags & VB_INIT_FLAG_WP_ENABLED)
		shared->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED;
	if (iparams->flags & VB_INIT_FLAG_SW_WP_ENABLED)
		shared->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED;
	if (iparams->flags & VB_INIT_FLAG_S3_RESUME)
		shared->flags |= VBSD_BOOT_S3_RESUME;
	if (iparams->flags & VB_INIT_FLAG_RO_NORMAL_SUPPORT)
		shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
	if (iparams->flags & VB_INIT_FLAG_EC_SOFTWARE_SYNC)
		shared->flags |= VBSD_EC_SOFTWARE_SYNC;
	if (iparams->flags & VB_INIT_FLAG_EC_SLOW_UPDATE)
		shared->flags |= VBSD_EC_SLOW_UPDATE;

	is_s3_resume = (iparams->flags & VB_INIT_FLAG_S3_RESUME ? 1 : 0);

	/* Check if the OS is requesting a debug S3 reset */
	VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &s3_debug_boot);
	if (s3_debug_boot) {
		if (is_s3_resume) {
			VBDEBUG(("VbInit() requesting S3 debug boot\n"));
			iparams->out_flags |= VB_INIT_OUT_S3_DEBUG_BOOT;
			is_s3_resume = 0;  /* Proceed as if normal boot */
		}

		/*
		 * Clear the request even if this is a normal boot, since we
		 * don't want the NEXT S3 resume to be a debug reset unless the
		 * OS asserts the request again.
		 */
		VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 0);
	}

	/*
	 * If this isn't a S3 resume, read the current recovery request, then
	 * clear it so we don't get stuck in recovery mode.
	 */
	if (!is_s3_resume) {
		VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &recovery);
		VBDEBUG(("VbInit sees recovery request = %d\n", recovery));
		if (VBNV_RECOVERY_NOT_REQUESTED != recovery)
			VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
				VBNV_RECOVERY_NOT_REQUESTED);
	}

	/*
	 * If the previous boot failed in the firmware somewhere outside of
	 * verified boot, and recovery is not requested for our own reasons,
	 * request recovery mode.  This gives the calling firmware a way to
	 * request recovery if it finds something terribly wrong.
	 */
	if (VBNV_RECOVERY_NOT_REQUESTED == recovery &&
	    iparams->flags & VB_INIT_FLAG_PREVIOUS_BOOT_FAIL) {
		recovery = VBNV_RECOVERY_RO_FIRMWARE;
	}

	/*
	 * If recovery button is pressed, override recovery reason.  Note that
	 * we do this in the S3 resume path also.
	 */
	if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED)
		recovery = VBNV_RECOVERY_RO_MANUAL;

	/*
	 * Copy current recovery reason to shared data. If we fail later on, it
	 * won't matter, since we'll just reboot.
	 */
	shared->recovery_reason = (uint8_t)recovery;
	VBDEBUG(("VbInit now sets shared->recovery_reason = %d\n", recovery));

	/*
	 * If this is a S3 resume, resume the TPM.
	 *
	 * FIXME: I think U-Boot won't ever ask us to do this. Can we remove
	 * it?
	 */
	if (is_s3_resume) {
		if (TPM_SUCCESS != RollbackS3Resume()) {
			/*
			 * If we can't resume, just do a full reboot.  No need
			 * to go to recovery mode here, since if the TPM is
			 * really broken we'll catch it on the next boot.
			 */
			retval = VBERROR_TPM_S3_RESUME;
		}
	} else {
		/* Should we pay attention to the TPM's virtual dev-switch? */
		if (iparams->flags & VB_INIT_FLAG_VIRTUAL_DEV_SWITCH) {
			shared->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
			has_virt_dev_switch = 1;
		}

		/*
		 * We always believe the HW dev-switch, since there's one
		 * attached to servo which may be active even on systems
		 * without a physical switch. The EC may also implement a fake
		 * dev-switch for testing.
		 */
		if (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON)
			is_hw_dev = 1;

		/* We may be asked to clear the virtual dev-switch at boot. */
		VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &disable_dev_request);

		/* Allow GBB flag to override dev switch */
		if (gbb.flags & GBB_FLAG_FORCE_DEV_SWITCH_ON)
			is_hw_dev = 1;

		/* Have we been explicitly asked to clear the TPM owner? */
		VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST,
			&clear_tpm_owner_request);

		/*
		 * Initialize the TPM. If the developer mode state has changed
		 * since the last boot, we need to clear TPM ownership. If the
		 * TPM space is initialized by this call, the virtual
		 * dev-switch will be disabled by default)
		 */
		VBDEBUG(("TPM: Call RollbackFirmwareSetup(r%d, d%d)\n",
			recovery, is_hw_dev));
		tpm_status = RollbackFirmwareSetup(is_hw_dev,
						   disable_dev_request,
						   clear_tpm_owner_request,
						   /* two outputs on success */
						   &is_virt_dev, &tpm_version);

		if (0 != tpm_status) {
			VBDEBUG(("Unable to setup TPM and read "
				 "firmware version (0x%x)\n", tpm_status));

			if (TPM_E_MUST_REBOOT == tpm_status) {
				/*
				 * TPM wants to reboot into the same mode we're
				 * in now
				 */
				VBDEBUG(("TPM requires a reboot.\n"));
				if (!recovery) {
					/*
					 * Not recovery mode.  Just reboot (not
					 * into recovery).
					 */
					retval = VBERROR_TPM_REBOOT_REQUIRED;
					goto VbInit_exit;
				} else if (VBNV_RECOVERY_RO_TPM_REBOOT !=
					   shared->recovery_reason) {
					/*
					 * In recovery mode now, and we haven't
					 * requested a TPM reboot yet, so
					 * request one.
					 */
					VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
						VBNV_RECOVERY_RO_TPM_REBOOT);
					retval = VBERROR_TPM_REBOOT_REQUIRED;
					goto VbInit_exit;
				}
			}

			if (!recovery) {
				VbNvSet(&vnc, VBNV_RECOVERY_REQUEST,
					VBNV_RECOVERY_RO_TPM_S_ERROR);
				VbNvSet(&vnc, VBNV_RECOVERY_SUBCODE,
					tpm_status);
				retval = VBERROR_TPM_FIRMWARE_SETUP;
				goto VbInit_exit;
			}
		}

		/* TPM setup succeeded, or we're in recovery mode and ignoring
		 * errors. What did we learn? */
		shared->fw_version_tpm_start = tpm_version;
		shared->fw_version_tpm = tpm_version;
		if (is_hw_dev || (has_virt_dev_switch && is_virt_dev)) {
			is_dev = 1;
			shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
		}
		if (disable_dev_request && !is_virt_dev)
			VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 0);
		if (clear_tpm_owner_request) {
			VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 0);
			VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, 1);
		}
	}

	/* Allow BIOS to load arbitrary option ROMs? */
	if (gbb.flags & GBB_FLAG_LOAD_OPTION_ROMS)
		iparams->out_flags |= VB_INIT_OUT_ENABLE_OPROM;

	/* Factory may need to boot custom OSes when the dev-switch is on */
	if (is_dev && (gbb.flags & GBB_FLAG_ENABLE_ALTERNATE_OS))
		iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS;

	/* Set output flags */
	if (VBNV_RECOVERY_NOT_REQUESTED != recovery) {
		/* Requesting recovery mode */
		iparams->out_flags |= (VB_INIT_OUT_ENABLE_RECOVERY |
				       VB_INIT_OUT_CLEAR_RAM |
				       VB_INIT_OUT_ENABLE_DISPLAY |
				       VB_INIT_OUT_ENABLE_USB_STORAGE);
	} else if (is_dev) {
		/* Developer switch is on, so need to support dev mode */
		iparams->out_flags |= (VB_INIT_OUT_ENABLE_DEVELOPER |
				       VB_INIT_OUT_CLEAR_RAM |
				       VB_INIT_OUT_ENABLE_DISPLAY |
				       VB_INIT_OUT_ENABLE_USB_STORAGE);
		/* ... which may or may not include custom OSes */
		VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &require_official_os);
		if (!require_official_os)
			iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS;

		/*
		 * Dev-mode needs the VGA option ROM to be loaded so it can
		 * display the scary boot screen. If we don't have it, we need
		 * to request it and reboot so it can be loaded.
		 */
		if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) &&
		    !(iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) {
			VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
			retval = VBERROR_VGA_OPROM_MISMATCH;
			VBDEBUG(("VbInit() needs oprom, doesn't have it\n"));
		}

	} else {
		/*
		 * Normal mode, so disable dev_boot_* flags.  This ensures they
		 * will be initially disabled if the user later transitions
		 * back into developer mode.
		 */
		VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 0);
		VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0);
		VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0);

		/*
		 * If we don't need the VGA option ROM but got it anyway, stop
		 * asking for it and reboot in case there's some vulnerability
		 * in using it.
		 */
		if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) &&
		    (iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) {
			VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0);
			retval = VBERROR_VGA_OPROM_MISMATCH;
			VBDEBUG(("VbInit() has oprom, doesn't need it\n"));
		}
	}

 VbInit_exit:

	/* Tear down NV storage */
	VbNvTeardown(&vnc);
	if (vnc.raw_changed)
		VbExNvStorageWrite(vnc.raw);

	VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags));

	shared->timer_vb_init_exit = VbExGetTimer();

	VBDEBUG(("VbInit() returning 0x%x\n", retval));

	return retval;
}
