From 2004552e62cb178a2b633e84371e459955aad150 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 4 Jan 2019 12:44:00 -0600 Subject: ti: k3: drivers: sec_proxy: Allow clearing a Secure Proxy receive thread It can be needed to discard all messages in a receive queue. This can be used during some error recovery situations. Signed-off-by: Andrew F. Davis Acked-by: Nishanth Menon --- plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c | 38 +++++++++++++++++++++++++ plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h | 9 ++++++ 2 files changed, 47 insertions(+) (limited to 'plat/ti/k3') diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c index 5dd54d4ff..4924b13b9 100644 --- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c @@ -162,6 +162,44 @@ static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt, return 0; } +/** + * k3_sec_proxy_clear_rx_thread() - Clear Secure Proxy thread + * + * @id: Channel Identifier + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id) +{ + struct k3_sec_proxy_thread *spt = &spm.threads[id]; + + /* Check for any errors already available */ + if (mmio_read_32(spt->rt + RT_THREAD_STATUS) & + RT_THREAD_STATUS_ERROR_MASK) { + ERROR("Thread %d is corrupted, cannot send data\n", spt->id); + return -EINVAL; + } + + /* Make sure thread is configured for right direction */ + if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) { + ERROR("Cannot clear a transmit thread %d\n", spt->id); + return -EINVAL; + } + + /* Read off messages from thread until empty */ + uint32_t try_count = 10; + while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) { + if (!(try_count--)) { + ERROR("Could not clear all messages from thread %d\n", spt->id); + return -ETIMEDOUT; + } + WARN("Clearing message from thread %d\n", spt->id); + mmio_read_32(spt->data + spm.desc.data_end_offset); + } + + return 0; +} + /** * k3_sec_proxy_send() - Send data over a Secure Proxy thread * @id: Channel Identifier diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h index 2d987f83a..6c4f5dfff 100644 --- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h +++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h @@ -37,6 +37,15 @@ struct k3_sec_proxy_msg { uint8_t *buf; }; +/** + * k3_sec_proxy_send() - Send data over a Secure Proxy thread + * @id: Channel Identifier + * @msg: Pointer to k3_sec_proxy_msg + * + * Return: 0 if all goes well, else appropriate error message + */ +int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id); + /** * k3_sec_proxy_send() - Send data over a Secure Proxy thread * @id: Channel Identifier -- cgit v1.2.3 From 73522f0087cee4d3e290356e4ee6f2de5c516be4 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 4 Jan 2019 12:49:16 -0600 Subject: ti: k3: drivers: ti_sci: Clear receive queue before transmitting Send and receive currently must be be serialized, any message already in the receive queue when a new message is to be sent will cause a mismatch with the expected response from this new message. Clear out all messages from the response queue before sending a new request. Signed-off-by: Andrew F. Davis Acked-by: Nishanth Menon --- plat/ti/k3/common/drivers/ti_sci/ti_sci.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'plat/ti/k3') diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c index b211bdf60..b4b120e4d 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -158,6 +158,13 @@ static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer) struct k3_sec_proxy_msg *msg = &xfer->tx_message; int ret; + /* Clear any spurious messages in receive queue */ + ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE); + if (ret) { + ERROR("Could not clear response queue (%d)\n", ret); + return ret; + } + /* Send the message */ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg); if (ret) { @@ -165,6 +172,7 @@ static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer) return ret; } + /* Get the response */ ret = ti_sci_get_response(xfer, SP_RESPONSE); if (ret) { ERROR("Failed to get response (%d)\n", ret); -- cgit v1.2.3