summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_nvstorage.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/lib/vboot_nvstorage.c')
-rw-r--r--firmware/lib/vboot_nvstorage.c455
1 files changed, 231 insertions, 224 deletions
diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index 3497392e..618c7124 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -11,9 +11,10 @@
#include "vboot_common.h"
#include "vboot_nvstorage.h"
-/* Constants for NV storage. We use this rather than structs and
- * bitfields so the data format is consistent across platforms and
- * compilers. */
+/*
+ * Constants for NV storage. We use this rather than structs and bitfields so
+ * the data format is consistent across platforms and compilers.
+ */
#define HEADER_OFFSET 0
#define HEADER_MASK 0xC0
#define HEADER_SIGNATURE 0x40
@@ -43,235 +44,241 @@
#define KERNEL_FIELD_OFFSET 11
#define CRC_OFFSET 15
+int VbNvSetup(VbNvContext *context)
+{
+ uint8_t *raw = context->raw;
-int VbNvSetup(VbNvContext* context) {
- uint8_t* raw = context->raw;
-
- /* Nothing has changed yet. */
- context->raw_changed = 0;
- context->regenerate_crc = 0;
-
- /* Check data for consistency */
- if ((HEADER_SIGNATURE != (raw[HEADER_OFFSET] & HEADER_MASK))
- || (Crc8(raw, CRC_OFFSET) != raw[CRC_OFFSET])) {
+ /* Nothing has changed yet. */
+ context->raw_changed = 0;
+ context->regenerate_crc = 0;
- /* Data is inconsistent (bad CRC or header), so reset defaults */
- Memset(raw, 0, VBNV_BLOCK_SIZE);
- raw[HEADER_OFFSET] = (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
- HEADER_KERNEL_SETTINGS_RESET);
+ /* Check data for consistency */
+ if ((HEADER_SIGNATURE != (raw[HEADER_OFFSET] & HEADER_MASK))
+ || (Crc8(raw, CRC_OFFSET) != raw[CRC_OFFSET])) {
+ /* Data is inconsistent (bad CRC or header); reset defaults */
+ Memset(raw, 0, VBNV_BLOCK_SIZE);
+ raw[HEADER_OFFSET] = (HEADER_SIGNATURE |
+ HEADER_FIRMWARE_SETTINGS_RESET |
+ HEADER_KERNEL_SETTINGS_RESET);
- /* Regenerate CRC on exit */
- context->regenerate_crc = 1;
- }
+ /* Regenerate CRC on exit */
+ context->regenerate_crc = 1;
+ }
- return 0;
+ return 0;
}
+int VbNvTeardown(VbNvContext *context)
+{
+ if (context->regenerate_crc) {
+ context->raw[CRC_OFFSET] = Crc8(context->raw, CRC_OFFSET);
+ context->regenerate_crc = 0;
+ context->raw_changed = 1;
+ }
-int VbNvTeardown(VbNvContext* context) {
-
- if (context->regenerate_crc) {
- context->raw[CRC_OFFSET] = Crc8(context->raw, CRC_OFFSET);
- context->regenerate_crc = 0;
- context->raw_changed = 1;
- }
-
- return 0;
+ return 0;
}
-
-int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest) {
- const uint8_t* raw = context->raw;
-
- switch (param) {
- case VBNV_FIRMWARE_SETTINGS_RESET:
- *dest = (raw[HEADER_OFFSET] & HEADER_FIRMWARE_SETTINGS_RESET ? 1 : 0);
- return 0;
-
- case VBNV_KERNEL_SETTINGS_RESET:
- *dest = (raw[HEADER_OFFSET] & HEADER_KERNEL_SETTINGS_RESET ? 1 : 0);
- return 0;
-
- case VBNV_DEBUG_RESET_MODE:
- *dest = (raw[BOOT_OFFSET] & BOOT_DEBUG_RESET_MODE ? 1 : 0);
- return 0;
-
- case VBNV_TRY_B_COUNT:
- *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT_MASK;
- return 0;
-
- case VBNV_RECOVERY_REQUEST:
- *dest = raw[RECOVERY_OFFSET];
- return 0;
-
- case VBNV_RECOVERY_SUBCODE:
- *dest = raw[RECOVERY_SUBCODE_OFFSET];
- return 0;
-
- case VBNV_LOCALIZATION_INDEX:
- *dest = raw[LOCALIZATION_OFFSET];
- 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));
- return 0;
-
- case VBNV_DEV_BOOT_USB:
- *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_USB_MASK ? 1 : 0);
- return 0;
-
- case VBNV_DEV_BOOT_LEGACY:
- *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_LEGACY_MASK ? 1 : 0);
- return 0;
-
- case VBNV_DEV_BOOT_SIGNED_ONLY:
- *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_SIGNED_ONLY_MASK ? 1 : 0);
- return 0;
-
- case VBNV_DISABLE_DEV_REQUEST:
- *dest = (raw[BOOT_OFFSET] & BOOT_DISABLE_DEV_REQUEST ? 1 : 0);
- return 0;
-
- case VBNV_OPROM_NEEDED:
- *dest = (raw[BOOT_OFFSET] & BOOT_OPROM_NEEDED ? 1 : 0);
- return 0;
-
- case VBNV_CLEAR_TPM_OWNER_REQUEST:
- *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_REQUEST ? 1 : 0);
- return 0;
-
- case VBNV_CLEAR_TPM_OWNER_DONE:
- *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_DONE ? 1 : 0);
- return 0;
-
- default:
- return 1;
- }
+int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest)
+{
+ const uint8_t *raw = context->raw;
+
+ switch (param) {
+ case VBNV_FIRMWARE_SETTINGS_RESET:
+ *dest = (raw[HEADER_OFFSET] & HEADER_FIRMWARE_SETTINGS_RESET ?
+ 1 : 0);
+ return 0;
+
+ case VBNV_KERNEL_SETTINGS_RESET:
+ *dest = (raw[HEADER_OFFSET] & HEADER_KERNEL_SETTINGS_RESET ?
+ 1 : 0);
+ return 0;
+
+ case VBNV_DEBUG_RESET_MODE:
+ *dest = (raw[BOOT_OFFSET] & BOOT_DEBUG_RESET_MODE ? 1 : 0);
+ return 0;
+
+ case VBNV_TRY_B_COUNT:
+ *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT_MASK;
+ return 0;
+
+ case VBNV_RECOVERY_REQUEST:
+ *dest = raw[RECOVERY_OFFSET];
+ return 0;
+
+ case VBNV_RECOVERY_SUBCODE:
+ *dest = raw[RECOVERY_SUBCODE_OFFSET];
+ return 0;
+
+ case VBNV_LOCALIZATION_INDEX:
+ *dest = raw[LOCALIZATION_OFFSET];
+ 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));
+ return 0;
+
+ case VBNV_DEV_BOOT_USB:
+ *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_USB_MASK ? 1 : 0);
+ return 0;
+
+ case VBNV_DEV_BOOT_LEGACY:
+ *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_LEGACY_MASK ? 1 : 0);
+ return 0;
+
+ case VBNV_DEV_BOOT_SIGNED_ONLY:
+ *dest = (raw[DEV_FLAGS_OFFSET] & DEV_BOOT_SIGNED_ONLY_MASK ?
+ 1 : 0);
+ return 0;
+
+ case VBNV_DISABLE_DEV_REQUEST:
+ *dest = (raw[BOOT_OFFSET] & BOOT_DISABLE_DEV_REQUEST ? 1 : 0);
+ return 0;
+
+ case VBNV_OPROM_NEEDED:
+ *dest = (raw[BOOT_OFFSET] & BOOT_OPROM_NEEDED ? 1 : 0);
+ return 0;
+
+ case VBNV_CLEAR_TPM_OWNER_REQUEST:
+ *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_REQUEST ?
+ 1 : 0);
+ return 0;
+
+ case VBNV_CLEAR_TPM_OWNER_DONE:
+ *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_DONE ? 1 : 0);
+ return 0;
+
+ default:
+ return 1;
+ }
}
-
-int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value) {
- uint8_t* raw = context->raw;
- uint32_t current;
-
- /* If we're not changing the value, we don't need to regenerate the CRC. */
- if (0 == VbNvGet(context, param, &current) && current == value)
- return 0;
-
- switch (param) {
- case VBNV_FIRMWARE_SETTINGS_RESET:
- if (value)
- raw[HEADER_OFFSET] |= HEADER_FIRMWARE_SETTINGS_RESET;
- else
- raw[HEADER_OFFSET] &= ~HEADER_FIRMWARE_SETTINGS_RESET;
- break;
-
- case VBNV_KERNEL_SETTINGS_RESET:
- if (value)
- raw[HEADER_OFFSET] |= HEADER_KERNEL_SETTINGS_RESET;
- else
- raw[HEADER_OFFSET] &= ~HEADER_KERNEL_SETTINGS_RESET;
- break;
-
- case VBNV_DEBUG_RESET_MODE:
- if (value)
- raw[BOOT_OFFSET] |= BOOT_DEBUG_RESET_MODE;
- else
- raw[BOOT_OFFSET] &= ~BOOT_DEBUG_RESET_MODE;
- break;
-
- case VBNV_TRY_B_COUNT:
- /* Clip to valid range. */
- if (value > BOOT_TRY_B_COUNT_MASK)
- value = BOOT_TRY_B_COUNT_MASK;
-
- raw[BOOT_OFFSET] &= ~BOOT_TRY_B_COUNT_MASK;
- raw[BOOT_OFFSET] |= (uint8_t)value;
- break;
-
- case VBNV_RECOVERY_REQUEST:
- /* Map values outside the valid range to the legacy reason, since we
- * can't determine if we're called from kernel or user mode. */
- if (value > 0xFF)
- value = VBNV_RECOVERY_LEGACY;
- raw[RECOVERY_OFFSET] = (uint8_t)value;
- break;
-
- case VBNV_RECOVERY_SUBCODE:
- raw[RECOVERY_SUBCODE_OFFSET] = (uint8_t)value;
- break;
-
- case VBNV_LOCALIZATION_INDEX:
- /* Map values outside the valid range to the default index. */
- if (value > 0xFF)
- value = 0;
- raw[LOCALIZATION_OFFSET] = (uint8_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);
- break;
-
- case VBNV_DEV_BOOT_USB:
- if (value)
- raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_USB_MASK;
- else
- raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_USB_MASK;
- break;
-
- case VBNV_DEV_BOOT_LEGACY:
- if (value)
- raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_LEGACY_MASK;
- else
- raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_LEGACY_MASK;
- break;
-
- case VBNV_DEV_BOOT_SIGNED_ONLY:
- if (value)
- raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_SIGNED_ONLY_MASK;
- else
- raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_SIGNED_ONLY_MASK;
- break;
-
- case VBNV_DISABLE_DEV_REQUEST:
- if (value)
- raw[BOOT_OFFSET] |= BOOT_DISABLE_DEV_REQUEST;
- else
- raw[BOOT_OFFSET] &= ~BOOT_DISABLE_DEV_REQUEST;
- break;
-
- case VBNV_OPROM_NEEDED:
- if (value)
- raw[BOOT_OFFSET] |= BOOT_OPROM_NEEDED;
- else
- raw[BOOT_OFFSET] &= ~BOOT_OPROM_NEEDED;
- break;
-
- case VBNV_CLEAR_TPM_OWNER_REQUEST:
- if (value)
- raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_REQUEST;
- else
- raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_REQUEST;
- break;
-
- case VBNV_CLEAR_TPM_OWNER_DONE:
- if (value)
- raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_DONE;
- else
- raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_DONE;
- break;
-
- default:
- return 1;
- }
-
- /* Need to regenerate CRC, since the value changed. */
- context->regenerate_crc = 1;
- return 0;
+int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
+{
+ uint8_t *raw = context->raw;
+ uint32_t current;
+
+ /* If not changing the value, don't regenerate the CRC. */
+ if (0 == VbNvGet(context, param, &current) && current == value)
+ return 0;
+
+ switch (param) {
+ case VBNV_FIRMWARE_SETTINGS_RESET:
+ if (value)
+ raw[HEADER_OFFSET] |= HEADER_FIRMWARE_SETTINGS_RESET;
+ else
+ raw[HEADER_OFFSET] &= ~HEADER_FIRMWARE_SETTINGS_RESET;
+ break;
+
+ case VBNV_KERNEL_SETTINGS_RESET:
+ if (value)
+ raw[HEADER_OFFSET] |= HEADER_KERNEL_SETTINGS_RESET;
+ else
+ raw[HEADER_OFFSET] &= ~HEADER_KERNEL_SETTINGS_RESET;
+ break;
+
+ case VBNV_DEBUG_RESET_MODE:
+ if (value)
+ raw[BOOT_OFFSET] |= BOOT_DEBUG_RESET_MODE;
+ else
+ raw[BOOT_OFFSET] &= ~BOOT_DEBUG_RESET_MODE;
+ break;
+
+ case VBNV_TRY_B_COUNT:
+ /* Clip to valid range. */
+ if (value > BOOT_TRY_B_COUNT_MASK)
+ value = BOOT_TRY_B_COUNT_MASK;
+
+ raw[BOOT_OFFSET] &= ~BOOT_TRY_B_COUNT_MASK;
+ raw[BOOT_OFFSET] |= (uint8_t)value;
+ break;
+
+ case VBNV_RECOVERY_REQUEST:
+ /*
+ * Map values outside the valid range to the legacy reason,
+ * since we can't determine if we're called from kernel or user
+ * mode.
+ */
+ if (value > 0xFF)
+ value = VBNV_RECOVERY_LEGACY;
+ raw[RECOVERY_OFFSET] = (uint8_t)value;
+ break;
+
+ case VBNV_RECOVERY_SUBCODE:
+ raw[RECOVERY_SUBCODE_OFFSET] = (uint8_t)value;
+ break;
+
+ case VBNV_LOCALIZATION_INDEX:
+ /* Map values outside the valid range to the default index. */
+ if (value > 0xFF)
+ value = 0;
+ raw[LOCALIZATION_OFFSET] = (uint8_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);
+ break;
+
+ case VBNV_DEV_BOOT_USB:
+ if (value)
+ raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_USB_MASK;
+ else
+ raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_USB_MASK;
+ break;
+
+ case VBNV_DEV_BOOT_LEGACY:
+ if (value)
+ raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_LEGACY_MASK;
+ else
+ raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_LEGACY_MASK;
+ break;
+
+ case VBNV_DEV_BOOT_SIGNED_ONLY:
+ if (value)
+ raw[DEV_FLAGS_OFFSET] |= DEV_BOOT_SIGNED_ONLY_MASK;
+ else
+ raw[DEV_FLAGS_OFFSET] &= ~DEV_BOOT_SIGNED_ONLY_MASK;
+ break;
+
+ case VBNV_DISABLE_DEV_REQUEST:
+ if (value)
+ raw[BOOT_OFFSET] |= BOOT_DISABLE_DEV_REQUEST;
+ else
+ raw[BOOT_OFFSET] &= ~BOOT_DISABLE_DEV_REQUEST;
+ break;
+
+ case VBNV_OPROM_NEEDED:
+ if (value)
+ raw[BOOT_OFFSET] |= BOOT_OPROM_NEEDED;
+ else
+ raw[BOOT_OFFSET] &= ~BOOT_OPROM_NEEDED;
+ break;
+
+ case VBNV_CLEAR_TPM_OWNER_REQUEST:
+ if (value)
+ raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_REQUEST;
+ else
+ raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_REQUEST;
+ break;
+
+ case VBNV_CLEAR_TPM_OWNER_DONE:
+ if (value)
+ raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_DONE;
+ else
+ raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_DONE;
+ break;
+
+ default:
+ return 1;
+ }
+
+ /* Need to regenerate CRC, since the value changed. */
+ context->regenerate_crc = 1;
+ return 0;
}