/* 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 kernel selection
 */

#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_audio.h"
#include "vboot_common.h"
#include "vboot_display.h"
#include "vboot_nvstorage.h"


/* Global variables */
static VbNvContext vnc;


#ifdef CHROMEOS_ENVIRONMENT
/* Global variable accessors for unit tests */
VbNvContext* VbApiKernelGetVnc(void) {
  return &vnc;
}
#endif


/* Set recovery request */
static void VbSetRecoveryRequest(uint32_t recovery_request) {
  VBDEBUG(("VbSetRecoveryRequest(%d)\n", (int)recovery_request));
  VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, recovery_request);
}


/* Attempt loading a kernel from the specified type(s) of disks.  If
 * successful, sets p->disk_handle to the disk for the kernel and returns
 * VBERROR_SUCCESS.
 *
 * Returns VBERROR_NO_DISK_FOUND if no disks of the specified type were found.
 *
 * May return other VBERROR_ codes for other failures. */
uint32_t VbTryLoadKernel(VbCommonParams* cparams, LoadKernelParams* p,
                         uint32_t get_info_flags) {
  VbError_t retval = VBERROR_UNKNOWN;
  VbDiskInfo* disk_info = NULL;
  uint32_t disk_count = 0;
  uint32_t i;

  VBDEBUG(("VbTryLoadKernel() start, get_info_flags=0x%x\n",
          (unsigned)get_info_flags));

  p->disk_handle = NULL;

  /* Find disks */
  if (VBERROR_SUCCESS != VbExDiskGetInfo(&disk_info, &disk_count,
                                         get_info_flags))
    disk_count = 0;

  VBDEBUG(("VbTryLoadKernel() found %d disks\n", (int)disk_count));
  if (0 == disk_count) {
    VbSetRecoveryRequest(VBNV_RECOVERY_RW_NO_DISK);
    return VBERROR_NO_DISK_FOUND;
  }

  /* Loop over disks */
  for (i = 0; i < disk_count; i++) {
    VBDEBUG(("VbTryLoadKernel() trying disk %d\n", (int)i));
    /* Sanity-check what we can. FWIW, VbTryLoadKernel() is always called
     * with only a single bit set in get_info_flags
     */
    if (512 != disk_info[i].bytes_per_lba || /* cgptlib restriction */
        32 > disk_info[i].lba_count ||       /* ditto */
        get_info_flags != disk_info[i].flags) { /* got only what we asked for */
      VBDEBUG(("  skipping: bytes_per_lba=%Ld lba_count=%Ld flags=0x%x\n",
               disk_info[i].bytes_per_lba, disk_info[i].lba_count,
               disk_info[i].flags));
      continue;
    }
    p->disk_handle = disk_info[i].handle;
    p->bytes_per_lba = disk_info[i].bytes_per_lba;
    p->ending_lba = disk_info[i].lba_count - 1;
    retval = LoadKernel(p);
    VBDEBUG(("VbTryLoadKernel() LoadKernel() returned %d\n", retval));

    /* Stop now if we found a kernel */
    /* TODO: If recovery requested, should track the farthest we get, instead
     * of just returning the value from the last disk attempted. */
    if (VBERROR_SUCCESS == retval)
      break;
  }

  /* If we didn't succeed, don't return a disk handle */
  if (VBERROR_SUCCESS != retval) {
    VbSetRecoveryRequest(VBNV_RECOVERY_RW_NO_DISK);
    p->disk_handle = NULL;
  }

  VbExDiskFreeInfo(disk_info, p->disk_handle);

  /* Pass through return code.  Recovery reason (if any) has already been set
   * by LoadKernel(). */
  return retval;
}

#define CONFIRM_KEY_DELAY 20  /* Check confirm screen keys every 20ms */

/* Ask the user to confirm something. We should display whatever the question
 * is first, then call this. ESC is always "no", ENTER is always "yes", and
 * we'll specify what SPACE means. We don't return until one of those keys is
 * pressed, or until asked to shut down.
 *
 * Returns: 1=yes, 0=no, -1 = shutdown.
 */
