mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-14 00:26:30 +00:00
There are several places where the same recovery_reason was used to report slightly different points of failure. Let's create some new codes instead. Remember that recovery mode is handled by RO firmware, so if an updated RW firmware uses one of the new error codes, pressing TAB at the recovery screen will say "We have no idea what this means". That's not a bug. This CL deprecates the original codes, so the fact that the RO firmware doesn't recognize it just means it's a new code reported by a new RW BIOS. BUG=chromium-os:36562 TEST=manual BRANCH=parrot Run make && make runtests It should pass. You can test some of the error cases on actual hardware by using crossystem recovery_reason=86 reboot and pressing TAB at the recovery screen. For that example you should see the message recovery_reason: 0x56 TPM lock error in rewritable firmare Change-Id: I123c781e6c6f6fe0284c4fd49f5f5a855eece7df Reviewed-on: https://gerrit.chromium.org/gerrit/38652 Commit-Ready: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
222 lines
9.1 KiB
C
222 lines
9.1 KiB
C
/* Copyright (c) 2012 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.
|
|
*/
|
|
|
|
/* Non-volatile storage routines for verified boot.
|
|
*/
|
|
|
|
#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
|
|
#define VBOOT_REFERENCE_NVSTORAGE_H_
|
|
|
|
#define VBNV_BLOCK_SIZE 16 /* Size of NV storage block in bytes */
|
|
|
|
typedef struct VbNvContext {
|
|
/* Raw NV data. Caller must fill this before calling VbNvSetup(). */
|
|
uint8_t raw[VBNV_BLOCK_SIZE];
|
|
/* Flag indicating whether raw data has changed. Set by VbNvTeardown() if
|
|
* the raw data has changed and needs to be stored to the underlying
|
|
* non-volatile data store. */
|
|
int raw_changed;
|
|
|
|
/* Internal data for NV storage routines. Caller should not touch
|
|
* these fields. */
|
|
int regenerate_crc;
|
|
|
|
} VbNvContext;
|
|
|
|
|
|
/* Parameter type for VbNvGet(), VbNvSet(). */
|
|
typedef enum VbNvParam {
|
|
/* Parameter values have been reset to defaults (flag for firmware).
|
|
* 0=clear; 1=set. */
|
|
VBNV_FIRMWARE_SETTINGS_RESET = 0,
|
|
/* Parameter values have been reset to defaults (flag for kernel).
|
|
* 0=clear; 1=set. */
|
|
VBNV_KERNEL_SETTINGS_RESET,
|
|
/* Request debug reset on next S3->S0 transition. 0=clear; 1=set. */
|
|
VBNV_DEBUG_RESET_MODE,
|
|
/* Number of times to try booting RW firmware slot B before slot A.
|
|
* Valid range: 0-15. */
|
|
VBNV_TRY_B_COUNT,
|
|
/* Request recovery mode on next boot; see VBNB_RECOVERY_* below for
|
|
* currently defined reason codes. 8-bit value. */
|
|
VBNV_RECOVERY_REQUEST,
|
|
/* Localization index for screen bitmaps displayed by firmware.
|
|
* 8-bit value. */
|
|
VBNV_LOCALIZATION_INDEX,
|
|
/* Field reserved for kernel/user-mode use; 32-bit value. */
|
|
VBNV_KERNEL_FIELD,
|
|
/* Allow booting from USB in developer mode. 0=no, 1=yes. */
|
|
VBNV_DEV_BOOT_USB,
|
|
/* Allow booting of legacy OSes in developer mode. 0=no, 1=yes. */
|
|
VBNV_DEV_BOOT_LEGACY,
|
|
/* Only boot Google-signed images in developer mode. 0=no, 1=yes. */
|
|
VBNV_DEV_BOOT_SIGNED_ONLY,
|
|
/* Set by userspace to request that RO firmware disable dev-mode on the next
|
|
* boot. This is likely only possible if the dev-switch is virtual. */
|
|
VBNV_DISABLE_DEV_REQUEST,
|
|
/* Set and cleared by vboot to request that the video Option ROM be loaded at
|
|
* boot time, so that BIOS screens can be displayed. 0=no, 1=yes. */
|
|
VBNV_OPROM_NEEDED,
|
|
/* Request that the firmware clear the TPM owner on the next boot. */
|
|
VBNV_CLEAR_TPM_OWNER_REQUEST,
|
|
/* Flag that TPM owner was cleared on request. */
|
|
VBNV_CLEAR_TPM_OWNER_DONE,
|
|
} VbNvParam;
|
|
|
|
|
|
/* Recovery reason codes for VBNV_RECOVERY_REQUEST */
|
|
/* Recovery not requested. */
|
|
#define VBNV_RECOVERY_NOT_REQUESTED 0x00
|
|
/* Recovery requested from legacy utility. (Prior to the NV storage
|
|
* spec, recovery mode was a single bitfield; this value is reserved
|
|
* so that scripts which wrote 1 to the recovery field are
|
|
* distinguishable from scripts whch use the recovery reasons listed
|
|
* here. */
|
|
#define VBNV_RECOVERY_LEGACY 0x01
|
|
/* User manually requested recovery via recovery button */
|
|
#define VBNV_RECOVERY_RO_MANUAL 0x02
|
|
/* RW firmware failed signature check (neither RW firmware slot was valid) */
|
|
#define VBNV_RECOVERY_RO_INVALID_RW 0x03
|
|
/* S3 resume failed */
|
|
#define VBNV_RECOVERY_RO_S3_RESUME 0x04
|
|
/* TPM error in read-only firmware (deprecated) */
|
|
#define VBNV_RECOVERY_DEP_RO_TPM_ERROR 0x05
|
|
/* Shared data error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_SHARED_DATA 0x06
|
|
/* Test error from S3Resume() */
|
|
#define VBNV_RECOVERY_RO_TEST_S3 0x07
|
|
/* Test error from LoadFirmwareSetup() */
|
|
#define VBNV_RECOVERY_RO_TEST_LFS 0x08
|
|
/* Test error from LoadFirmware() */
|
|
#define VBNV_RECOVERY_RO_TEST_LF 0x09
|
|
/* RW firmware failed signature check (neither RW firmware slot was valid).
|
|
* Recovery reason is VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + the check value
|
|
* for the slot which came closest to validating; see VBSD_LF_CHECK_* in
|
|
* vboot_struct.h. */
|
|
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN 0x10
|
|
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX 0x1F
|
|
/* Firmware boot failure outside of verified boot (RAM init, missing SSD,
|
|
* etc.). */
|
|
#define VBNV_RECOVERY_RO_FIRMWARE 0x20
|
|
/* Recovery mode TPM initialization requires a system reboot. The system was
|
|
* already in recovery mode for some other reason when this happened. */
|
|
#define VBNV_RECOVERY_RO_TPM_REBOOT 0x21
|
|
/* EC software sync - other error */
|
|
#define VBNV_RECOVERY_EC_SOFTWARE_SYNC 0x22
|
|
/* EC software sync - unable to determine active EC image */
|
|
#define VBNV_RECOVERY_EC_UNKNOWN_IMAGE 0x23
|
|
/* EC software sync - error obtaining EC image hash (deprecated) */
|
|
#define VBNV_RECOVERY_DEP_EC_HASH 0x24
|
|
/* EC software sync - error obtaining expected EC image */
|
|
#define VBNV_RECOVERY_EC_EXPECTED_IMAGE 0x25
|
|
/* EC software sync - error updating EC */
|
|
#define VBNV_RECOVERY_EC_UPDATE 0x26
|
|
/* EC software sync - unable to jump to EC-RW */
|
|
#define VBNV_RECOVERY_EC_JUMP_RW 0x27
|
|
/* EC software sync - unable to protect / unprotect EC-RW */
|
|
#define VBNV_RECOVERY_EC_PROTECT 0x28
|
|
/* Unspecified/unknown error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_UNSPECIFIED 0x3F
|
|
/* User manually requested recovery by pressing a key at developer
|
|
* warning screen */
|
|
#define VBNV_RECOVERY_RW_DEV_SCREEN 0x41
|
|
/* No OS kernel detected */
|
|
#define VBNV_RECOVERY_RW_NO_OS 0x42
|
|
/* OS kernel failed signature check */
|
|
#define VBNV_RECOVERY_RW_INVALID_OS 0x43
|
|
/* TPM error in rewritable firmware (deprecated) */
|
|
#define VBNV_RECOVERY_DEP_RW_TPM_ERROR 0x44
|
|
/* RW firmware in dev mode, but dev switch is off */
|
|
#define VBNV_RECOVERY_RW_DEV_MISMATCH 0x45
|
|
/* Shared data error in rewritable firmware */
|
|
#define VBNV_RECOVERY_RW_SHARED_DATA 0x46
|
|
/* Test error from LoadKernel() */
|
|
#define VBNV_RECOVERY_RW_TEST_LK 0x47
|
|
/* No bootable disk found (deprecated)*/
|
|
#define VBNV_RECOVERY_DEP_RW_NO_DISK 0x48
|
|
/* Rebooting did not correct TPM_E_FAIL or TPM_E_FAILEDSELFTEST */
|
|
#define VBNV_RECOVERY_TPM_E_FAIL 0x49
|
|
/* TPM setup error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_TPM_S_ERROR 0x50
|
|
/* TPM write error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_TPM_W_ERROR 0x51
|
|
/* TPM lock error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_TPM_L_ERROR 0x52
|
|
/* TPM update error in read-only firmware */
|
|
#define VBNV_RECOVERY_RO_TPM_U_ERROR 0x53
|
|
/* TPM read error in rewritable firmware */
|
|
#define VBNV_RECOVERY_RW_TPM_R_ERROR 0x54
|
|
/* TPM write error in rewritable firmware */
|
|
#define VBNV_RECOVERY_RW_TPM_W_ERROR 0x55
|
|
/* TPM lock error in rewritable firmware */
|
|
#define VBNV_RECOVERY_RW_TPM_L_ERROR 0x56
|
|
/* EC software sync unable to get EC image hash */
|
|
#define VBNV_RECOVERY_EC_HASH_FAILED 0x57
|
|
/* EC software sync invalid image hash size */
|
|
#define VBNV_RECOVERY_EC_HASH_SIZE 0x58
|
|
/* Unspecified error while trying to load kernel */
|
|
#define VBNV_RECOVERY_LK_UNSPECIFIED 0x59
|
|
/* No bootable storage device in system */
|
|
#define VBNV_RECOVERY_RW_NO_DISK 0x5A
|
|
/* No bootable kernel found on disk */
|
|
#define VBNV_RECOVERY_RW_NO_KERNEL 0x5B
|
|
/* Unspecified/unknown error in rewritable firmware */
|
|
#define VBNV_RECOVERY_RW_UNSPECIFIED 0x7F
|
|
/* DM-verity error */
|
|
#define VBNV_RECOVERY_KE_DM_VERITY 0x81
|
|
/* Unspecified/unknown error in kernel */
|
|
#define VBNV_RECOVERY_KE_UNSPECIFIED 0xBF
|
|
/* Recovery mode test from user-mode */
|
|
#define VBNV_RECOVERY_US_TEST 0xC1
|
|
/* Unspecified/unknown error in user-mode */
|
|
#define VBNV_RECOVERY_US_UNSPECIFIED 0xFF
|
|
|
|
|
|
/* Initialize the NV storage library. This must be called before any
|
|
* other functions in this library. Returns 0 if success, non-zero if
|
|
* error.
|
|
*
|
|
* Proper calling procedure:
|
|
* 1) Allocate a context struct.
|
|
* 2) If multi-threaded/multi-process, acquire a lock to prevent
|
|
* other processes from modifying the underlying storage.
|
|
* 3) Read underlying storage and fill in context->raw.
|
|
* 4) Call VbNvSetup().
|
|
*
|
|
* If you have access to global variables, you may want to wrap all
|
|
* that in your own VbNvOpen() function. We don't do that in here
|
|
* because there are no global variables in UEFI BIOS during the PEI
|
|
* phase (that's also why we have to pass around a context pointer). */
|
|
int VbNvSetup(VbNvContext* context);
|
|
|
|
/* Clean up and flush changes back to the raw data. This must be
|
|
* called after other functions in this library. Returns 0 if
|
|
* success, non-zero if error.
|
|
*
|
|
* Proper calling procedure:
|
|
* 1) Call VbNvExit().
|
|
* 2) If context.raw_changed, write data back to underlying storage.
|
|
* 3) Release any lock you acquired before calling VbNvSetup().
|
|
* 4) Free the context struct.
|
|
*
|
|
* If you have access to global variables, you may want to wrap this
|
|
* in your own VbNvClose() function. */
|
|
int VbNvTeardown(VbNvContext* context);
|
|
|
|
/* Read a NV storage parameter into *dest. Returns 0 if success,
|
|
* non-zero if error.
|
|
*
|
|
* This may only be called between VbNvSetup() and VbNvTeardown(). */
|
|
int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest);
|
|
|
|
/* Set a NV storage param to a new value. Returns 0 if success,
|
|
* non-zero if error.
|
|
*
|
|
* This may only be called between VbNvSetup() and VbNvTeardown(). */
|
|
int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value);
|
|
|
|
|
|
#endif /* VBOOT_REFERENCE_NVSTORAGE_H_ */
|