1*4f2df630SAndroid Build Coastguard Worker /* Copyright 2017 The ChromiumOS Authors 2*4f2df630SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 3*4f2df630SAndroid Build Coastguard Worker * found in the LICENSE file. 4*4f2df630SAndroid Build Coastguard Worker */ 5*4f2df630SAndroid Build Coastguard Worker 6*4f2df630SAndroid Build Coastguard Worker #ifndef __CROS_EC_EVENT_LOG_H 7*4f2df630SAndroid Build Coastguard Worker #define __CROS_EC_EVENT_LOG_H 8*4f2df630SAndroid Build Coastguard Worker 9*4f2df630SAndroid Build Coastguard Worker #include "config.h" 10*4f2df630SAndroid Build Coastguard Worker #include "common.h" 11*4f2df630SAndroid Build Coastguard Worker #include "compile_time_macros.h" 12*4f2df630SAndroid Build Coastguard Worker #include "stddef.h" 13*4f2df630SAndroid Build Coastguard Worker 14*4f2df630SAndroid Build Coastguard Worker enum flash_event_type { 15*4f2df630SAndroid Build Coastguard Worker FE_LOG_START = 0, 16*4f2df630SAndroid Build Coastguard Worker FE_LOG_CORRUPTED = 1, 17*4f2df630SAndroid Build Coastguard Worker FE_TPM_I2C_ERROR = 2, 18*4f2df630SAndroid Build Coastguard Worker FE_LOG_OVERFLOWS = 3, /* A single byte, overflow counter. */ 19*4f2df630SAndroid Build Coastguard Worker FE_LOG_LOCKS = 4, /* A single byte, lock failures counter. */ 20*4f2df630SAndroid Build Coastguard Worker FE_LOG_NVMEM = 5, /* NVMEM failure, variable structure. */ 21*4f2df630SAndroid Build Coastguard Worker FE_LOG_TPM_WIPE_ERROR = 6, /* Failed to wipe the TPM */ 22*4f2df630SAndroid Build Coastguard Worker FE_LOG_TRNG_STALL = 7, /* Stall while retrieving a random number. */ 23*4f2df630SAndroid Build Coastguard Worker FE_LOG_DCRYPTO_FAILURE = 8, /* Dcrypto had to be reset. */ 24*4f2df630SAndroid Build Coastguard Worker FE_LOG_AP_RO_VERIFICATION = 9, /* AP RO verification events. */ 25*4f2df630SAndroid Build Coastguard Worker FE_LOG_FIPS_FAILURE = 10, /* Error during continuous and/or known-answer 26*4f2df630SAndroid Build Coastguard Worker * tests for FIPS 140-2/3 27*4f2df630SAndroid Build Coastguard Worker */ 28*4f2df630SAndroid Build Coastguard Worker FE_LOG_BRDPROP = 11, /* Detected invalid board properties */ 29*4f2df630SAndroid Build Coastguard Worker /* 30*4f2df630SAndroid Build Coastguard Worker * Fixed padding value makes it easier to parse log space 31*4f2df630SAndroid Build Coastguard Worker * snapshots. 32*4f2df630SAndroid Build Coastguard Worker */ 33*4f2df630SAndroid Build Coastguard Worker FE_LOG_PAD = 253, 34*4f2df630SAndroid Build Coastguard Worker /* A test event, the highest possible event type value. */ 35*4f2df630SAndroid Build Coastguard Worker FE_LOG_TEST = 254, 36*4f2df630SAndroid Build Coastguard Worker }; 37*4f2df630SAndroid Build Coastguard Worker struct flash_log_entry { 38*4f2df630SAndroid Build Coastguard Worker /* 39*4f2df630SAndroid Build Coastguard Worker * Until real wall clock time is available this is a monotonically 40*4f2df630SAndroid Build Coastguard Worker * increasing entry number. 41*4f2df630SAndroid Build Coastguard Worker * 42*4f2df630SAndroid Build Coastguard Worker * TODO(vbendeb): however unlikely, there could be multiple events 43*4f2df630SAndroid Build Coastguard Worker * logged within the same 1 second interval. There needs to be a 44*4f2df630SAndroid Build Coastguard Worker * way to handle this. Maybe storing incremental time, having only 45*4f2df630SAndroid Build Coastguard Worker * the very first entry in the log carry the real time. Maybe 46*4f2df630SAndroid Build Coastguard Worker * enhancing the log traversion function to allow multiple entries 47*4f2df630SAndroid Build Coastguard Worker * with the same timestamp value. 48*4f2df630SAndroid Build Coastguard Worker */ 49*4f2df630SAndroid Build Coastguard Worker uint32_t timestamp; 50*4f2df630SAndroid Build Coastguard Worker uint8_t size; /* [7:6] caller-def'd [5:0] payload size in bytes. */ 51*4f2df630SAndroid Build Coastguard Worker uint8_t type; /* event type, caller-defined */ 52*4f2df630SAndroid Build Coastguard Worker uint8_t crc; 53*4f2df630SAndroid Build Coastguard Worker uint8_t payload[0]; /* optional additional data payload: 0..63 bytes. */ 54*4f2df630SAndroid Build Coastguard Worker } __packed; 55*4f2df630SAndroid Build Coastguard Worker 56*4f2df630SAndroid Build Coastguard Worker /* Payloads for various log events. */ 57*4f2df630SAndroid Build Coastguard Worker /* NVMEM failures. */ 58*4f2df630SAndroid Build Coastguard Worker enum nvmem_failure_type { 59*4f2df630SAndroid Build Coastguard Worker NVMEMF_MALLOC = 0, 60*4f2df630SAndroid Build Coastguard Worker NVMEMF_PH_SIZE_MISMATCH = 1, 61*4f2df630SAndroid Build Coastguard Worker NVMEMF_READ_UNDERRUN = 2, 62*4f2df630SAndroid Build Coastguard Worker NVMEMF_INCONSISTENT_FLASH_CONTENTS = 3, 63*4f2df630SAndroid Build Coastguard Worker NVMEMF_MIGRATION_FAILURE = 4, 64*4f2df630SAndroid Build Coastguard Worker NVMEMF_LEGACY_ERASE_FAILURE = 5, 65*4f2df630SAndroid Build Coastguard Worker NVMEMF_EXCESS_DELETE_OBJECTS = 6, 66*4f2df630SAndroid Build Coastguard Worker NVMEMF_UNEXPECTED_LAST_OBJ = 7, 67*4f2df630SAndroid Build Coastguard Worker NVMEMF_MISSING_OBJECT = 8, 68*4f2df630SAndroid Build Coastguard Worker NVMEMF_SECTION_VERIFY = 9, 69*4f2df630SAndroid Build Coastguard Worker NVMEMF_PRE_ERASE_MISMATCH = 10, 70*4f2df630SAndroid Build Coastguard Worker NVMEMF_PAGE_LIST_OVERFLOW = 11, 71*4f2df630SAndroid Build Coastguard Worker NVMEMF_CIPHER_ERROR = 12, 72*4f2df630SAndroid Build Coastguard Worker NVMEMF_CORRUPTED_INIT = 13, 73*4f2df630SAndroid Build Coastguard Worker NVMEMF_CONTAINER_HASH_MISMATCH = 14, 74*4f2df630SAndroid Build Coastguard Worker NVMEMF_UNRECOVERABLE_INIT = 15, 75*4f2df630SAndroid Build Coastguard Worker NVMEMF_NVMEM_WIPE = 16, 76*4f2df630SAndroid Build Coastguard Worker }; 77*4f2df630SAndroid Build Coastguard Worker 78*4f2df630SAndroid Build Coastguard Worker /* Not all nvmem failures require payload. */ 79*4f2df630SAndroid Build Coastguard Worker struct nvmem_failure_payload { 80*4f2df630SAndroid Build Coastguard Worker uint8_t failure_type; 81*4f2df630SAndroid Build Coastguard Worker union { 82*4f2df630SAndroid Build Coastguard Worker uint16_t size; /* How much memory was requested. */ 83*4f2df630SAndroid Build Coastguard Worker struct { 84*4f2df630SAndroid Build Coastguard Worker uint16_t ph_offset; 85*4f2df630SAndroid Build Coastguard Worker uint16_t expected; 86*4f2df630SAndroid Build Coastguard Worker } ph __packed; 87*4f2df630SAndroid Build Coastguard Worker uint16_t underrun_size; /* How many bytes short. */ 88*4f2df630SAndroid Build Coastguard Worker uint8_t last_obj_type; 89*4f2df630SAndroid Build Coastguard Worker } __packed; 90*4f2df630SAndroid Build Coastguard Worker } __packed; 91*4f2df630SAndroid Build Coastguard Worker 92*4f2df630SAndroid Build Coastguard Worker /* AP RO verification events. */ 93*4f2df630SAndroid Build Coastguard Worker enum ap_ro_verification_ev { 94*4f2df630SAndroid Build Coastguard Worker APROF_REFRESH_PRESSED = 0, 95*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_STOPPED = 1, 96*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_TIMED_OUT = 2, 97*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_TRIGGERED = 3, 98*4f2df630SAndroid Build Coastguard Worker APROF_SPACE_NOT_PROGRAMMED = 4, 99*4f2df630SAndroid Build Coastguard Worker APROF_SPACE_INVALID = 5, 100*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_FAILED = 6, 101*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_SUCCEEDED = 7, 102*4f2df630SAndroid Build Coastguard Worker APROF_CHECK_UNSUPPORTED = 8, 103*4f2df630SAndroid Build Coastguard Worker APROF_FAIL_CLEARED = 9, 104*4f2df630SAndroid Build Coastguard Worker APROF_SAVED_GBBD = 10, 105*4f2df630SAndroid Build Coastguard Worker APROF_FAIL_TO_SAVE_GBBD = 11, 106*4f2df630SAndroid Build Coastguard Worker APROF_FAIL_CORRUPTED_V1_DATA = 12, 107*4f2df630SAndroid Build Coastguard Worker APROF_FAIL_CORRUPTED_GBBD = 13, 108*4f2df630SAndroid Build Coastguard Worker }; 109*4f2df630SAndroid Build Coastguard Worker 110*4f2df630SAndroid Build Coastguard Worker struct ap_ro_entry_payload { 111*4f2df630SAndroid Build Coastguard Worker enum ap_ro_verification_ev event : 8; 112*4f2df630SAndroid Build Coastguard Worker } __packed; 113*4f2df630SAndroid Build Coastguard Worker 114*4f2df630SAndroid Build Coastguard Worker /*****************************************************************************/ 115*4f2df630SAndroid Build Coastguard Worker /* Brdprop Events */ 116*4f2df630SAndroid Build Coastguard Worker /* Each event can only be logged once per boot. */ 117*4f2df630SAndroid Build Coastguard Worker enum brdprop_ev { 118*4f2df630SAndroid Build Coastguard Worker BRDPROP_INVALID = 0, 119*4f2df630SAndroid Build Coastguard Worker BRDPROP_AMBIGUOUS = 1, 120*4f2df630SAndroid Build Coastguard Worker BRDPROP_NO_ENTRY = 2, 121*4f2df630SAndroid Build Coastguard Worker 122*4f2df630SAndroid Build Coastguard Worker /* 123*4f2df630SAndroid Build Coastguard Worker * If BRDPROP_COUNT goes above 8, increase the size of events in 124*4f2df630SAndroid Build Coastguard Worker * brdprop_payload. 125*4f2df630SAndroid Build Coastguard Worker */ 126*4f2df630SAndroid Build Coastguard Worker BRDPROP_COUNT = 3, 127*4f2df630SAndroid Build Coastguard Worker }; 128*4f2df630SAndroid Build Coastguard Worker 129*4f2df630SAndroid Build Coastguard Worker struct brdprop_payload { 130*4f2df630SAndroid Build Coastguard Worker uint8_t events; 131*4f2df630SAndroid Build Coastguard Worker uint32_t reset_flags; 132*4f2df630SAndroid Build Coastguard Worker uint8_t configs[BRDPROP_COUNT]; 133*4f2df630SAndroid Build Coastguard Worker } __packed; 134*4f2df630SAndroid Build Coastguard Worker 135*4f2df630SAndroid Build Coastguard Worker /* Returned in the "type" field, when there is no entry available */ 136*4f2df630SAndroid Build Coastguard Worker #define FLASH_LOG_NO_ENTRY 0xff 137*4f2df630SAndroid Build Coastguard Worker #define MAX_FLASH_LOG_PAYLOAD_SIZE ((1 << 6) - 1) 138*4f2df630SAndroid Build Coastguard Worker #define FLASH_LOG_PAYLOAD_SIZE_MASK (MAX_FLASH_LOG_PAYLOAD_SIZE) 139*4f2df630SAndroid Build Coastguard Worker 140*4f2df630SAndroid Build Coastguard Worker #define FLASH_LOG_PAYLOAD_SIZE(size) ((size) & FLASH_LOG_PAYLOAD_SIZE_MASK) 141*4f2df630SAndroid Build Coastguard Worker /* Size of log entry for a specific payload size. */ 142*4f2df630SAndroid Build Coastguard Worker #define FLASH_LOG_ENTRY_SIZE(payload_sz) \ 143*4f2df630SAndroid Build Coastguard Worker ((FLASH_LOG_PAYLOAD_SIZE(payload_sz) + \ 144*4f2df630SAndroid Build Coastguard Worker sizeof(struct flash_log_entry) + CONFIG_FLASH_WRITE_SIZE - 1) & \ 145*4f2df630SAndroid Build Coastguard Worker ~(CONFIG_FLASH_WRITE_SIZE - 1)) 146*4f2df630SAndroid Build Coastguard Worker 147*4f2df630SAndroid Build Coastguard Worker /* 148*4f2df630SAndroid Build Coastguard Worker * Flash log implementation expects minimum flash write size not to exceed the 149*4f2df630SAndroid Build Coastguard Worker * log header structure size. 150*4f2df630SAndroid Build Coastguard Worker * 151*4f2df630SAndroid Build Coastguard Worker * It will be easy to extend implementation to cover larger write sizes if 152*4f2df630SAndroid Build Coastguard Worker * necessary. 153*4f2df630SAndroid Build Coastguard Worker */ 154*4f2df630SAndroid Build Coastguard Worker BUILD_ASSERT(sizeof(struct flash_log_entry) >= CONFIG_FLASH_WRITE_SIZE); 155*4f2df630SAndroid Build Coastguard Worker 156*4f2df630SAndroid Build Coastguard Worker /* A helper structure to represent maximum size flash elog event entry. */ 157*4f2df630SAndroid Build Coastguard Worker union entry_u { 158*4f2df630SAndroid Build Coastguard Worker uint8_t entry[FLASH_LOG_ENTRY_SIZE(MAX_FLASH_LOG_PAYLOAD_SIZE)]; 159*4f2df630SAndroid Build Coastguard Worker struct flash_log_entry r; 160*4f2df630SAndroid Build Coastguard Worker }; 161*4f2df630SAndroid Build Coastguard Worker 162*4f2df630SAndroid Build Coastguard Worker #define COMPACTION_SPACE_PRESERVE (CONFIG_FLASH_LOG_SPACE / 4) 163*4f2df630SAndroid Build Coastguard Worker #define STARTUP_LOG_FULL_WATERMARK (CONFIG_FLASH_LOG_SPACE * 3 / 4) 164*4f2df630SAndroid Build Coastguard Worker #define RUN_TIME_LOG_FULL_WATERMARK (CONFIG_FLASH_LOG_SPACE * 9 / 10) 165*4f2df630SAndroid Build Coastguard Worker 166*4f2df630SAndroid Build Coastguard Worker /* 167*4f2df630SAndroid Build Coastguard Worker * Add an entry to the event log. No errors are reported, as there is little 168*4f2df630SAndroid Build Coastguard Worker * we can do if logging attempt fails. 169*4f2df630SAndroid Build Coastguard Worker */ 170*4f2df630SAndroid Build Coastguard Worker void flash_log_add_event(uint8_t type, uint8_t size, void *payload); 171*4f2df630SAndroid Build Coastguard Worker 172*4f2df630SAndroid Build Coastguard Worker /* 173*4f2df630SAndroid Build Coastguard Worker * Report the next event after the passed in number. 174*4f2df630SAndroid Build Coastguard Worker * 175*4f2df630SAndroid Build Coastguard Worker * Return 176*4f2df630SAndroid Build Coastguard Worker * - positive integer - the size of the retrieved event 177*4f2df630SAndroid Build Coastguard Worker * - 0 if there is no more events 178*4f2df630SAndroid Build Coastguard Worker * - -EC_ERROR_BUSY if event logging is in progress 179*4f2df630SAndroid Build Coastguard Worker * - -EC_ERROR_MEMORY_ALLOCATION if event body does not fit into the buffer 180*4f2df630SAndroid Build Coastguard Worker * - -EC_ERROR_INVAL in case log storage is corrupted 181*4f2df630SAndroid Build Coastguard Worker */ 182*4f2df630SAndroid Build Coastguard Worker int flash_log_dequeue_event(uint32_t event_after, void *buffer, 183*4f2df630SAndroid Build Coastguard Worker size_t buffer_size); 184*4f2df630SAndroid Build Coastguard Worker 185*4f2df630SAndroid Build Coastguard Worker void flash_log_register_flash_control_callback( 186*4f2df630SAndroid Build Coastguard Worker void (*flash_control)(int enable)); 187*4f2df630SAndroid Build Coastguard Worker 188*4f2df630SAndroid Build Coastguard Worker /* 189*4f2df630SAndroid Build Coastguard Worker * Set log timestamp base. The argument is current epoch time in seconds. 190*4f2df630SAndroid Build Coastguard Worker * Return value of EC_ERROR_INVAL indicates attempt to set the timestamp base 191*4f2df630SAndroid Build Coastguard Worker * to a value below the latest log entry timestamp. 192*4f2df630SAndroid Build Coastguard Worker */ 193*4f2df630SAndroid Build Coastguard Worker enum ec_error_list flash_log_set_tstamp(uint32_t tstamp); 194*4f2df630SAndroid Build Coastguard Worker 195*4f2df630SAndroid Build Coastguard Worker /* Get current log timestamp value. */ 196*4f2df630SAndroid Build Coastguard Worker uint32_t flash_log_get_tstamp(void); 197*4f2df630SAndroid Build Coastguard Worker 198*4f2df630SAndroid Build Coastguard Worker #if defined(TEST_BUILD) 199*4f2df630SAndroid Build Coastguard Worker void flash_log_init(void); 200*4f2df630SAndroid Build Coastguard Worker extern uint32_t last_used_timestamp; 201*4f2df630SAndroid Build Coastguard Worker extern uint32_t lock_failures_count; 202*4f2df630SAndroid Build Coastguard Worker extern uint8_t log_event_in_progress; 203*4f2df630SAndroid Build Coastguard Worker #endif 204*4f2df630SAndroid Build Coastguard Worker 205*4f2df630SAndroid Build Coastguard Worker #endif /* __CROS_EC_EVENT_LOG_H */ 206