static int VbUserConfirms(VbCommonParams* cparams, int space_means_no) {
  uint32_t key;

  VBDEBUG(("Entering %s(%d)\n", __func__, space_means_no));

  /* Await further instructions */
  while (1) {
    if (VbExIsShutdownRequested())
      return -1;
    key = VbExKeyboardRead();
    switch (key) {
    case '\r':
      VBDEBUG(("%s() - Yes (1)\n", __func__));
      return 1;
      break;
    case ' ':
      VBDEBUG(("%s() - Space (%s)\n", __func__, space_means_no));
      if (space_means_no)
        return 0;
      break;
    case 0x1b:
      VBDEBUG(("%s() - No (0)\n", __func__));
      return 0;
      break;
    default:
      VbCheckDisplayKey(cparams, key, &vnc);
    }
    VbExSleepMs(CONFIRM_KEY_DELAY);
  }
  /* not reached, but compiler will complain without it */
  return -1;
}

/* Handle a normal boot. */
VbError_t VbBootNormal(VbCommonParams* cparams, LoadKernelParams* p) {
  /* Boot from fixed disk only */
  VBDEBUG(("Entering %s()\n", __func__));
  return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}

/* Handle a developer-mode boot */
VbError_t VbBootDeveloper(VbCommonParams* cparams, LoadKernelParams* p) {
  GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  uint32_t allow_usb = 0;
  VbAudioContext* audio = 0;

  VBDEBUG(("Entering %s()\n", __func__));

  /* Check if USB booting is allowed */
  VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
  /* Handle GBB flag override */
  if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
    allow_usb = 1;

  /* Show the dev mode warning screen */
  VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);

  /* Get audio/delay context */
  audio = VbAudioOpen(cparams);

  /* We'll loop until we finish the delay or are interrupted */
  do {
    uint32_t key;

    if (VbExIsShutdownRequested()) {
      VBDEBUG(("VbBootDeveloper() - shutdown is requested!\n"));
      VbAudioClose(audio);
      return VBERROR_SHUTDOWN_REQUESTED;
    }

    key = VbExKeyboardRead();
    switch (key) {
      case 0:
        /* nothing pressed */
        break;
      case '\r':
        /* Enter only disables the virtual dev switch if allowed by GBB */
        if (!(gbb->flags & GBB_FLAG_ENTER_TRIGGERS_TONORM))
          break;
      case ' ':
        /* See if we should disable the virtual dev-mode switch. */
        VBDEBUG(("%s shared->flags=0x%x\n", __func__, shared->flags));
        if (shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
            shared->flags & VBSD_BOOT_DEV_SWITCH_ON) {
          VbAudioClose(audio);    /* Stop the countdown while we go ask... */
          if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) {
            /* TONORM won't work (only for non-shipping devices). */
            VBDEBUG(("%s() - TONORM rejected by GBB_FLAG_FORCE_DEV_SWITCH_ON\n",
                     __func__));
            VbExDisplayDebugInfo("WARNING: TONORM is prohibited by "
                                 "GBB_FLAG_FORCE_DEV_SWITCH_ON.\n\n");
            VbExBeep(120, 400);
            break;
          }
          VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_TO_NORM, 0, &vnc);
          switch (VbUserConfirms(cparams, 0)) { /* Ignore space */
          case 1:
            VBDEBUG(("%s() - leaving dev-mode...\n", __func__));
            VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 1);
            VbDisplayScreen(cparams, VB_SCREEN_TO_NORM_CONFIRMED, 0, &vnc);
            VbExSleepMs(5000);
            return VBERROR_TPM_REBOOT_REQUIRED;
          case -1:
            VBDEBUG(("%s() - shutdown requested\n", __func__));
            return VBERROR_SHUTDOWN_REQUESTED;
          default:                      /* stay in dev-mode */
            VBDEBUG(("%s() - stay in dev-mode\n", __func__));
            VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);
            audio = VbAudioOpen(cparams); /* Start new countdown */
          }
        } else {
          /* No virtual dev-mode switch, so go directly to recovery mode */
          VBDEBUG(("%s() - going to recovery\n", __func__));
          VbSetRecoveryRequest(VBNV_RECOVERY_RW_DEV_SCREEN);
          VbAudioClose(audio);
          return VBERROR_LOAD_KERNEL_RECOVERY;
        }
        break;
      case 0x04:
        /* Ctrl+D = dismiss warning; advance to timeout */
        VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+D; skip delay\n"));
        goto fallout;
        break;
      /* The Ctrl-Enter is special for Lumpy test purpose. */
      case VB_KEY_CTRL_ENTER:
      case 0x15:
        /* Ctrl+U = try USB boot, or beep if failure */
        VBDEBUG(("VbBootDeveloper() - user pressed Ctrl+U; try USB\n"));
        if (!allow_usb) {
          VBDEBUG(("VbBootDeveloper() - USB booting is disabled\n"));
          VbExDisplayDebugInfo("WARNING: Booting from external media (USB/SD) "
                               "has not been enabled. Refer to the "
                               "developer-mode documentation for details.\n");
          VbExBeep(120, 400);
          VbExSleepMs(120);
          VbExBeep(120, 400);
        } else {
          /* Clear the screen to show we get the Ctrl+U key press. */
          VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);
          if (VBERROR_SUCCESS ==
              VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE)) {
            VBDEBUG(("VbBootDeveloper() - booting USB\n"));
            VbAudioClose(audio);
            return VBERROR_SUCCESS;
          } else {
            VBDEBUG(("VbBootDeveloper() - no kernel found on USB\n"));
            VbExBeep(250, 200);
            VbExSleepMs(120);
            /* Clear recovery requests from failed kernel loading, so
             * that powering off at this point doesn't put us into
             * recovery mode. */
            VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);
            /* Show the dev mode warning screen again */
            VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);
          }
        }
        break;
      default:
        VBDEBUG(("VbBootDeveloper() - pressed key %d\n", key));
        VbCheckDisplayKey(cparams, key, &vnc);
        break;
    }

  } while( VbAudioLooping(audio) );

