aboutsummaryrefslogtreecommitdiff
path: root/firmware/2lib
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-09-23 12:20:31 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-04 00:59:48 +0000
commit782300d093a2fbf2ca24e446fb6d65f9f28e56a6 (patch)
tree07e711928061b4b1c19845ca6bb17f4992ae5487 /firmware/2lib
parent80872dbffcb2e0079bfe095d770ccc6c8bd5fd7a (diff)
downloadvboot_reference-782300d093a2fbf2ca24e446fb6d65f9f28e56a6.tar.gz
vboot2: Add previously tried slot and result to NV storage
This gives recovery mode information on two boots back instead of one, which may be handy for debugging. It also allows determining whether a failure of the current boot should try the other slot or go to recovery, using only information stored in NV storage. Added crossystem support for printing the fields, and unit tests. BUG=chrome-os-partner:32585 BRANCH=none TEST=make runtests; VBOOT2=1 make runtests Change-Id: Ia9f4186210d30217b902db7c513ae4ab8851f8f4 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/221230 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'firmware/2lib')
-rw-r--r--firmware/2lib/2misc.c4
-rw-r--r--firmware/2lib/2nvstorage.c28
-rw-r--r--firmware/2lib/include/2nvstorage.h6
3 files changed, 35 insertions, 3 deletions
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 94ad0c3b..bcf5b362 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -316,6 +316,10 @@ int vb2_select_fw_slot(struct vb2_context *ctx)
sd->last_fw_slot = vb2_nv_get(ctx, VB2_NV_FW_TRIED);
sd->last_fw_result = vb2_nv_get(ctx, VB2_NV_FW_RESULT);
+ /* Save to the previous result fields in NV storage */
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, sd->last_fw_slot);
+ vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, sd->last_fw_result);
+
/* Clear result, since we don't know what will happen this boot */
vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c
index 02904741..5c7b9800 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -31,7 +31,7 @@ enum vb2_nv_offset {
VB2_NV_OFFS_TPM = 5,
VB2_NV_OFFS_RECOVERY_SUBCODE = 6,
VB2_NV_OFFS_BOOT2 = 7,
- /* Offsets 7-10 are currently unused */
+ /* Offsets 8-10 are currently unused */
VB2_NV_OFFS_KERNEL = 11, /* 11-14; field is 32 bits */
/* CRC must be last field */
VB2_NV_OFFS_CRC = 15
@@ -50,10 +50,13 @@ enum vb2_nv_offset {
#define VB2_NV_BOOT_DISABLE_DEV 0x40
#define VB2_NV_BOOT_DEBUG_RESET 0x80
-/* Fields in VB2_NV_OFFS_BOOT2 (unused = 0xf0) */
+/* Fields in VB2_NV_OFFS_BOOT2 (unused = 0x80) */
#define VB2_NV_BOOT2_RESULT_MASK 0x03
#define VB2_NV_BOOT2_TRIED 0x04
#define VB2_NV_BOOT2_TRY_NEXT 0x08
+#define VB2_NV_BOOT2_PREV_RESULT_MASK 0x30
+#define VB2_NV_BOOT2_PREV_RESULT_SHIFT 4 /* Number of bits to shift result */
+#define VB2_NV_BOOT2_PREV_TRIED 0x40
/* Fields in VB2_NV_OFFS_DEV (unused = 0xf8) */
#define VB2_NV_DEV_FLAG_USB 0x01
@@ -156,6 +159,13 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param)
case VB2_NV_FW_RESULT:
return p[VB2_NV_OFFS_BOOT2] & VB2_NV_BOOT2_RESULT_MASK;
+ case VB2_NV_FW_PREV_TRIED:
+ return GETBIT(VB2_NV_OFFS_BOOT2, VB2_NV_BOOT2_PREV_TRIED);
+
+ case VB2_NV_FW_PREV_RESULT:
+ return (p[VB2_NV_OFFS_BOOT2] & VB2_NV_BOOT2_PREV_RESULT_MASK)
+ >> VB2_NV_BOOT2_PREV_RESULT_SHIFT;
+
case VB2_NV_RECOVERY_REQUEST:
return p[VB2_NV_OFFS_RECOVERY];
@@ -262,6 +272,20 @@ void vb2_nv_set(struct vb2_context *ctx,
p[VB2_NV_OFFS_BOOT2] |= (uint8_t)value;
break;
+ case VB2_NV_FW_PREV_TRIED:
+ SETBIT(VB2_NV_OFFS_BOOT2, VB2_NV_BOOT2_PREV_TRIED);
+ break;
+
+ case VB2_NV_FW_PREV_RESULT:
+ /* Map out of range values to unknown */
+ if (value > VB2_NV_BOOT2_RESULT_MASK)
+ value = VB2_FW_RESULT_UNKNOWN;
+
+ p[VB2_NV_OFFS_BOOT2] &= ~VB2_NV_BOOT2_PREV_RESULT_MASK;
+ p[VB2_NV_OFFS_BOOT2] |=
+ (uint8_t)(value << VB2_NV_BOOT2_PREV_RESULT_SHIFT);
+ break;
+
case VB2_NV_RECOVERY_REQUEST:
/*
* Map values outside the valid range to the legacy reason,
diff --git a/firmware/2lib/include/2nvstorage.h b/firmware/2lib/include/2nvstorage.h
index 11a77966..3bda9d78 100644
--- a/firmware/2lib/include/2nvstorage.h
+++ b/firmware/2lib/include/2nvstorage.h
@@ -74,9 +74,13 @@ enum vb2_nv_param {
VB2_NV_FW_TRIED,
/* Result of trying that firmware (see vb2_fw_result) */
VB2_NV_FW_RESULT,
+ /* Firmware slot tried previous boot (0=A, 1=B) */
+ VB2_NV_FW_PREV_TRIED,
+ /* Result of trying that firmware (see vb2_fw_result) */
+ VB2_NV_FW_PREV_RESULT,
};
-/* Result of trying the firmware in VB2_NV_FW_TRIED */
+/* Firmware result codes for VB2_NV_FW_RESULT and VB2_NV_FW_PREV_RESULT */
enum vb2_fw_result {
/* Unknown */
VB2_FW_RESULT_UNKNOWN = 0,