summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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_ */