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