soc/intel/common: Add HECI message retry count
Send/Receive HECI message with 5 retry count in order to avoid HECI message failure. TEST=Build and boot eve/soraka/reef/cnl-rvp Change-Id: I76662f8080fe312caa77c83d1660faeee0bdbe7e Signed-off-by: Subrata Banik <subrata.banik@intel.com> Reviewed-on: https://review.coreboot.org/22443 Reviewed-by: Furquan Shaikh <furquan@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
93bbd41ea8
commit
5c08c73dd1
|
@ -27,6 +27,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
|
||||||
|
#define MAX_HECI_MESSAGE_RETRY_COUNT 5
|
||||||
|
|
||||||
/* Wait up to 15 sec for HECI to get ready */
|
/* Wait up to 15 sec for HECI to get ready */
|
||||||
#define HECI_DELAY_READY (15 * 1000)
|
#define HECI_DELAY_READY (15 * 1000)
|
||||||
/* Wait up to 100 usec between circullar buffer polls */
|
/* Wait up to 100 usec between circullar buffer polls */
|
||||||
|
@ -309,45 +311,54 @@ send_one_message(uint32_t hdr, const void *buff)
|
||||||
int
|
int
|
||||||
heci_send(const void *msg, size_t len, uint8_t host_addr, uint8_t client_addr)
|
heci_send(const void *msg, size_t len, uint8_t host_addr, uint8_t client_addr)
|
||||||
{
|
{
|
||||||
|
uint8_t retry;
|
||||||
uint32_t csr, hdr;
|
uint32_t csr, hdr;
|
||||||
size_t sent = 0, remaining, cb_size, max_length;
|
size_t sent, remaining, cb_size, max_length;
|
||||||
uint8_t *p = (uint8_t *) msg;
|
const uint8_t *p;
|
||||||
|
|
||||||
if (!msg || !len)
|
if (!msg || !len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clear_int();
|
clear_int();
|
||||||
|
|
||||||
if (!wait_heci_ready()) {
|
for (retry = 0; retry < MAX_HECI_MESSAGE_RETRY_COUNT; retry++) {
|
||||||
printk(BIOS_ERR, "HECI: not ready\n");
|
p = msg;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
csr = read_cse_csr();
|
if (!wait_heci_ready()) {
|
||||||
cb_size = ((csr & CSR_CBD) >> CSR_CBD_START) * SLOT_SIZE;
|
printk(BIOS_ERR, "HECI: not ready\n");
|
||||||
/*
|
continue;
|
||||||
* Reserve one slot for the header. Limit max message length by 9
|
}
|
||||||
* bits that are available in the header.
|
|
||||||
*/
|
|
||||||
max_length = MIN(cb_size, (1 << MEI_HDR_LENGTH_SIZE) - 1) - SLOT_SIZE;
|
|
||||||
remaining = len;
|
|
||||||
|
|
||||||
/*
|
csr = read_cse_csr();
|
||||||
* Fragment the message into smaller messages not exceeding useful
|
cb_size = ((csr & CSR_CBD) >> CSR_CBD_START) * SLOT_SIZE;
|
||||||
* circullar buffer length. Mark last message complete.
|
/*
|
||||||
*/
|
* Reserve one slot for the header. Limit max message
|
||||||
do {
|
* length by 9 bits that are available in the header.
|
||||||
hdr = MIN(max_length, remaining) << MEI_HDR_LENGTH_START;
|
*/
|
||||||
hdr |= client_addr << MEI_HDR_CSE_ADDR_START;
|
max_length = MIN(cb_size, (1 << MEI_HDR_LENGTH_SIZE) - 1)
|
||||||
hdr |= host_addr << MEI_HDR_HOST_ADDR_START;
|
- SLOT_SIZE;
|
||||||
hdr |= (MIN(max_length, remaining) == remaining) ?
|
remaining = len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fragment the message into smaller messages not exceeding
|
||||||
|
* useful circullar buffer length. Mark last message complete.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
hdr = MIN(max_length, remaining)
|
||||||
|
<< MEI_HDR_LENGTH_START;
|
||||||
|
hdr |= client_addr << MEI_HDR_CSE_ADDR_START;
|
||||||
|
hdr |= host_addr << MEI_HDR_HOST_ADDR_START;
|
||||||
|
hdr |= (MIN(max_length, remaining) == remaining) ?
|
||||||
MEI_HDR_IS_COMPLETE : 0;
|
MEI_HDR_IS_COMPLETE : 0;
|
||||||
sent = send_one_message(hdr, p);
|
sent = send_one_message(hdr, p);
|
||||||
p += sent;
|
p += sent;
|
||||||
remaining -= sent;
|
remaining -= sent;
|
||||||
} while (remaining > 0 && sent != 0);
|
} while (remaining > 0 && sent != 0);
|
||||||
|
|
||||||
return remaining == 0;
|
if (!remaining)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
|
@ -383,6 +394,13 @@ recv_one_message(uint32_t *hdr, void *buff, size_t maxlen)
|
||||||
i += SLOT_SIZE;
|
i += SLOT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If ME is not ready, something went wrong and
|
||||||
|
* we received junk
|
||||||
|
*/
|
||||||
|
if (!cse_ready())
|
||||||
|
return 0;
|
||||||
|
|
||||||
remainder = recv_len % SLOT_SIZE;
|
remainder = recv_len % SLOT_SIZE;
|
||||||
|
|
||||||
if (remainder) {
|
if (remainder) {
|
||||||
|
@ -395,42 +413,44 @@ recv_one_message(uint32_t *hdr, void *buff, size_t maxlen)
|
||||||
|
|
||||||
int heci_receive(void *buff, size_t *maxlen)
|
int heci_receive(void *buff, size_t *maxlen)
|
||||||
{
|
{
|
||||||
|
uint8_t retry;
|
||||||
size_t left, received;
|
size_t left, received;
|
||||||
uint32_t hdr = 0;
|
uint32_t hdr = 0;
|
||||||
uint8_t *p = buff;
|
uint8_t *p;
|
||||||
|
|
||||||
if (!buff || !maxlen || !*maxlen)
|
if (!buff || !maxlen || !*maxlen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
left = *maxlen;
|
|
||||||
|
|
||||||
clear_int();
|
clear_int();
|
||||||
|
|
||||||
if (!wait_heci_ready()) {
|
for (retry = 0; retry < MAX_HECI_MESSAGE_RETRY_COUNT; retry++) {
|
||||||
printk(BIOS_ERR, "HECI: not ready\n");
|
p = buff;
|
||||||
return 0;
|
left = *maxlen;
|
||||||
|
|
||||||
|
if (!wait_heci_ready()) {
|
||||||
|
printk(BIOS_ERR, "HECI: not ready\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Receive multiple packets until we meet one marked
|
||||||
|
* complete or we run out of space in caller-provided buffer.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
received = recv_one_message(&hdr, p, left);
|
||||||
|
left -= received;
|
||||||
|
p += received;
|
||||||
|
/* If we read out everything ping to send more */
|
||||||
|
if (!(hdr & MEI_HDR_IS_COMPLETE) && !cse_filled_slots())
|
||||||
|
host_gen_interrupt();
|
||||||
|
} while (received && !(hdr & MEI_HDR_IS_COMPLETE) && left > 0);
|
||||||
|
|
||||||
|
if ((hdr & MEI_HDR_IS_COMPLETE) && received) {
|
||||||
|
*maxlen = p - (uint8_t *) buff;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
/*
|
|
||||||
* Receive multiple packets until we meet one marked complete or we run
|
|
||||||
* out of space in caller-provided buffer.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
received = recv_one_message(&hdr, p, left);
|
|
||||||
left -= received;
|
|
||||||
p += received;
|
|
||||||
/* If we read out everything ping to send more */
|
|
||||||
if (!(hdr & MEI_HDR_IS_COMPLETE) && !cse_filled_slots())
|
|
||||||
host_gen_interrupt();
|
|
||||||
} while (received && !(hdr & MEI_HDR_IS_COMPLETE) && left > 0);
|
|
||||||
|
|
||||||
*maxlen = p - (uint8_t *) buff;
|
|
||||||
|
|
||||||
/* If ME is not ready, something went wrong and we received junk */
|
|
||||||
if (!cse_ready())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return !!((hdr & MEI_HDR_IS_COMPLETE) && received);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue