diff options
-rw-r--r-- | src/commonlib/bsd/elog.c | 21 | ||||
-rw-r--r-- | src/commonlib/bsd/include/commonlib/bsd/elog.h | 77 | ||||
-rw-r--r-- | util/cbfstool/Makefile | 10 | ||||
-rw-r--r-- | util/cbfstool/Makefile.inc | 12 | ||||
-rw-r--r-- | util/cbfstool/elogtool.c | 161 | ||||
-rw-r--r-- | util/cbfstool/eventlog.c | 636 | ||||
-rw-r--r-- | util/cbfstool/eventlog.h | 10 |
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_ |