diff options
author | Ricardo Quesada <ricardoq@google.com> | 2021-07-16 16:49:04 -0700 |
---|---|---|
committer | Paul Fagerburg <pfagerburg@chromium.org> | 2021-08-05 22:00:35 +0000 |
commit | c2cf3946c95cca7a84b87725b453fdf2b8932ffd (patch) | |
tree | 0600ce9b494b28bafcb56d8ffc171443e7c648f3 /util/cbfstool | |
parent | cb4bb393b52d8feb0979afd972c2fb0c6e41d9eb (diff) |
util/elogtool: add tool to print elog events
Add a new tool that that prints elog events.
The tool, as input, accepts either a file with the RW_ELOG contents, or
if the file is not provided it reads the contents of RW_ELOG by calling
the "flashrom" tool.
The tool is based on "mosys eventlog list"[1]. For the moment it only
supports "list", but future commits will add additional functionality.
This commit also adds missing ELOG defines needed for the tool. These
defines are added with the rest of the ELOG defines, in
include/commonlib/bsd/elog.h
The tool is placed inside util/cbfstool. The rationale behind the
decision, is that this tool shares a lot in common with the other tools
located in cbfstool: vboot dependency, shared files like common.o and
valstr.o, and in spirit is similar to some of the tools located in
cbfstool/.
As an example, you call the tool like the following:
$ elogtool list -f rw_elog_dump.bin
[1]: https://chromium.googlesource.com/chromiumos/platform/mosys/+/refs/heads/main/lib/eventlog/elog.c
BUG=b:172210863
Signed-off-by: Ricardo Quesada <ricardoq@google.com>
Change-Id: Ia1fe1c9ed3c4c6bda846055d4b10943b54463935
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56406
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Diffstat (limited to 'util/cbfstool')
-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 |
5 files changed, 827 insertions, 2 deletions
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_ |