/* 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\n"));

    /* 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_W_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_L_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_U_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;
}
