/* Copyright (c) 2011 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 "tpm_bootmode.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_nvstorage.h"

VbError_t VbSelectFirmware(VbCommonParams* cparams,
                           VbSelectFirmwareParams* fparams) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  VbNvContext vnc;
  VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven successful */
  int is_rec = (shared->recovery_reason ? 1 : 0);
  int is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
  uint32_t tpm_status = 0;

  /* Start timer */
  shared->timer_vb_select_firmware_enter = VbExGetTimer();

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

  if (is_rec) {
    /* Recovery is requested; go straight to recovery without checking the
     * RW firmware. */
    VBDEBUG(("VbSelectFirmware() detected recovery request, reason=%d.\n",
             (int)shared->recovery_reason));

    /* Go directly to recovery mode */
    fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY;

  } else {
    /* Chain to LoadFirmware() */
    retval = LoadFirmware(cparams, fparams, &vnc);

    /* Exit if we failed to find an acceptable firmware */
    if (VBERROR_SUCCESS != retval)
      goto VbSelectFirmware_exit;

    /* Translate the selected firmware path */
    if (shared->flags & VBSD_LF_USE_RO_NORMAL) {
      /* Request the read-only normal/dev code path */
      fparams->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
    } else if (0 == shared->firmware_index)
      fparams->selected_firmware = VB_SELECT_FIRMWARE_A;
    else
      fparams->selected_firmware = VB_SELECT_FIRMWARE_B;

    /* Update TPM if necessary */
    if (shared->fw_version_tpm_start < shared->fw_version_tpm) {
      VBPERFSTART("VB_TPMU");
      tpm_status = RollbackFirmwareWrite(shared->fw_version_tpm);
      VBPERFEND("VB_TPMU");
      if (0 != tpm_status) {
        VBDEBUG(("Unable to write firmware version to TPM.\n"));
        VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
        retval = VBERROR_TPM_WRITE_FIRMWARE;
        goto VbSelectFirmware_exit;
      }
    }

    /* Lock firmware versions in TPM */
    VBPERFSTART("VB_TPML");
    tpm_status = RollbackFirmwareLock();
    VBPERFEND("VB_TPML");
    if (0 != tpm_status) {
      VBDEBUG(("Unable to lock firmware version in TPM.\n"));
      VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
      retval = VBERROR_TPM_LOCK_FIRMWARE;
      goto VbSelectFirmware_exit;
    }
  }

  /* At this point, we have a good idea of how we are going to
   * boot. Update the TPM with this state information. */
  tpm_status = SetTPMBootModeState(is_dev, is_rec, shared->fw_keyblock_flags);
  if (0 != tpm_status) {
    VBDEBUG(("Unable to update the TPM with boot mode information.\n"));
    if (!is_rec) {
      VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_ERROR);
      retval = VBERROR_TPM_SET_BOOT_MODE_STATE;
      goto VbSelectFirmware_exit;
    }
  }

  /* Success! */
  retval = VBERROR_SUCCESS;

VbSelectFirmware_exit:

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

  /* Stop timer */
  shared->timer_vb_select_firmware_exit = VbExGetTimer();

  /* Should always have a known error code */
  VbAssert(VBERROR_UNKNOWN != retval);

  return retval;
}
