aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Liu <ken.liu@arm.com>2018-06-26 16:50:53 +0800
committerEdison Ai <edison.ai@arm.com>2018-12-17 19:54:48 +0800
commit94e1321d91799d010fc810995fa89cb53dbe3e74 (patch)
treedde26db01f063146cb998b27f148012930d4d205
parent92afd6b67fe12c07a9eccdea5d316c6180542868 (diff)
downloadtrusted-firmware-m-94e1321d91799d010fc810995fa89cb53dbe3e74.tar.gz
Core: first draft for PSA service APIs
Draft PSA servie APIs. A global based message queue, and necessary APIs for first IPC Service Partition. Change-Id: Ifd46eaa13eb5ba2a62584f1335e438db3b2738d9 Signed-off-by: Ken Liu <ken.liu@arm.com>
-rw-r--r--secure_fw/core/CMakeLists.inc2
-rw-r--r--secure_fw/core/psa_api.c80
-rw-r--r--secure_fw/core/tfm_core.c11
-rw-r--r--secure_fw/core/tfm_queue.c104
-rw-r--r--secure_fw/core/tfm_queue.h35
5 files changed, 232 insertions, 0 deletions
diff --git a/secure_fw/core/CMakeLists.inc b/secure_fw/core/CMakeLists.inc
index 868fbbe845..00ee316752 100644
--- a/secure_fw/core/CMakeLists.inc
+++ b/secure_fw/core/CMakeLists.inc
@@ -44,6 +44,8 @@ if (NOT DEFINED TFM_PSA_API)
elseif (TFM_PSA_API)
list(APPEND SS_CORE_C_SRC "${SS_CORE_DIR}/tfm_psa_api_client.c"
"${SS_CORE_DIR}/tfm_thread.c"
+ "${SS_CORE_DIR}/tfm_queue.c"
+ "${SS_CORE_DIR}/psa_api.c"
)
endif()
diff --git a/secure_fw/core/psa_api.c b/secure_fw/core/psa_api.c
new file mode 100644
index 0000000000..d0a19840d3
--- /dev/null
+++ b/secure_fw/core/psa_api.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include "psa_client.h"
+#include "psa_service.h"
+#include "tfm_thread.h"
+#include "tfm_queue.h"
+#include "secure_utilities.h"
+
+/* Service APIs */
+
+/* FixMe: Initial prototype. */
+uint32_t psa_wait_any(uint32_t timeout)
+{
+ uint32_t msg_signals = 0;
+
+ while (1) {
+ msg_signals = tfm_queue_get_msg_signal();
+
+ if (msg_signals == 0 && timeout == PSA_BLOCK) {
+ tfm_thread_schedule();
+ } else {
+ break;
+ }
+ }
+ return msg_signals;
+}
+
+void psa_get(psa_signal_t signal, psa_msg_t *msg)
+{
+ if (msg) {
+ tfm_queue_get_msg_body(msg);
+ }
+}
+
+void psa_end(psa_handle_t msg_handle, psa_error_t retval)
+{
+ struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle;
+
+ q_msg->msg.handle = (psa_handle_t)0;
+}
+
+size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
+ void *buffer, size_t num_bytes)
+{
+ size_t bytes;
+ struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle;
+
+ if (invec_idx >= PSA_MAX_IOVEC) {
+ return 0;
+ }
+
+ bytes = num_bytes > q_msg->invec[invec_idx].len ?
+ q_msg->invec[invec_idx].len : num_bytes;
+
+ memcpy_m(buffer, q_msg->invec[invec_idx].base, bytes);
+
+ return bytes;
+}
+
+void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
+ const void *buffer, size_t num_bytes)
+{
+ size_t bytes;
+ struct tfm_msg_queue_item *q_msg = (struct tfm_msg_queue_item *)msg_handle;
+
+ if (outvec_idx >= PSA_MAX_IOVEC) {
+ return;
+ }
+
+ bytes = num_bytes > q_msg->outvec[outvec_idx].len ?
+ q_msg->outvec[outvec_idx].len : num_bytes;
+
+ memcpy_m(q_msg->outvec[outvec_idx].base, (void *)buffer, bytes);
+}
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index 81eeccde6b..d9f2199692 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -15,6 +15,12 @@
#include "secure_utilities.h"
#include "secure_fw/spm/spm_api.h"
#include "secure_fw/include/tfm_spm_services_api.h"
+#ifdef TFM_PSA_API
+#include "psa_client.h"
+#include "psa_service.h"
+#include "tfm_thread.h"
+#include "tfm_queue.h"
+#endif
/*
* Avoids the semihosting issue
@@ -170,6 +176,11 @@ int main(void)
LOG_MSG("Jumping to non-secure code...");
#endif
+#ifdef TFM_PSA_API
+ tfm_queue_init();
+ tfm_thread_init();
+#endif
+
/* We close the TFM_SP_CORE_ID partition, because its only purpose is
* to be able to pass the state checks for the tests started from secure.
*/
diff --git a/secure_fw/core/tfm_queue.c b/secure_fw/core/tfm_queue.c
new file mode 100644
index 0000000000..4a07aed117
--- /dev/null
+++ b/secure_fw/core/tfm_queue.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include "psa_client.h"
+#include "psa_service.h"
+#include "tfm_queue.h"
+#include "secure_utilities.h"
+
+/*
+ * Message queue
+ */
+static struct tfm_msg_queue_item msg_queue[TFM_MSG_QUEUE_DEPTH];
+static struct tfm_msg_queue_item *q_used, *q_avail;
+
+#define QUEUE_EMPTY() (q_used->msg.handle == (psa_handle_t)0)
+#define QUEUE_FULL() (q_avail->msg.handle != (psa_handle_t)0)
+
+void tfm_queue_init(void)
+{
+ struct tfm_msg_queue_item *p_item = msg_queue;
+ uint32_t i;
+
+ for (i = 0; i < TFM_MSG_QUEUE_DEPTH; i++) {
+ p_item[i].msg.handle = (psa_handle_t)0;
+ p_item[i].next = &p_item[(i + 1) % TFM_MSG_QUEUE_DEPTH];
+ p_item[i].prev = &p_item[(i + TFM_MSG_QUEUE_DEPTH - 1) %
+ TFM_MSG_QUEUE_DEPTH];
+ }
+
+ q_used = p_item;
+ q_avail = p_item;
+}
+
+uint32_t tfm_queue_get_msg_signal(void)
+{
+ if (QUEUE_EMPTY()) {
+ return 0;
+ }
+
+ return q_used->signal;
+}
+
+psa_error_t tfm_queue_put_msg(psa_signal_t signal, uint32_t type,
+ psa_invec *invec, size_t in_len,
+ psa_outvec *outvec, size_t out_len)
+{
+ uint32_t i;
+
+ /* FixMe: need to be clarified */
+ if (QUEUE_FULL()) {
+ return TFM_QUEUE_ERROR_GENERIC;
+ }
+
+ if ((!invec && in_len != 0) || (!outvec && out_len != 0)) {
+ ERROR_MSG("parameters error.\r\n");
+ return TFM_QUEUE_ERROR_GENERIC;
+ }
+
+ /* copy contents */
+ q_avail->signal = signal;
+
+ q_avail->msg.type = type;
+
+ q_avail->invec = invec;
+ q_avail->outvec = outvec;
+
+ for (i = 0; i < in_len; i++) {
+ q_avail->msg.in_size[i] = invec[i].len;
+ }
+
+ for (i = 0; i < out_len; i++) {
+ q_avail->msg.out_size[i] = outvec[i].len;
+ }
+
+ q_avail->msg.handle = (psa_handle_t)q_avail;
+
+ q_avail = q_avail->next;
+
+ return TFM_QUEUE_SUCCESS;
+}
+
+/* Utils */
+void *memcpy_m(void *dst, const void *src, uint32_t size)
+{
+ uint8_t *dst_8 = (uint8_t *)dst;
+ uint8_t *src_8 = (uint8_t *)src;
+
+ while (size--) {
+ *dst_8++ = *src_8++;
+ }
+
+ return dst;
+}
+
+void tfm_queue_get_msg_body(psa_msg_t *msg)
+{
+ memcpy_m(msg, &q_used->msg, sizeof(*msg));
+ q_used = q_used->next;
+}
diff --git a/secure_fw/core/tfm_queue.h b/secure_fw/core/tfm_queue.h
new file mode 100644
index 0000000000..9711addaff
--- /dev/null
+++ b/secure_fw/core/tfm_queue.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_QUEUE_H__
+#define __TFM_QUEUE_H__
+
+#define TFM_MSG_QUEUE_DEPTH 5
+
+struct tfm_msg_queue_item {
+ psa_msg_t msg;
+ uint32_t signal;
+ /* Put in/out vectors in msg body */
+ psa_invec *invec;
+ psa_outvec *outvec;
+ /* List opearators */
+ struct tfm_msg_queue_item *prev;
+ struct tfm_msg_queue_item *next;
+};
+
+/* internal error codes */
+#define TFM_QUEUE_SUCCESS 0
+#define TFM_QUEUE_ERROR_GENERIC (INT32_MIN)
+
+void tfm_queue_init(void);
+uint32_t tfm_queue_get_msg_signal(void);
+psa_error_t tfm_queue_put_msg(psa_signal_t signal, uint32_t type,
+ psa_invec *invec, size_t in_len,
+ psa_outvec *outvec, size_t out_len);
+void tfm_queue_get_msg_body(psa_msg_t *msg);
+void *memcpy_m(void *dst, const void *src, uint32_t size);
+
+#endif