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