diff options
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 6 | ||||
-rw-r--r-- | firmware/lib/vboot_firmware.c | 11 |
2 files changed, 17 insertions, 0 deletions
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index c2a722f9..6018349a 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -80,6 +80,12 @@ typedef enum VbNvParam { #define VBNV_RECOVERY_RO_TEST_LFS 0x08 /* Test error from LoadFirmware() */ #define VBNV_RECOVERY_RO_TEST_LF 0x09 +/* RW firmware failed signature check (neither RW firmware slot was valid). + * Recovery reason is VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + the check value + * for the slot which came closest to validating; see VBSD_LF_CHECK_* in + * vboot_struct.h. */ +#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN 0x10 +#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX 0x1F /* Unspecified/unknown error in read-only firmware */ #define VBNV_RECOVERY_RO_UNSPECIFIED 0x3F /* User manually requested recovery by pressing a key at developer diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index 4be4cb29..9a39c052 100644 --- a/firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c @@ -368,9 +368,20 @@ int LoadFirmware(LoadFirmwareParams* params) { shared->firmware_index = (uint8_t)params->firmware_index; retval = LOAD_FIRMWARE_SUCCESS; } else { + UINT8 a = shared->check_fw_a_result; + UINT8 b = shared->check_fw_b_result; + UINT8 best_check; + /* No good firmware, so go to recovery mode. */ VBDEBUG(("Alas, no good firmware.\n")); recovery = VBNV_RECOVERY_RO_INVALID_RW; + + /* If the best check result fits in the range of recovery reasons, provide + * more detail on how far we got in validation. */ + best_check = (a > b ? a : b) + VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN; + if (best_check >= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN && + best_check <= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX) + recovery = best_check; } LoadFirmwareExit: |