Sridhar Siricilla has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/62560 )
Change subject: soc/intel/common: Retry MEI CSE DISABLE command ......................................................................
soc/intel/common: Retry MEI CSE DISABLE command
The patch retries MEI CSE DISABLE command if cse doesn't respond or sends the garbled response. It retries the command additionally 2 more times.
TEST=build and boot the Brya board Signed-off-by: Sridhar Siricilla sridhar.siricilla@intel.com Change-Id: Id38a172d670a0cd44643744f27b85ca7e368ccdb --- M src/soc/intel/common/block/cse/cse_eop.c 1 file changed, 44 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/60/62560/1
diff --git a/src/soc/intel/common/block/cse/cse_eop.c b/src/soc/intel/common/block/cse/cse_eop.c index 5faf21b..1ddca2b 100644 --- a/src/soc/intel/common/block/cse/cse_eop.c +++ b/src/soc/intel/common/block/cse/cse_eop.c @@ -11,7 +11,8 @@ #include <timestamp.h> #include <types.h>
-#define MAX_RETRY_EOP_MSG 3 +#define MAX_RETRY_EOP_MSG 3 +#define MAX_RETRY_CSE_DISABLE_MSG 3
enum cse_eop_result { CSE_EOP_RESULT_GLOBAL_RESET_REQUESTED, @@ -21,7 +22,26 @@ CSE_EOP_RESULT_RETRY, };
-static bool cse_disable_mei_bus(void) +enum cse_cmd_result { + CSE_CMD_RESULT_SUCCESS, + CSE_CMD_RESULT_ERROR, + CSE_CMD_RESULT_RETRY, +}; + +static enum cse_cmd_result decode_heci_send_receive_error(enum cse_tx_rx_status ret) +{ + switch (ret) { + case CSE_TX_ERR_CSE_NOT_READY: + case CSE_RX_ERR_CSE_NOT_READY: + case CSE_RX_ERR_RESP_LEN_MISMATCH: + case CSE_RX_ERR_TIMEOUT: + return CSE_CMD_RESULT_RETRY; + default: + return CSE_CMD_RESULT_ERROR; + } +} + +static enum cse_cmd_result cse_disable_mei_bus(void) { struct bus_disable_message { uint8_t command; @@ -36,18 +56,35 @@ } __packed reply = {};
size_t reply_sz = sizeof(reply); + enum cse_tx_rx_status ret;
- if (heci_send_receive(&msg, sizeof(msg), &reply, &reply_sz, HECI_MEI_ADDR)) { + printk(BIOS_DEBUG, "HECI, Sending MEI BIOS DISABLE command\n"); + ret = heci_send_receive(&msg, sizeof(msg), &reply, &reply_sz, HECI_MEI_ADDR); + + if (ret) { printk(BIOS_ERR, "HECI: Failed to Disable MEI bus\n"); - return false; + return decode_heci_send_receive_error(ret); }
if (reply.status) { printk(BIOS_ERR, "HECI: MEI_Bus_Disable Failed (status: %d)\n", reply.status); - return false; + return CSE_CMD_RESULT_ERROR; }
- return true; + return CSE_CMD_RESULT_SUCCESS; +} + +static enum cse_cmd_result cse_send_bus_disable_message(void) +{ + size_t retry; + enum cse_cmd_result ret; + + for (retry = 0; retry < MAX_RETRY_CSE_DISABLE_MSG; retry++) { + ret = cse_disable_mei_bus(); + if (ret != CSE_CMD_RESULT_RETRY) + break; + } + return ret; }
static enum cse_eop_result decode_eop_error(enum cse_tx_rx_status ret) @@ -158,7 +195,7 @@ */ static void cse_handle_eop_error(void) { - if (!cse_disable_mei_bus()) + if (cse_send_bus_disable_message()) die("Failed to disable MEI bus while recovering from EOP error\n" "Preventing system from booting into an insecure state.\n");