summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHsuan Ting Chen <roccochen@chromium.org>2022-09-26 19:37:11 +0800
committerFelix Held <felix-coreboot@felixheld.de>2022-10-14 16:06:39 +0000
commitfec16a3574921743246bafe617659c4d73b8011f (patch)
tree5cefedff9f19012dc1f39bdda6edfdba3cdc9a33
parent4e85ec705e08c37a6e071bbb9d5f381eea018283 (diff)
downloadcoreboot-fec16a3574921743246bafe617659c4d73b8011f.tar.gz
coreboot-fec16a3574921743246bafe617659c4d73b8011f.tar.bz2
coreboot-fec16a3574921743246bafe617659c4d73b8011f.zip
util/elogtool: Add support for parsing CrOS diagnostics log
Remove the "_DEPRECATED_" tag from ChromeOS diagnostics event and add a subtype: "ELOG_CROS_DIAGNOSTICS_LOGS" under it. The data of "ELOG_CROS_DIAGNOSTICS_LOGS" (0x02) contains: * An uint8_t of subtype code * Any number of "ChromeOS diagnostics logs" events Each "ChromeOS diagnostics log" represents the result of one ChromeOS diagnostics test run. It is stored within an uint8_t raw[3]: * [23:19] = ELOG_CROS_DIAG_TYPE_* * [18:16] = ELOG_CROS_DIAG_RESULT_* * [15:0] = Running time in seconds Also add support for parsing this event. The parser will first calculate the number of runs it contains, and try to parse the result one by one. BUG=b:226551117 TEST=Build and boot google/tomato to OS, localhost ~ # elogtool list 0 | 2022-09-26 04:25:32 | Log area cleared | 186 1 | 2022-09-26 04:25:50 | System boot | 0 2 | 2022-09-26 04:25:50 | Firmware vboot info | boot_mode=Manual recovery | recovery_reason=0x2/0 (Recovery button pressed) | fw_tried=A | fw_try_count=0 | fw_prev_tried=A | fw_prev_result=Unknown 3 | 2022-09-26 04:25:50 | EC Event | Keyboard Recovery 4 | 2022-09-26 04:26:01 | Memory Cache Update | Normal | Success 5 | 2022-09-26 04:26:06 | System boot | 0 6 | 2022-09-26 04:26:07 | Firmware vboot info | boot_mode=Diagnostic | fw_tried=A | fw_try_count=0 | fw_prev_tried=A | fw_prev_result=Unknown 7 | 2022-09-26 04:26:07 | Diagnostics Mode | Diagnostics Logs | type=Memory check (quick), result=Aborted, time=0m0s | type=Memory check (full), result=Aborted, time=0m0s | type=Storage self-test (extended), result=Aborted, time=0m1s Change-Id: I02428cd21be2ed797eb7aab45f1ef1d782a9c047 Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/67834 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/elog.h41
-rw-r--r--util/cbfstool/eventlog.c64
2 files changed, 98 insertions, 7 deletions
diff --git a/src/commonlib/bsd/include/commonlib/bsd/elog.h b/src/commonlib/bsd/include/commonlib/bsd/elog.h
index b49b37550037..06ea5a77d5b0 100644
--- a/src/commonlib/bsd/include/commonlib/bsd/elog.h
+++ b/src/commonlib/bsd/include/commonlib/bsd/elog.h
@@ -306,8 +306,45 @@ struct elog_event_mem_cache_update {
#define ELOG_TYPE_MI_HR 0xb5
/* ChromeOS diagnostics-related events */
-#define ELOG_DEPRECATED_TYPE_CROS_DIAGNOSTICS 0xb6
-#define ELOG_DEPRECATED_CROS_LAUNCH_DIAGNOSTICS 0x01
+#define ELOG_TYPE_CROS_DIAGNOSTICS 0xb6
+#define ELOG_DEPRECATED_CROS_LAUNCH_DIAGNOSTICS 0x01
+#define ELOG_CROS_DIAGNOSTICS_LOGS 0x02
+/* Type codes for elog_event_cros_diag_log in ELOG_CROS_DIAGNOSTICS_LOGS */
+#define ELOG_CROS_DIAG_TYPE_NONE 0x00
+#define ELOG_CROS_DIAG_TYPE_STORAGE_HEALTH 0x01
+#define ELOG_CROS_DIAG_TYPE_STORAGE_TEST_SHORT 0x02
+#define ELOG_CROS_DIAG_TYPE_STORAGE_TEST_EXTENDED 0x03
+#define ELOG_CROS_DIAG_TYPE_MEMORY_QUICK 0x04
+#define ELOG_CROS_DIAG_TYPE_MEMORY_FULL 0x05
+/* Result codes for elog_event_cros_diag_log in ELOG_CROS_DIAGNOSTICS_LOGS */
+#define ELOG_CROS_DIAG_RESULT_PASSED 0x01
+#define ELOG_CROS_DIAG_RESULT_ERROR 0x02
+#define ELOG_CROS_DIAG_RESULT_FAILED 0x03
+#define ELOG_CROS_DIAG_RESULT_ABORTED 0x04
+
+/*
+ * ChromeOS diagnostics log format:
+ * [23:19] = ELOG_CROS_DIAG_TYPE_*
+ * [18:16] = ELOG_CROS_DIAG_RESULT_*
+ * [15:0] = Running time in seconds
+ */
+#define ELOG_CROS_DIAG_LOG_TYPE_BITS 5
+#define ELOG_CROS_DIAG_LOG_RESULT_BITS 3
+union elog_event_cros_diag_log {
+ uint8_t raw[3];
+ struct {
+ /* 5-bit type code, see ELOG_CROS_DIAG_TYPE_* above */
+ uint8_t type : ELOG_CROS_DIAG_LOG_TYPE_BITS;
+ /* 3-bit result code, see ELOG_CROS_DIAG_RESULT_* above */
+ uint8_t result : ELOG_CROS_DIAG_LOG_RESULT_BITS;
+ /*
+ * The running time of this diagnostics test item. If the
+ * running time exceeds the UINT16_MAX, it will be stored as
+ * UINT16_MAX instead.
+ */
+ uint16_t time_s;
+ } __packed;
+} __packed;
struct elog_event_extended_event {
uint8_t event_type;
diff --git a/util/cbfstool/eventlog.c b/util/cbfstool/eventlog.c
index bb423576593f..b42a7fdfc411 100644
--- a/util/cbfstool/eventlog.c
+++ b/util/cbfstool/eventlog.c
@@ -157,7 +157,7 @@ static void eventlog_print_type(const struct event_header *event)
{ELOG_TYPE_CR50_NEED_RESET, "cr50 Reset Required"},
{ELOG_TYPE_EC_DEVICE_EVENT, "EC Device"},
{ELOG_TYPE_EXTENDED_EVENT, "Extended Event"},
- {ELOG_DEPRECATED_TYPE_CROS_DIAGNOSTICS, "Diagnostics Mode"},
+ {ELOG_TYPE_CROS_DIAGNOSTICS, "Diagnostics Mode"},
{ELOG_TYPE_FW_VBOOT_INFO, "Firmware vboot info"},
{ELOG_TYPE_EOL, "End of log"},
@@ -436,8 +436,27 @@ static int eventlog_print_data(const struct event_header *event)
{0, NULL},
};
- static const struct valstr cros_deprecated_diagnostics_types[] = {
+ static const struct valstr cros_diagnostics_types[] = {
{ELOG_DEPRECATED_CROS_LAUNCH_DIAGNOSTICS, "Launch Diagnostics"},
+ {ELOG_CROS_DIAGNOSTICS_LOGS, "Diagnostics Logs"},
+ {0, NULL},
+ };
+
+ static const struct valstr cros_diagnostics_diag_types[] = {
+ {ELOG_CROS_DIAG_TYPE_NONE, "None"},
+ {ELOG_CROS_DIAG_TYPE_STORAGE_HEALTH, "Storage Health Info"},
+ {ELOG_CROS_DIAG_TYPE_STORAGE_TEST_SHORT, "Storage self-test (short)"},
+ {ELOG_CROS_DIAG_TYPE_STORAGE_TEST_EXTENDED, "Storage self-test (extended)"},
+ {ELOG_CROS_DIAG_TYPE_MEMORY_QUICK, "Memory check (quick)"},
+ {ELOG_CROS_DIAG_TYPE_MEMORY_FULL, "Memory check (full)"},
+ {0, NULL},
+ };
+
+ static const struct valstr cros_diagnostics_diag_results[] = {
+ {ELOG_CROS_DIAG_RESULT_PASSED, "Passed"},
+ {ELOG_CROS_DIAG_RESULT_ERROR, "Error"},
+ {ELOG_CROS_DIAG_RESULT_FAILED, "Failed"},
+ {ELOG_CROS_DIAG_RESULT_ABORTED, "Aborted"},
{0, NULL},
};
@@ -522,9 +541,44 @@ static int eventlog_print_data(const struct event_header *event)
eventlog_printf("0x%X", ext_event->event_complement);
break;
}
- case ELOG_DEPRECATED_TYPE_CROS_DIAGNOSTICS: {
- const uint8_t *type = event_get_data(event);
- eventlog_printf("%s", val2str(*type, cros_deprecated_diagnostics_types));
+ case ELOG_TYPE_CROS_DIAGNOSTICS: {
+ const uint8_t *data = event_get_data(event);
+ const uint8_t subtype = *data;
+ eventlog_printf("%s", val2str(subtype, cros_diagnostics_types));
+
+ /*
+ * If the subtype is diagnostics logs, there will be many
+ * elog_event_diag_log events after subtype:
+ *
+ * [event_header][(subtype)(log 1)(log 2)...(log n)][checksum]
+ *
+ * Parse them one by one.
+ */
+ if (subtype == ELOG_CROS_DIAGNOSTICS_LOGS) {
+ size_t i, base_size, log_size, num_logs;
+ const union elog_event_cros_diag_log *log;
+
+ /*
+ * base_size = event header + checksum + subtype;
+ * log_size = event length - base_size.
+ */
+ base_size = sizeof(*event) + 1 + sizeof(subtype);
+ /* Validity check to prevent log_size overflow */
+ if (event->length > base_size) {
+ log_size = event->length - base_size;
+ num_logs = log_size / sizeof(union elog_event_cros_diag_log);
+ log = (const union elog_event_cros_diag_log *)(data + 1);
+ for (i = 0; i < num_logs; i++) {
+ eventlog_printf("type=%s, result=%s, time=%um%us",
+ val2str(log->type,
+ cros_diagnostics_diag_types),
+ val2str(log->result,
+ cros_diagnostics_diag_results),
+ log->time_s / 60, log->time_s % 60);
+ log++;
+ }
+ }
+ }
break;
}
case ELOG_TYPE_FW_VBOOT_INFO: {