diff options
author | Sridhar Siricilla <sridhar.siricilla@intel.com> | 2022-02-20 00:30:31 +0530 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-03-16 16:56:34 +0000 |
commit | 92bd71ff741f61787fbd05155c03c56e5ffaca10 (patch) | |
tree | b290552ee4585d332284553559baee7945506040 /src/soc/intel | |
parent | bddb16ba7679df4fe634f0c3ae5aa9b8fb0dca99 (diff) |
soc/intel/common: Retry END_OF_POST command
As per ME BWG, the patch retries END_OF_POST command if CSE doesn't
respond or sends the garbled response. It retries the command
additionally 2 more times.
BUG=b:200251277
TEST=Verify EOP retry mechanism for brya board.
Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Change-Id: Ieaec4d5564e3d962c1cc866351e9e7eaa8e58683
Reviewed-on: https://review.coreboot.org/c/coreboot/+/62192
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/common/block/cse/cse_eop.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/soc/intel/common/block/cse/cse_eop.c b/src/soc/intel/common/block/cse/cse_eop.c index bc6d83764e..c6b527778f 100644 --- a/src/soc/intel/common/block/cse/cse_eop.c +++ b/src/soc/intel/common/block/cse/cse_eop.c @@ -11,13 +11,29 @@ #include <timestamp.h> #include <types.h> +#define CSE_MAX_RETRY_CMD 3 + enum cse_cmd_result { CSE_CMD_RESULT_GLOBAL_RESET_REQUESTED, CSE_CMD_RESULT_SUCCESS, CSE_CMD_RESULT_ERROR, CSE_CMD_RESULT_DISABLED, + 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 bool cse_disable_mei_bus(void) { struct bus_disable_message { @@ -49,6 +65,7 @@ static bool cse_disable_mei_bus(void) static enum cse_cmd_result cse_send_eop(void) { + enum cse_tx_rx_status ret; enum { EOP_REQUESTED_ACTION_CONTINUE = 0, EOP_REQUESTED_ACTION_GLOBAL_RESET = 1, @@ -98,10 +115,9 @@ static enum cse_cmd_result cse_send_eop(void) printk(BIOS_INFO, "HECI: Sending End-of-Post\n"); - if (heci_send_receive(&msg, sizeof(msg), &resp, &resp_size, HECI_MKHI_ADDR)) { - printk(BIOS_ERR, "HECI: EOP send/receive fail\n"); - return CSE_CMD_RESULT_ERROR; - } + ret = heci_send_receive(&msg, sizeof(msg), &resp, &resp_size, HECI_MKHI_ADDR); + if (ret) + return decode_heci_send_receive_error(ret); if (resp.hdr.result) { printk(BIOS_ERR, "HECI: EOP Resp Failed: %u\n", resp.hdr.result); @@ -123,6 +139,18 @@ static enum cse_cmd_result cse_send_eop(void) } } +static enum cse_cmd_result cse_send_cmd_retries(enum cse_cmd_result (*cse_send_command)(void)) +{ + size_t retry; + enum cse_cmd_result ret; + for (retry = 0; retry < CSE_MAX_RETRY_CMD; retry++) { + ret = cse_send_command(); + if (ret != CSE_CMD_RESULT_RETRY) + break; + } + return ret; +} + /* * On EOP error, the BIOS is required to send an MEI bus disable message to the * CSE, followed by disabling all MEI devices. After successfully completing @@ -193,7 +221,7 @@ static void do_send_end_of_post(void) set_cse_device_state(PCH_DEVFN_CSE, DEV_ACTIVE); timestamp_add_now(TS_ME_END_OF_POST_START); - handle_cse_eop_result(cse_send_eop()); + handle_cse_eop_result(cse_send_cmd_retries(cse_send_eop)); timestamp_add_now(TS_ME_END_OF_POST_END); set_cse_device_state(PCH_DEVFN_CSE, DEV_IDLE); |