From d16187ed2a6bf23022119c735d24c14d6fafae4b Mon Sep 17 00:00:00 2001 From: Sridhar Siricilla Date: Wed, 27 Nov 2019 16:02:47 +0530 Subject: soc/intel/common/block/cse: Modify handling of HMRFPO_ENABLE command Below changes are done: 1. Allow execution of HMRFPO_ENABLE command if CSE meets below prerequisites: - Current operation mode(COM) is Normal and Curret working state(CWS) is Normal. -(or) COM is Soft Temp Disable and CWS is Normal if ME's Firmware SKU is Custom. 2. Check response status. 3. Add documentation for send_hmrfpo_enable_msg(). 4. Rename padding field of hmrfpo_enable_resp to reserved. The HMRFPO (Host ME Region Flash Protection Override) 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(End of Post). For Custom SKU, follow below procedure to place CSE in HMRFPO mode: 1. Ensure CSE boots from BP1. When CSE boots from BP1, it will have opmode Temp Disable Mode. 2. Send HMRFPO_ENABLE command to CSE. Then, CSE enters HMRFPO mode. CSE Firmware Custom SKU Image Layout: = [RO] + [RW + DATA PART] = [BP1] + [BP2 + DATA PART] Here, BP1 will have reduced functionality of BP2, and the BP1 will be CSE's RO partition and [BP2 + DATA PART] together will represent CSE's RW partition. CSE can boot from either BP1(RO) or BP2(RW). CSE Image Layout in Consumer SKU: BP2 + BP3 + DATA PART TEST=Verfied on hatch board. Change-Id: I7c87998fa105947e5ba4638a8e68625e46703448 Signed-off-by: Sridhar Siricilla Reviewed-on: https://review.coreboot.org/c/coreboot/+/37283 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/soc/intel/common/block/cse/cse.c | 48 +++++++++++++++------- .../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); -- cgit v1.2.3