diff options
-rw-r--r-- | src/commonlib/bsd/include/commonlib/bsd/elog.h | 41 | ||||
-rw-r--r-- | util/cbfstool/eventlog.c | 64 |
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 b49b375500..06ea5a77d5 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 bb42357659..b42a7fdfc4 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: { |