diff options
-rw-r--r-- | src/soc/intel/common/block/cse/cse.c | 48 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/cse.h | 16 |
2 files changed, 47 insertions, 17 deletions
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index c9712dbb2c..041656a498 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -650,6 +650,26 @@ int cse_request_global_reset(enum rst_req_type rst_type) return status; } +static bool cse_is_hmrfpo_enable_allowed(void) +{ + /* + * Allow sending HMRFPO ENABLE command only if: + * - CSE's current working state is Normal and current operation mode is Normal + * - (or) cse's current working state is normal and current operation mode is + * Soft Temp Disable if CSE's Firmware SKU is Custom + */ + if (!cse_is_hfs1_cws_normal()) + return false; + + if (cse_is_hfs1_com_normal()) + return true; + + if (cse_is_hfs3_fw_sku_custom() && cse_is_hfs1_com_soft_temp_disable()) + return true; + + return false; +} + /* Sends HMRFPO Enable command to CSE */ int cse_hmrfpo_enable(void) { @@ -675,36 +695,34 @@ int cse_hmrfpo_enable(void) /* Length of factory data area, not relevant for client SKUs */ uint32_t fct_limit; uint8_t status; - uint8_t padding[3]; + uint8_t reserved[3]; } __packed; struct hmrfpo_enable_resp resp; size_t resp_size = sizeof(struct hmrfpo_enable_resp); printk(BIOS_DEBUG, "HECI: Send HMRFPO Enable Command\n"); - /* - * This command can be run only if: - * - Working state is normal and - * - Operation mode is normal or temporary disable mode. - */ - if (!cse_is_hfs1_cws_normal() || - (!cse_is_hfs1_com_normal() && !cse_is_hfs1_com_soft_temp_disable())) { - printk(BIOS_ERR, "HECI: ME not in required Mode\n"); - goto failed; + + if (!cse_is_hmrfpo_enable_allowed()) { + printk(BIOS_ERR, "HECI: CSE does not meet required prerequisites\n"); + return 0; } if (!heci_send_receive(&msg, sizeof(struct hmrfpo_enable_msg), &resp, &resp_size)) - goto failed; + return 0; if (resp.hdr.result) { printk(BIOS_ERR, "HECI: Resp Failed:%d\n", resp.hdr.result); - goto failed; + return 0; } - return 1; -failed: - return 0; + if (resp.status) { + printk(BIOS_ERR, "HECI: HMRFPO_Enable Failed (resp status: %d)\n", resp.status); + return 0; + } + + return 1; } /* diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index 93d1ce1d04..595c7d8d6b 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -136,8 +136,20 @@ enum rst_req_type { int cse_request_global_reset(enum rst_req_type rst_type); /* - * Send HMRFPO_ENABLE command. - * returns 0 on failure and 1 on success. + * Sends HMRFPO_ENABLE command. + * HMRFPO - Host ME Region Flash Protection Override. + * For CSE Firmware SKU Custom, procedure to place CSE in HMRFPO (SECOVER_MEI_MSG) mode: + * 1. Ensure CSE boots from BP1(RO). + * - Send set_next_boot_partition(BP1) + * - Issue CSE Only Reset + * 2. Send HMRFPO_ENABLE command to CSE. Further, no reset is required. + * + * The HMRFPO mode prevents CSE to execute SPI I/O cycles to CSE region, and unlocks + * the CSE region to perform updates to it. + * This command is only valid before EOP. + * + * Returns 0 on failure to send HECI command and to enable HMRFPO mode, and 1 on success. + * */ int cse_hmrfpo_enable(void); |