fallout:
  /* Timeout or Ctrl+D; attempt loading from fixed disk */
  VBDEBUG(("VbBootDeveloper() - trying fixed disk\n"));
  VbAudioClose(audio);
  return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}

/* Delay in recovery mode */
#define REC_DISK_DELAY 1000     /* Check disks every 1s */
#define REC_KEY_DELAY  20       /* Check keys every 20ms */

/* Handle a recovery-mode boot */
VbError_t VbBootRecovery(VbCommonParams* cparams, LoadKernelParams* p) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  uint32_t retval;
  uint32_t key;
  int i;

  VBDEBUG(("VbBootRecovery() start\n"));

  /* If the dev-mode switch is off and the user didn't press the recovery
   * button, require removal of all external media. */
  if (!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
      !(shared->flags & VBSD_BOOT_REC_SWITCH_ON)) {
    VbDiskInfo* disk_info = NULL;
    uint32_t disk_count = 0;

    VBDEBUG(("VbBootRecovery() forcing device removal\n"));

    while (1) {
      if (VBERROR_SUCCESS != VbExDiskGetInfo(&disk_info, &disk_count,
                                             VB_DISK_FLAG_REMOVABLE))
        disk_count = 0;
      VbExDiskFreeInfo(disk_info, NULL);

      if (0 == disk_count) {
        VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);
        break;
      }

      VBDEBUG(("VbBootRecovery() waiting for %d disks to be removed\n",
               (int)disk_count));

      VbDisplayScreen(cparams, VB_SCREEN_RECOVERY_REMOVE, 0, &vnc);

      /* Scan keyboard more frequently than media, since x86 platforms
       * don't like to scan USB too rapidly. */
      for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
        VbCheckDisplayKey(cparams, VbExKeyboardRead(), &vnc);
        if (VbExIsShutdownRequested())
          return VBERROR_SHUTDOWN_REQUESTED;
        VbExSleepMs(REC_KEY_DELAY);
      }
    }
  }

  /* Loop and wait for a recovery image */
  while (1) {
    VBDEBUG(("VbBootRecovery() attempting to load kernel2\n"));
    retval = VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE);

    /* Clear recovery requests from failed kernel loading, since we're
     * already in recovery mode.  Do this now, so that powering off after
     * inserting an invalid disk doesn't leave us stuck in recovery mode. */
    VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);

    if (VBERROR_SUCCESS == retval)
      break;                            /* Found a recovery kernel */

    VbDisplayScreen(cparams, VBERROR_NO_DISK_FOUND == retval ?
                    VB_SCREEN_RECOVERY_INSERT : VB_SCREEN_RECOVERY_NO_GOOD,
                    0, &vnc);

    /* Scan keyboard more frequently than media, since x86 platforms don't like
     * to scan USB too rapidly. */
    for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
      key = VbExKeyboardRead();
      /* We might want to enter dev-mode from the Insert screen if... */
      if (key == 0x04 &&                /* user pressed Ctrl-D */
          shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH && /* we can do that */
          !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) && /* not in dev-mode */
          (shared->flags & VBSD_BOOT_REC_SWITCH_ON) && /* user forced rec */
          VbExTrustEC()) {                             /* EC isn't pwned */
        /* Ask the user to confirm entering dev-mode */
        VbDisplayScreen(cparams, VB_SCREEN_RECOVERY_TO_DEV, 0, &vnc);
        switch (VbUserConfirms(cparams, 1)) { /* SPACE means no */
        case 1:
          VBDEBUG(("%s() - Enabling dev-mode...\n", __func__));
          if (TPM_SUCCESS != SetVirtualDevMode(1))
            return VBERROR_TPM_SET_BOOT_MODE_STATE;
          VBDEBUG(("%s() - Reboot so it will take effect\n", __func__));
          return VBERROR_TPM_REBOOT_REQUIRED;
        case -1:
          VBDEBUG(("%s() - Shutdown requested\n", __func__));
          return VBERROR_SHUTDOWN_REQUESTED;
        default:                        /* zero, actually */
          VBDEBUG(("%s() - Not enabling dev-mode\n", __func__));
          /* Jump out of the outer loop to refresh the display quickly. */
          i = 4;
          break;
        }
      } else
        VbCheckDisplayKey(cparams, key, &vnc);
      if (VbExIsShutdownRequested())
        return VBERROR_SHUTDOWN_REQUESTED;
      VbExSleepMs(REC_KEY_DELAY);
    }
  }

  return VBERROR_SUCCESS;
}

