diff options
Diffstat (limited to 'firmware/lib/vboot_nvstorage.c')
-rw-r--r-- | firmware/lib/vboot_nvstorage.c | 455 |
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, ¤t) && 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, ¤t) && 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; } |