/* Copyright (c) 2012 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 "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 = (GoogleBinaryBlockHeader*)cparams->gbb_data;
  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;

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

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

  /* 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_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 this is a 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;

    /* Check if we've been explicitly asked to clear the TPM owner */
    VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, &clear_tpm_owner_request);

    VBPERFSTART("VB_TPMI");
    /* 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) */
    tpm_status = RollbackFirmwareSetup(recovery, is_hw_dev, disable_dev_request,
                                       clear_tpm_owner_request,
                                       /* two outputs on success */
                                       &is_virt_dev, &tpm_version);
    VBPERFEND("VB_TPMI");
    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. 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;

  /* The factory may need to boot custom OSes whenever 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_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;
}
