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