blob: e9a4e8e734ed52d7b615812a889cfcfd83c13a42 [file] [log] [blame]
Ricardo Quesadac2cf3942021-07-16 16:49:04 -07001/* SPDX-License-Identifier: BSD-3-Clause */
2
3#include "eventlog.h"
4
5#include <inttypes.h>
6#include <stdarg.h>
7#include <stdlib.h>
8#include <time.h>
9
10#include <commonlib/console/post_codes.h>
11#include <commonlib/bsd/elog.h>
12#include <vb2_api.h>
13
Ricardo Quesada49a96a92021-08-16 11:25:52 -070014#include "common.h"
Ricardo Quesadac2cf3942021-07-16 16:49:04 -070015#include "valstr.h"
16
17#define PATH_PCI_BUS_SHIFT 8
18#define PATH_PCI_BUS_MASK 0xff
19#define PATH_PCI_DEV_SHIFT 3
20#define PATH_PCI_DEV_MASK 0x1f
21#define PATH_PCI_FN_SHIFT 0
22#define PATH_PCI_FN_MASK 0x03
23#define PATH_I2C_MODE10BIT_SHIFT 8
24#define PATH_I2C_MODE10BIT_MASK 0xff
25#define PATH_I2C_ADDRESS_MASK 0xff
26
27/* When true, then the separator is not printed */
28static int eventlog_printf_ignore_separator_once = 1;
29
30static void eventlog_printf(const char *format, ...)
31{
32 va_list args;
33
34 // Separator for each field
35 if (eventlog_printf_ignore_separator_once)
36 eventlog_printf_ignore_separator_once = 0;
37 else
38 fprintf(stdout, " | ");
39
40 va_start(args, format);
41 vfprintf(stdout, format, args);
42 va_end(args);
43}
44
45/*
46 * eventlog_print_timestamp - forms the key-value pair for event timestamp
47 *
48 * @entry: the smbios log entry to get the data information
49 *
50 * Forms the key-value description pair for the event timestamp.
51 */
52static void eventlog_print_timestamp(const struct event_header *event)
53{
54 const char *tm_format = "%y-%m-%d%t%H:%M:%S";
55 char tm_string[40];
56 struct tm tm;
57 time_t time;
58
59 memset(&tm, 0, sizeof(tm));
60
61 /* Time is in "hexa". Convert it to decimal, and then convert it to "tm" struct */
62 snprintf(tm_string, sizeof(tm_string), "%02x-%02x-%02x %02x:%02x:%02x", event->year,
63 event->month, event->day, event->hour, event->minute, event->second);
64
65 if (strptime(tm_string, tm_format, &tm) == NULL) {
66 /* Backup in case string could not be parsed. Timezone not included */
67 eventlog_printf("%02d%02x-%02x-%02x %02x:%02x:%02x",
68 (event->year > 0x80 && event->year < 0x99) ? 19 : 20,
69 event->year, event->month, event->day, event->hour,
70 event->minute, event->second);
71 return;
72 }
73
74 /* Set DST flag to -1 to indicate "not available" and let
75 * system determine if DST is on based on date */
76 tm.tm_isdst = -1;
77
78 time = mktime(&tm);
79 time += tm.tm_gmtoff; /* force adjust for timezone */
80
81 strftime(tm_string, sizeof(tm_string), "%Y-%m-%d %H:%M:%S", localtime(&time));
82
83 eventlog_printf("%s", tm_string);
84}
85
86
87/*
88 * eventlog_print_type - print the type of the entry
89 *
90 * @entry: the smbios log entry to get type information
91 *
92 */
93static void eventlog_print_type(const struct event_header *event)
94{
95 const char *type;
96 static const struct valstr elog_event_types[] = {
97 /* SMBIOS Event Log types, SMBIOSv2.4 section 3.3.16.1 */
98 {ELOG_TYPE_UNDEFINED_EVENT, "Reserved"},
99 {ELOG_TYPE_SINGLE_BIT_ECC_MEM_ERR, "Single-bit ECC memory error"},
100 {ELOG_TYPE_MULTI_BIT_ECC_MEM_ERR, "Multi-bit ECC memory error"},
101 {ELOG_TYPE_MEM_PARITY_ERR, "Parity memory error"},
102 {ELOG_TYPE_BUS_TIMEOUT, "Bus timeout"},
103 {ELOG_TYPE_IO_CHECK, "I/O channel check"},
104 {ELOG_TYPE_SW_NMI, "Software NMI"},
105 {ELOG_TYPE_POST_MEM_RESIZE, "POST memory resize"},
106 {ELOG_TYPE_POST_ERR, "POST error"},
107 {ELOG_TYPE_PCI_PERR, "PCI parity error"},
108 {ELOG_TYPE_PCI_SERR, "PCI system error"},
109 {ELOG_TYPE_CPU_FAIL, "CPU failure"},
110 {ELOG_TYPE_EISA_TIMEOUT, "EISA failsafe timer timeout"},
111 {ELOG_TYPE_CORRECTABLE_MEMLOG_DIS, "Correctable memory log disabled"},
112 {ELOG_TYPE_LOG_DISABLED, "Logging disabled, too many errors"},
113 {ELOG_TYPE_UNDEFINED_EVENT2, "Reserved"},
114 {ELOG_TYPE_SYS_LIMIT_EXCEED, "System limit exceeded"},
115 {ELOG_TYPE_ASYNC_HW_TIMER_EXPIRED, "Hardware watchdog reset"},
116 {ELOG_TYPE_SYS_CONFIG_INFO, "System configuration information"},
117 {ELOG_TYPE_HDD_INFO, "Hard-disk information"},
118 {ELOG_TYPE_SYS_RECONFIG, "System reconfigured"},
119 {ELOG_TYPE_CPU_ERROR, "Uncorrectable CPU-complex error"},
120 {ELOG_TYPE_LOG_CLEAR, "Log area cleared"},
121 {ELOG_TYPE_BOOT, "System boot"},
122
123 /* Extended events defined by OEMs */
124 {ELOG_TYPE_OS_EVENT, "Kernel Event"},
125 {ELOG_TYPE_OS_BOOT, "OS Boot"},
126 {ELOG_TYPE_EC_EVENT, "EC Event"},
127 {ELOG_TYPE_POWER_FAIL, "Power Fail"},
128 {ELOG_TYPE_SUS_POWER_FAIL, "SUS Power Fail"},
129 {ELOG_TYPE_PWROK_FAIL, "PWROK Fail"},
130 {ELOG_TYPE_SYS_PWROK_FAIL, "SYS PWROK Fail"},
131 {ELOG_TYPE_POWER_ON, "Power On"},
132 {ELOG_TYPE_POWER_BUTTON, "Power Button"},
133 {ELOG_TYPE_POWER_BUTTON_OVERRIDE, "Power Button Override"},
134 {ELOG_TYPE_RESET_BUTTON, "Reset Button"},
135 {ELOG_TYPE_SYSTEM_RESET, "System Reset"},
136 {ELOG_TYPE_RTC_RESET, "RTC Reset"},
137 {ELOG_TYPE_TCO_RESET, "TCO Reset"},
138 {ELOG_TYPE_ACPI_ENTER, "ACPI Enter"},
139 {ELOG_TYPE_ACPI_WAKE, "ACPI Wake"},
140 {ELOG_TYPE_ACPI_DEEP_WAKE, "ACPI Wake"},
141 {ELOG_TYPE_S0IX_ENTER, "S0ix Enter"},
142 {ELOG_TYPE_S0IX_EXIT, "S0ix Exit"},
143 {ELOG_TYPE_WAKE_SOURCE, "Wake Source"},
Jon Murphyc4e90452022-06-28 10:36:23 -0600144 {ELOG_TYPE_CROS_DEVELOPER_MODE, "ChromeOS Developer Mode"},
145 {ELOG_TYPE_CROS_RECOVERY_MODE, "ChromeOS Recovery Mode"},
Ricardo Quesadac2cf3942021-07-16 16:49:04 -0700146 {ELOG_TYPE_MANAGEMENT_ENGINE, "Management Engine"},
147 {ELOG_TYPE_MANAGEMENT_ENGINE_EXT, "Management Engine Extra"},
148 {ELOG_TYPE_LAST_POST_CODE, "Last post code in previous boot"},
149 {ELOG_TYPE_POST_EXTRA, "Extra info from previous boot"},
150 {ELOG_TYPE_EC_SHUTDOWN, "EC Shutdown"},
151 {ELOG_TYPE_SLEEP, "Sleep"},
152 {ELOG_TYPE_WAKE, "Wake"},
153 {ELOG_TYPE_FW_WAKE, "FW Wake"},
154 {ELOG_TYPE_MEM_CACHE_UPDATE, "Memory Cache Update"},
155 {ELOG_TYPE_THERM_TRIP, "CPU Thermal Trip"},
156 {ELOG_TYPE_CR50_UPDATE, "cr50 Update Reset"},
157 {ELOG_TYPE_CR50_NEED_RESET, "cr50 Reset Required"},
158 {ELOG_TYPE_EC_DEVICE_EVENT, "EC Device"},
159 {ELOG_TYPE_EXTENDED_EVENT, "Extended Event"},
Hsuan Ting Chena5cbe272021-11-01 19:14:01 +0800160 {ELOG_TYPE_CROS_DIAGNOSTICS, "Diagnostics Mode"},
Subrata Banik8b468402022-07-17 18:20:24 +0530161 {ELOG_TYPE_FW_VBOOT_INFO, "Firmware vboot info"},
Ricardo Quesadac2cf3942021-07-16 16:49:04 -0700162
163 {ELOG_TYPE_EOL, "End of log"},
164 };
165
166 /* Passing NULL as default, because we want to print the event->type if it fails */
167 type = val2str_default(event->type, elog_event_types, NULL);
168
169 if (type == NULL) {
170 /* Indicate unknown type in value pair */
171 eventlog_printf("Unknown");
172 eventlog_printf("0x%02x", event->type);
173 return;
174 }
175
176 eventlog_printf("%s", type);
177}
178
179/*
180 * CMOS Extra log format:
181 * [31:24] = Extra Log Type
182 * [23:0] = Extra Log Data
183 *
184 * If Extra Log Type is 0x01 then Data is Device Path
185 * [23:16] = Device Type
186 * [15:0] = Encoded Device Path
187 */
188static int eventlog_print_post_extra(uint32_t extra)
189{
190 static const struct valstr path_type_values[] = {
191 {ELOG_DEV_PATH_TYPE_NONE, "None"},
192 {ELOG_DEV_PATH_TYPE_ROOT, "Root"},
193 {ELOG_DEV_PATH_TYPE_PCI, "PCI"},
194 {ELOG_DEV_PATH_TYPE_PNP, "PNP"},
195 {ELOG_DEV_PATH_TYPE_I2C, "I2C"},
196 {ELOG_DEV_PATH_TYPE_APIC, "APIC"},
197 {ELOG_DEV_PATH_TYPE_DOMAIN, "DOMAIN"},
198 {ELOG_DEV_PATH_TYPE_CPU_CLUSTER, "CPU Cluster"},
199 {ELOG_DEV_PATH_TYPE_CPU, "CPU"},
200 {ELOG_DEV_PATH_TYPE_CPU_BUS, "CPU Bus"},
201 {ELOG_DEV_PATH_TYPE_IOAPIC, "IO-APIC"},
202 {0, NULL},
203 };
204 const uint8_t type = (extra >> 16) & 0xff;
205
206 /* Currently only know how to print device path */
207 if ((extra >> 24) != ELOG_TYPE_POST_EXTRA_PATH) {
208 eventlog_printf("0x%08x", extra);
209 return 0;
210 }
211
212 eventlog_printf("%s", val2str(type, path_type_values));
213
214 /* Handle different device path types */
215 switch (type) {
216 case ELOG_DEV_PATH_TYPE_PCI:
217 eventlog_printf("%02x:%02x.%1x",
218 (extra >> PATH_PCI_BUS_SHIFT) & PATH_PCI_BUS_MASK,
219 (extra >> PATH_PCI_DEV_SHIFT) & PATH_PCI_DEV_MASK,
220 (extra >> PATH_PCI_FN_SHIFT) & PATH_PCI_FN_MASK);
221 break;
222 case ELOG_DEV_PATH_TYPE_PNP:
223 case ELOG_DEV_PATH_TYPE_I2C:
224 eventlog_printf("%02x:%02x",
225 (extra >> PATH_I2C_MODE10BIT_SHIFT) & PATH_I2C_MODE10BIT_MASK,
226 extra & PATH_I2C_ADDRESS_MASK);
227 break;
228 case ELOG_DEV_PATH_TYPE_APIC:
229 case ELOG_DEV_PATH_TYPE_DOMAIN:
230 case ELOG_DEV_PATH_TYPE_CPU_CLUSTER:
231 case ELOG_DEV_PATH_TYPE_CPU:
232 case ELOG_DEV_PATH_TYPE_CPU_BUS:
233 case ELOG_DEV_PATH_TYPE_IOAPIC:
234 eventlog_printf("0x%04x", extra & 0xffff);
235 break;
236 }
237
238 return 0;
239}
240
241/*
242 * eventlog_print_data - print the data associated with the entry
243 *
244 * @event: the smbios log entry to get the data information
245 *
246 * Returns 0 on failure, 1 on success.
247 */
248static int eventlog_print_data(const struct event_header *event)
249{
250 static const struct valstr os_events[] = {
251 {ELOG_OS_EVENT_CLEAN, "Clean Shutdown"},
252 {ELOG_OS_EVENT_NMIWDT, "NMI Watchdog"},
253 {ELOG_OS_EVENT_PANIC, "Panic"},
254 {ELOG_OS_EVENT_OOPS, "Oops"},
255 {ELOG_OS_EVENT_DIE, "Die"},
256 {ELOG_OS_EVENT_MCE, "MCE"},
257 {ELOG_OS_EVENT_SOFTWDT, "Software Watchdog"},
258 {ELOG_OS_EVENT_MBE, "Multi-bit Error"},
259 {ELOG_OS_EVENT_TRIPLE, "Triple Fault"},
260 {ELOG_OS_EVENT_THERMAL, "Critical Thermal Threshold"},
261 {0, NULL},
262 };
263 static const struct valstr wake_source_types[] = {
264 {ELOG_WAKE_SOURCE_PCIE, "PCI Express"},
265 {ELOG_WAKE_SOURCE_PME, "PCI PME"},
266 {ELOG_WAKE_SOURCE_PME_INTERNAL, "Internal PME"},
267 {ELOG_WAKE_SOURCE_RTC, "RTC Alarm"},
268 {ELOG_WAKE_SOURCE_GPE, "GPE #"},
269 {ELOG_WAKE_SOURCE_SMBUS, "SMBALERT"},
270 {ELOG_WAKE_SOURCE_PWRBTN, "Power Button"},
271 {ELOG_WAKE_SOURCE_PME_HDA, "PME - HDA"},
272 {ELOG_WAKE_SOURCE_PME_GBE, "PME - GBE"},
273 {ELOG_WAKE_SOURCE_PME_EMMC, "PME - EMMC"},
274 {ELOG_WAKE_SOURCE_PME_SDCARD, "PME - SDCARD"},
275 {ELOG_WAKE_SOURCE_PME_PCIE1, "PME - PCIE1"},
276 {ELOG_WAKE_SOURCE_PME_PCIE2, "PME - PCIE2"},
277 {ELOG_WAKE_SOURCE_PME_PCIE3, "PME - PCIE3"},
278 {ELOG_WAKE_SOURCE_PME_PCIE4, "PME - PCIE4"},
279 {ELOG_WAKE_SOURCE_PME_PCIE5, "PME - PCIE5"},
280 {ELOG_WAKE_SOURCE_PME_PCIE6, "PME - PCIE6"},
281 {ELOG_WAKE_SOURCE_PME_PCIE7, "PME - PCIE7"},
282 {ELOG_WAKE_SOURCE_PME_PCIE8, "PME - PCIE8"},
283 {ELOG_WAKE_SOURCE_PME_PCIE9, "PME - PCIE9"},
284 {ELOG_WAKE_SOURCE_PME_PCIE10, "PME - PCIE10"},
285 {ELOG_WAKE_SOURCE_PME_PCIE11, "PME - PCIE11"},
286 {ELOG_WAKE_SOURCE_PME_PCIE12, "PME - PCIE12"},
287 {ELOG_WAKE_SOURCE_PME_SATA, "PME - SATA"},
288 {ELOG_WAKE_SOURCE_PME_CSE, "PME - CSE"},
289 {ELOG_WAKE_SOURCE_PME_CSE2, "PME - CSE2"},
290 {ELOG_WAKE_SOURCE_PME_CSE3, "PME - CSE"},
291 {ELOG_WAKE_SOURCE_PME_XHCI, "PME - XHCI"},
292 {ELOG_WAKE_SOURCE_PME_XDCI, "PME - XDCI"},
293 {ELOG_WAKE_SOURCE_PME_XHCI_USB_2, "PME - XHCI (USB 2.0 port)"},
294 {ELOG_WAKE_SOURCE_PME_XHCI_USB_3, "PME - XHCI (USB 3.0 port)"},
295 {ELOG_WAKE_SOURCE_PME_WIFI, "PME - WIFI"},
296 {ELOG_WAKE_SOURCE_PME_PCIE13, "PME - PCIE13"},
297 {ELOG_WAKE_SOURCE_PME_PCIE14, "PME - PCIE14"},
298 {ELOG_WAKE_SOURCE_PME_PCIE15, "PME - PCIE15"},
299 {ELOG_WAKE_SOURCE_PME_PCIE16, "PME - PCIE16"},
300 {ELOG_WAKE_SOURCE_PME_PCIE17, "PME - PCIE17"},
301 {ELOG_WAKE_SOURCE_PME_PCIE18, "PME - PCIE18"},
302 {ELOG_WAKE_SOURCE_PME_PCIE19, "PME - PCIE19"},
303 {ELOG_WAKE_SOURCE_PME_PCIE20, "PME - PCIE20"},
304 {ELOG_WAKE_SOURCE_PME_PCIE21, "PME - PCIE21"},
305 {ELOG_WAKE_SOURCE_PME_PCIE22, "PME - PCIE22"},
306 {ELOG_WAKE_SOURCE_PME_PCIE23, "PME - PCIE23"},
307 {ELOG_WAKE_SOURCE_PME_PCIE24, "PME - PCIE24"},
308 {ELOG_WAKE_SOURCE_GPIO, " GPIO #"},
309 {ELOG_WAKE_SOURCE_PME_TBT, "PME - Thunderbolt"},
310 {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS XHCI"},
311 {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS XDCI"},
312 {ELOG_WAKE_SOURCE_PME_TCSS_XHCI, "PME - TCSS DMA"},
313 {0, NULL},
314 };
315 static const struct valstr ec_event_types[] = {
316 {EC_EVENT_LID_CLOSED, "Lid Closed"},
317 {EC_EVENT_LID_OPEN, "Lid Open"},
318 {EC_EVENT_POWER_BUTTON, "Power Button"},
319 {EC_EVENT_AC_CONNECTED, "AC Connected"},
320 {EC_EVENT_AC_DISCONNECTED, "AC Disconnected"},
321 {EC_EVENT_BATTERY_LOW, "Battery Low"},
322 {EC_EVENT_BATTERY_CRITICAL, "Battery Critical"},
323 {EC_EVENT_BATTERY, "Battery"},
324 {EC_EVENT_THERMAL_THRESHOLD, "Thermal Threshold"},
325 {EC_EVENT_DEVICE_EVENT, "Device Event"},
326 {EC_EVENT_THERMAL, "Thermal"},
327 {EC_EVENT_USB_CHARGER, "USB Charger"},
328 {EC_EVENT_KEY_PRESSED, "Key Pressed"},
329 {EC_EVENT_INTERFACE_READY, "Host Interface Ready"},
330 {EC_EVENT_KEYBOARD_RECOVERY, "Keyboard Recovery"},
331 {EC_EVENT_THERMAL_SHUTDOWN, "Thermal Shutdown in previous boot"},
332 {EC_EVENT_BATTERY_SHUTDOWN, "Battery Shutdown in previous boot"},
333 {EC_EVENT_THROTTLE_START, "Throttle Requested"},
334 {EC_EVENT_THROTTLE_STOP, "Throttle Request Removed"},
335 {EC_EVENT_HANG_DETECT, "Host Event Hang"},
336 {EC_EVENT_HANG_REBOOT, "Host Event Hang Reboot"},
337 {EC_EVENT_PD_MCU, "PD MCU Request"},
338 {EC_EVENT_BATTERY_STATUS, "Battery Status Request"},
339 {EC_EVENT_PANIC, "Panic Reset in previous boot"},
340 {EC_EVENT_KEYBOARD_FASTBOOT, "Keyboard Fastboot Recovery"},
341 {EC_EVENT_RTC, "RTC"},
342 {EC_EVENT_MKBP, "MKBP"},
343 {EC_EVENT_USB_MUX, "USB MUX change"},
344 {EC_EVENT_MODE_CHANGE, "Mode change"},
345 {EC_EVENT_KEYBOARD_RECOVERY_HWREINIT,
346 "Keyboard Recovery Forced Hardware Reinit"},
347 {EC_EVENT_EXTENDED, "Extended EC events"},
348 {0, NULL},
349 };
350 static const struct valstr ec_device_event_types[] = {
351 {ELOG_EC_DEVICE_EVENT_TRACKPAD, "Trackpad"},
352 {ELOG_EC_DEVICE_EVENT_DSP, "DSP"},
353 {ELOG_EC_DEVICE_EVENT_WIFI, "WiFi"},
354 {0, NULL},
355 };
356
357 static const struct valstr cros_recovery_reasons[] = {
358 {VB2_RECOVERY_LEGACY, "Legacy Utility"},
359 {VB2_RECOVERY_RO_MANUAL, "Recovery Button Pressed"},
360 {VB2_RECOVERY_RO_INVALID_RW, "RW Failed Signature Check"},
361 {VB2_RECOVERY_DEPRECATED_RO_S3_RESUME, "S3 Resume Failed"},
362 {VB2_RECOVERY_DEPRECATED_RO_TPM_ERROR, "TPM Error in RO Firmware"},
363 {VB2_RECOVERY_RO_SHARED_DATA, "Shared Data Error in RO Firmware"},
364 {VB2_RECOVERY_DEPRECATED_RO_TEST_S3, "Test Error from S3 Resume()"},
365 {VB2_RECOVERY_DEPRECATED_RO_TEST_LF, "Test Error from LoadFirmware()"},
366 {VB2_RECOVERY_DEPRECATED_RO_TEST_LFS, "Test Error from LoadFirmwareSetup()"},
367 {VB2_RECOVERY_DEPRECATED_RW_NOT_DONE, "RW firmware check not done"},
368 {VB2_RECOVERY_DEPRECATED_RW_DEV_FLAG_MISMATCH,
369 "RW firmware developer flag mismatch"},
370 {VB2_RECOVERY_DEPRECATED_RW_REC_FLAG_MISMATCH,
371 "RW firmware recovery flash mismatch"},
372 {VB2_RECOVERY_FW_KEYBLOCK, "RW firmware unable to verify keyblock"},
373 {VB2_RECOVERY_FW_KEY_ROLLBACK, "RW firmware key version rollback detected"},
374 {VB2_RECOVERY_DEPRECATED_RW_DATA_KEY_PARSE,
375 "RW firmware unable to parse data key"},
376 {VB2_RECOVERY_FW_PREAMBLE, "RW firmware unable to verify preamble"},
377 {VB2_RECOVERY_FW_ROLLBACK, "RW firmware version rollback detected"},
378 {VB2_RECOVERY_DEPRECATED_FW_HEADER_VALID, "RW firmware header is valid"},
379 {VB2_RECOVERY_DEPRECATED_FW_GET_FW_BODY,
380 "RW firmware unable to get firmware body"},
381 {VB2_RECOVERY_DEPRECATED_FW_HASH_WRONG_SIZE, "RW firmware hash is wrong size"},
382 {VB2_RECOVERY_FW_BODY, "RW firmware unable to verify firmware body"},
383 {VB2_RECOVERY_DEPRECATED_FW_VALID, "RW firmware is valid"},
384 {VB2_RECOVERY_DEPRECATED_FW_NO_RO_NORMAL,
385 "RW firmware read-only normal path is not supported"},
386 {VB2_RECOVERY_RO_FIRMWARE, "Firmware Boot Failure"},
387 {VB2_RECOVERY_RO_TPM_REBOOT, "Recovery Mode TPM Reboot"},
388 {VB2_RECOVERY_EC_SOFTWARE_SYNC, "EC Software Sync Error"},
389 {VB2_RECOVERY_EC_UNKNOWN_IMAGE, "Unable to determine active EC image"},
390 {VB2_RECOVERY_DEPRECATED_EC_HASH,
391 "EC software sync error obtaining EC image hash"},
392 {VB2_RECOVERY_DEPRECATED_EC_EXPECTED_IMAGE,
393 "EC software sync error obtaining expected EC image from BIOS"},
394 {VB2_RECOVERY_EC_UPDATE, "EC software sync error updating EC"},
395 {VB2_RECOVERY_EC_JUMP_RW, "EC software sync unable to jump to EC-RW"},
396 {VB2_RECOVERY_EC_PROTECT, "EC software sync protection error"},
397 {VB2_RECOVERY_EC_EXPECTED_HASH,
398 "EC software sync error obtaining expected EC hash from BIOS"},
399 {VB2_RECOVERY_DEPRECATED_EC_HASH_MISMATCH,
400 "EC software sync error comparing expected EC hash and image"},
401 {VB2_RECOVERY_SECDATA_FIRMWARE_INIT, "Secure NVRAM (TPM) initialization error"},
402 {VB2_RECOVERY_GBB_HEADER, "Error parsing GBB header"},
403 {VB2_RECOVERY_TPM_CLEAR_OWNER, "Error trying to clear TPM owner"},
404 {VB2_RECOVERY_DEV_SWITCH, "Error reading or updating developer switch"},
405 {VB2_RECOVERY_FW_SLOT, "Error selecting RW firmware slot"},
406 {VB2_RECOVERY_AUXFW_UPDATE, "Error updating AUX firmware"},
407 {VB2_RECOVERY_INTEL_CSE_LITE_SKU, "Intel CSE Lite SKU fimrware failure"},
408 {VB2_RECOVERY_RO_UNSPECIFIED, "Unknown Error in RO Firmware"},
409 {VB2_RECOVERY_DEPRECATED_RW_DEV_SCREEN, "User Requested from Developer Screen"},
410 {VB2_RECOVERY_DEPRECATED_RW_NO_OS, "No OS Kernel Detected"},
411 {VB2_RECOVERY_RW_INVALID_OS, "OS kernel or rootfs failed signature check"},
412 {VB2_RECOVERY_DEPRECATED_RW_TPM_ERROR, "TPM Error in RW Firmware"},
413 {VB2_RECOVERY_DEPRECATED_RW_DEV_MISMATCH, "RW Dev Firmware but not Dev Mode"},
414 {VB2_RECOVERY_RW_SHARED_DATA, "Shared Data Error in RW Firmware"},
415 {VB2_RECOVERY_DEPRECATED_RW_TEST_LK, "Test Error from LoadKernel()"},
416 {VB2_RECOVERY_DEPRECATED_RW_NO_DISK, "No Bootable Disk Found"},
417 {VB2_RECOVERY_TPM_E_FAIL, "TPM_E_FAIL or TPM_E_FAILEDSELFTEST"},
418 {VB2_RECOVERY_RO_TPM_S_ERROR, "TPM setup error in read-only firmware"},
419 {VB2_RECOVERY_RO_TPM_W_ERROR, "TPM write error in read-only firmware"},
420 {VB2_RECOVERY_RO_TPM_L_ERROR, "TPM lock error in read-only firmware"},
421 {VB2_RECOVERY_RO_TPM_U_ERROR, "TPM update error in read-only firmware"},
422 {VB2_RECOVERY_RW_TPM_R_ERROR, "TPM read error in rewritable firmware"},
423 {VB2_RECOVERY_RW_TPM_W_ERROR, "TPM write error in rewritable firmware"},
424 {VB2_RECOVERY_RW_TPM_L_ERROR, "TPM lock error in rewritable firmware"},
425 {VB2_RECOVERY_EC_HASH_FAILED, "EC software sync unable to get EC image hash"},
426 {VB2_RECOVERY_EC_HASH_SIZE, "EC software sync invalid image hash size"},
427 {VB2_RECOVERY_LK_UNSPECIFIED, "Unspecified error while trying to load kernel"},
428 {VB2_RECOVERY_RW_NO_DISK, "No bootable storage device in system"},
429 {VB2_RECOVERY_RW_NO_KERNEL, "No bootable kernel found on disk"},
430 {VB2_RECOVERY_DEPRECATED_RW_BCB_ERROR, "BCB partition error on disk"},
431 {VB2_RECOVERY_SECDATA_KERNEL_INIT,
432 "Kernel secure NVRAM (TPM) initialization error"},
433 {VB2_RECOVERY_DEPRECATED_FW_FASTBOOT, "Fastboot-mode requested in firmware"},
434 {VB2_RECOVERY_RO_TPM_REC_HASH_L_ERROR,
435 "Recovery hash space lock error in RO firmware"},
436 {VB2_RECOVERY_TPM_DISABLE_FAILED,
437 "Failed to disable TPM before running untrusted code"},
438 {VB2_RECOVERY_ALTFW_HASH_MISMATCH,
439 "Verification of alternative firmware payload failed"},
440 {VB2_RECOVERY_SECDATA_FWMP_INIT, "FWMP secure data initialization failed"},
441 {VB2_RECOVERY_CR50_BOOT_MODE, "Failed to get boot mode from TPM/Cr50"},
442 {VB2_RECOVERY_ESCAPE_NO_BOOT,
443 "Attempt to escape from NO_BOOT mode was detected"},
444 {VB2_RECOVERY_RW_UNSPECIFIED, "Unspecified/unknown error in RW firmware"},
445 {VB2_RECOVERY_DEPRECATED_KE_DM_VERITY, "DM-verity error"},
446 {VB2_RECOVERY_DEPRECATED_KE_UNSPECIFIED, "Unspecified/unknown error in kernel"},
447 {VB2_RECOVERY_US_TEST, "Recovery mode test from user-mode"},
448 {VB2_RECOVERY_DEPRECATED_BCB_USER_MODE, "User-mode requested recovery via BCB"},
449 {VB2_RECOVERY_DEPRECATED_US_FASTBOOT, "User-mode requested fastboot mode"},
450 {VB2_RECOVERY_TRAIN_AND_REBOOT,
451 "User requested recovery for training memory and rebooting"},
452 {VB2_RECOVERY_US_UNSPECIFIED, "Unknown Error in User Mode"},
453 {0, NULL},
454 };
455 static const struct valstr me_path_types[] = {
456 {ELOG_ME_PATH_NORMAL, "Normal"},
457 {ELOG_ME_PATH_NORMAL, "S3 Wake"},
458 {ELOG_ME_PATH_ERROR, "Error"},
459 {ELOG_ME_PATH_RECOVERY, "Recovery"},
460 {ELOG_ME_PATH_DISABLED, "Disabled"},
461 {ELOG_ME_PATH_FW_UPDATE, "Firmware Update"},
462 {0, NULL},
463 };
464 static const struct valstr coreboot_post_codes[] = {
465 {POST_RESET_VECTOR_CORRECT, "Reset Vector Correct"},
466 {POST_ENTER_PROTECTED_MODE, "Enter Protected Mode"},
467 {POST_PREPARE_RAMSTAGE, "Prepare RAM stage"},
468 {POST_ENTRY_C_START, "RAM stage Start"},
469 {POST_MEM_PREINIT_PREP_START, "Preparing memory init params"},
470 {POST_MEM_PREINIT_PREP_END, "Memory init param preparation complete"},
471 {POST_CONSOLE_READY, "Console is ready"},
472 {POST_CONSOLE_BOOT_MSG, "Console Boot Message"},
473 {POST_ENABLING_CACHE, "Before Enabling Cache"},
474 {POST_PRE_HARDWAREMAIN, "Before Hardware Main"},
475 {POST_ENTRY_HARDWAREMAIN, "First call in Hardware Main"},
476 {POST_BS_PRE_DEVICE, "Before Device Probe"},
477 {POST_BS_DEV_INIT_CHIPS, "Initialize Chips"},
478 {POST_BS_DEV_ENUMERATE, "Device Enumerate"},
479 {POST_BS_DEV_RESOURCES, "Device Resource Allocation"},
480 {POST_BS_DEV_ENABLE, "Device Enable"},
481 {POST_BS_DEV_INIT, "Device Initialize"},
482 {POST_BS_POST_DEVICE, "After Device Probe"},
483 {POST_BS_OS_RESUME_CHECK, "OS Resume Check"},
484 {POST_BS_OS_RESUME, "OS Resume"},
485 {POST_BS_WRITE_TABLES, "Write Tables"},
486 {POST_BS_PAYLOAD_LOAD, "Load Payload"},
487 {POST_BS_PAYLOAD_BOOT, "Boot Payload"},
488 {POST_FSP_NOTIFY_BEFORE_END_OF_FIRMWARE, "FSP Notify Before End of Firmware"},
489 {POST_FSP_NOTIFY_AFTER_END_OF_FIRMWARE, "FSP Notify After End of Firmware"},
490 {POST_FSP_TEMP_RAM_INIT, "FSP-T Enter"},
491 {POST_FSP_TEMP_RAM_EXIT, "FSP-T Exit"},
492 {POST_FSP_MEMORY_INIT, "FSP-M Enter"},
493 {POST_FSP_SILICON_INIT, "FSP-S Enter"},
494 {POST_FSP_NOTIFY_BEFORE_ENUMERATE, "FSP Notify Before Enumerate"},
495 {POST_FSP_NOTIFY_BEFORE_FINALIZE, "FSP Notify Before Finalize"},
496 {POST_OS_ENTER_PTS, "ACPI _PTS Method"},
497 {POST_OS_ENTER_WAKE, "ACPI _WAK Method"},
498 {POST_FSP_MEMORY_EXIT, "FSP-M Exit"},
499 {POST_FSP_SILICON_EXIT, "FSP-S Exit"},
500 {POST_FSP_MULTI_PHASE_SI_INIT_ENTRY, "FSP-S Init Enter"},
501 {POST_FSP_MULTI_PHASE_SI_INIT_EXIT, "FPS-S Init Exit"},
502 {POST_FSP_NOTIFY_AFTER_ENUMERATE, "FSP Notify After Enumerate"},
503 {POST_FSP_NOTIFY_AFTER_FINALIZE, "FSP Notify After Finalize"},
504 {POST_INVALID_ROM, "Invalid ROM"},
505 {POST_INVALID_CBFS, "Invalid CBFS"},
506 {POST_INVALID_VENDOR_BINARY, "Invalid Vendor Binary"},
507 {POST_RAM_FAILURE, "RAM Failure"},
508 {POST_HW_INIT_FAILURE, "Hardware Init Failure"},
509 {POST_VIDEO_FAILURE, "Video Failure"},
510 {POST_TPM_FAILURE, "TPM Failure"},
511 {POST_DEAD_CODE, "Dead Code"},
512 {POST_RESUME_FAILURE, "Resume Failure"},
513 {POST_JUMPING_TO_PAYLOAD, "Before Jump to Payload"},
514 {POST_ENTER_ELF_BOOT, "Before ELF Boot"},
515 {POST_OS_RESUME, "Before OS Resume"},
516 {POST_OS_BOOT, "Before OS Boot"},
517 {POST_DIE, "coreboot Dead"},
518 {0, NULL},
519 };
520 static const struct valstr mem_cache_slots[] = {
521 {ELOG_MEM_CACHE_UPDATE_SLOT_NORMAL, "Normal"},
522 {ELOG_MEM_CACHE_UPDATE_SLOT_RECOVERY, "Recovery"},
523 {ELOG_MEM_CACHE_UPDATE_SLOT_VARIABLE, "Variable"},
524 {0, NULL},
525 };
526 static const struct valstr mem_cache_statuses[] = {
527 {ELOG_MEM_CACHE_UPDATE_STATUS_SUCCESS, "Success"},
528 {ELOG_MEM_CACHE_UPDATE_STATUS_FAIL, "Fail"},
529 {0, NULL},
530 };
531
532 static const struct valstr extended_event_subtypes[] = {
533 {ELOG_SLEEP_PENDING_PM1_WAKE, "S3 failed due to pending wake event, PM1"},
534 {ELOG_SLEEP_PENDING_GPE0_WAKE, "S3 failed due to pending wake event, GPE0"},
535 {0, NULL},
536 };
537
Hsuan Ting Chena5cbe272021-11-01 19:14:01 +0800538 static const struct valstr cros_diagnostics_types[] = {
539 {ELOG_CROS_LAUNCH_DIAGNOSTICS, "Launch Diagnostics"},
540 {0, NULL},
541 };
542
Ricardo Quesadac2cf3942021-07-16 16:49:04 -0700543 switch (event->type) {
544 case ELOG_TYPE_LOG_CLEAR: {
545 const uint16_t *bytes = event_get_data(event);
546 eventlog_printf("%u", *bytes);
547 break;
548 }
549
550 case ELOG_TYPE_BOOT: {
551 const uint32_t *count = event_get_data(event);
552 eventlog_printf("%u", *count);
553 break;
554 }
555 case ELOG_TYPE_LAST_POST_CODE: {
556 const uint16_t *code = event_get_data(event);
557 eventlog_printf("0x%02x", *code);
558 eventlog_printf("%s", val2str(*code, coreboot_post_codes));
559 break;
560 }
561 case ELOG_TYPE_POST_EXTRA: {
562 const uint32_t *extra = event_get_data(event);
563 eventlog_print_post_extra(*extra);
564 break;
565 }
566 case ELOG_TYPE_OS_EVENT: {
567 const uint32_t *osevent = event_get_data(event);
568 eventlog_printf("%s", val2str(*osevent, os_events));
569 break;
570 }
571 case ELOG_TYPE_ACPI_ENTER:
572 case ELOG_TYPE_ACPI_WAKE: {
573 const uint8_t *state = event_get_data(event);
574 eventlog_printf("S%u", *state);
575 break;
576 }
577 case ELOG_TYPE_ACPI_DEEP_WAKE: {
578 const uint8_t *state = event_get_data(event);
579 eventlog_printf("Deep S%u", *state);
580 break;
581 }
582 case ELOG_TYPE_WAKE_SOURCE: {
583 const struct elog_event_data_wake *wake_source;
584 wake_source = event_get_data(event);
585 eventlog_printf("%s", val2str(wake_source->source, wake_source_types));
586 eventlog_printf("%u", wake_source->instance);
587 break;
588 }
589 case ELOG_TYPE_EC_EVENT: {
590 const uint8_t *ec_event = event_get_data(event);
591 eventlog_printf("%s", val2str(*ec_event, ec_event_types));
592 break;
593 }
594 case ELOG_TYPE_EC_DEVICE_EVENT: {
595 const uint8_t *dev_event = event_get_data(event);
596 eventlog_printf("%s", val2str(*dev_event, ec_device_event_types));
597 break;
598 }
599 case ELOG_TYPE_CROS_RECOVERY_MODE: {
600 const uint8_t *reason = event_get_data(event);
601 eventlog_printf("%s", val2str(*reason, cros_recovery_reasons));
602 eventlog_printf("0x%02x", *reason);
603 break;
604 }
605 case ELOG_TYPE_MANAGEMENT_ENGINE: {
606 const uint8_t *path = event_get_data(event);
607 eventlog_printf("%s", val2str(*path, me_path_types));
608 break;
609 }
610 case ELOG_TYPE_MEM_CACHE_UPDATE: {
611 const struct elog_event_mem_cache_update *update;
612 update = event_get_data(event);
613 eventlog_printf("%s", val2str(update->slot, mem_cache_slots));
614 eventlog_printf("%s", val2str(update->status, mem_cache_statuses));
615 break;
616 }
617 case ELOG_TYPE_EXTENDED_EVENT: {
618 const struct elog_event_extended_event *ext_event;
619 ext_event = event_get_data(event);
620 eventlog_printf("%s", val2str(ext_event->event_type, extended_event_subtypes));
621 eventlog_printf("0x%X", ext_event->event_complement);
622 break;
623 }
Hsuan Ting Chena5cbe272021-11-01 19:14:01 +0800624 case ELOG_TYPE_CROS_DIAGNOSTICS: {
625 const uint8_t *type = event_get_data(event);
626 eventlog_printf("%s", val2str(*type, cros_diagnostics_types));
Subrata Banik8b468402022-07-17 18:20:24 +0530627 break;
628 }
629 case ELOG_TYPE_FW_VBOOT_INFO: {
630 const union vb2_fw_boot_info *info = event_get_data(event);
631
632 eventlog_printf("boot_mode=%s", vb2_boot_mode_string(info->boot_mode));
633
634 if (info->boot_mode == VB2_BOOT_MODE_BROKEN_SCREEN ||
635 info->boot_mode == VB2_BOOT_MODE_MANUAL_RECOVERY)
636 eventlog_printf("recovery_reason=%#x/%#x (%s)",
637 info->recovery_reason, info->recovery_subcode,
638 vb2_get_recovery_reason_string(info->recovery_reason));
639
640 eventlog_printf("fw_tried=%s", vb2_slot_string(info->slot));
641 eventlog_printf("fw_try_count=%d", info->tries);
642 eventlog_printf("fw_prev_tried=%s", vb2_slot_string(info->prev_slot));
643 eventlog_printf("fw_prev_result=%s", vb2_result_string(info->prev_result));
644 break;
Hsuan Ting Chena5cbe272021-11-01 19:14:01 +0800645 }
Ricardo Quesadac2cf3942021-07-16 16:49:04 -0700646 default:
647 break;
648 }
649
650 return 0;
651}
652
653void eventlog_print_event(const struct event_header *event, int count)
654{
655 /* Ignore the printf separator at the beginning and end of each line */
656 eventlog_printf_ignore_separator_once = 1;
657
658 eventlog_printf("%d", count);
659 eventlog_print_timestamp(event);
660 eventlog_print_type(event);
661 eventlog_print_data(event);
662
663 /* End of line, after printing each event */
664 eventlog_printf_ignore_separator_once = 1;
665 eventlog_printf("\n");
666}
Ricardo Quesada49a96a92021-08-16 11:25:52 -0700667
668/*
669 * Initializes the eventlog header with the given type and data,
670 * and calculates the checksum.
671 * buffer_get() points to the event to be initialized.
672 * On success it returns 1, otherwise 0.
673 */
674int eventlog_init_event(const struct buffer *buf, uint8_t type,
675 const void *data, int data_size)
676{
677 struct event_header *event;
678 time_t secs = time(NULL);
679 struct tm tm;
680
681 /* Must have at least size for data + checksum byte */
682 if (buffer_size(buf) < (size_t)data_size + 1)
683 return 0;
684
685 event = buffer_get(buf);
686
687 event->type = type;
688 gmtime_r(&secs, &tm);
Ricardo Quesada1427f122021-09-22 20:08:35 -0700689 /* Month should be +1, since gmtime uses 0 as first month */
Ricardo Quesada49a96a92021-08-16 11:25:52 -0700690 elog_fill_timestamp(event, tm.tm_sec, tm.tm_min, tm.tm_hour,
Ricardo Quesada1427f122021-09-22 20:08:35 -0700691 tm.tm_mday, tm.tm_mon + 1, tm.tm_year);
Ricardo Quesada49a96a92021-08-16 11:25:52 -0700692
693 if (data && data_size) {
694 uint32_t *ptr = (uint32_t *)&event[1];
695 memcpy(ptr, data, data_size);
696 }
697
698 /* Header + data + checksum */
699 event->length = sizeof(*event) + data_size + 1;
700
701 /* Zero the checksum byte and then compute checksum */
702 elog_update_checksum(event, 0);
703 elog_update_checksum(event, -(elog_checksum_event(event)));
704
705 return 1;
706}