xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/include/intelblocks/cse.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #ifndef SOC_INTEL_COMMON_CSE_H
4 #define SOC_INTEL_COMMON_CSE_H
5 
6 #include <intelblocks/cse_telemetry.h>
7 #include <types.h>
8 #include <vb2_api.h>
9 
10 /* MKHI Command groups */
11 enum mkhi_group_id {
12 	MKHI_GROUP_ID_CBM	 = 0x0,
13 	MKHI_GROUP_ID_HMRFPO	 = 0x5,
14 	MKHI_GROUP_ID_GEN	 = 0xff,
15 	MKHI_GROUP_ID_BUP_COMMON = 0xf0,
16 	MKHI_GROUP_ID_FWCAPS	 = 0x3,
17 };
18 
19 /* Global Reset Command ID */
20 #define MKHI_CBM_GLOBAL_RESET_REQ	0xb
21 
22 /* Set State Command ID */
23 #define MKHI_SET_ME_DISABLE	0x3
24 #define MKHI_SET_ME_ENABLE	0x3
25 
26 /* Origin of Global Reset command */
27 #define GR_ORIGIN_BIOS_POST	0x2
28 
29 /* HMRFPO Command Ids */
30 #define MKHI_HMRFPO_ENABLE	0x1
31 #define MKHI_HMRFPO_GET_STATUS	0x3
32 
33 /* Get Firmware Version Command Id */
34 #define MKHI_GEN_GET_FW_VERSION	0x2
35 
36 /* Firmware Feature Shipment Time State Override Command Id */
37 #define MKHI_GEN_FW_FEATURE_SHIPMENT_OVER	0x14
38 #define   ME_FW_FEATURE_PTT			BIT(29)
39 
40 /* Get Firmware Feature State Command Id */
41 #define MKHI_FWCAPS_GET_FW_FEATURE_STATE	0x02
42 #define   ME_FEATURE_STATE_RULE_ID		0x20
43 #define   ME_FW_FEATURE_PSR			BIT(5)
44 /* MEI bus disable command. Must be sent to MEI client endpoint, not MKHI */
45 #define MEI_BUS_DISABLE_COMMAND	0xc
46 
47 /* Set End-of-POST in CSE */
48 #define MKHI_END_OF_POST	0xc
49 
50 /* Boot partition info and set boot partition info command ids */
51 #define MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO	0x1c
52 #define MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO	0x1d
53 #define MKHI_BUP_COMMON_DATA_CLEAR		0x20
54 #define GEN_GET_IMAGE_FW_VERSION	0x1c
55 
56 /* Get boot performance command id */
57 #define MKHI_BUP_COMMON_GET_BOOT_PERF_DATA	0x8
58 
59 /* ME Current Working States */
60 #define ME_HFS1_CWS_NORMAL	0x5
61 
62 /* ME Current Operation Modes */
63 #define ME_HFS1_COM_NORMAL	0x0
64 #define ME_HFS1_COM_SOFT_TEMP_DISABLE	0x3
65 #define ME_HFS1_COM_SECOVER_MEI_MSG	0x5
66 
67 /* ME Disable Rule */
68 #define ME_DISABLE_RULE_ID	6
69 #define ME_DISABLE_RULE_LENGTH	4
70 #define ME_DISABLE_COMMAND	0
71 #define ME_DISABLE_ATTEMPTS	3
72 
73 /* ME Firmware SKU Types */
74 enum me_fw_sku {
75 	ME_HFS3_FW_SKU_CONSUMER	 = 0x2,
76 	ME_HFS3_FW_SKU_CORPORATE = 0x3,
77 	ME_HFS3_FW_SKU_LITE	 = 0x5,
78 };
79 
80 /* Number of cse boot performance data */
81 #define NUM_CSE_BOOT_PERF_DATA	64
82 
83 /* PSR_HECI_FW_DOWNGRADE_BACKUP Command */
84 #define PSR_HECI_FW_DOWNGRADE_BACKUP 0x3
85 
86 /* HFSTS register offsets in PCI config space */
87 enum {
88 	PCI_ME_HFSTS1 = 0x40,
89 	PCI_ME_HFSTS2 = 0x48,
90 	PCI_ME_HFSTS3 = 0x60,
91 	PCI_ME_HFSTS4 = 0x64,
92 	PCI_ME_HFSTS5 = 0x68,
93 	PCI_ME_HFSTS6 = 0x6C,
94 };
95 
96 /* CSE partition list */
97 enum fpt_partition_id {
98 	FPT_PARTITION_NAME_UNDEFINED = 0x0,
99 	FPT_PARTITION_NAME_ISHC = 0x43485349,
100 };
101 
102 /* MKHI Message Header */
103 struct mkhi_hdr {
104 	uint8_t group_id;
105 	uint8_t command:7;
106 	uint8_t is_resp:1;
107 	uint8_t rsvd;
108 	uint8_t result;
109 } __packed;
110 
111 /* PSR HECI message status */
112 enum psr_status {
113 	PSR_STATUS_SUCCESS,
114 	PSR_STATUS_FEATURE_NOT_SUPPORTED,
115 	PSR_STATUS_UPID_DISABLED,
116 	PSR_STATUS_ACTION_NOT_ALLOWED,
117 	PSR_STATUS_INVALID_INPUT_PARAMETER,
118 	PSR_STATUS_INTERNAL_ERROR,
119 	PSR_STATUS_NOT_ALLOWED_AFTER_EOP,
120 };
121 
122 /* PSR HECI message header */
123 struct psr_heci_header {
124 	uint8_t command;
125 	uint8_t reserved;
126 	uint16_t length;
127 } __packed;
128 
129 /* CSE FW Version */
130 struct fw_version {
131 	uint16_t major;
132 	uint16_t minor;
133 	uint16_t hotfix;
134 	uint16_t build;
135 } __packed;
136 
137 /* ME FW Version */
138 struct me_version {
139 	uint16_t minor;
140 	uint16_t major;
141 	uint16_t build;
142 	uint16_t hotfix;
143 } __packed;
144 
145 /* ME FW Version response */
146 struct me_fw_ver_resp {
147 	struct mkhi_hdr hdr;
148 	struct me_version code;
149 	struct me_version rec;
150 	struct me_version fitc;
151 } __packed;
152 
153 /* Module data from manifest */
154 struct flash_partition_data {
155 	enum fpt_partition_id partition_id;
156 	uint8_t reserved1[8];
157 	struct fw_version version;
158 	uint32_t vendor_id;
159 	uint32_t tcb_svn;
160 	uint32_t arb_svn;
161 	uint32_t vcn;
162 	uint32_t reserved2[13];
163 };
164 
165 /* Response header for partition information request */
166 struct fw_version_resp {
167 	struct mkhi_hdr hdr;
168 	uint32_t module_count;
169 	struct flash_partition_data manifest_data;
170 };
171 
172 /* ISHC version */
173 struct cse_fw_ish_version_info {
174 	struct fw_version prev_cse_fw_version;
175 	struct fw_version cur_ish_fw_version;
176 };
177 
178 /* CSE and ISHC version */
179 struct cse_fw_partition_info {
180 	struct fw_version cur_cse_fw_version;
181 	struct cse_fw_ish_version_info ish_partition_info;
182 };
183 
184 /* CSE Specific Information */
185 struct cse_specific_info {
186 	struct cse_fw_partition_info cse_fwp_version;
187 	bool cse_downgrade_requested;
188 	uint32_t crc;
189 };
190 
191 /* PSR backup status */
192 enum psr_backup_state {
193 	PSR_BACKUP_DONE	= 0,
194 	PSR_BACKUP_PENDING = 1,
195 };
196 
197 struct psr_backup_status {
198 	uint32_t signature;
199 	int8_t value;
200 	uint16_t checksum;
201 };
202 
203 /* CSE RX and TX error status */
204 enum cse_tx_rx_status {
205 	/*
206 	 * Transmission of HECI message is success or
207 	 * Reception of HECI message is success.
208 	 */
209 	CSE_TX_RX_SUCCESS = 0,
210 
211 	 /* Timeout to send a message to CSE */
212 	CSE_TX_ERR_TIMEOUT = 1,
213 
214 	/* Timeout to receive the response message from CSE */
215 	CSE_RX_ERR_TIMEOUT = 2,
216 
217 	/*
218 	 * Response length doesn't match with expected
219 	 * response message length
220 	 */
221 	CSE_RX_ERR_RESP_LEN_MISMATCH = 3,
222 
223 	/* CSE is not ready during TX flow */
224 	CSE_TX_ERR_CSE_NOT_READY = 4,
225 
226 	/* CSE is not ready during RX flow */
227 	CSE_RX_ERR_CSE_NOT_READY = 5,
228 
229 	/* Invalid input arguments provided for TX API */
230 	CSE_TX_ERR_INPUT = 6,
231 
232 	/* Invalid input arguments provided for RX API */
233 	CSE_RX_ERR_INPUT = 7,
234 };
235 
236 /* CSE recovery sub-error codes */
237 enum csme_failure_reason {
238 	/* No error */
239 	CSE_NO_ERROR = 0,
240 
241 	/* Unspecified error */
242 	CSE_ERROR_UNSPECIFIED = 1,
243 
244 	/* CSE fails to boot from RW */
245 	CSE_LITE_SKU_RW_JUMP_ERROR = 2,
246 
247 	/* CSE RW boot partition access error */
248 	CSE_LITE_SKU_RW_ACCESS_ERROR = 3,
249 
250 	/* Fails to set next boot partition as RW */
251 	CSE_LITE_SKU_RW_SWITCH_ERROR = 4,
252 
253 	/* CSE firmware update failure */
254 	CSE_LITE_SKU_FW_UPDATE_ERROR = 5,
255 
256 	/* Fails to communicate with CSE */
257 	CSE_COMMUNICATION_ERROR = 6,
258 
259 	/* Fails to wipe CSE runtime data */
260 	CSE_LITE_SKU_DATA_WIPE_ERROR = 7,
261 
262 	/* CSE RW is not found */
263 	CSE_LITE_SKU_RW_BLOB_NOT_FOUND = 8,
264 
265 	/* CSE CBFS RW SHA-256 mismatch with the provided SHA */
266 	CSE_LITE_SKU_RW_BLOB_SHA256_MISMATCH = 9,
267 
268 	/* CSE CBFS RW metadata is not found */
269 	CSE_LITE_SKU_RW_METADATA_NOT_FOUND = 10,
270 
271 	/* CSE CBFS RW blob layout is not correct */
272 	CSE_LITE_SKU_LAYOUT_MISMATCH_ERROR = 11,
273 
274 	/* Error sending EOP to CSE */
275 	CSE_EOP_FAIL = 12,
276 
277 	/* CSE Sub-partition update fail */
278 	CSE_LITE_SKU_SUB_PART_UPDATE_FAIL = 13,
279 
280 	/* CSE sub-partition access failure */
281 	CSE_LITE_SKU_SUB_PART_ACCESS_ERR = 14,
282 
283 	/* CSE CBFS sub-partition access error */
284 	CSE_LITE_SKU_SUB_PART_BLOB_ACCESS_ERR = 15,
285 
286 	/* CSE Lite sub-partition update is not required */
287 	CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ = 16,
288 
289 	/* CSE Lite sub-partition layout mismatch error */
290 	CSE_LITE_SKU_SUB_PART_LAYOUT_MISMATCH_ERROR = 17,
291 
292 	/* CSE Lite sub-partition update success */
293 	CSE_LITE_SKU_PART_UPDATE_SUCCESS = 18,
294 };
295 
296 /* CSE boot performance data */
297 struct cse_boot_perf_rsp {
298 	struct mkhi_hdr hdr;
299 
300 	/* Data version */
301 	uint32_t version;
302 
303 	/* Data length in DWORDs, represents number of valid elements in timestamp array */
304 	uint32_t num_valid_timestamps;
305 
306 	/* Boot performance data */
307 	uint32_t timestamp[NUM_CSE_BOOT_PERF_DATA];
308 } __packed;
309 
310 /*
311  * Initialize the CSE device.
312  *
313  * Set up CSE device for use in early boot environment with temp bar.
314  */
315 void cse_init(uintptr_t bar);
316 
317 /* Initialize the HECI devices. */
318 void heci_init(void);
319 
320 /*
321  * Send message msg of size len to host from host_addr to cse_addr.
322  * Returns CSE_TX_RX_SUCCESS on success and other enum values on failure scenarios.
323  * Also, in case of errors, heci_reset() is triggered.
324  */
325 enum cse_tx_rx_status heci_send(const void *msg, size_t len, uint8_t host_addr,
326 				uint8_t client_addr);
327 
328 /*
329  * Receive message into buff not exceeding maxlen. Message is considered
330  * successfully received if a 'complete' indication is read from ME side
331  * and there was enough space in the buffer to fit that message. maxlen
332  * is updated with size of message that was received.
333  * Returns CSE_TX_RX_SUCCESS on success and other enum values on failure scenarios.
334  * Also, in case of errors, heci_reset() is triggered.
335  */
336 enum cse_tx_rx_status heci_receive(void *buff, size_t *maxlen);
337 
338 /*
339  * Send message from BIOS_HOST_ADDR to cse_addr.
340  * Sends snd_msg of size snd_sz, and reads message into buffer pointed by
341  * rcv_msg of size rcv_sz
342  * Returns CSE_TX_RX_SUCCESS on success and other enum values on failure scenarios.
343  */
344 enum cse_tx_rx_status heci_send_receive(const void *snd_msg, size_t snd_sz, void *rcv_msg,
345 					size_t *rcv_sz,	uint8_t cse_addr);
346 
347 /*
348  * Attempt device reset. This is useful and perhaps only thing left to do when
349  * CPU and CSE are out of sync or CSE fails to respond.
350  * Returns 0 on failure and 1 on success.
351  */
352 int heci_reset(void);
353 /* Disable HECI1 using Sideband interface communication */
354 void heci1_disable(void);
355 
356 /* Reads config value from a specified offset in the CSE PCI Config space. */
357 uint32_t me_read_config32(int offset);
358 
359 /*
360  * Check if the CSE device as per function argument `devfn` is enabled in device tree
361  * and also visible on the PCI bus.
362  */
363 bool is_cse_devfn_visible(unsigned int devfn);
364 
365 /*
366  * Check if the CSE device is enabled in device tree. Also check if the device
367  * is visible on the PCI bus by reading config space.
368  * Return true if device present and config space enabled, else return false.
369  */
370 bool is_cse_enabled(void);
371 
372 /* Makes the host ready to communicate with CSE */
373 void cse_set_host_ready(void);
374 
375 /*
376  * Polls for ME state 'HECI_OP_MODE_SEC_OVERRIDE' for 15 seconds.
377  * Returns 0 on failure and 1 on success.
378  */
379 uint8_t cse_wait_sec_override_mode(void);
380 
381 enum rst_req_type {
382 	GLOBAL_RESET = 1,
383 	CSE_RESET_ONLY = 3,
384 };
385 
386 /*
387  * Sends GLOBAL_RESET_REQ cmd to CSE with reset type GLOBAL_RESET.
388  * Returns 0 on failure and 1 on success.
389  */
390 int cse_request_global_reset(void);
391 /*
392  * Sends HMRFPO_ENABLE command.
393  * HMRFPO - Host ME Region Flash Protection Override.
394  * For CSE Lite SKU, procedure to place CSE in HMRFPO (SECOVER_MEI_MSG) mode:
395  *	1. Ensure CSE boots from RO(BP1).
396  *		- Set CSE's next boot partition to RO
397  *		- Issue GLOBAL_RESET command to reset the system
398  *	2. Send HMRFPO_ENABLE command to CSE. Further, no reset is required.
399  *
400  * The HMRFPO mode prevents CSE to execute SPI I/O cycles to CSE region, and unlocks
401  * the CSE region to perform updates to it.
402  * This command is only valid before EOP.
403  *
404  * Returns 0 on failure to send HECI command and to enable HMRFPO mode, and 1 on success.
405  *
406  */
407 enum cb_err cse_hmrfpo_enable(void);
408 
409 /*
410  * Send HMRFPO_GET_STATUS command.
411  * returns -1 on failure and 0 (DISABLED)/ 1 (LOCKED)/ 2 (ENABLED)
412  * on success.
413  */
414 int cse_hmrfpo_get_status(void);
415 
416 /* Fixed Address MEI Header's Host Address field value */
417 #define BIOS_HOST_ADDR	0x00
418 
419 /* Fixed Address MEI Header's ME Address field value */
420 #define HECI_MKHI_ADDR	0x07
421 
422 /* Fixed Address MEI Header's ME Address field value for PSR messages */
423 #define HECI_PSR_ADDR	0x04
424 
425 /* Fixed Address MEI Header's ME Address for MEI bus messages */
426 #define HECI_MEI_ADDR	0x00
427 
428 /* HMRFPO Status types */
429 /* Host can't access ME region */
430 #define MKHI_HMRFPO_DISABLED	0
431 
432 /*
433  * ME Firmware locked down HMRFPO Feature.
434  * Host can't access ME region.
435  */
436 #define MKHI_HMRFPO_LOCKED	1
437 
438 /* Host can access ME region */
439 #define MKHI_HMRFPO_ENABLED	2
440 
441 /*
442  * Queries and logs ME firmware version
443  */
444 void print_me_fw_version(void *unused);
445 
446 /*
447  * Checks current working operation state is normal or not.
448  * Returns true if CSE's current working state is normal, otherwise false.
449  */
450 bool cse_is_hfs1_cws_normal(void);
451 
452 /*
453  * Checks CSE's current operation mode is normal or not.
454  * Returns true if CSE's current operation mode is normal, otherwise false.
455  */
456 bool cse_is_hfs1_com_normal(void);
457 
458 /*
459  * Checks CSE's current operation mode is SECOVER_MEI_MSG or not.
460  * Returns true if CSE's current operation mode is SECOVER_MEI_MSG, otherwise false.
461  */
462 bool cse_is_hfs1_com_secover_mei_msg(void);
463 
464 /*
465  * Checks CSE's current operation mode is Soft Disable Mode or not.
466  * Returns true if CSE's current operation mode is Soft Disable Mode, otherwise false.
467  */
468 bool cse_is_hfs1_com_soft_temp_disable(void);
469 
470 /*
471  * Checks CSE's spi protection mode is protected or unprotected.
472  * Returns true if CSE's spi protection mode is protected, otherwise false.
473  */
474 bool cse_is_hfs1_spi_protected(void);
475 
476 /*
477  * Checks CSE's Firmware SKU is Lite or not.
478  * Returns true if CSE's Firmware SKU is Lite, otherwise false
479  */
480 bool cse_is_hfs3_fw_sku_lite(void);
481 
482 /*
483  * Polls for CSE's current operation mode 'Soft Temp Disable'.
484  * Returns 0 on failure and 1 on success.
485  */
486 uint8_t cse_wait_com_soft_temp_disable(void);
487 
488 /*
489  * The CSE Lite SKU supports notion of RO and RW boot partitions. The function will set
490  * CSE's boot partition as per ChromeOS boot modes. In normal mode, the function allows CSE to
491  * boot from RW and triggers recovery mode if CSE fails to jump to RW.
492  * In software triggered recovery mode, the function allows CSE to boot from whatever is
493  * currently selected partition.
494  */
495 void cse_fw_sync(void);
496 
497 /* Perform a board-specific reset sequence for CSE RO<->RW jump */
498 void cse_board_reset(void);
499 
500 /* Perform a misc operation before CSE firmware update. */
501 void cse_fw_update_misc_oper(void);
502 
503 /* Trigger vboot recovery mode on a CSE error */
504 void cse_trigger_vboot_recovery(enum csme_failure_reason reason);
505 
506 enum cse_device_state {
507 	DEV_IDLE,
508 	DEV_ACTIVE,
509 };
510 
511 /* Function to get the current CSE device state as per `cse_device_state` */
512 enum cse_device_state get_cse_device_state(unsigned int devfn);
513 
514 /* Function that put the CSE into desired state based on `requested_state` */
515 bool set_cse_device_state(unsigned int devfn, enum cse_device_state requested_state);
516 
517 /*
518  * Check if cse sub-parition update is required or not.
519  * Returns true if cse sub-parition update is required otherwise false.
520  */
521 bool skip_cse_sub_part_update(void);
522 
523 /*
524  * This command retrieves a set of boot performance timestamps CSME collected during
525  * the last platform boot flow.
526  */
527 enum cb_err cse_get_boot_performance_data(struct cse_boot_perf_rsp *boot_perf);
528 
529 /* Function to make cse disable using PMC IPC */
530 bool cse_disable_mei_devices(void);
531 
532 /* Set CSE device state to D0I3 */
533 void cse_set_to_d0i3(void);
534 
535 /* Function sets D0I3 for all HECI devices */
536 void heci_set_to_d0i3(void);
537 
538 /* Function performs the global reset lock */
539 void cse_control_global_reset_lock(void);
540 
541 /* Send End of Post (EOP) command to CSE device */
542 void cse_send_end_of_post(void);
543 
544 /*
545  * This function to perform essential post EOP cse related operations
546  * upon SoC selecting `SOC_INTEL_CSE_SEND_EOP_LATE` config
547  */
548 void cse_late_finalize(void);
549 
550 /*
551  * SoC override API to make heci1 disable using PCR.
552  *
553  * Allow SoC to implement heci1 disable override due to PSF registers being
554  * different across SoC generation.
555  */
556 void soc_disable_heci1_using_pcr(void);
557 
558 /*
559  * SoC override API to identify if ISH Firmware existed inside CSE FPT.
560  *
561  * This override is required to avoid making default call into non-ISH
562  * supported SKU to attempt to retrieve ISH version which would results into
563  * increased boot time by 100ms+.
564  *
565  * Ideally SoC with UFS enabled would like to keep ISH enabled as well, hence
566  * identifying the UFS enabled device is enough to conclude if ISH partition is
567  * available.
568  */
569 #if CONFIG(SOC_INTEL_STORE_ISH_FW_VERSION)
570 bool soc_is_ish_partition_enabled(void);
571 #else
soc_is_ish_partition_enabled(void)572 static inline bool soc_is_ish_partition_enabled(void)
573 {
574 	/* Default implementation, ISH not enabled. */
575 	return false;
576 }
577 #endif
578 
579 /*
580  * Injects CSE timestamps into cbmem timestamp table. SoC code needs to
581  * implement it since timestamp definitions differ from SoC to SoC.
582  */
583 void soc_cbmem_inject_telemetry_data(s64 *ts, s64 current_time);
584 
585 /*
586  * Get all the timestamps CSE collected using cse_get_boot_performance_data() and
587  * insert them into the CBMEM timestamp table.
588  */
589 void cse_get_telemetry_data(void);
590 
591 /* Function to log the cse WP information like range, if WP etc. */
592 void cse_log_ro_write_protection_info(bool mfg_mode);
593 
594 /*
595  * Changes Intel PTT feature state at runtime. Global reset is required after
596  * successful HECI command completion.
597  */
598 void cse_enable_ptt(bool state);
599 
600 /*
601  * Queries CSE for runtime status of firmware features.
602  * Returns 0 on success and < 0 on failure.
603  */
604 enum cb_err cse_get_fw_feature_state(uint32_t *feature_state);
605 
606 /* Fills the CSE Boot Partition Info response */
607 void cse_fill_bp_info(void);
608 
609 /*
610  * Check if a CSE Firmware update is required
611  * Returns true if an update is required, false otherwise
612  */
613 bool is_cse_fw_update_required(void);
614 #endif // SOC_INTEL_COMMON_CSE_H
615