Merge changes from topic "k3-sequence-fix" into integration

* changes:
  ti: k3: drivers: ti_sci: Retry message receive on bad sequence ID
  ti: k3: drivers: ti_sci: Cleanup sequence ID usage
  ti: k3: drivers: sec_proxy: Use direction definitions
  ti: k3: drivers: sec_proxy: Fix printf format specifiers
This commit is contained in:
Antonio Niño Díaz 2019-04-24 10:04:52 +00:00 committed by TrustedFirmware Code Review
commit 5bec1e9264
2 changed files with 48 additions and 42 deletions

View File

@ -51,14 +51,14 @@ struct k3_sec_proxy_desc {
}; };
/** /**
* struct k3_sec_proxy_thread - Description of a secure proxy Thread * struct k3_sec_proxy_thread - Description of a Secure Proxy Thread
* @id: Thread ID * @name: Thread Name
* @data: Thread Data path region for target * @data: Thread Data path region for target
* @scfg: Secure Config Region for Thread * @scfg: Secure Config Region for Thread
* @rt: RealTime Region for Thread * @rt: RealTime Region for Thread
*/ */
struct k3_sec_proxy_thread { struct k3_sec_proxy_thread {
uint32_t id; const char *name;
uintptr_t data; uintptr_t data;
uintptr_t scfg; uintptr_t scfg;
uintptr_t rt; uintptr_t rt;
@ -83,7 +83,7 @@ struct k3_sec_proxy_mbox {
*/ */
#define SP_THREAD(_x) \ #define SP_THREAD(_x) \
[_x] = { \ [_x] = { \
.id = _x, \ .name = #_x, \
.data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \ .data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \
.scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \ .scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \
.rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \ .rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \
@ -131,19 +131,19 @@ static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
/* Check for any errors already available */ /* Check for any errors already available */
if (mmio_read_32(spt->rt + RT_THREAD_STATUS) & if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
RT_THREAD_STATUS_ERROR_MASK) { RT_THREAD_STATUS_ERROR_MASK) {
ERROR("Thread %d is corrupted, cannot send data\n", spt->id); ERROR("Thread %s is corrupted, cannot send data\n", spt->name);
return -EINVAL; return -EINVAL;
} }
/* Make sure thread is configured for right direction */ /* Make sure thread is configured for right direction */
if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK) if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
!= (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) { != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
if (dir) if (dir == THREAD_IS_TX)
ERROR("Trying to send data on RX Thread %d\n", ERROR("Trying to send data on RX Thread %s\n",
spt->id); spt->name);
else else
ERROR("Trying to receive data on TX Thread %d\n", ERROR("Trying to receive data on TX Thread %s\n",
spt->id); spt->name);
return -EINVAL; return -EINVAL;
} }
@ -151,10 +151,12 @@ static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
uint32_t tick_start = (uint32_t)read_cntpct_el0(); uint32_t tick_start = (uint32_t)read_cntpct_el0();
uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000; uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000;
while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) { while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) {
VERBOSE("Waiting for thread %d to clear\n", spt->id); VERBOSE("Waiting for thread %s to %s\n",
spt->name, (dir == THREAD_IS_TX) ? "empty" : "fill");
if (((uint32_t)read_cntpct_el0() - tick_start) > if (((uint32_t)read_cntpct_el0() - tick_start) >
(spm.desc.timeout_us * ticks_per_us)) { (spm.desc.timeout_us * ticks_per_us)) {
ERROR("Timeout waiting for thread %d to clear\n", spt->id); ERROR("Timeout waiting for thread %s to %s\n",
spt->name, (dir == THREAD_IS_TX) ? "empty" : "fill");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} }
@ -176,13 +178,13 @@ int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id)
/* Check for any errors already available */ /* Check for any errors already available */
if (mmio_read_32(spt->rt + RT_THREAD_STATUS) & if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
RT_THREAD_STATUS_ERROR_MASK) { RT_THREAD_STATUS_ERROR_MASK) {
ERROR("Thread %d is corrupted, cannot send data\n", spt->id); ERROR("Thread %s is corrupted, cannot send data\n", spt->name);
return -EINVAL; return -EINVAL;
} }
/* Make sure thread is configured for right direction */ /* Make sure thread is configured for right direction */
if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) { if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) {
ERROR("Cannot clear a transmit thread %d\n", spt->id); ERROR("Cannot clear a transmit thread %s\n", spt->name);
return -EINVAL; return -EINVAL;
} }
@ -190,10 +192,10 @@ int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id)
uint32_t try_count = 10; uint32_t try_count = 10;
while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) { while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) {
if (!(try_count--)) { if (!(try_count--)) {
ERROR("Could not clear all messages from thread %d\n", spt->id); ERROR("Could not clear all messages from thread %s\n", spt->name);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
WARN("Clearing message from thread %d\n", spt->id); WARN("Clearing message from thread %s\n", spt->name);
mmio_read_32(spt->data + spm.desc.data_end_offset); mmio_read_32(spt->data + spm.desc.data_end_offset);
} }
@ -216,14 +218,14 @@ int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_ms
ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX); ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX);
if (ret) { if (ret) {
ERROR("Thread %d verification failed (%d)\n", spt->id, ret); ERROR("Thread %s verification failed (%d)\n", spt->name, ret);
return ret; return ret;
} }
/* Check the message size */ /* Check the message size */
if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) { if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) {
ERROR("Thread %d message length %lu > max msg size\n", ERROR("Thread %s message length %lu > max msg size\n",
spt->id, msg->len); spt->name, msg->len);
return -EINVAL; return -EINVAL;
} }
@ -263,7 +265,7 @@ int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_ms
if (data_reg <= spm.desc.data_end_offset) if (data_reg <= spm.desc.data_end_offset)
mmio_write_32(spt->data + spm.desc.data_end_offset, 0); mmio_write_32(spt->data + spm.desc.data_end_offset, 0);
VERBOSE("Message successfully sent on thread %ud\n", id); VERBOSE("Message successfully sent on thread %s\n", spt->name);
return 0; return 0;
} }
@ -275,7 +277,7 @@ int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_ms
* *
* Return: 0 if all goes well, else appropriate error message * Return: 0 if all goes well, else appropriate error message
*/ */
int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg) int k3_sec_proxy_recv(enum k3_sec_proxy_chan_id id, struct k3_sec_proxy_msg *msg)
{ {
struct k3_sec_proxy_thread *spt = &spm.threads[id]; struct k3_sec_proxy_thread *spt = &spm.threads[id];
union sec_msg_hdr secure_header; union sec_msg_hdr secure_header;
@ -284,7 +286,7 @@ int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg)
ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX); ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX);
if (ret) { if (ret) {
ERROR("Thread %d verification failed (%d)\n", spt->id, ret); ERROR("Thread %s verification failed (%d)\n", spt->name, ret);
return ret; return ret;
} }
@ -323,7 +325,7 @@ int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg)
/* TODO: Verify checksum */ /* TODO: Verify checksum */
(void)secure_header.checksum; (void)secure_header.checksum;
VERBOSE("Message successfully received from thread %ud\n", id); VERBOSE("Message successfully received from thread %s\n", spt->name);
return 0; return 0;
} }