/* Wrapper around VbExEcProtectRW() which sets recovery reason on error */
static VbError_t EcProtectRW(void) {
  int rv = VbExEcProtectRW();

  if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
    VBDEBUG(("VbExEcProtectRW() needs reboot\n"));
  } else if (rv != VBERROR_SUCCESS) {
    VBDEBUG(("VbExEcProtectRW() returned %d\n", rv));
    VbSetRecoveryRequest(VBNV_RECOVERY_EC_PROTECT);
  }
  return rv;
}

VbError_t VbEcSoftwareSync(VbCommonParams* cparams) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  int in_rw = 0;
  int rv;
  const uint8_t *ec_hash;
  int ec_hash_size;
  const uint8_t *expected;
  int expected_size;
  uint8_t expected_hash[SHA256_DIGEST_SIZE];
  int need_update;
  int i;

  /* Determine whether the EC is in RO or RW */
  rv = VbExEcRunningRW(&in_rw);

  if (shared->recovery_reason) {
    /* Recovery mode; just verify the EC is in RO code */
    if (rv == VBERROR_SUCCESS && in_rw == 1) {
      /* EC is definitely in RW firmware.  We want it in read-only code, so
       * preserve the current recovery reason and reboot.
       *
       * We don't reboot on error or unknown EC code, because we could end
       * up in an endless reboot loop.  If we had some way to track that we'd
       * already rebooted for this reason, we could retry only once. */
      VBDEBUG(("VbEcSoftwareSync() - want recovery but got EC-RW\n"));
      VbSetRecoveryRequest(shared->recovery_reason);
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
    }

    VBDEBUG(("VbEcSoftwareSync() in recovery; EC-RO\n"));
    return VBERROR_SUCCESS;
  }

  /* Not in recovery.  If we couldn't determine where the EC was,
   * reboot to recovery. */
  if (rv != VBERROR_SUCCESS) {
    VBDEBUG(("VbEcSoftwareSync() - VbEcSoftwareSync() returned %d\n", rv));
    VbSetRecoveryRequest(VBNV_RECOVERY_EC_UNKNOWN_IMAGE);
    return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
  }

  /* If AP is read-only normal, EC should be in its RO code also. */
  if (shared->flags & VBSD_LF_USE_RO_NORMAL) {
    /* If EC is in RW code, request reboot back to RO */
    if (in_rw == 1) {
      VBDEBUG(("VbEcSoftwareSync() - want RO-normal but got EC-RW\n"));
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
    }

    /* Protect the RW flash and stay in EC-RO */
    rv = EcProtectRW();
    if (rv != VBERROR_SUCCESS)
      return rv;

    rv = VbExEcStayInRO();
    if (rv != VBERROR_SUCCESS) {
      VBDEBUG(("VbEcSoftwareSync() - VbExEcStayInRO() returned %d\n", rv));
      VbSetRecoveryRequest(VBNV_RECOVERY_EC_SOFTWARE_SYNC);
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
    }

    VBDEBUG(("VbEcSoftwareSync() in RO-Normal; EC-RO\n"));

    /* If shutdown is requested, just power the AP back off.  This covers the
     * case where the lid is closed when then system boots. */
    if (VbExIsShutdownRequested()) {
      VBDEBUG(("VbEcSoftwareSync() sees shutdown-requested\n"));
      return VBERROR_SHUTDOWN_REQUESTED;
    }

    return VBERROR_SUCCESS;
  }

  /* Get hash of EC-RW */
  rv = VbExEcHashRW(&ec_hash, &ec_hash_size);
  if (rv) {
      VBDEBUG(("VbEcSoftwareSync() - VbExEcHashRW() returned %d\n", rv));
      VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH);
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
  }
  if (ec_hash_size != SHA256_DIGEST_SIZE) {
      VBDEBUG(("VbEcSoftwareSync() - VbExEcHashRW() returned wrong size %d\n",
               ec_hash_size));
      VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH);
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
  }

  VBDEBUG(("EC hash:"));
  for (i = 0; i < SHA256_DIGEST_SIZE; i++)
    VBDEBUG(("%02x", ec_hash[i]));
  VBDEBUG(("\n"));

  /* Get expected EC-RW code. Note that we've already checked for RO_NORMAL,
   * so we know that the BIOS must be RW-A or RW-B, and therefore the EC must
   * match. */
  rv = VbExEcGetExpectedRW(
    shared->firmware_index ? VB_SELECT_FIRMWARE_B : VB_SELECT_FIRMWARE_A,
    &expected, &expected_size);
  if (rv) {
    VBDEBUG(("VbEcSoftwareSync() - VbExEcGetExpectedRW() returned %d\n", rv));
    VbSetRecoveryRequest(VBNV_RECOVERY_EC_EXPECTED_IMAGE);
    return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
  }
  VBDEBUG(("VbEcSoftwareSync() - expected len = %d\n", expected_size));

  /* Hash expected code */
  internal_SHA256(expected, expected_size, expected_hash);
  VBDEBUG(("Expected hash:"));
  for (i = 0; i < SHA256_DIGEST_SIZE; i++)
    VBDEBUG(("%02x", expected_hash[i]));
  VBDEBUG(("\n"));

  need_update = SafeMemcmp(ec_hash, expected_hash, SHA256_DIGEST_SIZE);

  /* TODO: GBB flag to override whether we need update; needed for EC
   * development */

  if (in_rw) {
    if (need_update) {
      /* EC is running the wrong RW code.  Reboot the EC to RO so we can update
       * it on the next boot. */
      VBDEBUG(("VbEcSoftwareSync() - in RW, need to update RW, so reboot\n"));
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
    }

    VBDEBUG(("VbEcSoftwareSync() in EC-RW and it matches\n"));
    return VBERROR_SUCCESS;
  }

  /* Update EC if necessary */
  if (need_update) {
    VBDEBUG(("VbEcSoftwareSync() updating EC-RW...\n"));

    if (shared->flags & VBSD_EC_SLOW_UPDATE) {
      VBDEBUG(("VbEcSoftwareSync() - EC is slow. Show WAIT screen.\n"));
      /* FIXME(crosbug.com/p/12257): Ensure the VGA Option ROM is loaded! */
      VbDisplayScreen(cparams, VB_SCREEN_WAIT, 0, &vnc);
    }

    rv = VbExEcUpdateRW(expected, expected_size);
    if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
      /* Reboot required.  May need to unprotect RW before updating,
       * or may need to reboot after RW updated.  Either way, it's not
       * an error requiring recovery mode. */
      VBDEBUG(("VbEcSoftwareSync() - VbExEcUpdateRW() needs reboot\n"));
      return rv;
    } else if (rv != VBERROR_SUCCESS) {
      VBDEBUG(("VbEcSoftwareSync() - VbExEcUpdateRW() returned %d\n", rv));
      VbSetRecoveryRequest(VBNV_RECOVERY_EC_UPDATE);
      return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
    }

    /*
     * TODO: should ask EC to recompute its hash to verify it's correct
     * before continuing?
     */
  }

  /* Protect EC-RW flash */
  rv = EcProtectRW();
  if (rv != VBERROR_SUCCESS)
    return rv;

  /* Tell EC to jump to its RW code */
  VBDEBUG(("VbEcSoftwareSync() jumping to EC-RW\n"));
  rv = VbExEcJumpToRW();
  if (rv != VBERROR_SUCCESS) {
    VBDEBUG(("VbEcSoftwareSync() - VbExEcJumpToRW() returned %d\n", rv));
    VbSetRecoveryRequest(VBNV_RECOVERY_EC_JUMP_RW);
    return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
  }

  VBDEBUG(("VbEcSoftwareSync() in RW; done\n"));

  /* If shutdown is requested, just power the AP back off.  This covers the
   * case where the lid is closed when then system boots. */
  if (VbExIsShutdownRequested()) {
    VBDEBUG(("VbEcSoftwareSync() sees shutdown-requested\n"));
    return VBERROR_SHUTDOWN_REQUESTED;
  }

  return VBERROR_SUCCESS;
}


VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams,
                                VbSelectAndLoadKernelParams* kparams) {
  VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob;
  VbError_t retval = VBERROR_SUCCESS;
  LoadKernelParams p;
  uint32_t tpm_status = 0;

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

  VbExNvStorageRead(vnc.raw);
  VbNvSetup(&vnc);

  /* Clear output params in case we fail */
  kparams->disk_handle = NULL;
  kparams->partition_number = 0;
  kparams->bootloader_address = 0;
  kparams->bootloader_size = 0;
  Memset(kparams->partition_guid, 0, sizeof(kparams->partition_guid));

  /* Do EC software sync if necessary */
  if (shared->flags & VBSD_EC_SOFTWARE_SYNC) {
    retval = VbEcSoftwareSync(cparams);
    if (retval != VBERROR_SUCCESS)
      goto VbSelectAndLoadKernel_exit;
  }

  /* Read the kernel version from the TPM.  Ignore errors in recovery mode. */
  tpm_status = RollbackKernelRead(&shared->kernel_version_tpm);
  if (0 != tpm_status) {
    VBDEBUG(("Unable to get kernel versions from TPM\n"));
    if (!shared->recovery_reason) {
      VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_ERROR);
      retval = VBERROR_TPM_READ_KERNEL;
      goto VbSelectAndLoadKernel_exit;
    }
  }
  shared->kernel_version_tpm_start = shared->kernel_version_tpm;

  /* Fill in params for calls to LoadKernel() */
  Memset(&p, 0, sizeof(p));
  p.shared_data_blob = cparams->shared_data_blob;
  p.shared_data_size = cparams->shared_data_size;
  p.gbb_data = cparams->gbb_data;
  p.gbb_size = cparams->gbb_size;

  /*
   * this could be set to NULL, in which case the vboot header information
   * about the load address and size will be used
   */
  p.kernel_buffer = kparams->kernel_buffer;
  p.kernel_buffer_size = kparams->kernel_buffer_size;

  p.nv_context = &vnc;
  p.boot_flags = 0;
  if (shared->flags & VBSD_BOOT_DEV_SWITCH_ON)
    p.boot_flags |= BOOT_FLAG_DEVELOPER;

  /* Handle separate normal and developer firmware builds. */
