Files
OpenCellular/firmware/include/vboot_nvstorage.h
Julius Werner dc8ec103c0 vboot1: Add vboot2 recovery reason strings and subcode to TAB display
vboot2 added a few new recovery reasons (and abolished many old ones).
In the current vboot2/vboot1 hybrid architecture used on Veyron, the
vboot1 kernel verification part controls the status display when
pressing the TAB key, which may try to show recovery reasons set by the
vboot2 firmware verification part. These currently result in the not
very helpful "We have no idea what this means", so lets hack a few more
strings into vboot1 which will be otherwise harmless. Also add the
recovery_subcode field to the display, which is used much more
extensively by vboot2 and often very useful in firguring out what really
went wrong.

BRANCH=veyron
BUG=None
TEST=Manually set a few recovery reasons and subcodes through crossystem
and made sure they get displayed correctly on my Jerry.

Change-Id: I3f3e6c6ae6e7981337841c0c5e3cd767628472c3
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/248391
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2015-02-11 23:05:29 +00:00

332 lines
12 KiB
C

/* 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.
*/
/* Non-volatile storage routines for verified boot. */
#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
#define VBOOT_REFERENCE_NVSTORAGE_H_
#include <stdint.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.
*
* Vboot2: Number of times to try the firmware in VBNV_FW_TRY_NEXT.
*
* These refer to the same field, but have different enum values so
* case statement don't complain about duplicates.
*/
VBNV_TRY_B_COUNT,
VBNV_FW_TRY_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,
/* More details on recovery reason */
VBNV_RECOVERY_SUBCODE,
/* Request that NVRAM be backed up at next boot if possible. */
VBNV_BACKUP_NVRAM_REQUEST,
/* Vboot2: Firmware slot to try next. 0=A, 1=B */
VBNV_FW_TRY_NEXT,
/* Vboot2: Firmware slot tried this boot (0=A, 1=B) */
VBNV_FW_TRIED,
/* Vboot2: Result of trying that firmware (see vb2_fw_result) */
VBNV_FW_RESULT,
/* Firmware slot tried previous boot (0=A, 1=B) */
VBNV_FW_PREV_TRIED,
/* Result of trying that firmware (see vb2_fw_result) */
VBNV_FW_PREV_RESULT,
} VbNvParam;
/* Result of trying the firmware in VBNV_FW_TRIED */
typedef enum VbFwResult {
/* Unknown */
VBNV_FW_RESULT_UNKNOWN = 0,
/* Trying a new slot, but haven't reached success/failure */
VBNV_FW_RESULT_TRYING = 1,
/* Successfully booted to the OS */
VBNV_FW_RESULT_SUCCESS = 2,
/* Known failure */
VBNV_FW_RESULT_FAILURE = 3,
} VbFwResult;
/* 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
/* EC software sync - error obtaining expected EC hash */
#define VBNV_RECOVERY_EC_EXPECTED_HASH 0x29
/* EC software sync - expected EC image doesn't match hash */
#define VBNV_RECOVERY_EC_HASH_MISMATCH 0x2A
/* VB2: Secure data inititalization error */
#define VBNV_RECOVERY_VB2_SECDATA_INIT 0x2B
/* VB2: GBB header is bad */
#define VBNV_RECOVERY_VB2_GBB_HEADER 0x2C
/* VB2: Unable to clear TPM owner */
#define VBNV_RECOVERY_VB2_TPM_CLEAR_OWNER 0x2D
/* VB2: Error determining/updating virtual dev switch */
#define VBNV_RECOVERY_VB2_DEV_SWITCH 0x2E
/* VB2: Error determining firmware slot */
#define VBNV_RECOVERY_VB2_FW_SLOT 0x2F
/* 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);
/**
* Attempt to restore some fields of a lost VbNvContext from a backup area.
* The rest of the fields are unchanged, so they'd need to be set to their
* appropriate defaults by calling VbNvSetup() first (which is usually how we
* know the fields have been lost).
*
* Returns 0 if success, non-zero if error.
*
* This may only be called between VbNvSetup() and VbNvTeardown().
*/
int RestoreNvFromBackup(VbNvContext *vnc);
/**
* Attempt to save some fields of the VbNvContext to a backup area.
*
* Returns 0 if success, non-zero if error. If it succeeds, it will clear the
* VBNV_BACKUP_NVRAM_REQUEST flag in the VbNvContext.
*
* This may only be called when the backup area is writable.
*/
int SaveNvToBackup(VbNvContext *vnc);
#endif /* VBOOT_REFERENCE_NVSTORAGE_H_ */