diff options
-rw-r--r-- | firmware/2lib/2nvstorage.c | 24 | ||||
-rw-r--r-- | firmware/2lib/include/2nvstorage.h | 9 | ||||
-rw-r--r-- | firmware/2lib/include/2nvstorage_fields.h | 8 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 5 | ||||
-rw-r--r-- | firmware/lib/vboot_nvstorage.c | 35 | ||||
-rw-r--r-- | host/lib/crossystem.c | 12 | ||||
-rw-r--r-- | tests/vb2_nvstorage_tests.c | 4 | ||||
-rw-r--r-- | tests/vboot_nvstorage_test.c | 4 | ||||
-rw-r--r-- | utility/crossystem.c | 4 |
9 files changed, 76 insertions, 29 deletions
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c index b40bbe78..08363362 100644 --- a/firmware/2lib/2nvstorage.c +++ b/firmware/2lib/2nvstorage.c @@ -121,10 +121,7 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param) return p[VB2_NV_OFFS_LOCALIZATION]; case VB2_NV_KERNEL_FIELD: - return (p[VB2_NV_OFFS_KERNEL] - | (p[VB2_NV_OFFS_KERNEL + 1] << 8) - | (p[VB2_NV_OFFS_KERNEL + 2] << 16) - | (p[VB2_NV_OFFS_KERNEL + 3] << 24)); + return p[VB2_NV_OFFS_KERNEL1] | (p[VB2_NV_OFFS_KERNEL2] << 8); case VB2_NV_DEV_BOOT_USB: return GETBIT(VB2_NV_OFFS_DEV, VB2_NV_DEV_FLAG_USB); @@ -175,6 +172,12 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param) case VB2_NV_BATTERY_CUTOFF_REQUEST: return GETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF); + + case VB2_NV_KERNEL_MAX_ROLLFORWARD: + return (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1] + | (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2] << 8) + | (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3] << 16) + | (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4] << 24)); } /* @@ -280,10 +283,8 @@ void vb2_nv_set(struct vb2_context *ctx, break; case VB2_NV_KERNEL_FIELD: - p[VB2_NV_OFFS_KERNEL] = (uint8_t)(value); - p[VB2_NV_OFFS_KERNEL + 1] = (uint8_t)(value >> 8); - p[VB2_NV_OFFS_KERNEL + 2] = (uint8_t)(value >> 16); - p[VB2_NV_OFFS_KERNEL + 3] = (uint8_t)(value >> 24); + p[VB2_NV_OFFS_KERNEL1] = (uint8_t)(value); + p[VB2_NV_OFFS_KERNEL2] = (uint8_t)(value >> 8); break; case VB2_NV_DEV_BOOT_USB: @@ -356,6 +357,13 @@ void vb2_nv_set(struct vb2_context *ctx, case VB2_NV_BATTERY_CUTOFF_REQUEST: SETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF); break; + + case VB2_NV_KERNEL_MAX_ROLLFORWARD: + p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1] = (uint8_t)(value); + p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2] = (uint8_t)(value >> 8); + p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3] = (uint8_t)(value >> 16); + p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4] = (uint8_t)(value >> 24); + break; } /* diff --git a/firmware/2lib/include/2nvstorage.h b/firmware/2lib/include/2nvstorage.h index 66a5fdf1..e3226a58 100644 --- a/firmware/2lib/include/2nvstorage.h +++ b/firmware/2lib/include/2nvstorage.h @@ -42,7 +42,7 @@ enum vb2_nv_param { * 8-bit value. */ VB2_NV_LOCALIZATION_INDEX, - /* Field reserved for kernel/user-mode use; 32-bit value. */ + /* Field reserved for kernel/user-mode use; 16-bit value. */ VB2_NV_KERNEL_FIELD, /* Allow booting from USB in developer mode. 0=no, 1=yes. */ VB2_NV_DEV_BOOT_USB, @@ -94,10 +94,15 @@ enum vb2_nv_param { VB2_NV_FASTBOOT_UNLOCK_IN_FW, /* Boot system when AC detected (0=no, 1=yes). */ VB2_NV_BOOT_ON_AC_DETECT, - /* Try to update the EC-RO image after updating the EC-RW image(0=no, 1=yes). */ + /* + * Try to update the EC-RO image after updating the EC-RW image + * (0=no, 1=yes). + */ VB2_NV_TRY_RO_SYNC, /* Cut off battery and shutdown on next boot. */ VB2_NV_BATTERY_CUTOFF_REQUEST, + /* Maximum kernel version to roll forward to */ + VB2_NV_KERNEL_MAX_ROLLFORWARD, }; /* Set default boot in developer mode */ diff --git a/firmware/2lib/include/2nvstorage_fields.h b/firmware/2lib/include/2nvstorage_fields.h index 018bdeb7..0ed3325a 100644 --- a/firmware/2lib/include/2nvstorage_fields.h +++ b/firmware/2lib/include/2nvstorage_fields.h @@ -29,8 +29,12 @@ enum vb2_nv_offset { VB2_NV_OFFS_RECOVERY_SUBCODE = 6, VB2_NV_OFFS_BOOT2 = 7, VB2_NV_OFFS_MISC = 8, - /* Offsets 9-10 are currently unused */ - VB2_NV_OFFS_KERNEL = 11, /* 11-14; field is 32 bits */ + VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1 = 9, /* bits 0-7 of 32 */ + VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2 = 10, /* bits 8-15 of 32 */ + VB2_NV_OFFS_KERNEL1 = 11, /* bits 0-7 of 16 */ + VB2_NV_OFFS_KERNEL2 = 12, /* bits 8-15 of 16 */ + VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3 = 13, /* bits 16-23 of 32 */ + VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4 = 14, /* bits 24-31 of 32 */ /* CRC must be last field */ VB2_NV_OFFS_CRC = 15 }; diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index 8c7ff9d3..ecb5d007 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -122,8 +122,11 @@ typedef enum VbNvParam { VBNV_TRY_RO_SYNC, /* * Finish mode transition (if requested), perform battery cut-off and - * shutdown in next boot. */ + * shutdown in next boot. + */ VBNV_BATTERY_CUTOFF_REQUEST, + /* Maximum kernel version to roll forward to */ + VBNV_KERNEL_MAX_ROLLFORWARD, } VbNvParam; /* Set default boot in developer mode */ diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c index 3d6a65d7..9dc9dc3d 100644 --- a/firmware/lib/vboot_nvstorage.c +++ b/firmware/lib/vboot_nvstorage.c @@ -66,7 +66,14 @@ #define MISC_TRY_RO_SYNC 0x04 #define MISC_BATTERY_CUTOFF_REQUEST 0x08 -#define KERNEL_FIELD_OFFSET 11 +#define KERNEL_MAX_ROLLFORWARD1_OFFSET 9 /* Low bits */ +#define KERNEL_MAX_ROLLFORWARD2_OFFSET 10 +#define KERNEL_MAX_ROLLFORWARD3_OFFSET 13 +#define KERNEL_MAX_ROLLFORWARD4_OFFSET 14 /* High bits */ + +#define KERNEL_FIELD1_OFFSET 11 /* Low bits */ +#define KERNEL_FIELD2_OFFSET 12 /* Low bits */ + #define CRC_OFFSET 15 int VbNvSetup(VbNvContext *context) @@ -141,10 +148,8 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest) return 0; case VBNV_KERNEL_FIELD: - *dest = (raw[KERNEL_FIELD_OFFSET] - | (raw[KERNEL_FIELD_OFFSET + 1] << 8) - | (raw[KERNEL_FIELD_OFFSET + 2] << 16) - | (raw[KERNEL_FIELD_OFFSET + 3] << 24)); + *dest = (raw[KERNEL_FIELD1_OFFSET] + | (raw[KERNEL_FIELD2_OFFSET] << 8)); return 0; case VBNV_DEV_BOOT_USB: @@ -237,6 +242,13 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest) ? 1 : 0; return 0; + case VBNV_KERNEL_MAX_ROLLFORWARD: + *dest = (raw[KERNEL_MAX_ROLLFORWARD1_OFFSET] + | (raw[KERNEL_MAX_ROLLFORWARD2_OFFSET] << 8) + | (raw[KERNEL_MAX_ROLLFORWARD3_OFFSET] << 16) + | (raw[KERNEL_MAX_ROLLFORWARD4_OFFSET] << 24)); + return 0; + default: return 1; } @@ -306,10 +318,8 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value) break; case VBNV_KERNEL_FIELD: - raw[KERNEL_FIELD_OFFSET] = (uint8_t)(value); - raw[KERNEL_FIELD_OFFSET + 1] = (uint8_t)(value >> 8); - raw[KERNEL_FIELD_OFFSET + 2] = (uint8_t)(value >> 16); - raw[KERNEL_FIELD_OFFSET + 3] = (uint8_t)(value >> 24); + raw[KERNEL_FIELD1_OFFSET] = (uint8_t)(value); + raw[KERNEL_FIELD2_OFFSET] = (uint8_t)(value >> 8); break; case VBNV_DEV_BOOT_USB: @@ -469,6 +479,13 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value) raw[MISC_OFFSET] &= ~MISC_BATTERY_CUTOFF_REQUEST; break; + case VBNV_KERNEL_MAX_ROLLFORWARD: + raw[KERNEL_MAX_ROLLFORWARD1_OFFSET] = (uint8_t)(value); + raw[KERNEL_MAX_ROLLFORWARD2_OFFSET] = (uint8_t)(value >> 8); + raw[KERNEL_MAX_ROLLFORWARD3_OFFSET] = (uint8_t)(value >> 16); + raw[KERNEL_MAX_ROLLFORWARD4_OFFSET] = (uint8_t)(value >> 24); + break; + default: return 1; } diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index 16ba2116..216ff32c 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -72,14 +72,14 @@ static const char *fw_results[] = {"unknown", "trying", "success", "failure"}; static const char *default_boot[] = {"disk", "usb", "legacy"}; /* Masks for kern_nv usage by kernel. */ -#define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F -#define KERN_NV_BLOCK_DEVMODE_FLAG 0x00000010 -#define KERN_NV_TPM_ATTACK_FLAG 0x00000020 +#define KERN_NV_FWUPDATE_TRIES_MASK 0x000F +#define KERN_NV_BLOCK_DEVMODE_FLAG 0x0010 +#define KERN_NV_TPM_ATTACK_FLAG 0x0020 /* If you want to use the remaining currently-unused bits in kern_nv * for something kernel-y, define a new field (the way we did for * fwupdate_tries). Don't just modify kern_nv directly, because that * makes it too easy to accidentally corrupt other sub-fields. */ -#define KERN_NV_CURRENTLY_UNUSED 0xFFFFFFC0 +#define KERN_NV_CURRENTLY_UNUSED 0xFFC0 /* Return true if the FWID starts with the specified string. */ int FwidStartsWith(const char *start) @@ -523,6 +523,8 @@ int VbGetSystemPropertyInt(const char *name) value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE); } else if (!strcasecmp(name,"wipeout_request")) { value = VbGetNvStorage(VBNV_FW_REQ_WIPEOUT); + } else if (!strcasecmp(name,"kernel_max_rollforward")) { + value = VbGetNvStorage(VBNV_KERNEL_MAX_ROLLFORWARD); } /* Other parameters */ else if (!strcasecmp(name,"cros_debug")) { @@ -716,6 +718,8 @@ int VbSetSystemPropertyInt(const char *name, int value) return VbSetNvStorage_WithBackup(VBNV_TRY_RO_SYNC, value); } else if (!strcasecmp(name, "battery_cutoff_request")) { return VbSetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST, value); + } else if (!strcasecmp(name,"kernel_max_rollforward")) { + return VbSetNvStorage(VBNV_KERNEL_MAX_ROLLFORWARD, value); } return -1; diff --git a/tests/vb2_nvstorage_tests.c b/tests/vb2_nvstorage_tests.c index 2056f101..fe31a5ee 100644 --- a/tests/vb2_nvstorage_tests.c +++ b/tests/vb2_nvstorage_tests.c @@ -41,7 +41,7 @@ static struct nv_field nvfields[] = { {VB2_NV_RECOVERY_REQUEST, 0, 0x42, 0xED, "recovery request"}, {VB2_NV_RECOVERY_SUBCODE, 0, 0x56, 0xAC, "recovery subcode"}, {VB2_NV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"}, - {VB2_NV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"}, + {VB2_NV_KERNEL_FIELD, 0, 0x1234, 0xFEDC, "kernel field"}, {VB2_NV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"}, {VB2_NV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"}, {VB2_NV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"}, @@ -56,6 +56,8 @@ static struct nv_field nvfields[] = { {VB2_NV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in fw"}, {VB2_NV_BOOT_ON_AC_DETECT, 0, 1, 0, "boot on ac detect"}, {VB2_NV_TRY_RO_SYNC, 0, 1, 0, "try read only software sync"}, + {VB2_NV_KERNEL_MAX_ROLLFORWARD, 0, 0x12345678, 0xFEDCBA98, + "kernel max rollforward"}, {0, 0, 0, 0, NULL} }; diff --git a/tests/vboot_nvstorage_test.c b/tests/vboot_nvstorage_test.c index 687048e1..c461978f 100644 --- a/tests/vboot_nvstorage_test.c +++ b/tests/vboot_nvstorage_test.c @@ -29,7 +29,7 @@ static VbNvField nvfields[] = { {VBNV_TRY_B_COUNT, 0, 6, 15, "try B count"}, {VBNV_RECOVERY_REQUEST, 0, 0x42, 0xED, "recovery request"}, {VBNV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"}, - {VBNV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"}, + {VBNV_KERNEL_FIELD, 0, 0x1234, 0xFEDC, "kernel field"}, {VBNV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"}, {VBNV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"}, {VBNV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"}, @@ -49,6 +49,8 @@ static VbNvField nvfields[] = { {VBNV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in firmware"}, {VBNV_BOOT_ON_AC_DETECT, 0, 1, 0, "boot on ac detect"}, {VBNV_TRY_RO_SYNC, 0, 1, 0, "try read only software sync"}, + {VBNV_KERNEL_MAX_ROLLFORWARD, 0, 0x12345678, 0xFEDCBA98, + "kernel max rollforward"}, {0, 0, 0, 0, NULL} }; diff --git a/utility/crossystem.c b/utility/crossystem.c index 62e8a921..911d585d 100644 --- a/utility/crossystem.c +++ b/utility/crossystem.c @@ -70,7 +70,9 @@ const Param sys_param_list[] = { {"fw_prev_result", IS_STRING, "Firmware result of previous boot (vboot2)"}, {"hwid", IS_STRING, "Hardware ID"}, {"inside_vm", 0, "Running in a VM?"}, - {"kern_nv", 0, "Non-volatile field for kernel use", "0x%08x"}, + {"kern_nv", 0, "Non-volatile field for kernel use", "0x%04x"}, + {"kernel_max_rollforward", CAN_WRITE, "Max kernel version to store into TPM", + "0x%08x"}, {"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"}, {"loc_idx", CAN_WRITE, "Localization index for firmware screens (writable)"}, {"mainfw_act", IS_STRING, "Active main firmware"}, |