aboutsummaryrefslogtreecommitdiff
path: root/interface/src
diff options
context:
space:
mode:
authorDavid Hu <david.hu@arm.com>2019-11-12 18:43:34 +0800
committerDavid Hu <david.hu@arm.com>2020-02-14 11:05:29 +0800
commit3684ee71ca38c0d6a184cc34223f00f4036ccb6f (patch)
treed43c47e1c7a5aa87593a84df0f7a68456c8c5c7f /interface/src
parentc617ba146297fb3733d455da5f922adb5f833a1b (diff)
downloadtrusted-firmware-m-3684ee71ca38c0d6a184cc34223f00f4036ccb6f.tar.gz
Dualcpu: Add NS mailbox functions to handle reply in IRQ handler
Add tfm_ns_mailbox_fetch_reply_msg_isr() to fetch the handle of the first replied mailbox message from NSPE mailbox queue in platform inter-processor communication interrupt handler. NS OS can get the handle of the waiting caller task by calling tfm_ns_mailbox_get_msg_owner() and wake-up the caller task according to the handle value. Change-Id: Id86e0b23819cf8963831006fd037142d9efb4d9f Signed-off-by: David Hu <david.hu@arm.com>
Diffstat (limited to 'interface/src')
-rw-r--r--interface/src/tfm_ns_mailbox.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/interface/src/tfm_ns_mailbox.c b/interface/src/tfm_ns_mailbox.c
index 9ab3004769..98193e8c80 100644
--- a/interface/src/tfm_ns_mailbox.c
+++ b/interface/src/tfm_ns_mailbox.c
@@ -64,6 +64,13 @@ static inline void clear_queue_slot_replied(uint8_t idx)
}
}
+static inline void set_queue_slot_woken(uint8_t idx)
+{
+ if (idx < NUM_MAILBOX_QUEUE_SLOT) {
+ mailbox_queue_ptr->queue[idx].is_woken = true;
+ }
+}
+
static uint8_t acquire_empty_slot(const struct ns_mailbox_queue_t *queue)
{
uint8_t idx;
@@ -170,8 +177,13 @@ int32_t tfm_ns_mailbox_rx_client_reply(mailbox_msg_handle_t handle,
set_msg_owner(idx, NULL);
tfm_ns_mailbox_hal_enter_critical();
- set_queue_slot_empty(idx);
clear_queue_slot_replied(idx);
+ clear_queue_slot_woken(idx);
+ /*
+ * Make sure that the empty flag is set after all the other status flags are
+ * re-initialized.
+ */
+ set_queue_slot_empty(idx);
tfm_ns_mailbox_hal_exit_critical();
return MAILBOX_SUCCESS;
@@ -207,6 +219,56 @@ bool tfm_ns_mailbox_is_msg_replied(mailbox_msg_handle_t handle)
return false;
}
+mailbox_msg_handle_t tfm_ns_mailbox_fetch_reply_msg_isr(void)
+{
+ uint8_t idx;
+ mailbox_msg_handle_t handle;
+ mailbox_queue_status_t replied_status;
+
+ if (!mailbox_queue_ptr) {
+ return MAILBOX_MSG_NULL_HANDLE;
+ }
+
+ tfm_ns_mailbox_hal_enter_critical_isr();
+ replied_status = mailbox_queue_ptr->replied_slots;
+ tfm_ns_mailbox_hal_exit_critical_isr();
+
+ if (!replied_status) {
+ return MAILBOX_MSG_NULL_HANDLE;
+ }
+
+ for (idx = 0; idx < NUM_MAILBOX_QUEUE_SLOT; idx++) {
+ /* Find the first replied message in queue */
+ if (replied_status & (0x1UL << idx)) {
+ tfm_ns_mailbox_hal_enter_critical_isr();
+ clear_queue_slot_replied(idx);
+ set_queue_slot_woken(idx);
+ tfm_ns_mailbox_hal_exit_critical_isr();
+
+ if (get_mailbox_msg_handle(idx, &handle) == MAILBOX_SUCCESS) {
+ return handle;
+ }
+ }
+ }
+
+ return MAILBOX_MSG_NULL_HANDLE;
+}
+
+const void *tfm_ns_mailbox_get_msg_owner(mailbox_msg_handle_t handle)
+{
+ uint8_t idx;
+
+ if (get_mailbox_msg_idx(handle, &idx) != MAILBOX_SUCCESS) {
+ return NULL;
+ }
+
+ if (idx < NUM_MAILBOX_QUEUE_SLOT) {
+ return mailbox_queue_ptr->queue[idx].owner;
+ }
+
+ return NULL;
+}
+
int32_t tfm_ns_mailbox_init(struct ns_mailbox_queue_t *queue)
{
int32_t ret;