aboutsummaryrefslogtreecommitdiff
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
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>
-rw-r--r--interface/include/tfm_mailbox.h11
-rw-r--r--interface/include/tfm_ns_mailbox.h26
-rw-r--r--interface/src/tfm_ns_mailbox.c64
3 files changed, 97 insertions, 4 deletions
diff --git a/interface/include/tfm_mailbox.h b/interface/include/tfm_mailbox.h
index bb23b7a097..76759aa360 100644
--- a/interface/include/tfm_mailbox.h
+++ b/interface/include/tfm_mailbox.h
@@ -15,6 +15,7 @@
#ifndef __TFM_MAILBOX_H__
#define __TFM_MAILBOX_H__
+#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "psa/client.h"
@@ -108,9 +109,13 @@ struct mailbox_reply_t {
struct ns_mailbox_slot_t {
struct mailbox_msg_t msg;
struct mailbox_reply_t reply;
- const void *owner; /* Handle of the owner task of this
- * slot
- */
+ const void *owner; /* Handle of the owner task of this
+ * slot
+ */
+ bool is_woken; /* Indicate that owner task has been
+ * or should be woken up, after the
+ * replied is received.
+ */
};
typedef uint32_t mailbox_queue_status_t;
diff --git a/interface/include/tfm_ns_mailbox.h b/interface/include/tfm_ns_mailbox.h
index 3340735260..49c4ca6043 100644
--- a/interface/include/tfm_ns_mailbox.h
+++ b/interface/include/tfm_ns_mailbox.h
@@ -88,6 +88,32 @@ static inline const void *tfm_ns_mailbox_get_task_handle(void)
#endif
/**
+ * \brief Fetch the handle to the first replied mailbox message in the NSPE
+ * mailbox queue.
+ * This function is intended to be called inside platform specific
+ * notification IRQ handler.
+ *
+ * \note The replied status of the fetched mailbox message will be cleaned after
+ * the message is fetched. When this function is called again, it fetches
+ * the next replied mailbox message from the NSPE mailbox queue.
+ *
+ * \return Return the handle to the first replied mailbox message in the
+ * queue.
+ * Return \ref MAILBOX_MSG_NULL_HANDLE if no mailbox message is replied.
+ */
+mailbox_msg_handle_t tfm_ns_mailbox_fetch_reply_msg_isr(void);
+
+/**
+ * \brief Return the handle of owner task of a mailbox message according to the
+ * \ref mailbox_msg_handle_t
+ *
+ * \param[in] handle The handle of mailbox message.
+ *
+ * \return Return the handle value of the owner task.
+ */
+const void *tfm_ns_mailbox_get_msg_owner(mailbox_msg_handle_t handle);
+
+/**
* \brief Platform specific NSPE mailbox initialization.
* Invoked by \ref tfm_ns_mailbox_init().
*
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;