xref: /aosp_15_r20/external/gsc-utils/include/flash_log.h (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
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