summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/2lib/2nvstorage.c24
-rw-r--r--firmware/2lib/include/2nvstorage.h9
-rw-r--r--firmware/2lib/include/2nvstorage_fields.h8
-rw-r--r--firmware/include/vboot_nvstorage.h5
-rw-r--r--firmware/lib/vboot_nvstorage.c35
-rw-r--r--host/lib/crossystem.c12
-rw-r--r--tests/vb2_nvstorage_tests.c4
-rw-r--r--tests/vboot_nvstorage_test.c4
-rw-r--r--utility/crossystem.c4
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"},