|
|
@ -51,14 +51,14 @@ struct k3_sec_proxy_desc { |
|
|
|
}; |
|
|
|
|
|
|
|
/**
|
|
|
|
* struct k3_sec_proxy_thread - Description of a secure proxy Thread |
|
|
|
* @id: Thread ID |
|
|
|
* struct k3_sec_proxy_thread - Description of a Secure Proxy Thread |
|
|
|
* @name: Thread Name |
|
|
|
* @data: Thread Data path region for target |
|
|
|
* @scfg: Secure Config Region for Thread |
|
|
|
* @rt: RealTime Region for Thread |
|
|
|
*/ |
|
|
|
struct k3_sec_proxy_thread { |
|
|
|
uint32_t id; |
|
|
|
const char *name; |
|
|
|
uintptr_t data; |
|
|
|
uintptr_t scfg; |
|
|
|
uintptr_t rt; |
|
|
@ -83,7 +83,7 @@ struct k3_sec_proxy_mbox { |
|
|
|
*/ |
|
|
|
#define SP_THREAD(_x) \ |
|
|
|
[_x] = { \ |
|
|
|
.id = _x, \ |
|
|
|
.name = #_x, \ |
|
|
|
.data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \ |
|
|
|
.scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_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 */ |
|
|
|
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); |
|
|
|
ERROR("Thread %s is corrupted, cannot send data\n", spt->name); |
|
|
|
return -EINVAL; |
|
|
|
} |
|
|
|
|
|
|
|
/* Make sure thread is configured for right direction */ |
|
|
|
if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK) |
|
|
|
!= (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) { |
|
|
|
if (dir) |
|
|
|
ERROR("Trying to send data on RX Thread %d\n", |
|
|
|
spt->id); |
|
|
|
if (dir == THREAD_IS_TX) |
|
|
|
ERROR("Trying to send data on RX Thread %s\n", |
|
|
|
spt->name); |
|
|
|
else |
|
|
|
ERROR("Trying to receive data on TX Thread %d\n", |
|
|
|
spt->id); |
|
|
|
ERROR("Trying to receive data on TX Thread %s\n", |
|
|
|
spt->name); |
|
|
|
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 ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000; |
|
|
|
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) > |
|
|
|
(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; |
|
|
|
} |
|
|
|
} |
|
|
@ -176,13 +178,13 @@ int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id 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); |
|
|
|
ERROR("Thread %s is corrupted, cannot send data\n", spt->name); |
|
|
|
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); |
|
|
|
ERROR("Cannot clear a transmit thread %s\n", spt->name); |
|
|
|
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; |
|
|
|
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); |
|
|
|
ERROR("Could not clear all messages from thread %s\n", spt->name); |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
@ -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); |
|
|
|
if (ret) { |
|
|
|
ERROR("Thread %d verification failed (%d)\n", spt->id, ret); |
|
|
|
ERROR("Thread %s verification failed (%d)\n", spt->name, ret); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
/* Check the message size */ |
|
|
|
if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) { |
|
|
|
ERROR("Thread %d message length %lu > max msg size\n", |
|
|
|
spt->id, msg->len); |
|
|
|
ERROR("Thread %s message length %lu > max msg size\n", |
|
|
|
spt->name, msg->len); |
|
|
|
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) |
|
|
|
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; |
|
|
|
} |
|
|
@ -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 |
|
|
|
*/ |
|
|
|
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]; |
|
|
|
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); |
|
|
|
if (ret) { |
|
|
|
ERROR("Thread %d verification failed (%d)\n", spt->id, ret); |
|
|
|
ERROR("Thread %s verification failed (%d)\n", spt->name, ret); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
@ -323,7 +325,7 @@ int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg) |
|
|
|
/* TODO: Verify 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; |
|
|
|
} |
|
|
|