summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/bsd/elog.c21
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/elog.h77
-rw-r--r--util/cbfstool/Makefile10
-rw-r--r--util/cbfstool/Makefile.inc12
-rw-r--r--util/cbfstool/elogtool.c161
-rw-r--r--util/cbfstool/eventlog.c636
-rw-r--r--util/cbfstool/eventlog.h10
7 files changed, 923 insertions, 4 deletions
diff --git a/src/commonlib/bsd/elog.c b/src/commonlib/bsd/elog.c
index 62149daa42..6c927aaf22 100644
--- a/src/commonlib/bsd/elog.c
+++ b/src/commonlib/bsd/elog.c
@@ -23,3 +23,24 @@ enum cb_err elog_verify_header(const struct elog_header *header)
return CB_SUCCESS;
}
+
+/*
+ * return the next elog event.
+ * return NULL if event is invalid.
+ */
+const struct event_header *elog_get_next_event(const struct event_header *event)
+{
+ if (!event)
+ return NULL;
+
+ /* Point to next event */
+ return (const struct event_header *)((const void *)(event) + event->length);
+}
+
+/* return the data associated to the event_header. */
+const void *event_get_data(const struct event_header *event)
+{
+ // Pointing to the next event returns the data, since data is the first field
+ // right after the header.
+ return (const void *)(&event[1]);
+}
diff --git a/src/commonlib/bsd/include/commonlib/bsd/elog.h b/src/commonlib/bsd/include/commonlib/bsd/elog.h
index 3a6830c46d..0d41157758 100644
--- a/src/commonlib/bsd/include/commonlib/bsd/elog.h
+++ b/src/commonlib/bsd/include/commonlib/bsd/elog.h
@@ -71,12 +71,57 @@ struct event_header {
/* OS/kernel events */
#define ELOG_TYPE_OS_EVENT 0x81
+#define ELOG_OS_EVENT_CLEAN 0 /* Clean Shutdown */
+#define ELOG_OS_EVENT_NMIWDT 1 /* NMI Watchdog */
+#define ELOG_OS_EVENT_PANIC 2 /* Panic */
+#define ELOG_OS_EVENT_OOPS 3 /* Oops */
+#define ELOG_OS_EVENT_DIE 4 /* Die */
+#define ELOG_OS_EVENT_MCE 5 /* MCE */
+#define ELOG_OS_EVENT_SOFTWDT 6 /* Software Watchdog */
+#define ELOG_OS_EVENT_MBE 7 /* MBE */
+#define ELOG_OS_EVENT_TRIPLE 8 /* Triple Fault */
+#define ELOG_OS_EVENT_THERMAL 9 /* Critical Thermal Threshold */
/* Last event from coreboot */
#define ELOG_TYPE_OS_BOOT 0x90
/* Embedded controller event */
#define ELOG_TYPE_EC_EVENT 0x91
+#define EC_EVENT_LID_CLOSED 0x01
+#define EC_EVENT_LID_OPEN 0x02
+#define EC_EVENT_POWER_BUTTON 0x03
+#define EC_EVENT_AC_CONNECTED 0x04
+#define EC_EVENT_AC_DISCONNECTED 0x05
+#define EC_EVENT_BATTERY_LOW 0x06
+#define EC_EVENT_BATTERY_CRITICAL 0x07
+#define EC_EVENT_BATTERY 0x08
+#define EC_EVENT_THERMAL_THRESHOLD 0x09
+#define EC_EVENT_DEVICE_EVENT 0x0a
+#define EC_EVENT_THERMAL 0x0b
+#define EC_EVENT_USB_CHARGER 0x0c
+#define EC_EVENT_KEY_PRESSED 0x0d
+#define EC_EVENT_INTERFACE_READY 0x0e
+#define EC_EVENT_KEYBOARD_RECOVERY 0x0f
+#define EC_EVENT_THERMAL_SHUTDOWN 0x10
+#define EC_EVENT_BATTERY_SHUTDOWN 0x11
+#define EC_EVENT_THROTTLE_START 0x12
+#define EC_EVENT_THROTTLE_STOP 0x13
+#define EC_EVENT_HANG_DETECT 0x14
+#define EC_EVENT_HANG_REBOOT 0x15
+#define EC_EVENT_PD_MCU 0x16
+#define EC_EVENT_BATTERY_STATUS 0x17
+#define EC_EVENT_PANIC 0x18
+#define EC_EVENT_KEYBOARD_FASTBOOT 0x19
+#define EC_EVENT_RTC 0x1a
+#define EC_EVENT_MKBP 0x1b
+#define EC_EVENT_USB_MUX 0x1c
+#define EC_EVENT_MODE_CHANGE 0x1d
+#define EC_EVENT_KEYBOARD_RECOVERY_HWREINIT 0x1e
+#define EC_EVENT_EXTENDED 0x1f
+struct elog_ec_event {
+ uint8_t event;
+ uint8_t checksum;
+} __packed;
/* Power */
#define ELOG_TYPE_POWER_FAIL 0x92
@@ -163,8 +208,22 @@ struct elog_event_data_wake {
#define ELOG_CROS_RECOVERY_MODE_BUTTON 0x02
/* Management Engine Events */
-#define ELOG_TYPE_MANAGEMENT_ENGINE 0xa2
-#define ELOG_TYPE_MANAGEMENT_ENGINE_EXT 0xa4
+#define ELOG_TYPE_MANAGEMENT_ENGINE 0xa2
+#define ELOG_ME_PATH_NORMAL 0x00
+#define ELOG_ME_PATH_S3WAKE 0x01
+#define ELOG_ME_PATH_ERROR 0x02
+#define ELOG_ME_PATH_RECOVERY 0x03
+#define ELOG_ME_PATH_DISABLED 0x04
+#define ELOG_ME_PATH_FW_UPDATE 0x05
+
+#define ELOG_TYPE_MANAGEMENT_ENGINE_EXT 0xa4
+#define ELOG_ME_PHASE_ROM 0
+#define ELOG_ME_PHASE_BRINGUP 1
+#define ELOG_ME_PHASE_UKERNEL 2
+#define ELOG_ME_PHASE_POLICY 3
+#define ELOG_ME_PHASE_MODULE 4
+#define ELOG_ME_PHASE_UNKNOWN 5
+#define ELOG_ME_PHASE_HOST 6
struct elog_event_data_me_extended {
uint8_t current_working_state;
uint8_t operation_state;
@@ -178,6 +237,18 @@ struct elog_event_data_me_extended {
/* Last post code from previous boot */
#define ELOG_TYPE_LAST_POST_CODE 0xa3
#define ELOG_TYPE_POST_EXTRA 0xa6
+#define ELOG_TYPE_POST_EXTRA_PATH 0x01
+#define ELOG_DEV_PATH_TYPE_NONE 0
+#define ELOG_DEV_PATH_TYPE_ROOT 1
+#define ELOG_DEV_PATH_TYPE_PCI 2
+#define ELOG_DEV_PATH_TYPE_PNP 3
+#define ELOG_DEV_PATH_TYPE_I2C 4
+#define ELOG_DEV_PATH_TYPE_APIC 5
+#define ELOG_DEV_PATH_TYPE_DOMAIN 6
+#define ELOG_DEV_PATH_TYPE_CPU_CLUSTER 7
+#define ELOG_DEV_PATH_TYPE_CPU 8
+#define ELOG_DEV_PATH_TYPE_CPU_BUS 9
+#define ELOG_DEV_PATH_TYPE_IOAPIC 10
/* EC Shutdown Reason */
#define ELOG_TYPE_EC_SHUTDOWN 0xa5
@@ -240,5 +311,7 @@ struct elog_event_extended_event {
enum cb_err elog_verify_header(const struct elog_header *header);
+const struct event_header *elog_get_next_event(const struct event_header *event);
+const void *event_get_data(const struct event_header *event);
#endif /* _COMMONLIB_BSD_ELOG_H_ */
diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile
index 7d7befef95..f5e0c6917e 100644
--- a/util/cbfstool/Makefile
+++ b/util/cbfstool/Makefile
@@ -13,7 +13,7 @@ VBOOT_SOURCE ?= $(top)/3rdparty/vboot
VBOOT_HOST_BUILD ?= $(abspath $(objutil)/vboot_lib)
.PHONY: all
-all: cbfstool ifittool fmaptool rmodtool ifwitool cbfs-compression-tool
+all: cbfstool ifittool fmaptool rmodtool ifwitool cbfs-compression-tool elogtool
cbfstool: $(objutil)/cbfstool/cbfstool
@@ -27,7 +27,9 @@ ifittool: $(objutil)/cbfstool/ifittool
cbfs-compression-tool: $(objutil)/cbfstool/cbfs-compression-tool
-.PHONY: clean cbfstool ifittool fmaptool rmodtool ifwitool cbfs-compression-tool
+elogtool: $(objutil)/cbfstool/elogtool
+
+.PHONY: clean cbfstool ifittool fmaptool rmodtool ifwitool cbfs-compression-tool elogtool
clean:
$(RM) fmd_parser.c fmd_parser.h fmd_scanner.c fmd_scanner.h
$(RM) $(objutil)/cbfstool/cbfstool $(cbfsobj)
@@ -36,6 +38,7 @@ clean:
$(RM) $(objutil)/cbfstool/ifwitool $(ifwiobj)
$(RM) $(objutil)/cbfstool/ifittool $(ifitobj)
$(RM) $(objutil)/cbfstool/cbfs-compression-tool $(cbfscompobj)
+ $(RM) $(objutil)/cbfstool/elogtool $(elogobj)
$(RM) -r $(VBOOT_HOST_BUILD)
linux_trampoline.c: linux_trampoline.S
@@ -57,6 +60,7 @@ install: all
$(INSTALL) ifwitool $(DESTDIR)$(BINDIR)
$(INSTALL) ifittool $(DESTDIR)$(BINDIR)
$(INSTALL) cbfs-compression-tool $(DESTDIR)$(BINDIR)
+ $(INSTALL) elogtool $(DESTDIR)$(BINDIR)
distclean: clean
@@ -69,6 +73,7 @@ help:
@echo " ifwitool - Manipulate Intel FW Image (IFWI)"
@echo " ifittool - Manipulate Intel FW Interface Table (FIT)"
@echo " cbfs-compression-tool - benchmark compression algorithms"
+ @echo " elogtool - Display ELOG events"
ifneq ($(V),1)
.SILENT:
@@ -77,6 +82,7 @@ endif
include Makefile.inc
$(objutil)/cbfstool/cbfstool.o: $(VBOOT_SOURCE)/firmware/include/vb2_sha.h
+$(objutil)/cbfstool/elogtool.o: $(VBOOT_SOURCE)/firmware/include/vb2_sha.h
$(VBOOT_SOURCE)/firmware/include/vb2_sha.h:
cd $(VBOOT_SOURCE) && git submodule update --init .
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index 94dacf47cc..1113c86c51 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -89,6 +89,13 @@ amdcompobj += elfheaders.o
amdcompobj += common.o
amdcompobj += xdr.o
+elogobj :=
+elogobj := elogtool.o
+elogobj += eventlog.o
+elogobj += valstr.o
+elogobj += elog.o
+elogobj += common.o
+
TOOLCFLAGS ?= -Werror -Wall -Wextra -Wshadow
TOOLCFLAGS += -Wcast-qual -Wmissing-prototypes -Wredundant-decls -Wshadow
TOOLCFLAGS += -Wstrict-prototypes -Wwrite-strings
@@ -104,6 +111,7 @@ TOOLCPPFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler
TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/include
TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/2lib/include
TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/host/include
+TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/host/lib/include
# UEFI header file support. It's not pretty, but that's what we currently
# have right now.
TOOLCPPFLAGS += -I$(top)/src
@@ -198,6 +206,10 @@ $(objutil)/cbfstool/amdcompress: $(addprefix $(objutil)/cbfstool/,$(amdcompobj))
printf " HOSTCC $(subst $(objutil)/,,$(@)) (link)\n"
$(HOSTCC) $(TOOLLDFLAGS) -o $@ $(addprefix $(objutil)/cbfstool/,$(amdcompobj)) -lz
+$(objutil)/cbfstool/elogtool: $(addprefix $(objutil)/cbfstool/,$(elogobj)) $(VBOOT_HOSTLIB)
+ printf " HOSTCC $(subst $(objutil)/,,$(@)) (link)\n"
+ $(HOSTCC) $(TOOLLDFLAGS) -o $@ $(addprefix $(objutil)/cbfstool/,$(elogobj)) $(VBOOT_HOSTLIB)
+
# Yacc source is superset of header
$(objutil)/cbfstool/fmd.o: TOOLCFLAGS += -Wno-redundant-decls
$(objutil)/cbfstool/fmd_parser.o: TOOLCFLAGS += -Wno-redundant-decls
diff --git a/util/cbfstool/elogtool.c b/util/cbfstool/elogtool.c
new file mode 100644
index 0000000000..ba59eac514
--- /dev/null
+++ b/util/cbfstool/elogtool.c
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#include <getopt.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <common.h>
+#include <commonlib/bsd/elog.h>
+#include <flashrom.h>
+
+#include "eventlog.h"
+
+enum elogtool_return {
+ ELOGTOOL_EXIT_SUCCESS = 0,
+ ELOGTOOL_EXIT_BAD_ARGS,
+ ELOGTOOL_EXIT_BAD_INPUT_PATH,
+ ELOGTOOL_EXIT_NOT_ENOUGH_MEMORY,
+ ELOGTOOL_EXIT_INVALID_ELOG_FORMAT,
+};
+
+static struct option long_options[] = {
+ {"file", required_argument, 0, 'f'},
+ {"help", no_argument, 0, 'h'},
+ {NULL, 0, 0, 0},
+};
+
+static void usage(char *invoked_as)
+{
+ fprintf(stderr, "elogtool: list elog events\n\n"
+ "USAGE:\n"
+ "\t%s COMMAND [-f <filename>]\n\n"
+ "where, COMMAND is:\n"
+ " list = lists all the event logs in human readable format\n\n"
+ "ARGS\n"
+ "-f, --file <filename> Input file that holds event log partition.\n"
+ " If empty it will try to read from the RW_ELOG ROM region\n"
+ "-h, --help Print this help\n",
+ invoked_as);
+}
+
+// If filename is empty, read RW_ELOG from flashrom. Otherwise read the RW_ELOG from a file.
+// Buffer must be freed by caller.
+static int elog_read(const char *filename, struct buffer *buffer)
+{
+ if (filename == NULL) {
+ uint8_t *buf;
+ uint32_t buf_size;
+
+ if (flashrom_read(FLASHROM_PROGRAMMER_INTERNAL_AP, "RW_ELOG", &buf, &buf_size)
+ != VB2_SUCCESS) {
+ fprintf(stderr, "Could not read RW_ELOG region using flashrom\n");
+ return ELOGTOOL_EXIT_BAD_INPUT_PATH;
+ }
+ buffer_init(buffer, NULL, buf, buf_size);
+ } else {
+ if (buffer_from_file(buffer, filename) != 0) {
+ fprintf(stderr, "Could not read input file: %s\n", filename);
+ return ELOGTOOL_EXIT_BAD_INPUT_PATH;
+ }
+ }
+
+ return 0;
+}
+
+static int elog_list_events(const struct buffer *buf)
+{
+ const struct event_header *event;
+ const void *data;
+ uint32_t data_len;
+ unsigned int count = 0;
+
+ data = buffer_get(buf);
+ data_len = buffer_size(buf);
+
+ if (elog_verify_header(data) != CB_SUCCESS) {
+ fprintf(stderr, "FATAL: Invalid elog header\n");
+ return ELOGTOOL_EXIT_INVALID_ELOG_FORMAT;
+ }
+
+ /* Point to first event */
+ event = (const struct event_header *)(data + sizeof(struct elog_header));
+
+ while ((const void *)(event) < data + data_len) {
+ if (event->type == ELOG_TYPE_EOL || event->length == 0)
+ break;
+
+ eventlog_print_event(event, count);
+ event = elog_get_next_event(event);
+ count++;
+ }
+
+ return ELOGTOOL_EXIT_SUCCESS;
+}
+
+static int cmd_list(const char *filename)
+{
+ int ret;
+
+ // Returned buffer must be freed.
+ struct buffer buf;
+ ret = elog_read(filename, &buf);
+ if (ret != 0)
+ return ret;
+
+ ret = elog_list_events(&buf);
+
+ buffer_delete(&buf);
+ return ret;
+}
+
+
+int main(int argc, char **argv)
+{
+ int argflag;
+ char *input_file = NULL;
+
+ if (argc < 2) {
+ usage(argv[0]);
+ return ELOGTOOL_EXIT_BAD_ARGS;
+ }
+
+ while (1) {
+ int option_index;
+ argflag = getopt_long(argc, argv, "hf:", long_options, &option_index);
+ if (argflag == -1)
+ break;
+
+ switch (argflag) {
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ return ELOGTOOL_EXIT_SUCCESS;
+
+ case 'f':
+ if (!optarg) {
+ usage(argv[0]);
+ return ELOGTOOL_EXIT_BAD_ARGS;
+ }
+
+ input_file = optarg;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* At least one command must be available. */
+ if (optind >= argc) {
+ usage(argv[0]);
+ return ELOGTOOL_EXIT_BAD_ARGS;
+ }
+
+ if (!strcmp(argv[optind], "list"))
+ return cmd_list(input_file);
+
+ return ELOGTOOL_EXIT_SUCCESS;
+}
diff --git a/util/cbfstool/eventlog.c b/util/cbfstool/eventlog.c
new file mode 100644
index 0000000000..2d99f9237a
--- /dev/null
+++ b/util/cbfstool/eventlog.c
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#include "eventlog.h"
+
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <commonlib/console/post_codes.h>
+#include <commonlib/bsd/elog.h>
+#include <vb2_api.h>
+
+#include "valstr.h"
+
+#define PATH_PCI_BUS_SHIFT 8
+#define PATH_PCI_BUS_MASK 0xff
+#define PATH_PCI_DEV_SHIFT 3
+#define PATH_PCI_DEV_MASK 0x1f
+#define PATH_PCI_FN_SHIFT 0
+#define PATH_PCI_FN_MASK 0x03
+#define PATH_I2C_MODE10BIT_SHIFT 8
+#define PATH_I2C_MODE10BIT_MASK 0xff
+#define PATH_I2C_ADDRESS_MASK 0xff
+
+/* When true, then the separator is not printed */
+static int eventlog_printf_ignore_separator_once = 1;
+
+static void eventlog_printf(const char *format, ...)
+{
+ va_list args;
+
+ // Separator for each field
+ if (eventlog_printf_ignore_separator_once)
+ eventlog_printf_ignore_separator_once = 0;
+ else
+ fprintf(stdout, " | ");
+
+ va_start(args, format);
+ vfprintf(stdout, format, args);
+ va_end(args);
+}
+
+/*
+ * eventlog_print_timestamp - forms the key-value pair for event timestamp
+ *
+ * @entry: the smbios log entry to get the data information
+ *
+ * Forms the key-value description pair for the event timestamp.
+ */
+static void eventlog_print_timestamp(const struct event_header *event)
+{
+ const char *tm_format = "%y-%m-%d%t%H:%M:%S";
+ char tm_string[40];
+ struct tm tm;
+ time_t time;
+
+ memset(&tm, 0, sizeof(tm));
+
+ /* Time is in "hexa". Convert it to decimal, and then convert it to "tm" struct */
+ snprintf(tm_string, sizeof(tm_string), "%02x-%02x-%02x %02x:%02x:%02x", event->year,
+ event->month, event->day, event->hour, event->minute, event->second);
+
+ if (strptime(tm_string, tm_format, &tm) == NULL) {
+ /* Backup in case string could not be parsed. Timezone not included */
+ eventlog_printf("%02d%02x-%02x-%02x %02x:%02x:%02x",
+ (event->year > 0x80 && event->year < 0x99) ? 19 : 20,
+ event->year, event->month, event->day, event->hour,
+ event->minute, event->second);
+ return;
+ }
+
+ /* Set DST flag to -1 to indicate "not available" and let
+ * system determine if DST is on based on date */
+ tm.tm_isdst = -1;
+
+ time = mktime(&tm);
+ time += tm.tm_gmtoff; /* force adjust for timezone */
+
+ strftime(tm_string, sizeof(tm_string), "%Y-%m-%d %H:%M:%S", localtime(&time));
+
+ eventlog_printf("%s", tm_string);
+}
+
+
+/*
+ * eventlog_print_type - print the type of the entry
+ *
+ * @entry: the smbios log entry to get type information
+ *
+ */
+static void eventlog_print_type(const struct event_header *event)
+{
+ const char *type;
+ static const struct valstr elog_event_types[] = {
+ /* SMBIOS Event Log types, SMBIOSv2.4 section 3.3.16.1 */
+ {ELOG_TYPE_UNDEFINED_EVENT, "Reserved"},
+ {ELOG_TYPE_SINGLE_BIT_ECC_MEM_ERR, "Single-bit ECC memory error"},
+ {ELOG_TYPE_MULTI_BIT_ECC_MEM_ERR, "Multi-bit ECC memory error"},
+ {ELOG_TYPE_MEM_PARITY_ERR, "Parity memory error"},
+ {ELOG_TYPE_BUS_TIMEOUT, "Bus timeout"},
+ {ELOG_TYPE_IO_CHECK, "I/O channel check"},
+ {ELOG_TYPE_SW_NMI, "Software NMI"},
+ {ELOG_TYPE_POST_MEM_RESIZE, "POST memory resize"},
+ {ELOG_TYPE_POST_ERR, "POST error"},
+ {ELOG_TYPE_PCI_PERR, "PCI parity error"},
+ {ELOG_TYPE_PCI_SERR, "PCI system error"},
+ {ELOG_TYPE_CPU_FAIL, "CPU failure"},
+ {ELOG_TYPE_EISA_TIMEOUT, "EISA failsafe timer timeout"},
+ {ELOG_TYPE_CORRECTABLE_MEMLOG_DIS, "Correctable memory log disabled"},
+ {ELOG_TYPE_LOG_DISABLED, "Logging disabled, too many errors"},
+ {ELOG_TYPE_UNDEFINED_EVENT2, "Reserved"},
+ {ELOG_TYPE_SYS_LIMIT_EXCEED, "System limit exceeded"},
+ {ELOG_TYPE_ASYNC_HW_TIMER_EXPIRED, "Hardware watchdog reset"},
+ {ELOG_TYPE_SYS_CONFIG_INFO, "System configuration information"},
+ {ELOG_TYPE_HDD_INFO, "Hard-disk information"},
+ {ELOG_TYPE_SYS_RECONFIG, "System reconfigured"},
+ {ELOG_TYPE_CPU_ERROR, "Uncorrectable CPU-complex error"},
+ {ELOG_TYPE_LOG_CLEAR, "Log area cleared"},
+ {ELOG_TYPE_BOOT, "System boot"},
+
+ /* Extended events defined by OEMs */
+ {ELOG_TYPE_OS_EVENT, "Kernel Event"},
+ {ELOG_TYPE_OS_BOOT, "OS Boot"},
+ {ELOG_TYPE_EC_EVENT, "EC Event"},
+ {ELOG_TYPE_POWER_FAIL, "Power Fail"},
+ {ELOG_TYPE_SUS_POWER_FAIL, "SUS Power Fail"},
+ {ELOG_TYPE_PWROK_FAIL, "PWROK Fail"},
+ {ELOG_TYPE_SYS_PWROK_FAIL, "SYS PWROK Fail"},
+ {ELOG_TYPE_POWER_ON, "Power On"},
+ {ELOG_TYPE_POWER_BUTTON, "Power Button"},
+ {ELOG_TYPE_POWER_BUTTON_OVERRIDE, "Power Button Override"},
+ {ELOG_TYPE_RESET_BUTTON, "Reset Button"},
+ {ELOG_TYPE_SYSTEM_RESET, "System Reset"},
+ {ELOG_TYPE_RTC_RESET, "RTC Reset"},
+ {ELOG_TYPE_TCO_RESET, "TCO Reset"},
+ {ELOG_TYPE_ACPI_ENTER, "ACPI Enter"},
+ {ELOG_TYPE_ACPI_WAKE, "ACPI Wake"},
+ {ELOG_TYPE_ACPI_DEEP_WAKE, "ACPI Wake"},
+ {ELOG_TYPE_S0IX_ENTER, "S0ix Enter"},
+ {ELOG_TYPE_S0IX_EXIT, "S0ix Exit"},
+ {ELOG_TYPE_WAKE_SOURCE, "Wake Source"},
+ {ELOG_TYPE_CROS_DEVELOPER_MODE, "Chrome OS Developer Mode"},
+ {ELOG_TYPE_CROS_RECOVERY_MODE, "Chrome OS Recovery Mode"},
+ {ELOG_TYPE_MANAGEMENT_ENGINE, "Management Engine"},
+ {ELOG_TYPE_MANAGEMENT_ENGINE_EXT, "Management Engine Extra"},
+ {ELOG_TYPE_LAST_POST_CODE, "Last post code in previous boot"},
+ {ELOG_TYPE_POST_EXTRA, "Extra info from previous boot"},
+ {ELOG_TYPE_EC_SHUTDOWN, "EC Shutdown"},
+ {ELOG_TYPE_SLEEP, "Sleep"},
+ {ELOG_TYPE_WAKE, "Wake"},
+ {ELOG_TYPE_FW_WAKE, "FW Wake"},
+ {ELOG_TYPE_MEM_CACHE_UPDATE, "Memory Cache Update"},
+ {ELOG_TYPE_THERM_TRIP, "CPU Thermal Trip"},
+ {ELOG_TYPE_CR50_UPDATE, "cr50 Update Reset"},
+ {ELOG_TYPE_CR50_NEED_RESET, "cr50 Reset Required"},
+ {ELOG_TYPE_EC_DEVICE_EVENT, "EC Device"},
+ {ELOG_TYPE_EXTENDED_EVENT, "Extended Event"},
+
+ {ELOG_TYPE_EOL, "End of log"},
+ };
+
+ /* Passing NULL as default, because we want to print the event->type if it fails */
+ type = val2str_default(event->type, elog_event_types, NULL);
+
+ if (type == NULL) {
+ /* Indicate unknown type in value pair */
+ eventlog_printf("Unknown");
+ eventlog_printf("0x%02x", event->type);
+ return;
+ }
+
+ eventlog_printf("%s", type);
+}
+
+/*
+ * CMOS Extra log format:
+ * [31:24] = Extra Log Type
+ * [23:0] = Extra Log Data
+ *
+ * If Extra Log Type is 0x01 then Data is Device Path
+ * [23:16] = Device Type
+ * [15:0] = Encoded Device Path
+ */
+static int eventlog_print_post_extra(uint32_t extra)
+{
+ static const struct valstr path_type_values[] = {
+ {ELOG_DEV_PATH_TYPE_NONE, "None"},
+ {ELOG_DEV_PATH_TYPE_ROOT, "Root"},
+ {ELOG_DEV_PATH_TYPE_PCI, "PCI"},
+ {ELOG_DEV_PATH_TYPE_PNP, "PNP"},
+ {ELOG_DEV_PATH_TYPE_I2C, "I2C"},
+ {ELOG_DEV_PATH_TYPE_APIC, "APIC"},
+ {ELOG_DEV_PATH_TYPE_DOMAIN, "DOMAIN"},
+ {ELOG_DEV_PATH_TYPE_CPU_CLUSTER, "CPU Cluster"},
+ {ELOG_DEV_PATH_TYPE_CPU, "CPU"},
+ {ELOG_DEV_PATH_TYPE_CPU_BUS, "CPU Bus"},
+ {ELOG_DEV_PATH_TYPE_IOAPIC, "IO-APIC"},
+ {0, NULL},
+ };
+ const uint8_t type = (extra >> 16) & 0xff;
+
+ /* Currently only know how to print device path */
+ if ((extra >> 24) != ELOG_TYPE_POST_EXTRA_PATH) {
+ eventlog_printf("0x%08x", extra);
+ return 0;
+ }
+
+ eventlog_printf("%s", val2str(type, path_type_values));
+
+ /* Handle different device path types */
+ switch (type) {
+ case ELOG_DEV_PATH_TYPE_PCI:
+ eventlog_printf("%02x:%02x.%1x",
+ (extra >> PATH_PCI_BUS_SHIFT) & PATH_PCI_BUS_MASK,
+ (extra >> PATH_PCI_DEV_SHIFT) & PATH_PCI_DEV_MASK,
+ (extra >> PATH_PCI_FN_SHIFT) & PATH_PCI_FN_MASK);
+ break;
+ case ELOG_DEV_PATH_TYPE_PNP:
+ case ELOG_DEV_PATH_TYPE_I2C:
+ eventlog_printf("%02x:%02x",
+ (extra >> PATH_I2C_MODE10BIT_SHIFT) & PATH_I2C_MODE10BIT_MASK,
+ extra & PATH_I2C_ADDRESS_MASK);
+ break;
+ case ELOG_DEV_PATH_TYPE_APIC:
+ case ELOG_DEV_PATH_TYPE_DOMAIN:
+ case ELOG_DEV_PATH_TYPE_CPU_CLUSTER:
+ case ELOG_DEV_PATH_TYPE_CPU:
+ case ELOG_DEV_PATH_TYPE_CPU_BUS:
+ case ELOG_DEV_PATH_TYPE_IOAPIC:
+ eventlog_printf("0x%04x", extra & 0xffff);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * eventlog_print_data - print the data associated with the entry
+ *
+ * @event: the smbios log entry to get the data information
+ *
+ * Returns 0 on failure, 1 on success.
+ */
+static int eventlog_print_data(const struct event_header *event)
+{
+ static const struct valstr os_events[] = {
+ {ELOG_OS_EVENT_CLEAN, "Clean Shutdown"},
+ {ELOG_OS_EVENT_NMIWDT, "NMI Watchdog"},
+ {ELOG_OS_EVENT_PANIC, "Panic"},
+ {ELOG_OS_EVENT_OOPS, "Oops"},
+ {ELOG_OS_EVENT_DIE, "Die"},
+ {ELOG_OS_EVENT_MCE, "MCE"},
+ {ELOG_OS_EVENT_SOFTWDT, "Software Watchdog"},
+ {ELOG_OS_EVENT_MBE, "Multi-bit Error"},
+ {ELOG_OS_EVENT_TRIPLE, "Triple Fault"},
+ {ELOG_OS_EVENT_THERMAL, "Critical Thermal Threshold"},
+ {0, NULL},
+ };
+ static const struct valstr wake_source_types[] = {
+ {ELOG_WAKE_SOURCE_PCIE, "PCI Express"},
+ {ELOG_WAKE_SOURCE_PME, "PCI PME"},
+ {ELOG_WAKE_SOURCE_PME_INTERNAL, "Internal PME"},
+ {ELOG_WAKE_SOURCE_RTC, "RTC Alarm"},
+ {ELOG_WAKE_SOURCE_GPE, "GPE #"},
+ {ELOG_WAKE_SOURCE_SMBUS, "SMBALERT"},
+ {ELOG_WAKE_SOURCE_PWRBTN, "Power Button"},
+ {ELOG_WAKE_SOURCE_PME_HDA, "PME - HDA"},
+ {ELOG_WAKE_SOURCE_PME_GBE, "PME - GBE"},
+ {ELOG_WAKE_SOURCE_PME_EMMC, "PME - EMMC"},
+ {ELOG_WAKE_SOURCE_PME_SDCARD, "PME - SDCARD"},
+ {ELOG_WAKE_SOURCE_PME_PCIE1, "PME - PCIE1"},
+ {ELOG_WAKE_SOURCE_PME_PCIE2, "PME - PCIE2"},
+ {ELOG_WAKE_SOURCE_PME_PCIE3, "PME - PCIE3"},
+ {ELOG_WAKE_SOURCE_PME_PCIE4, "PME - PCIE4"},
+ {ELOG_WAKE_SOURCE_PME_PCIE5, "PME - PCIE5"},
+ {ELOG_WAKE_SOURCE_PME_PCIE6, "PME - PCIE6"},
+ {ELOG_WAKE_SOURCE_PME_PCIE7, "PME - PCIE7"},
+ {ELOG_WAKE_SOURCE_PME_PCIE8, "PME - PCIE8"},
+ {ELOG_WAKE_SOURCE_PME_PCIE9, "PME - PCIE9"},
+ {ELOG_WAKE_SOURCE_PME_PCIE10, "PME - PCIE10"},
+ {ELOG_WAKE_SOURCE_PME_PCIE11, "PME - PCIE11"},
+ {ELOG_WAKE_SOURCE_PME_PCIE12, "PME - PCIE12"},
+ {ELOG_WAKE_SOURCE_PME_SATA, "PME - SATA"},
+ {ELOG_WAKE_SOURCE_PME_CSE, "PME - CSE"},
+ {ELOG_WAKE_SOURCE_PME_CSE2, "PME - CSE2"},
+ {ELOG_WAKE_SOURCE_PME_CSE3, "PME - CSE"},
+ {ELOG_WAKE_SOURCE_PME_XHCI, "PME - XHCI"},
+ {ELOG_WAKE_SOURCE_PME_XDCI, "PME - XDCI"},
+ {ELOG_WAKE_SOURCE_PME_XHCI_USB_2, "PME - XHCI (USB 2.0 port)"},
+ {ELOG_WAKE_SOURCE_PME_XHCI_USB_3, "PME - XHCI (USB 3.0 port)"},
+ {ELOG_WAKE_SOURCE_PME_WIFI, "PME - WIFI"},
+ {ELOG_WAKE_SOURCE_PME_PCIE13, "PME - PCIE13"},
+ {ELOG_WAKE_SOURCE_PME_PCIE14, "PME - PCIE14"},
+ {ELOG_WAKE_SOURCE_PME_PCIE15, "PME - PCIE15"},
+ {ELOG_WAKE_SOURCE_PME_PCIE16, "PME - PCIE16"},
+ {ELOG_WAKE_SOURCE_PME_PCIE17, "PME - PCIE17"},
+ {ELOG_WAKE_SOURCE_PME_PCIE18, "PME - PCIE18"},
+ {ELOG_WAKE_SOURCE_PME_PCIE19, "PME - PCIE19"},
+ {ELOG_WAKE_SOURCE_PME_PCIE20, "PME - PCIE20"},
+ {ELOG_WAKE_SOURCE_PME_PCIE21, "PME - PCIE21"},
+ {ELOG_WAKE_SOURCE_PME_PCIE22, "PME - PCIE22"},
+ {ELOG_WAKE_SOURCE_PME_PCIE23, "PME - PCIE23"},
+ {ELOG_WAKE_SOURCE_PME_PCIE24, "PME - PCIE24"},
+ {ELOG_WAKE_SOURCE_GPIO, " GPIO #"},
+ {ELOG_WAKE_SOURCE_PME_TBT, "PME - Thunderbolt"},
+ {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS XHCI"},
+ {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS XDCI"},
+ {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS DMA"},
+ {0, NULL},
+ };
+ static const struct valstr ec_event_types[] = {
+ {EC_EVENT_LID_CLOSED, "Lid Closed"},
+ {EC_EVENT_LID_OPEN, "Lid Open"},
+ {EC_EVENT_POWER_BUTTON, "Power Button"},
+ {EC_EVENT_AC_CONNECTED, "AC Connected"},
+ {EC_EVENT_AC_DISCONNECTED, "AC Disconnected"},
+ {EC_EVENT_BATTERY_LOW, "Battery Low"},
+ {EC_EVENT_BATTERY_CRITICAL, "Battery Critical"},
+ {EC_EVENT_BATTERY, "Battery"},
+ {EC_EVENT_THERMAL_THRESHOLD, "Thermal Threshold"},
+ {EC_EVENT_DEVICE_EVENT, "Device Event"},
+ {EC_EVENT_THERMAL, "Thermal"},
+ {EC_EVENT_USB_CHARGER, "USB Charger"},
+ {EC_EVENT_KEY_PRESSED, "Key Pressed"},
+ {EC_EVENT_INTERFACE_READY, "Host Interface Ready"},
+ {EC_EVENT_KEYBOARD_RECOVERY, "Keyboard Recovery"},
+ {EC_EVENT_THERMAL_SHUTDOWN, "Thermal Shutdown in previous boot"},
+ {EC_EVENT_BATTERY_SHUTDOWN, "Battery Shutdown in previous boot"},
+ {EC_EVENT_THROTTLE_START, "Throttle Requested"},
+ {EC_EVENT_THROTTLE_STOP, "Throttle Request Removed"},
+ {EC_EVENT_HANG_DETECT, "Host Event Hang"},
+ {EC_EVENT_HANG_REBOOT, "Host Event Hang Reboot"},
+ {EC_EVENT_PD_MCU, "PD MCU Request"},
+ {EC_EVENT_BATTERY_STATUS, "Battery Status Request"},
+ {EC_EVENT_PANIC, "Panic Reset in previous boot"},
+ {EC_EVENT_KEYBOARD_FASTBOOT, "Keyboard Fastboot Recovery"},
+ {EC_EVENT_RTC, "RTC"},
+ {EC_EVENT_MKBP, "MKBP"},
+ {EC_EVENT_USB_MUX, "USB MUX change"},
+ {EC_EVENT_MODE_CHANGE, "Mode change"},
+ {EC_EVENT_KEYBOARD_RECOVERY_HWREINIT,
+ "Keyboard Recovery Forced Hardware Reinit"},
+ {EC_EVENT_EXTENDED, "Extended EC events"},
+ {0, NULL},
+ };
+ static const struct valstr ec_device_event_types[] = {
+ {ELOG_EC_DEVICE_EVENT_TRACKPAD, "Trackpad"},
+ {ELOG_EC_DEVICE_EVENT_DSP, "DSP"},
+ {ELOG_EC_DEVICE_EVENT_WIFI, "WiFi"},
+ {0, NULL},
+ };
+
+ static const struct valstr cros_recovery_reasons[] = {
+ {VB2_RECOVERY_LEGACY, "Legacy Utility"},
+ {VB2_RECOVERY_RO_MANUAL, "Recovery Button Pressed"},
+ {VB2_RECOVERY_RO_INVALID_RW, "RW Failed Signature Check"},
+ {VB2_RECOVERY_DEPRECATED_RO_S3_RESUME, "S3 Resume Failed"},
+ {VB2_RECOVERY_DEPRECATED_RO_TPM_ERROR, "TPM Error in RO Firmware"},
+ {VB2_RECOVERY_RO_SHARED_DATA, "Shared Data Error in RO Firmware"},
+ {VB2_RECOVERY_DEPRECATED_RO_TEST_S3, "Test Error from S3 Resume()"},
+ {VB2_RECOVERY_DEPRECATED_RO_TEST_LF, "Test Error from LoadFirmware()"},
+ {VB2_RECOVERY_DEPRECATED_RO_TEST_LFS, "Test Error from LoadFirmwareSetup()"},
+ {VB2_RECOVERY_DEPRECATED_RW_NOT_DONE, "RW firmware check not done"},
+ {VB2_RECOVERY_DEPRECATED_RW_DEV_FLAG_MISMATCH,
+ "RW firmware developer flag mismatch"},
+ {VB2_RECOVERY_DEPRECATED_RW_REC_FLAG_MISMATCH,
+ "RW firmware recovery flash mismatch"},
+ {VB2_RECOVERY_FW_KEYBLOCK, "RW firmware unable to verify keyblock"},
+ {VB2_RECOVERY_FW_KEY_ROLLBACK, "RW firmware key version rollback detected"},
+ {VB2_RECOVERY_DEPRECATED_RW_DATA_KEY_PARSE,
+ "RW firmware unable to parse data key"},
+ {VB2_RECOVERY_FW_PREAMBLE, "RW firmware unable to verify preamble"},
+ {VB2_RECOVERY_FW_ROLLBACK, "RW firmware version rollback detected"},
+ {VB2_RECOVERY_DEPRECATED_FW_HEADER_VALID, "RW firmware header is valid"},
+ {VB2_RECOVERY_DEPRECATED_FW_GET_FW_BODY,
+ "RW firmware unable to get firmware body"},
+ {VB2_RECOVERY_DEPRECATED_FW_HASH_WRONG_SIZE, "RW firmware hash is wrong size"},
+ {VB2_RECOVERY_FW_BODY, "RW firmware unable to verify firmware body"},
+ {VB2_RECOVERY_DEPRECATED_FW_VALID, "RW firmware is valid"},
+ {VB2_RECOVERY_DEPRECATED_FW_NO_RO_NORMAL,
+ "RW firmware read-only normal path is not supported"},
+ {VB2_RECOVERY_RO_FIRMWARE, "Firmware Boot Failure"},
+ {VB2_RECOVERY_RO_TPM_REBOOT, "Recovery Mode TPM Reboot"},
+ {VB2_RECOVERY_EC_SOFTWARE_SYNC, "EC Software Sync Error"},
+ {VB2_RECOVERY_EC_UNKNOWN_IMAGE, "Unable to determine active EC image"},
+ {VB2_RECOVERY_DEPRECATED_EC_HASH,
+ "EC software sync error obtaining EC image hash"},
+ {VB2_RECOVERY_DEPRECATED_EC_EXPECTED_IMAGE,
+ "EC software sync error obtaining expected EC image from BIOS"},
+ {VB2_RECOVERY_EC_UPDATE, "EC software sync error updating EC"},
+ {VB2_RECOVERY_EC_JUMP_RW, "EC software sync unable to jump to EC-RW"},
+ {VB2_RECOVERY_EC_PROTECT, "EC software sync protection error"},
+ {VB2_RECOVERY_EC_EXPECTED_HASH,
+ "EC software sync error obtaining expected EC hash from BIOS"},
+ {VB2_RECOVERY_DEPRECATED_EC_HASH_MISMATCH,
+ "EC software sync error comparing expected EC hash and image"},
+ {VB2_RECOVERY_SECDATA_FIRMWARE_INIT, "Secure NVRAM (TPM) initialization error"},
+ {VB2_RECOVERY_GBB_HEADER, "Error parsing GBB header"},
+ {VB2_RECOVERY_TPM_CLEAR_OWNER, "Error trying to clear TPM owner"},
+ {VB2_RECOVERY_DEV_SWITCH, "Error reading or updating developer switch"},
+ {VB2_RECOVERY_FW_SLOT, "Error selecting RW firmware slot"},
+ {VB2_RECOVERY_AUXFW_UPDATE, "Error updating AUX firmware"},
+ {VB2_RECOVERY_INTEL_CSE_LITE_SKU, "Intel CSE Lite SKU fimrware failure"},
+ {VB2_RECOVERY_RO_UNSPECIFIED, "Unknown Error in RO Firmware"},
+ {VB2_RECOVERY_DEPRECATED_RW_DEV_SCREEN, "User Requested from Developer Screen"},
+ {VB2_RECOVERY_DEPRECATED_RW_NO_OS, "No OS Kernel Detected"},
+ {VB2_RECOVERY_RW_INVALID_OS, "OS kernel or rootfs failed signature check"},
+ {VB2_RECOVERY_DEPRECATED_RW_TPM_ERROR, "TPM Error in RW Firmware"},
+ {VB2_RECOVERY_DEPRECATED_RW_DEV_MISMATCH, "RW Dev Firmware but not Dev Mode"},
+ {VB2_RECOVERY_RW_SHARED_DATA, "Shared Data Error in RW Firmware"},
+ {VB2_RECOVERY_DEPRECATED_RW_TEST_LK, "Test Error from LoadKernel()"},
+ {VB2_RECOVERY_DEPRECATED_RW_NO_DISK, "No Bootable Disk Found"},
+ {VB2_RECOVERY_TPM_E_FAIL, "TPM_E_FAIL or TPM_E_FAILEDSELFTEST"},
+ {VB2_RECOVERY_RO_TPM_S_ERROR, "TPM setup error in read-only firmware"},
+ {VB2_RECOVERY_RO_TPM_W_ERROR, "TPM write error in read-only firmware"},
+ {VB2_RECOVERY_RO_TPM_L_ERROR, "TPM lock error in read-only firmware"},
+ {VB2_RECOVERY_RO_TPM_U_ERROR, "TPM update error in read-only firmware"},
+ {VB2_RECOVERY_RW_TPM_R_ERROR, "TPM read error in rewritable firmware"},
+ {VB2_RECOVERY_RW_TPM_W_ERROR, "TPM write error in rewritable firmware"},
+ {VB2_RECOVERY_RW_TPM_L_ERROR, "TPM lock error in rewritable firmware"},
+ {VB2_RECOVERY_EC_HASH_FAILED, "EC software sync unable to get EC image hash"},
+ {VB2_RECOVERY_EC_HASH_SIZE, "EC software sync invalid image hash size"},
+ {VB2_RECOVERY_LK_UNSPECIFIED, "Unspecified error while trying to load kernel"},
+ {VB2_RECOVERY_RW_NO_DISK, "No bootable storage device in system"},
+ {VB2_RECOVERY_RW_NO_KERNEL, "No bootable kernel found on disk"},
+ {VB2_RECOVERY_DEPRECATED_RW_BCB_ERROR, "BCB partition error on disk"},
+ {VB2_RECOVERY_SECDATA_KERNEL_INIT,
+ "Kernel secure NVRAM (TPM) initialization error"},
+ {VB2_RECOVERY_DEPRECATED_FW_FASTBOOT, "Fastboot-mode requested in firmware"},
+ {VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR,
+ "Recovery hash space lock error in RO firmware"},
+ {VB2_RECOVERY_TPM_DISABLE_FAILED,
+ "Failed to disable TPM before running untrusted code"},
+ {VB2_RECOVERY_ALTFW_HASH_MISMATCH,
+ "Verification of alternative firmware payload failed"},
+ {VB2_RECOVERY_SECDATA_FWMP_INIT, "FWMP secure data initialization failed"},
+ {VB2_RECOVERY_CR50_BOOT_MODE, "Failed to get boot mode from TPM/Cr50"},
+ {VB2_RECOVERY_ESCAPE_NO_BOOT,
+ "Attempt to escape from NO_BOOT mode was detected"},
+ {VB2_RECOVERY_RW_UNSPECIFIED, "Unspecified/unknown error in RW firmware"},
+ {VB2_RECOVERY_DEPRECATED_KE_DM_VERITY, "DM-verity error"},
+ {VB2_RECOVERY_DEPRECATED_KE_UNSPECIFIED, "Unspecified/unknown error in kernel"},
+ {VB2_RECOVERY_US_TEST, "Recovery mode test from user-mode"},
+ {VB2_RECOVERY_DEPRECATED_BCB_USER_MODE, "User-mode requested recovery via BCB"},
+ {VB2_RECOVERY_DEPRECATED_US_FASTBOOT, "User-mode requested fastboot mode"},
+ {VB2_RECOVERY_TRAIN_AND_REBOOT,
+ "User requested recovery for training memory and rebooting"},
+ {VB2_RECOVERY_US_UNSPECIFIED, "Unknown Error in User Mode"},
+ {0, NULL},
+ };
+ static const struct valstr me_path_types[] = {
+ {ELOG_ME_PATH_NORMAL, "Normal"},
+ {ELOG_ME_PATH_NORMAL, "S3 Wake"},
+ {ELOG_ME_PATH_ERROR, "Error"},
+ {ELOG_ME_PATH_RECOVERY, "Recovery"},
+ {ELOG_ME_PATH_DISABLED, "Disabled"},
+ {ELOG_ME_PATH_FW_UPDATE, "Firmware Update"},
+ {0, NULL},
+ };
+ static const struct valstr coreboot_post_codes[] = {
+ {POST_RESET_VECTOR_CORRECT, "Reset Vector Correct"},
+ {POST_ENTER_PROTECTED_MODE, "Enter Protected Mode"},
+ {POST_PREPARE_RAMSTAGE, "Prepare RAM stage"},
+ {POST_ENTRY_C_START, "RAM stage Start"},
+ {POST_MEM_PREINIT_PREP_START, "Preparing memory init params"},
+ {POST_MEM_PREINIT_PREP_END, "Memory init param preparation complete"},
+ {POST_CONSOLE_READY, "Console is ready"},
+ {POST_CONSOLE_BOOT_MSG, "Console Boot Message"},
+ {POST_ENABLING_CACHE, "Before Enabling Cache"},
+ {POST_PRE_HARDWAREMAIN, "Before Hardware Main"},
+ {POST_ENTRY_HARDWAREMAIN, "First call in Hardware Main"},
+ {POST_BS_PRE_DEVICE, "Before Device Probe"},
+ {POST_BS_DEV_INIT_CHIPS, "Initialize Chips"},
+ {POST_BS_DEV_ENUMERATE, "Device Enumerate"},
+ {POST_BS_DEV_RESOURCES, "Device Resource Allocation"},
+ {POST_BS_DEV_ENABLE, "Device Enable"},
+ {POST_BS_DEV_INIT, "Device Initialize"},
+ {POST_BS_POST_DEVICE, "After Device Probe"},
+ {POST_BS_OS_RESUME_CHECK, "OS Resume Check"},
+ {POST_BS_OS_RESUME, "OS Resume"},
+ {POST_BS_WRITE_TABLES, "Write Tables"},
+ {POST_BS_PAYLOAD_LOAD, "Load Payload"},
+ {POST_BS_PAYLOAD_BOOT, "Boot Payload"},
+ {POST_FSP_NOTIFY_BEFORE_END_OF_FIRMWARE, "FSP Notify Before End of Firmware"},
+ {POST_FSP_NOTIFY_AFTER_END_OF_FIRMWARE, "FSP Notify After End of Firmware"},
+ {POST_FSP_TEMP_RAM_INIT, "FSP-T Enter"},
+ {POST_FSP_TEMP_RAM_EXIT, "FSP-T Exit"},
+ {POST_FSP_MEMORY_INIT, "FSP-M Enter"},
+ {POST_FSP_SILICON_INIT, "FSP-S Enter"},
+ {POST_FSP_NOTIFY_BEFORE_ENUMERATE, "FSP Notify Before Enumerate"},
+ {POST_FSP_NOTIFY_BEFORE_FINALIZE, "FSP Notify Before Finalize"},
+ {POST_OS_ENTER_PTS, "ACPI _PTS Method"},
+ {POST_OS_ENTER_WAKE, "ACPI _WAK Method"},
+ {POST_FSP_MEMORY_EXIT, "FSP-M Exit"},
+ {POST_FSP_SILICON_EXIT, "FSP-S Exit"},
+ {POST_FSP_MULTI_PHASE_SI_INIT_ENTRY, "FSP-S Init Enter"},
+ {POST_FSP_MULTI_PHASE_SI_INIT_EXIT, "FPS-S Init Exit"},
+ {POST_FSP_NOTIFY_AFTER_ENUMERATE, "FSP Notify After Enumerate"},
+ {POST_FSP_NOTIFY_AFTER_FINALIZE, "FSP Notify After Finalize"},
+ {POST_INVALID_ROM, "Invalid ROM"},
+ {POST_INVALID_CBFS, "Invalid CBFS"},
+ {POST_INVALID_VENDOR_BINARY, "Invalid Vendor Binary"},
+ {POST_RAM_FAILURE, "RAM Failure"},
+ {POST_HW_INIT_FAILURE, "Hardware Init Failure"},
+ {POST_VIDEO_FAILURE, "Video Failure"},
+ {POST_TPM_FAILURE, "TPM Failure"},
+ {POST_DEAD_CODE, "Dead Code"},
+ {POST_RESUME_FAILURE, "Resume Failure"},
+ {POST_JUMPING_TO_PAYLOAD, "Before Jump to Payload"},
+ {POST_ENTER_ELF_BOOT, "Before ELF Boot"},
+ {POST_OS_RESUME, "Before OS Resume"},
+ {POST_OS_BOOT, "Before OS Boot"},
+ {POST_DIE, "coreboot Dead"},
+ {0, NULL},
+ };
+ static const struct valstr mem_cache_slots[] = {
+ {ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL, "Normal"},
+ {ELOG_MEM_CACHE_UPDATE_SLOT_RECOVERY, "Recovery"},
+ {ELOG_MEM_CACHE_UPDATE_SLOT_VARIABLE, "Variable"},
+ {0, NULL},
+ };
+ static const struct valstr mem_cache_statuses[] = {
+ {ELOG_MEM_CACHE_UPDATE_STATUS_SUCCESS, "Success"},
+ {ELOG_MEM_CACHE_UPDATE_STATUS_FAIL, "Fail"},
+ {0, NULL},
+ };
+
+ static const struct valstr extended_event_subtypes[] = {
+ {ELOG_SLEEP_PENDING_PM1_WAKE, "S3 failed due to pending wake event, PM1"},
+ {ELOG_SLEEP_PENDING_GPE0_WAKE, "S3 failed due to pending wake event, GPE0"},
+ {0, NULL},
+ };
+
+ switch (event->type) {
+ case ELOG_TYPE_LOG_CLEAR: {
+ const uint16_t *bytes = event_get_data(event);
+ eventlog_printf("%u", *bytes);
+ break;
+ }
+
+ case ELOG_TYPE_BOOT: {
+ const uint32_t *count = event_get_data(event);
+ eventlog_printf("%u", *count);
+ break;
+ }
+ case ELOG_TYPE_LAST_POST_CODE: {
+ const uint16_t *code = event_get_data(event);
+ eventlog_printf("0x%02x", *code);
+ eventlog_printf("%s", val2str(*code, coreboot_post_codes));
+ break;
+ }
+ case ELOG_TYPE_POST_EXTRA: {
+ const uint32_t *extra = event_get_data(event);
+ eventlog_print_post_extra(*extra);
+ break;
+ }
+ case ELOG_TYPE_OS_EVENT: {
+ const uint32_t *osevent = event_get_data(event);
+ eventlog_printf("%s", val2str(*osevent, os_events));
+ break;
+ }
+ case ELOG_TYPE_ACPI_ENTER:
+ case ELOG_TYPE_ACPI_WAKE: {
+ const uint8_t *state = event_get_data(event);
+ eventlog_printf("S%u", *state);
+ break;
+ }
+ case ELOG_TYPE_ACPI_DEEP_WAKE: {
+ const uint8_t *state = event_get_data(event);
+ eventlog_printf("Deep S%u", *state);
+ break;
+ }
+ case ELOG_TYPE_WAKE_SOURCE: {
+ const struct elog_event_data_wake *wake_source;
+ wake_source = event_get_data(event);
+ eventlog_printf("%s", val2str(wake_source->source, wake_source_types));
+ eventlog_printf("%u", wake_source->instance);
+ break;
+ }
+ case ELOG_TYPE_EC_EVENT: {
+ const uint8_t *ec_event = event_get_data(event);
+ eventlog_printf("%s", val2str(*ec_event, ec_event_types));
+ break;
+ }
+ case ELOG_TYPE_EC_DEVICE_EVENT: {
+ const uint8_t *dev_event = event_get_data(event);
+ eventlog_printf("%s", val2str(*dev_event, ec_device_event_types));
+ break;
+ }
+ case ELOG_TYPE_CROS_RECOVERY_MODE: {
+ const uint8_t *reason = event_get_data(event);
+ eventlog_printf("%s", val2str(*reason, cros_recovery_reasons));
+ eventlog_printf("0x%02x", *reason);
+ break;
+ }
+ case ELOG_TYPE_MANAGEMENT_ENGINE: {
+ const uint8_t *path = event_get_data(event);
+ eventlog_printf("%s", val2str(*path, me_path_types));
+ break;
+ }
+ case ELOG_TYPE_MEM_CACHE_UPDATE: {
+ const struct elog_event_mem_cache_update *update;
+ update = event_get_data(event);
+ eventlog_printf("%s", val2str(update->slot, mem_cache_slots));
+ eventlog_printf("%s", val2str(update->status, mem_cache_statuses));
+ break;
+ }
+ case ELOG_TYPE_EXTENDED_EVENT: {
+ const struct elog_event_extended_event *ext_event;
+ ext_event = event_get_data(event);
+ eventlog_printf("%s", val2str(ext_event->event_type, extended_event_subtypes));
+ eventlog_printf("0x%X", ext_event->event_complement);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+void eventlog_print_event(const struct event_header *event, int count)
+{
+ /* Ignore the printf separator at the beginning and end of each line */
+ eventlog_printf_ignore_separator_once = 1;
+
+ eventlog_printf("%d", count);
+ eventlog_print_timestamp(event);
+ eventlog_print_type(event);
+ eventlog_print_data(event);
+
+ /* End of line, after printing each event */
+ eventlog_printf_ignore_separator_once = 1;
+ eventlog_printf("\n");
+}
diff --git a/util/cbfstool/eventlog.h b/util/cbfstool/eventlog.h
new file mode 100644
index 0000000000..baecb21db6
--- /dev/null
+++ b/util/cbfstool/eventlog.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#ifndef EVENTLOG_H_
+#define EVENTLOG_H_
+
+struct event_header;
+
+void eventlog_print_event(const struct event_header *event, int count);
+
+#endif // EVENTLOG_H_