added reboot return codes to load kernel and firmware

Review URL: http://codereview.chromium.org/2844044
diff --git a/firmware/include/load_firmware_fw.h b/firmware/include/load_firmware_fw.h
index 2332564..6bdcc6a 100644
--- a/firmware/include/load_firmware_fw.h
+++ b/firmware/include/load_firmware_fw.h
@@ -19,6 +19,7 @@
 /* Return codes for LoadFirmware() */
 #define LOAD_FIRMWARE_SUCCESS 0   /* Success */
 #define LOAD_FIRMWARE_RECOVERY 1  /* Reboot to recovery mode */
+#define LOAD_FIRMWARE_REBOOT 2    /* Reboot to same mode as current boot */
 
 /* Boot flags for LoadFirmware().boot_flags */
 #define BOOT_FLAG_DEVELOPER UINT64_C(0x01)  /* Developer switch is on */
diff --git a/firmware/include/load_kernel_fw.h b/firmware/include/load_kernel_fw.h
index 4f86b40..31c3081 100644
--- a/firmware/include/load_kernel_fw.h
+++ b/firmware/include/load_kernel_fw.h
@@ -18,6 +18,8 @@
 #define LOAD_KERNEL_NOT_FOUND 1  /* No kernel found on device */
 #define LOAD_KERNEL_INVALID 2    /* Only invalid kernels found on device */
 #define LOAD_KERNEL_RECOVERY 3   /* Internal error; reboot to recovery mode */
+#define LOAD_KERNEL_REBOOT 4     /* Internal error; reboot to current mode */
+
 
 /* Boot flags for LoadKernel().boot_flags */
 #define BOOT_FLAG_DEVELOPER UINT64_C(0x01)  /* Developer switch is on */
diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h
index fd5f72a..513454b 100644
--- a/firmware/lib/include/rollback_index.h
+++ b/firmware/lib/include/rollback_index.h
@@ -10,6 +10,7 @@
 #define VBOOT_REFERENCE_ROLLBACK_INDEX_H_
 
 #include "sysincludes.h"
+#include "tss_constants.h"
 
 /* Rollback version types. */
 #define FIRMWARE_VERSIONS 0
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c
index 944104b..02fcee5 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -20,6 +20,7 @@
 #define RETURN_ON_FAILURE(tpm_command) do {             \
     uint32_t result;                                    \
     if ((result = (tpm_command)) != TPM_SUCCESS) {      \
+      VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \
       return result;                                    \
     }                                                   \
   } while (0)
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c
index c445a81..b88dc20 100644
--- a/firmware/lib/vboot_firmware.c
+++ b/firmware/lib/vboot_firmware.c
@@ -40,6 +40,7 @@
   uint16_t tpm_fw_version = 0;
   uint64_t lowest_key_version = 0xFFFF;
   uint64_t lowest_fw_version = 0xFFFF;
+  uint32_t status;
   int good_index = -1;
   int index;
 
@@ -60,13 +61,17 @@
   }
 
   /* Initialize the TPM and read rollback indices. */
-  if (0 != RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER)) {
+  status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER);
+  if (0 != status) {
     VBDEBUG(("Unable to setup TPM.\n"));
-    return LOAD_FIRMWARE_RECOVERY;
+    return (status == TPM_E_MUST_REBOOT ?
+            LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
   }
-  if (0 != RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version)) {
+  status = RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version);
+  if (0 != status) {
     VBDEBUG(("Unable to read stored versions.\n"));
-    return LOAD_FIRMWARE_RECOVERY;
+    return (status == TPM_E_MUST_REBOOT ?
+            LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
   }
 
   /* Allocate our internal data */
@@ -219,17 +224,23 @@
     if ((lowest_key_version > tpm_key_version) ||
         (lowest_key_version == tpm_key_version &&
          lowest_fw_version > tpm_fw_version)) {
-      if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version,
-                                     (uint16_t)lowest_fw_version)) {
+
+
+      status = RollbackFirmwareWrite((uint16_t)lowest_key_version,
+                                     (uint16_t)lowest_fw_version);
+      if (0 != status) {
         VBDEBUG(("Unable to write stored versions.\n"));
-        return LOAD_FIRMWARE_RECOVERY;
+        return (status == TPM_E_MUST_REBOOT ?
+                LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
       }
     }
 
     /* Lock firmware versions in TPM */
-    if (0 != RollbackFirmwareLock()) {
+    status = RollbackFirmwareLock();
+    if (0 != status) {
       VBDEBUG(("Unable to lock firmware versions.\n"));
-      return LOAD_FIRMWARE_RECOVERY;
+      return (status == TPM_E_MUST_REBOOT ?
+              LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY);
     }
 
     /* Success */
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 23ea913..ddbceed 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -129,6 +129,7 @@
   int is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
   int is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0);
   int is_normal = (!is_dev && !is_rec);
+  uint32_t status;
 
   /* Clear output params in case we fail */
   params->partition_number = 0;
@@ -147,9 +148,11 @@
   if (is_normal) {
     /* Read current kernel key index from TPM.  Assumes TPM is already
      * initialized. */
-    if (0 != RollbackKernelRead(&tpm_key_version, &tpm_kernel_version)) {
+    status = RollbackKernelRead(&tpm_key_version, &tpm_kernel_version);
+    if (0 != status) {
       VBDEBUG(("Unable to get kernel versions from TPM\n"));
-      return LOAD_KERNEL_RECOVERY;
+      return (status == TPM_E_MUST_REBOOT ?
+              LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
     }
   } else if (is_dev && !is_rec) {
     /* In developer mode, we ignore the kernel subkey, and just use
@@ -367,20 +370,25 @@
       if ((lowest_key_version > tpm_key_version) ||
           (lowest_key_version == tpm_key_version &&
            lowest_kernel_version > tpm_kernel_version)) {
-        if (0 != RollbackKernelWrite((uint16_t)lowest_key_version,
-                                     (uint16_t)lowest_kernel_version)) {
+
+        status = RollbackKernelWrite((uint16_t)lowest_key_version,
+                                     (uint16_t)lowest_kernel_version);
+        if (0 != status) {
           VBDEBUG(("Error writing kernel versions to TPM.\n"));
-          return LOAD_KERNEL_RECOVERY;
+      return (status == TPM_E_MUST_REBOOT ?
+              LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
         }
       }
     }
 
     /* Lock the kernel versions */
-    if (0 != RollbackKernelLock()) {
+    status = RollbackKernelLock();
+    if (0 != status) {
       VBDEBUG(("Error locking kernel versions.\n"));
       /* Don't reboot to recovery mode if we're already there */
       if (!is_rec)
-        return LOAD_KERNEL_RECOVERY;
+        return (status == TPM_E_MUST_REBOOT ?
+                LOAD_KERNEL_REBOOT : LOAD_KERNEL_RECOVERY);
     }
 
     /* Success! */
diff --git a/firmware/version.c b/firmware/version.c
index 2d4dc14..a9136bb 100644
--- a/firmware/version.c
+++ b/firmware/version.c
@@ -1 +1 @@
-char* VbootVersion = "VBOOv=983af25b";
+char* VbootVersion = "VBOOv=ba8bd4f8";