summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubrata Banik <subratabanik@google.com>2022-07-13 23:48:23 +0530
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-07-29 09:37:19 +0000
commit81b8d3faabad2f16bfd08efa6920bdaaeb637ce8 (patch)
treea8842889f148b4b56d93892e40a179c3dc0c3543
parentaa4671712ddb54216febc103cc9ff530b586b54a (diff)
downloadvboot-81b8d3faabad2f16bfd08efa6920bdaaeb637ce8.tar.gz
firmware/2lib: Introduce `vb2api_get_fw_boot_info` API
This patch introduces a new API named `vb2api_get_fw_boot_info` to get the FW slot information like tries, current boot slot, previous boot slot, previous boot status and boot mode. Additionally, moved the required data structures from 2api.h to newly created 2info.h file to keep vboot information and inline functions for coreboot/eventlog usage. BUG=b:215615970 TEST=Able to compile the Google/Kano board using the emerge command. Signed-off-by: Subrata Banik <subratabanik@google.com> Change-Id: Ib3f197c851dc4b445dbf64868c3f9157a4f6c9fe Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3737570 Auto-Submit: Subrata Banik <subratabanik@chromium.org> Commit-Queue: Yu-Ping Wu <yupingso@chromium.org> Tested-by: Subrata Banik <subratabanik@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r--firmware/2lib/2api.c30
-rw-r--r--firmware/2lib/include/2api.h94
-rw-r--r--firmware/2lib/include/2info.h146
3 files changed, 203 insertions, 67 deletions
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c
index 9184b23d..13b3a697 100644
--- a/firmware/2lib/2api.c
+++ b/firmware/2lib/2api.c
@@ -365,3 +365,33 @@ int vb2api_check_hash(struct vb2_context *ctx)
{
return vb2api_check_hash_get_digest(ctx, NULL, 0);
}
+
+union vb2_fw_boot_info vb2api_get_fw_boot_info(struct vb2_context *ctx)
+{
+ union vb2_fw_boot_info info;
+
+ struct vb2_shared_data *sd = vb2_get_sd(ctx);
+
+ info.tries = vb2_nv_get(ctx, VB2_NV_TRY_COUNT);
+ info.slot = sd->fw_slot;
+ info.prev_slot = sd->last_fw_slot;
+ info.prev_result = sd->last_fw_result;
+ info.boot_mode = ctx->boot_mode;
+
+ VB2_DEBUG("boot_mode=`%s`\n", vb2_boot_mode_string(info.boot_mode));
+
+ if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
+ info.recovery_reason = sd->recovery_reason;
+ info.recovery_subcode = vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE);
+ VB2_DEBUG("recovery_reason: %#x / %#x\n",
+ info.recovery_reason, info.recovery_subcode);
+ }
+
+ VB2_DEBUG("fw_tried=`%s` fw_try_count=%d "
+ "fw_prev_tried=`%s` fw_prev_result=`%s`.\n",
+ vb2_slot_string(info.slot), info.tries,
+ vb2_slot_string(info.prev_slot),
+ vb2_result_string(info.prev_result));
+
+ return info;
+}
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index a833da7c..904b7105 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -24,6 +24,7 @@
#include "2fw_hash_tags.h"
#include "2gbb_flags.h"
#include "2id.h"
+#include "2info.h"
#include "2recovery_reasons.h"
#include "2return_codes.h"
#include "2rsa.h"
@@ -266,73 +267,6 @@ enum vb2_context_flags {
VB2_CONTEXT_DISABLE_TPM = (1 << 28),
};
-/* Boot mode decided in vb2api_fw_phase1.
- *
- * Boot mode is a constant set by verified boot and may be read (but should not
- * be set or cleared) by the caller.
- * The boot modes are mutually exclusive. If a boot fulfill more than one
- * constraints of the listing boot modes, it will be set to the most important
- * one. The priority is the same as the listing order.
- */
-enum vb2_boot_mode {
- /* Undefined, The boot mode is not set. */
- VB2_BOOT_MODE_UNDEFINED = 0,
-
- /*
- * Manual recovery boot, regardless of dev mode state.
- *
- * VB2_CONTEXT_RECOVERY_MODE is set and the recovery is physically
- * requested (a.k.a. Manual recovery). All other recovery requests
- * including manual recovery requested by a (compromised) host will end
- * up with a broken screen.
- */
- VB2_BOOT_MODE_MANUAL_RECOVERY = 1,
-
- /*
- * Broken screen.
- *
- * If a recovery boot is not a manual recovery (a.k.a. not requested
- * physically), the recovery is not allowed and will end up with
- * broken screen.
- */
- VB2_BOOT_MODE_BROKEN_SCREEN = 2,
-
- /*
- * Diagnostic boot.
- *
- * If diagnostic boot is enabled (a.k.a. vb2api_diagnostic_ui_enabled)
- * and the nvdata contains VB2_NV_DIAG_REQUEST from previous boot, it
- * will boot to diagnostic mode.
- */
- VB2_BOOT_MODE_DIAGNOSTICS = 3,
-
- /*
- * Developer boot: self-signed kernel okay.
- *
- * The developer mode switch is set (a.k.a. VB2_CONTEXT_DEVELOPER_MODE)
- * and we are in the developer boot mode.
- */
- VB2_BOOT_MODE_DEVELOPER = 4,
-
- /* Normal boot: kernel must be verified. */
- VB2_BOOT_MODE_NORMAL = 5,
-};
-
-/* Firmware result codes for VB2_NV_FW_RESULT and VB2_NV_FW_PREV_RESULT */
-enum vb2_fw_result {
- /* Unknown */
- VB2_FW_RESULT_UNKNOWN = 0,
-
- /* Trying a new slot, but haven't reached success/failure */
- VB2_FW_RESULT_TRYING = 1,
-
- /* Successfully booted to the OS */
- VB2_FW_RESULT_SUCCESS = 2,
-
- /* Known failure */
- VB2_FW_RESULT_FAILURE = 3,
-};
-
/* Helper for aligning fields in vb2_context. */
#define VB2_PAD_STRUCT3(size, align, count) \
uint8_t _pad##count[align - (((size - 1) % align) + 1)]
@@ -1520,4 +1454,30 @@ uint32_t vb2ex_mtime(void);
*/
void vb2ex_msleep(uint32_t msec);
+union vb2_fw_boot_info {
+ uint8_t raw[4];
+ struct {
+ uint8_t tries : 4;
+ uint8_t slot : 1;
+ uint8_t prev_slot : 1;
+ uint8_t prev_result : 2;
+ uint8_t boot_mode;
+ /* The following 2 bytes only exist for recovery mode */
+ uint8_t recovery_reason;
+ uint8_t recovery_subcode;
+ };
+};
+
+/**
+ * Return `vb2_fw_boot_info` and can be used
+ * to log information about the current boot in a compact format.
+ *
+ * Note: Only call this API at minimum after `vb2api_fw_phase2` function
+ * returns.
+ *
+ * @param ctx Vboot context
+ * @return filled out vb2 info as per `union vb2_fw_boot_info`.
+ */
+union vb2_fw_boot_info vb2api_get_fw_boot_info(struct vb2_context *ctx);
+
#endif /* VBOOT_REFERENCE_2API_H_ */
diff --git a/firmware/2lib/include/2info.h b/firmware/2lib/include/2info.h
new file mode 100644
index 00000000..be2ea604
--- /dev/null
+++ b/firmware/2lib/include/2info.h
@@ -0,0 +1,146 @@
+/* Copyright 2022 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.
+ *
+ * Helper functions to retrieve vboot firmware information.
+ */
+
+#ifndef VBOOT_REFERENCE_2INFO_H_
+#define VBOOT_REFERENCE_2INFO_H_
+
+/* Boot mode decided in vb2api_fw_phase1.
+ *
+ * Boot mode is a constant set by verified boot and may be read (but should not
+ * be set or cleared) by the caller.
+ * The boot modes are mutually exclusive. If a boot fulfill more than one
+ * constraints of the listing boot modes, it will be set to the most important
+ * one. The priority is the same as the listing order.
+ */
+enum vb2_boot_mode {
+ /* Undefined, The boot mode is not set. */
+ VB2_BOOT_MODE_UNDEFINED = 0,
+
+ /*
+ * Manual recovery boot, regardless of dev mode state.
+ *
+ * VB2_CONTEXT_RECOVERY_MODE is set and the recovery is physically
+ * requested (a.k.a. Manual recovery). All other recovery requests
+ * including manual recovery requested by a (compromised) host will end
+ * up with a broken screen.
+ */
+ VB2_BOOT_MODE_MANUAL_RECOVERY = 1,
+
+ /*
+ * Broken screen.
+ *
+ * If a recovery boot is not a manual recovery (a.k.a. not requested
+ * physically), the recovery is not allowed and will end up with
+ * broken screen.
+ */
+ VB2_BOOT_MODE_BROKEN_SCREEN = 2,
+
+ /*
+ * Diagnostic boot.
+ *
+ * If diagnostic boot is enabled (a.k.a. vb2api_diagnostic_ui_enabled)
+ * and the nvdata contains VB2_NV_DIAG_REQUEST from previous boot, it
+ * will boot to diagnostic mode.
+ */
+ VB2_BOOT_MODE_DIAGNOSTICS = 3,
+
+ /*
+ * Developer boot: self-signed kernel okay.
+ *
+ * The developer mode switch is set (a.k.a. VB2_CONTEXT_DEVELOPER_MODE)
+ * and we are in the developer boot mode.
+ */
+ VB2_BOOT_MODE_DEVELOPER = 4,
+
+ /* Normal boot: kernel must be verified. */
+ VB2_BOOT_MODE_NORMAL = 5,
+};
+
+/* Firmware slot codes */
+enum vb2_fw_slot {
+ /* Slot A */
+ VB2_FW_SLOT_A = 0,
+
+ /* Slot B */
+ VB2_FW_SLOT_B = 1,
+};
+
+/* Firmware result codes for VB2_NV_FW_RESULT and VB2_NV_FW_PREV_RESULT */
+enum vb2_fw_result {
+ /* Unknown */
+ VB2_FW_RESULT_UNKNOWN = 0,
+
+ /* Trying a new slot, but haven't reached success/failure */
+ VB2_FW_RESULT_TRYING = 1,
+
+ /* Successfully booted to the OS */
+ VB2_FW_RESULT_SUCCESS = 2,
+
+ /* Known failure */
+ VB2_FW_RESULT_FAILURE = 3,
+};
+
+/**
+ * Convert Firmware Boot Mode into supported string
+ *
+ * @return char* firmware boot mode string
+ */
+static inline const char *vb2_boot_mode_string(uint8_t boot_mode)
+{
+ switch ((enum vb2_boot_mode)boot_mode) {
+ /* 0x00 */ case VB2_BOOT_MODE_UNDEFINED:
+ return "Undefined";
+ /* 0x01 */ case VB2_BOOT_MODE_MANUAL_RECOVERY:
+ return "Manual recovery";
+ /* 0x02 */ case VB2_BOOT_MODE_BROKEN_SCREEN:
+ return "Broken screen";
+ /* 0x03 */ case VB2_BOOT_MODE_DIAGNOSTICS:
+ return "Diagnostic";
+ /* 0x04 */ case VB2_BOOT_MODE_DEVELOPER:
+ return "Developer";
+ /* 0x05 */ case VB2_BOOT_MODE_NORMAL:
+ return "Secure";
+ }
+
+ return "Unknown";
+}
+
+/**
+ * Convert Firmware Slot result into supported string
+ *
+ * @return char* firmware slot result string
+ */
+static inline const char *vb2_result_string(uint8_t result)
+{
+ switch ((enum vb2_fw_result)result) {
+ /* 0x00 */ case VB2_FW_RESULT_UNKNOWN:
+ return "Unknown";
+ /* 0x01 */ case VB2_FW_RESULT_TRYING:
+ return "Trying";
+ /* 0x02 */ case VB2_FW_RESULT_SUCCESS:
+ return "Success";
+ /* 0x03 */ case VB2_FW_RESULT_FAILURE:
+ return "Failure";
+ }
+
+ return "Unknown";
+}
+
+/**
+ * Convert Firmware Slot into supported string
+ *
+ * @return char* firmware slot name string
+ */
+static inline const char *vb2_slot_string(uint8_t slot)
+{
+ if ((enum vb2_fw_slot)slot == VB2_FW_SLOT_A)
+ /* 0x00 */ return "A";
+ else
+ /* 0x01 */ return "B";
+}
+
+#endif /* VBOOT_REFERENCE_2INFO_H_ */