aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hu <david.hu@arm.com>2019-09-23 15:58:34 +0800
committerDavid Hu <david.hu@arm.com>2019-10-17 14:08:31 +0800
commitfb38d5683d8693fb3c3f1fbc387d08364418d028 (patch)
tree96dfe0b742709249c5b07d788ef531364e94285f
parent5923bc24ac61dc10bf9e2e3b37896448736e1f94 (diff)
downloadtrusted-firmware-m-fb38d5683d8693fb3c3f1fbc387d08364418d028.tar.gz
Twincpu: Add RPC into TF-M PSA client call handling and reply routines
Add TF-M Remote Procedure Call (RPC) to deal with PSA client call from NSPE in multi-core topology, in TF-M PSA client call handling and reply routines. - Insert tfm_rpc_client_call_handler() into PendSV handler to process PSA client call request from non-secure core. - Add tfm_rpc_client_call_reply() into tfm_svcall_psa_reply() to return PSA client call return result to non-secure core. Change-Id: I8ece001b5ac241f05236c02d93f42b7eca14688b Signed-off-by: David Hu <david.hu@arm.com>
-rw-r--r--secure_fw/core/ipc/include/tfm_rpc.h30
-rw-r--r--secure_fw/core/ipc/tfm_svcalls.c12
-rw-r--r--secure_fw/spm/spm_api_ipc.c15
3 files changed, 54 insertions, 3 deletions
diff --git a/secure_fw/core/ipc/include/tfm_rpc.h b/secure_fw/core/ipc/include/tfm_rpc.h
index 5ed5261f3f..6080604f5d 100644
--- a/secure_fw/core/ipc/include/tfm_rpc.h
+++ b/secure_fw/core/ipc/include/tfm_rpc.h
@@ -170,9 +170,39 @@ void tfm_rpc_client_call_handler(void);
*/
void tfm_rpc_client_call_reply(const void *owner, int32_t ret);
+/*
+ * Check if the message was allocated for a non-secure request via RPC
+ *
+ * \param[in] msg The message body context pointer
+ * \ref msg_body_t structures
+ *
+ * \retval true The message was allocated for a NS request via RPC.
+ * \retval false Otherwise.
+ */
+__STATIC_INLINE bool is_tfm_rpc_msg(const struct tfm_msg_body_t *msg)
+{
+ /*
+ * FIXME
+ * The ID should be smaller than 0 if the message is allocated by a
+ * non-secure caller.
+ * However, current TF-M implementation use 0 as the default non-secure
+ * caller ID. Therefore, treat the caller as non-secure when client_id == 0.
+ *
+ * This condition check should be improved after TF-M non-secure client ID
+ * management is implemented.
+ */
+ if (msg && (msg->msg.client_id <= 0) && !msg->ack_evnt.owner) {
+ return true;
+ }
+
+ return false;
+}
+
#else /* TFM_MULTI_CORE_TOPOLOGY */
/* RPC is only available in multi-core scenario */
+#define is_tfm_rpc_msg(x) (false)
+
#define tfm_rpc_client_call_handler() do {} while (0)
#define tfm_rpc_client_call_reply(owner, ret) do {} while (0)
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index c271acf726..b0867675f0 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -26,6 +26,7 @@
#include "spm_db.h"
#include "tfm_core_utils.h"
#include "tfm_psa_client_call.h"
+#include "tfm_rpc.h"
void tfm_irq_handler(uint32_t partition_id, psa_signal_t signal,
int32_t irq_line);
@@ -589,7 +590,10 @@ static void update_caller_outvec_len(struct tfm_msg_body_t *msg)
* FixeMe: abstract these part into dedicated functions to avoid
* accessing thread context in psa layer
*/
- TFM_ASSERT(msg->ack_evnt.owner->status == THRD_STAT_BLOCK);
+ /* If it is a NS request via RPC, the owner of this message is not set */
+ if (!is_tfm_rpc_msg(msg)) {
+ TFM_ASSERT(msg->ack_evnt.owner->status == THRD_STAT_BLOCK);
+ }
while (msg->msg.out_size[i] != 0) {
TFM_ASSERT(msg->caller_outvec[i].base == msg->outvec[i].base);
@@ -696,7 +700,11 @@ static void tfm_svcall_psa_reply(uint32_t *args)
}
}
- tfm_event_wake(&msg->ack_evnt, ret);
+ if (is_tfm_rpc_msg(msg)) {
+ tfm_rpc_client_call_reply(NULL, ret);
+ } else {
+ tfm_event_wake(&msg->ack_evnt, ret);
+ }
}
/**
diff --git a/secure_fw/spm/spm_api_ipc.c b/secure_fw/spm/spm_api_ipc.c
index 98f7a0efb7..4677421759 100644
--- a/secure_fw/spm/spm_api_ipc.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -28,6 +28,7 @@
#include "tfm_nspm.h"
#include "tfm_memory_utils.h"
#include "tfm_core_utils.h"
+#include "tfm_rpc.h"
#include "secure_fw/services/tfm_service_list.inc"
@@ -375,7 +376,13 @@ int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
tfm_event_wake(&p_runtime_data->signal_evnt, (p_runtime_data->signals &
p_runtime_data->signal_mask));
- tfm_event_wait(&msg->ack_evnt);
+ /*
+ * If it is a NS request via RPC, it is unnecessary to block current
+ * thread.
+ */
+ if (!is_tfm_rpc_msg(msg)) {
+ tfm_event_wait(&msg->ack_evnt);
+ }
return IPC_SUCCESS;
}
@@ -581,4 +588,10 @@ void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb)
tfm_thrd_context_switch(ctxb, pth_curr, pth_next);
}
+
+ /*
+ * Handle pending mailbox message from NS in multi-core topology.
+ * Empty operation on single Armv8-M platform.
+ */
+ tfm_rpc_client_call_handler();
}