diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/2lib/2nvstorage.c | 5 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 31 | ||||
-rw-r--r-- | firmware/lib/vboot_nvstorage.c | 45 |
3 files changed, 81 insertions, 0 deletions
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c index 067f0aef..02904741 100644 --- a/firmware/2lib/2nvstorage.c +++ b/firmware/2lib/2nvstorage.c @@ -15,6 +15,11 @@ * Constants for NV storage. We use this rather than structs and bitfields so * the data format is consistent across platforms and compilers. Total NV * storage size is VB2_NVDATA_SIZE = 16 bytes. + * + * These constants must match the equivalent constants in + * lib/vboot_nvstorage.c. (We currently don't share a common header file + * because we're tring to keep the two libs independent, and we hope to + * deprecate that one.) */ enum vb2_nv_offset { diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index 534fb7e4..0a9a4841 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -45,8 +45,14 @@ typedef enum VbNvParam { /* * Number of times to try booting RW firmware slot B before slot A. * Valid range: 0-15. + * + * Vboot2: Number of times to try the firmware in VBNV_FW_TRY_NEXT. + * + * These refer to the same field, but have different enum values so + * case statement don't complain about duplicates. */ VBNV_TRY_B_COUNT, + VBNV_FW_TRY_COUNT, /* * Request recovery mode on next boot; see VBNB_RECOVERY_* below for * currently defined reason codes. 8-bit value. @@ -85,8 +91,33 @@ typedef enum VbNvParam { VBNV_RECOVERY_SUBCODE, /* Request that NVRAM be backed up at next boot if possible. */ VBNV_BACKUP_NVRAM_REQUEST, + + /* Vboot2: Firmware slot to try next. 0=A, 1=B */ + VBNV_FW_TRY_NEXT, + /* Vboot2: Firmware slot tried this boot (0=A, 1=B) */ + VBNV_FW_TRIED, + /* Vboot2: Result of trying that firmware (see vb2_fw_result) */ + VBNV_FW_RESULT, + + } VbNvParam; +/* Result of trying the firmware in VBNV_FW_TRIED */ +typedef enum VbFwResult { + /* Unknown */ + VBNV_FW_RESULT_UNKNOWN = 0, + + /* Trying a new slot, but haven't reached success/failure */ + VBNV_FW_RESULT_TRYING = 1, + + /* Successfully booted to the OS */ + VBNV_FW_RESULT_SUCCESS = 2, + + /* Known failure */ + VBNV_FW_RESULT_FAILURE = 3, + +} VbFwResult; + /* Recovery reason codes for VBNV_RECOVERY_REQUEST */ /* Recovery not requested. */ #define VBNV_RECOVERY_NOT_REQUESTED 0x00 diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c index 258e5aff..3c5d1e27 100644 --- a/firmware/lib/vboot_nvstorage.c +++ b/firmware/lib/vboot_nvstorage.c @@ -17,6 +17,10 @@ /* * Constants for NV storage. We use this rather than structs and bitfields so * the data format is consistent across platforms and compilers. + * + * These constants must match the equivalent constants in 2lib/2nvstorage.c. + * (We currently don't share a common header file because we're tring to keep + * the two libs independent, and we hope to deprecate this one.) */ #define HEADER_OFFSET 0 #define HEADER_MASK 0xC0 @@ -45,6 +49,11 @@ #define RECOVERY_SUBCODE_OFFSET 6 +#define BOOT2_OFFSET 7 +#define BOOT2_RESULT_MASK 0x03 +#define BOOT2_TRIED 0x04 +#define BOOT2_TRY_NEXT 0x08 + #define KERNEL_FIELD_OFFSET 11 #define CRC_OFFSET 15 @@ -103,6 +112,7 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest) return 0; case VBNV_TRY_B_COUNT: + case VBNV_FW_TRY_COUNT: *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT_MASK; return 0; @@ -159,6 +169,18 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest) *dest = (raw[BOOT_OFFSET] & BOOT_BACKUP_NVRAM ? 1 : 0); return 0; + case VBNV_FW_TRY_NEXT: + *dest = (raw[BOOT2_OFFSET] & BOOT2_TRY_NEXT ? 1 : 0); + return 0; + + case VBNV_FW_TRIED: + *dest = (raw[BOOT2_OFFSET] & BOOT2_TRIED ? 1 : 0); + return 0; + + case VBNV_FW_RESULT: + *dest = raw[BOOT2_OFFSET] & BOOT2_RESULT_MASK; + return 0; + default: return 1; } @@ -196,6 +218,7 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value) break; case VBNV_TRY_B_COUNT: + case VBNV_FW_TRY_COUNT: /* Clip to valid range. */ if (value > BOOT_TRY_B_COUNT_MASK) value = BOOT_TRY_B_COUNT_MASK; @@ -289,6 +312,28 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value) raw[BOOT_OFFSET] &= ~BOOT_BACKUP_NVRAM; break; + case VBNV_FW_TRY_NEXT: + if (value) + raw[BOOT2_OFFSET] |= BOOT2_TRY_NEXT; + else + raw[BOOT2_OFFSET] &= ~BOOT2_TRY_NEXT; + break; + + case VBNV_FW_TRIED: + if (value) + raw[BOOT2_OFFSET] |= BOOT2_TRIED; + else + raw[BOOT2_OFFSET] &= ~BOOT2_TRIED; + break; + + case VBNV_FW_RESULT: + /* Map out of range values to unknown */ + if (value > BOOT2_RESULT_MASK) + value = VBNV_FW_RESULT_UNKNOWN; + + raw[BOOT2_OFFSET] &= ~BOOT2_RESULT_MASK; + raw[BOOT2_OFFSET] |= (uint8_t)value; + break; default: return 1; |