#if defined(VBOOT_FIRMWARE_TYPE_NORMAL)
  /* Normal-type firmware always acts like the dev switch is off. */
  p.boot_flags &= ~BOOT_FLAG_DEVELOPER;
#elif defined(VBOOT_FIRMWARE_TYPE_DEVELOPER)
  /* Developer-type firmware fails if the dev switch is off. */
  if (!(p.boot_flags & BOOT_FLAG_DEVELOPER)) {
    /* Dev firmware should be signed with a key that only verifies
     * when the dev switch is on, so we should never get here. */
    VBDEBUG(("Developer firmware called with dev switch off!\n"));
    VbSetRecoveryRequest(VBNV_RECOVERY_RW_DEV_MISMATCH);
    retval = VBERROR_DEV_FIRMWARE_SWITCH_MISMATCH;
    goto VbSelectAndLoadKernel_exit;
  }
#else
  /* Recovery firmware, or merged normal+developer firmware.  No
   * need to override flags. */
#endif

  /* Select boot path */
  if (shared->recovery_reason) {
    /* Recovery boot */
    p.boot_flags |= BOOT_FLAG_RECOVERY;
    retval = VbBootRecovery(cparams, &p);
    VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);

  } else if (p.boot_flags & BOOT_FLAG_DEVELOPER) {
    /* Developer boot */
    retval = VbBootDeveloper(cparams, &p);
    VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);

  } else {
    /* Normal boot */
    retval = VbBootNormal(cparams, &p);

    if ((1 == shared->firmware_index) && (shared->flags & VBSD_FWB_TRIED)) {
      /* Special cases for when we're trying a new firmware B.  These are
       * needed because firmware updates also usually change the kernel key,
       * which means that the B firmware can only boot a new kernel, and the
       * old firmware in A can only boot the previous kernel. */

      /* Don't advance the TPM if we're trying a new firmware B, because we
       * don't yet know if the new kernel will successfully boot.  We still
       * want to be able to fall back to the previous firmware+kernel if the
       * new firmware+kernel fails. */

      /* If we found only invalid kernels, reboot and try again.  This allows
       * us to fall back to the previous firmware+kernel instead of giving up
       * and going to recovery mode right away.  We'll still go to recovery
       * mode if we run out of tries and the old firmware can't find a kernel
       * it likes. */
      if (VBERROR_INVALID_KERNEL_FOUND == retval) {
        VBDEBUG(("Trying firmware B, and only found invalid kernels.\n"));
        VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);
        goto VbSelectAndLoadKernel_exit;
      }
    } else {
      /* Not trying a new firmware B. */
      /* See if we need to update the TPM. */
      VBDEBUG(("Checking if TPM kernel version needs advancing\n"));
      if (shared->kernel_version_tpm > shared->kernel_version_tpm_start) {
        tpm_status = RollbackKernelWrite(shared->kernel_version_tpm);
        if (0 != tpm_status) {
          VBDEBUG(("Error writing kernel versions to TPM.\n"));
          VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_ERROR);
          retval = VBERROR_TPM_WRITE_KERNEL;
          goto VbSelectAndLoadKernel_exit;
        }
      }
    }
  }

  if (VBERROR_SUCCESS != retval)
    goto VbSelectAndLoadKernel_exit;

  /* Save disk parameters */
  kparams->disk_handle = p.disk_handle;
  kparams->partition_number = (uint32_t)p.partition_number;
  kparams->bootloader_address = p.bootloader_address;
  kparams->bootloader_size = (uint32_t)p.bootloader_size;
  Memcpy(kparams->partition_guid, p.partition_guid,
         sizeof(kparams->partition_guid));

  /* Lock the kernel versions.  Ignore errors in recovery mode. */
  tpm_status = RollbackKernelLock();
  if (0 != tpm_status) {
    VBDEBUG(("Error locking kernel versions.\n"));
    if (!shared->recovery_reason) {
      VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_ERROR);
      retval = VBERROR_TPM_LOCK_KERNEL;
      goto VbSelectAndLoadKernel_exit;
    }
  }

VbSelectAndLoadKernel_exit:

  VbNvTeardown(&vnc);
  if (vnc.raw_changed)
    VbExNvStorageWrite(vnc.raw);

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

  kparams->kernel_buffer = p.kernel_buffer;
  kparams->kernel_buffer_size = p.kernel_buffer_size;

  VBDEBUG(("VbSelectAndLoadKernel() returning %d\n", (int)retval));

  /* Pass through return value from boot path */
  return retval;
}