View File

@ -45,7 +45,6 @@ static struct ti_sci_info info = {
.host_id = TI_SCI_HOST_ID, .host_id = TI_SCI_HOST_ID,
.max_msg_size = TI_SCI_MAX_MESSAGE_SIZE, .max_msg_size = TI_SCI_MAX_MESSAGE_SIZE,
}, },
.seq = 0x0a,
}; };
/** /**
@ -89,10 +88,8 @@ static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags,
tx_message_size < sizeof(*hdr)) tx_message_size < sizeof(*hdr))
return -ERANGE; return -ERANGE;
info.seq++;
hdr = (struct ti_sci_msg_hdr *)tx_buf; hdr = (struct ti_sci_msg_hdr *)tx_buf;
hdr->seq = info.seq; hdr->seq = ++info.seq;
hdr->type = msg_type; hdr->type = msg_type;
hdr->host = info.desc.host_id; hdr->host = info.desc.host_id;
hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED; hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
@ -119,21 +116,28 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer,
{ {
struct k3_sec_proxy_msg *msg = &xfer->rx_message; struct k3_sec_proxy_msg *msg = &xfer->rx_message;
struct ti_sci_msg_hdr *hdr; struct ti_sci_msg_hdr *hdr;
unsigned int retry = 5;
int ret; int ret;
/* Receive the response */ for (; retry > 0; retry--) {
ret = k3_sec_proxy_recv(chan, msg); /* Receive the response */
if (ret) { ret = k3_sec_proxy_recv(chan, msg);
ERROR("Message receive failed (%d)\n", ret); if (ret) {
return ret; ERROR("Message receive failed (%d)\n", ret);
return ret;
}
/* msg is updated by Secure Proxy driver */
hdr = (struct ti_sci_msg_hdr *)msg->buf;
/* Sanity check for message response */
if (hdr->seq == info.seq)
break;
else
WARN("Message with sequence ID %u is not expected\n", hdr->seq);
} }
if (!retry) {
/* msg is updated by Secure Proxy driver */ ERROR("Timed out waiting for message\n");
hdr = (struct ti_sci_msg_hdr *)msg->buf;
/* Sanity check for message response */
if (hdr->seq != info.seq) {
ERROR("Message for %d is not expected\n", hdr->seq);
return -EINVAL; return -EINVAL;
} }
@ -425,7 +429,7 @@ int ti_sci_device_put_no_wait(uint32_t id)
return -ERANGE; return -ERANGE;
hdr = (struct ti_sci_msg_hdr *)&req; hdr = (struct ti_sci_msg_hdr *)&req;
hdr->seq = info.seq; hdr->seq = ++info.seq;
hdr->type = TI_SCI_MSG_SET_DEVICE_STATE; hdr->type = TI_SCI_MSG_SET_DEVICE_STATE;
hdr->host = info.desc.host_id; hdr->host = info.desc.host_id;
/* Setup with NORESPONSE flag to keep response queue clean */ /* Setup with NORESPONSE flag to keep response queue clean */
@ -1408,7 +1412,7 @@ int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id,
return -ERANGE; return -ERANGE;
hdr = (struct ti_sci_msg_hdr *)&req; hdr = (struct ti_sci_msg_hdr *)&req;
hdr->seq = info.seq; hdr->seq = ++info.seq;
hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL; hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL;
hdr->host = info.desc.host_id; hdr->host = info.desc.host_id;
/* Setup with NORESPONSE flag to keep response queue clean */ /* Setup with NORESPONSE flag to keep response queue clean */
@ -1650,7 +1654,7 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
return -ERANGE; return -ERANGE;
hdr = (struct ti_sci_msg_hdr *)&req; hdr = (struct ti_sci_msg_hdr *)&req;
hdr->seq = info.seq; hdr->seq = ++info.seq;
hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS; hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS;
hdr->host = info.desc.host_id; hdr->host = info.desc.host_id;
/* Setup with NORESPONSE flag to keep response queue clean */ /* Setup with NORESPONSE flag to keep response queue clean */