diff options
author | David Hu <david.hu@arm.com> | 2019-11-12 18:43:34 +0800 |
---|---|---|
committer | David Hu <david.hu@arm.com> | 2020-02-14 11:05:29 +0800 |
commit | 3684ee71ca38c0d6a184cc34223f00f4036ccb6f (patch) | |
tree | d43c47e1c7a5aa87593a84df0f7a68456c8c5c7f /interface/src | |
parent | c617ba146297fb3733d455da5f922adb5f833a1b (diff) | |
download | trusted-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.c | 64 |
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; |