Core: Update IPC implementation framework
Initial IPC patches showcases API usage with a rough design. To follow
PSA FF specification, an updated framework needs to take place instead
of previous design.
The modification details are:
- Remove legacy version files which unused anymore: psa_api.c,
tfm_queue.c, tfm_queue.h, tfm_thread.c and tfm_thread.h.
- Add psa client and service implement on secure side in thread mode.
- Add syscalls for psa client and service, empty now and to be
implemented.
- Those files in 'core' folder which needed by ipc will be added in
'ipc' folder. So there is no ipc file to be built in 'library' mode.
Change-Id: I5ab5ea2774dfb70b24f4bfd0499129ae48b2b3de
Signed-off-by: Edison Ai <edison.ai@arm.com>
Co-authored-by: Ken Liu <ken.liu@arm.com>
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 3154027..1f99ad1 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2018, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -28,11 +28,12 @@
endif()
include(${SECURE_FW_DIR}/spm/CMakeLists.inc)
-include(${SECURE_FW_DIR}/core/CMakeLists.inc)
include(${SECURE_FW_DIR}/ns_callable/CMakeLists.inc)
-# Involve IPC sources only PSA APIs are there
+#Involve all IPC related sources in ipc's CMakeLists.inc, and switch core between IPC and Library.
if(TFM_PSA_API)
include(${SECURE_FW_DIR}/core/ipc/CMakeLists.inc)
+else()
+ include(${SECURE_FW_DIR}/core/CMakeLists.inc)
endif()
set(BUILD_CMSIS_CORE On)
diff --git a/secure_fw/core/CMakeLists.inc b/secure_fw/core/CMakeLists.inc
index 31216d1..0b290d5 100644
--- a/secure_fw/core/CMakeLists.inc
+++ b/secure_fw/core/CMakeLists.inc
@@ -39,12 +39,6 @@
"${SS_CORE_DIR}/tfm_boot_data.c"
)
-if (NOT DEFINED TFM_PSA_API)
- message(FATAL_ERROR "Incomplete build configuration: TFM_PSA_API is undefined. ")
-elseif (TFM_PSA_API)
- list(APPEND SS_CORE_C_SRC "${SS_CORE_DIR}/tfm_psa_api_client.c")
-endif()
-
#Append all our source files to global lists.
list(APPEND ALL_SRC_C ${SS_CORE_C_SRC})
unset(SS_CORE_C_SRC)
diff --git a/secure_fw/core/ipc/CMakeLists.inc b/secure_fw/core/ipc/CMakeLists.inc
index 4753fdb..87437ae 100644
--- a/secure_fw/core/ipc/CMakeLists.inc
+++ b/secure_fw/core/ipc/CMakeLists.inc
@@ -33,9 +33,16 @@
if (NOT DEFINED TFM_PSA_API)
message(FATAL_ERROR "Incomplete build configuration: TFM_PSA_API is undefined. ")
elseif (TFM_PSA_API)
- set (SS_IPC_C_SRC "${SS_IPC_DIR}/tfm_thread.c"
- "${SS_IPC_DIR}/tfm_queue.c"
- "${SS_IPC_DIR}/psa_api.c"
+ set (SS_IPC_C_SRC "${SS_IPC_DIR}/tfm_svcalls.c"
+ "${SS_IPC_DIR}/psa_service.c"
+ "${SS_IPC_DIR}/psa_client.c"
+ "${SS_IPC_DIR}/../tfm_core.c"
+ "${SS_IPC_DIR}/../tfm_secure_api.c"
+ "${SS_IPC_DIR}/../tfm_spm_services.c"
+ "${SS_IPC_DIR}/../tfm_handler.c"
+ "${SS_IPC_DIR}/../tfm_psa_api_client.c"
+ "${SS_IPC_DIR}/../tfm_nspm.c"
+ "${SS_IPC_DIR}/../tfm_boot_data.c"
)
endif()
@@ -49,6 +56,7 @@
embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/spm ABSOLUTE)
embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core ABSOLUTE)
embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core/ipc ABSOLUTE)
+embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core/ipc/include ABSOLUTE)
if(NOT DEFINED PLATFORM_CMAKE_FILE)
message (FATAL_ERROR "Platform specific CMake is not defined. Please set PLATFORM_CMAKE_FILE.")
diff --git a/secure_fw/core/ipc/include/tfm_svcalls.h b/secure_fw/core/ipc/include/tfm_svcalls.h
new file mode 100644
index 0000000..c64ce74
--- /dev/null
+++ b/secure_fw/core/ipc/include/tfm_svcalls.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_SVCALLS_H__
+#define __TFM_SVCALLS_H__
+
+/* Svcall for PSA Client APIs */
+
+/**
+ * \brief SVC handler for \ref psa_framework_version.
+ *
+ * \return version The version of the PSA Framework implementation
+ * that is providing the runtime services to the
+ * caller.
+ */
+uint32_t tfm_svcall_psa_framework_version(void);
+
+/**
+ * \brief SVC handler for \ref psa_version.
+ *
+ * \param[in] args Include all input arguments: sid.
+ * \param[in] ns_caller If 'non-zero', call from non-secure client.
+ * Or from secure client.
+ *
+ * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
+ * caller is not permitted to access the service.
+ * \retval > 0 The minor version of the implemented RoT
+ * Service.
+ */
+uint32_t tfm_svcall_psa_version(uint32_t *args, int32_t ns_caller);
+
+/**
+ * \brief SVC handler for \ref psa_connect.
+ *
+ * \param[in] args Include all input arguments:
+ * sid, minor_version.
+ * \param[in] ns_caller If 'non-zero', call from non-secure client.
+ * Or from secure client.
+ *
+ * \retval > 0 A handle for the connection.
+ * \retval PSA_CONNECTION_REFUSED The SPM or RoT Service has refused the
+ * connection.
+ * \retval PSA_CONNECTION_BUSY The SPM or RoT Service cannot make the
+ * connection at the moment.
+ * \retval "Does not return" The RoT Service ID and version are not
+ * supported, or the caller is not permitted to
+ * access the service.
+ */
+psa_handle_t tfm_svcall_psa_connect(uint32_t *args, int32_t ns_caller);
+
+/**
+ * \brief SVC handler for \ref psa_call.
+ *
+ * \param[in] args Include all input arguments:
+ * handle, in_vec, in_len, out_vec, out_len.
+ * \param[in] ns_caller If 'non-zero', call from non-secure client.
+ * Or from secure client.
+ *
+ * \retval >=0 RoT Service-specific status value.
+ * \retval <0 RoT Service-specific error code.
+ * \retval PSA_DROP_CONNECTION The connection has been dropped by the RoT
+ * Service. This indicates that either this or
+ * a previous message was invalid.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg An invalid handle was passed.
+ * \arg The connection is already handling a request.
+ * \arg An invalid memory reference was provided.
+ * \arg in_len + out_len > PSA_MAX_IOVEC.
+ * \arg The message is unrecognized by the RoT
+ * Service or incorrectly formatted.
+ */
+psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller);
+
+/**
+ * \brief SVC handler for \ref psa_close.
+ *
+ * \param[in] args Include all input arguments: handle.
+ * \param[in] ns_caller If 'non-zero', call from non-secure client.
+ * Or from secure client.
+ *
+ * \retval void Success.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg An invalid handle was provided that is not
+ * the null handle.
+ * \arg The connection is handling a request.
+ */
+void tfm_svcall_psa_close(uint32_t *args, int32_t ns_caller);
+
+/**
+ * \brief SVC handler for IPC functions
+ *
+ * \param[in] svc_num SVC number
+ * \param[in] ctx Argument context
+ *
+ * \returns Return values from those who has,
+ * or PSA_SUCCESS.
+ */
+int32_t SVC_Handler_IPC(tfm_svc_number_t svc_num, uint32_t *ctx);
+
+#endif
diff --git a/secure_fw/core/ipc/psa_api.c b/secure_fw/core/ipc/psa_api.c
deleted file mode 100644
index 5c5f593..0000000
--- a/secure_fw/core/ipc/psa_api.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2018-2019, 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. */
-psa_signal_t psa_wait(psa_signal_t signal_mask, 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;
-}
-
-psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
-{
- if (msg) {
- tfm_queue_get_msg_body(msg);
- }
- return PSA_SUCCESS;
-}
-
-void psa_reply(psa_handle_t msg_handle, psa_status_t status)
-{
- 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/ipc/psa_client.c b/secure_fw/core/ipc/psa_client.c
new file mode 100644
index 0000000..f8fe605
--- /dev/null
+++ b/secure_fw/core/ipc/psa_client.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include "tfm_svc.h"
+#include "psa_client.h"
+
+__attribute__((naked))
+uint32_t psa_framework_version(void)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
+}
+
+__attribute__((naked))
+uint32_t psa_version(uint32_t sid)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_VERSION));
+}
+
+__attribute__((naked))
+psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_CONNECT));
+}
+
+__attribute__((naked))
+psa_status_t psa_call(psa_handle_t handle,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_CALL));
+}
+
+__attribute__((naked))
+void psa_close(psa_handle_t handle)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_CLOSE));
+}
diff --git a/secure_fw/core/ipc/psa_service.c b/secure_fw/core/ipc/psa_service.c
new file mode 100644
index 0000000..4871971
--- /dev/null
+++ b/secure_fw/core/ipc/psa_service.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include "tfm_svc.h"
+#include "psa_client.h"
+#include "psa_service.h"
+
+__attribute__((naked))
+psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
+
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_WAIT));
+}
+
+__attribute__((naked))
+psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_GET));
+}
+
+__attribute__((naked))
+void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_SET_RHANDLE));
+}
+
+__attribute__((naked))
+size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
+ void *buffer, size_t num_bytes)
+
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_READ));
+}
+
+__attribute__((naked))
+size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_SKIP));
+}
+
+__attribute__((naked))
+void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
+ const void *buffer, size_t num_bytes)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_WRITE));
+}
+
+__attribute__((naked))
+void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_REPLY));
+}
+
+__attribute__((naked))
+void psa_notify(int32_t partition_id)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_NOTIFY));
+}
+
+__attribute__((naked))
+void psa_clear(void)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_CLEAR));
+}
+
+__attribute__((naked))
+void psa_eoi(psa_signal_t irq_signal)
+{
+ __ASM("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PSA_EOI));
+}
diff --git a/secure_fw/core/ipc/tfm_queue.c b/secure_fw/core/ipc/tfm_queue.c
deleted file mode 100644
index 7143801..0000000
--- a/secure_fw/core/ipc/tfm_queue.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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_status_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/ipc/tfm_queue.h b/secure_fw/core/ipc/tfm_queue.h
deleted file mode 100644
index afa530d..0000000
--- a/secure_fw/core/ipc/tfm_queue.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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_status_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
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
new file mode 100644
index 0000000..9f46cc0
--- /dev/null
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "psa_client.h"
+#include "psa_service.h"
+#include "tfm_svc.h"
+#include "tfm_svcalls.h"
+
+/************************* SVC handler for PSA Client APIs *******************/
+
+uint32_t tfm_svcall_psa_framework_version(void)
+{
+ return PSA_FRAMEWORK_VERSION;
+}
+
+uint32_t tfm_svcall_psa_version(uint32_t *args, int32_t ns_caller)
+{
+ return PSA_VERSION_NONE;
+}
+
+psa_handle_t tfm_svcall_psa_connect(uint32_t *args, int32_t ns_caller)
+{
+ return PSA_NULL_HANDLE;
+}
+
+psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller)
+{
+ return PSA_SUCCESS;
+}
+
+void tfm_svcall_psa_close(uint32_t *args, int32_t ns_caller)
+{
+}
+
+/*********************** SVC handler for PSA Service APIs ********************/
+
+/**
+ * \brief SVC handler for \ref psa_wait.
+ *
+ * \param[in] args Include all input arguments:
+ * signal_mask, timeout.
+ *
+ * \retval >0 At least one signal is asserted.
+ * \retval 0 No signals are asserted. This is only seen when
+ * a polling timeout is used.
+ */
+static psa_signal_t tfm_svcall_psa_wait(uint32_t *args)
+{
+ return 0;
+}
+
+/**
+ * \brief SVC handler for \ref psa_get.
+ *
+ * \param[in] args Include all input arguments: signal, msg.
+ *
+ * \retval PSA_SUCCESS Success, *msg will contain the delivered
+ * message.
+ * \retval PSA_ERR_NOMSG Message could not be delivered.
+ * \retval "Does not return" The call is invalid because one or more of the
+ * following are true:
+ * \arg signal has more than a single bit set.
+ * \arg signal does not correspond to a RoT Service.
+ * \arg The RoT Service signal is not currently
+ * asserted.
+ * \arg The msg pointer provided is not a valid memory
+ * reference.
+ */
+static psa_status_t tfm_svcall_psa_get(uint32_t *args)
+{
+ return PSA_SUCCESS;
+}
+
+/**
+ * \brief SVC handler for \ref psa_set_rhandle.
+ *
+ * \param[in] args Include all input arguments:
+ * msg_handle, rhandle.
+ *
+ * \retval void Success, rhandle will be provided with all
+ * subsequent messages delivered on this
+ * connection.
+ * \retval "Does not return" msg_handle is invalid.
+ */
+static void tfm_svcall_psa_set_rhandle(uint32_t *args)
+{
+}
+
+/**
+ * \brief SVC handler for \ref psa_read.
+ *
+ * \param[in] args Include all input arguments:
+ * msg_handle, invec_idx, buffer, num_bytes.
+ *
+ * \retval >0 Number of bytes copied.
+ * \retval 0 There was no remaining data in this input
+ * vector.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg msg_handle is invalid.
+ * \arg msg_handle does not refer to a
+ * \ref PSA_IPC_CALL message.
+ * \arg invec_idx is equal to or greater than
+ * \ref PSA_MAX_IOVEC.
+ * \arg the memory reference for buffer is invalid or
+ * not writable.
+ */
+static size_t tfm_svcall_psa_read(uint32_t *args)
+{
+ return 0;
+}
+
+/**
+ * \brief SVC handler for \ref psa_skip.
+ *
+ * \param[in] args Include all input arguments:
+ * msg_handle, invec_idx, num_bytes.
+ *
+ * \retval >0 Number of bytes skipped.
+ * \retval 0 There was no remaining data in this input
+ * vector.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg msg_handle is invalid.
+ * \arg msg_handle does not refer to a
+ * \ref PSA_IPC_CALL message.
+ * \arg invec_idx is equal to or greater than
+ * \ref PSA_MAX_IOVEC.
+ */
+static size_t tfm_svcall_psa_skip(uint32_t *args)
+{
+ return 0;
+}
+
+/**
+ * \brief SVC handler for \ref psa_write.
+ *
+ * \param[in] args Include all input arguments:
+ * msg_handle, outvec_idx, buffer, num_bytes.
+ *
+ * \retval void Success
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg msg_handle is invalid.
+ * \arg msg_handle does not refer to a
+ * \ref PSA_IPC_CALL message.
+ * \arg outvec_idx is equal to or greater than
+ * \ref PSA_MAX_IOVEC.
+ * \arg The memory reference for buffer is invalid.
+ * \arg The call attempts to write data past the end
+ * of the client output vector.
+ */
+static void tfm_svcall_psa_write(uint32_t *args)
+{
+}
+
+/**
+ * \brief SVC handler for \ref psa_reply.
+ *
+ * \param[in] args Include all input arguments:
+ * msg_handle, status.
+ *
+ * \retval void Success.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg msg_handle is invalid.
+ * \arg An invalid status code is specified for the
+ * type of message.
+ */
+static void tfm_svcall_psa_reply(uint32_t *args)
+{
+}
+
+/**
+ * \brief SVC handler for \ref psa_notify.
+ *
+ * \param[in] args Include all input arguments: partition_id.
+ *
+ * \retval void Success.
+ * \retval "Does not return" partition_id does not correspond to a Secure
+ * Partition.
+ */
+static void tfm_svcall_psa_notify(uint32_t *args)
+{
+}
+
+/**
+ * \brief SVC handler for \ref psa_clear.
+ *
+ * \retval void Success.
+ * \retval "Does not return" The Secure Partition's doorbell signal is not
+ * currently asserted.
+ */
+static void tfm_svcall_psa_clear(uint32_t *args)
+{
+}
+
+/**
+ * \brief SVC handler for \ref psa_eoi.
+ *
+ * \param[in] args Include all input arguments: irq_signal.
+ *
+ * \retval void Success.
+ * \retval "Does not return" The call is invalid, one or more of the
+ * following are true:
+ * \arg irq_signal is not an interrupt signal.
+ * \arg irq_signal indicates more than one signal.
+ * \arg irq_signal is not currently asserted.
+ */
+static void tfm_svcall_psa_eoi(uint32_t *args)
+{
+}
+
+int32_t SVC_Handler_IPC(tfm_svc_number_t svc_num, uint32_t *ctx)
+{
+ switch (svc_num) {
+ case TFM_SVC_PSA_FRAMEWORK_VERSION:
+ return tfm_svcall_psa_framework_version();
+ case TFM_SVC_PSA_VERSION:
+ return tfm_svcall_psa_version(ctx, 0);
+ case TFM_SVC_PSA_CONNECT:
+ return tfm_svcall_psa_connect(ctx, 0);
+ case TFM_SVC_PSA_CALL:
+ return tfm_svcall_psa_call(ctx, 0);
+ case TFM_SVC_PSA_CLOSE:
+ tfm_svcall_psa_close(ctx, 0);
+ break;
+ case TFM_SVC_PSA_WAIT:
+ return tfm_svcall_psa_wait(ctx);
+ case TFM_SVC_PSA_GET:
+ return tfm_svcall_psa_get(ctx);
+ case TFM_SVC_PSA_SET_RHANDLE:
+ tfm_svcall_psa_set_rhandle(ctx);
+ break;
+ case TFM_SVC_PSA_READ:
+ return tfm_svcall_psa_read(ctx);
+ case TFM_SVC_PSA_SKIP:
+ return tfm_svcall_psa_skip(ctx);
+ case TFM_SVC_PSA_WRITE:
+ tfm_svcall_psa_write(ctx);
+ break;
+ case TFM_SVC_PSA_REPLY:
+ tfm_svcall_psa_reply(ctx);
+ break;
+ case TFM_SVC_PSA_NOTIFY:
+ tfm_svcall_psa_notify(ctx);
+ break;
+ case TFM_SVC_PSA_CLEAR:
+ tfm_svcall_psa_clear(ctx);
+ break;
+ case TFM_SVC_PSA_EOI:
+ tfm_svcall_psa_eoi(ctx);
+ break;
+ default:
+ break;
+ }
+ return PSA_SUCCESS;
+}
diff --git a/secure_fw/core/ipc/tfm_thread.c b/secure_fw/core/ipc/tfm_thread.c
deleted file mode 100644
index 58bca8e..0000000
--- a/secure_fw/core/ipc/tfm_thread.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-#include <inttypes.h>
-#include <stdio.h>
-#include "tfm_thread.h"
-
-/*
- * Thread functionality:
- * 1. PSA compliant APIs
- * 2. No priority, no interrupt and tickless
- * 3. Passive context switch in m-series thread mode
- *
- * Steps:
- * 1. Provide a `two threads` context switch first <we are here>;
- * 2. Support multiple thread scheduling and waiting objects;
- * 3. Full thread management;
- */
-
-#if defined(__ARM_ARCH_8M_MAIN__)
-/* FIXME: this function needs to be moved into cpu specfic source! */
-__attribute__((naked)) static void _context_switch(void *curr, void *next)
-{
- /*
- * r0 = curr : place to save current context
- * r1 = next : next context to be loaded and executed
- */
- __asm(
- "stmia r0, {r4-r11, lr} \n"
- "ldmia r1, {r4-r11, lr} \n"
- "mrs r2, msp \n"
- "str r2, [r0, %0] \n"
- "mrs r2, msplim \n"
- "str r2, [r0, %1] \n"
- "ldr r2, [r1, %0] \n"
- "msr msp, r2 \n"
- "ldr r2, [r1, %1] \n"
- "msr msplim, r2 \n"
- "mov r0, #0 \n" /* clear r0-r3, r12 for security */
- "mov r1, #0 \n"
- "mov r2, #0 \n"
- "mov r3, #0 \n"
- "mov r12, #0 \n"
- "bx lr \n"
- ::"I"(SP_POS), "I"(SP_LIMIT_POS)
- );
-}
-#elif defined(__ARM_ARCH_8M_BASE__)
-__attribute__((naked)) static void _context_switch(void *curr, void *next)
-{
-}
-#else
-#error "Unsupported ARM Architecture."
-#endif
-
-/* Main thread is the first executing conext */
-static struct tfm_thread_info main_thrd;
-static struct tfm_thread_info *p_current;
-
-/*
- * FIXME: this global needs to be replaced with thread list
- * when multiple thread is supported
- */
-extern struct tfm_thread_info test_thrd;
-
-static void _thread_wrapper(void)
-{
- /*
- * Use local variable to save client thread conext in case
- * lost tracking of wrapper client due to global changed.
- */
- struct tfm_thread_info *p_thrd_info = p_current;
- /*
- * Wrapper runs in client thread context and wait for thread
- * function return. A return indicates thread is finished.
- */
- p_thrd_info->status = TFM_THRD_ACTIVATED;
- p_thrd_info->retval = p_thrd_info->p_fn(p_thrd_info->param);
- p_thrd_info->status = TFM_THRD_EXITED;
-
- /* This thread context is done; switch back to main thread */
- _context_switch(&p_thrd_info->ctx, &main_thrd.ctx);
-}
-
-/*
- * Schedule current has no scheduling for current;
- * direct switch to another thread.
- */
-void tfm_thread_schedule()
-{
- struct tfm_thread_info *p_background = p_current;
-
- if (p_current == &main_thrd) {
- p_current = &test_thrd;
- } else {
- p_current = &main_thrd;
- }
-
- if (p_current->status != TFM_THRD_EXITED) {
- _context_switch(&p_background->ctx, &p_current->ctx);
- }
-}
-
-int32_t tfm_thread_init()
-{
- /*
- * Mark current main thread activated; ignore other info items
- * since they do not make sense here
- */
- main_thrd.status = TFM_THRD_ACTIVATED;
- p_current = &main_thrd;
-
- /*
- * FIXME: change client thread context with thread management
- * logics later after multiple thread is supported.
- */
- test_thrd.ctx.sp = (uint32_t)test_thrd.sp;
- test_thrd.ctx.sp_limit = (uint32_t)test_thrd.sp_limit;
- test_thrd.ctx.lr = (uint32_t)_thread_wrapper;
-
- return 0;
-}
diff --git a/secure_fw/core/ipc/tfm_thread.h b/secure_fw/core/ipc/tfm_thread.h
deleted file mode 100644
index 99534c4..0000000
--- a/secure_fw/core/ipc/tfm_thread.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-#ifndef __TFM_THREAD_H__
-#define __TFM_THREAD_H__
-
-/* FIXME: CPU specific settings, needs to be moved into CPU headers ! */
-struct _ctx {
- uint32_t r4;
- uint32_t r5;
- uint32_t r6;
- uint32_t r7;
- uint32_t r8;
- uint32_t r9;
- uint32_t r10;
- uint32_t r11;
- uint32_t lr;
- uint32_t sp;
- uint32_t sp_limit;
-};
-
-#define SP_POS 0x24
-#define SP_LIMIT_POS 0x28
-
-/* thread types */
-#define TFM_THRD_CREATED 0
-#define TFM_THRD_ACTIVATED 1
-#define TFM_THRD_EXITED 2
-
-typedef void *(*thrd_func_t)(void *);
-
-struct tfm_thread_info {
- uint32_t status; /* THRD_ACTIVATED or THRD_EXITED */
- thrd_func_t p_fn; /* entry function */
- uint8_t *sp; /* stack pointer */
- uint8_t *sp_limit; /* stack limit */
- void *param; /* entry param */
- void *retval; /* return value */
- struct _ctx ctx;
-};
-
-/* init thread module */
-int32_t tfm_thread_init(void);
-void tfm_thread_schedule(void);
-
-/* No dynamic allocation is there; all thread context are static allocated */
-#define REGISTER_TFM_THREAD(thrd_func, param, stack_size) \
- static uint8_t stack_test[stack_size] __attribute__((aligned(4))); \
- struct tfm_thread_info test_thrd = {TFM_THRD_CREATED, \
- thrd_func, \
- stack_test + stack_size, \
- stack_test, \
- (param), \
- NULL}
-#endif
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index d9f2199..81eeccd 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -15,12 +15,6 @@
#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
@@ -176,11 +170,6 @@
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_handler.c b/secure_fw/core/tfm_handler.c
index 2b7ce44..58e0123 100644
--- a/secure_fw/core/tfm_handler.c
+++ b/secure_fw/core/tfm_handler.c
@@ -16,6 +16,10 @@
#include "region_defs.h"
#include "tfm_api.h"
#include "tfm_internal.h"
+#ifdef TFM_PSA_API
+#include <stdbool.h>
+#include "tfm_svcalls.h"
+#endif
/* This SVC handler is called when a secure partition requests access to a
* buffer area
@@ -185,6 +189,25 @@
case TFM_SVC_GET_BOOT_DATA:
tfm_core_get_boot_data_handler(svc_args);
break;
+#ifdef TFM_PSA_API
+ case TFM_SVC_PSA_FRAMEWORK_VERSION:
+ case TFM_SVC_PSA_VERSION:
+ case TFM_SVC_PSA_CONNECT:
+ case TFM_SVC_PSA_CALL:
+ case TFM_SVC_PSA_CLOSE:
+ case TFM_SVC_PSA_WAIT:
+ case TFM_SVC_PSA_GET:
+ case TFM_SVC_PSA_SET_RHANDLE:
+ case TFM_SVC_PSA_READ:
+ case TFM_SVC_PSA_SKIP:
+ case TFM_SVC_PSA_WRITE:
+ case TFM_SVC_PSA_REPLY:
+ case TFM_SVC_PSA_NOTIFY:
+ case TFM_SVC_PSA_CLEAR:
+ case TFM_SVC_PSA_EOI:
+ svc_args[0] = SVC_Handler_IPC(svc_number, svc_args);
+ break;
+#endif
default:
LOG_MSG("Unknown SVC number requested!");
break;
diff --git a/secure_fw/core/tfm_psa_api_client.c b/secure_fw/core/tfm_psa_api_client.c
index fb93829..af6089e 100644
--- a/secure_fw/core/tfm_psa_api_client.c
+++ b/secure_fw/core/tfm_psa_api_client.c
@@ -8,11 +8,9 @@
#include <stdio.h>
#include "psa_client.h"
#include "psa_service.h"
-#include "tfm_thread.h"
#include "secure_utilities.h"
#include "tfm_secure_api.h"
#include "tfm_api.h"
-#include "tfm_queue.h"
/* FixMe: check if this is really needed */
extern int32_t tfm_secure_lock;
@@ -101,18 +99,7 @@
* In case of library model, this function always returns a valid handle.
* In thread model, it needs to perform the procedures outlined in PSA IPC
*/
- uint32_t version = minor_version;
- uint32_t ret;
- psa_invec in_vecs = {&version, sizeof(version)};
-
- /* FixMe: just use '1' as sid for example */
- ret = tfm_queue_put_msg(1, PSA_IPC_CONNECT, &in_vecs, 1, NULL, 0);
- if (ret != TFM_QUEUE_SUCCESS)
- return TFM_ERROR_GENERIC;
- tfm_thread_schedule();
-
- /* FixMe: just return a fix handle*/
- return 1;
+ return PSA_SUCCESS;
}
__tfm_secure_gateway_attributes__
@@ -130,14 +117,7 @@
/* In case of library model, call the function referenced by the handle
* In thread model, it needs to perform the procedures outlined in PSA IPC
*/
- uint32_t ret;
- ret = tfm_queue_put_msg(1, PSA_IPC_CALL, (psa_invec *)in_vecs->base,
- in_vecs->len, (psa_outvec *)out_vecs->base,
- out_vecs->len);
- if (ret != TFM_QUEUE_SUCCESS)
- return TFM_ERROR_GENERIC;
- tfm_thread_schedule();
- return TFM_SUCCESS;
+ return PSA_SUCCESS;
}
__tfm_secure_gateway_attributes__
@@ -153,12 +133,7 @@
{
/* perform sanity check */
/* Close connection referenced by handle */
- uint32_t ret;
- ret = tfm_queue_put_msg(1, PSA_IPC_DISCONNECT, NULL, 0, NULL, 0);
- if (ret != TFM_QUEUE_SUCCESS)
- return TFM_ERROR_GENERIC;
- tfm_thread_schedule();
- return TFM_SUCCESS;
+ return PSA_SUCCESS;
}
__tfm_secure_gateway_attributes__
diff --git a/secure_fw/core/tfm_svc.h b/secure_fw/core/tfm_svc.h
index 4fa241a..286a210 100644
--- a/secure_fw/core/tfm_svc.h
+++ b/secure_fw/core/tfm_svc.h
@@ -22,6 +22,23 @@
TFM_SVC_GET_BOOT_DATA,
#ifdef TFM_PSA_API
TFM_SVC_IPC_REQUEST,
+ /* PSA Client SVC */
+ TFM_SVC_PSA_FRAMEWORK_VERSION,
+ TFM_SVC_PSA_VERSION,
+ TFM_SVC_PSA_CONNECT,
+ TFM_SVC_PSA_CALL,
+ TFM_SVC_PSA_CLOSE,
+ /* PSA Service SVC */
+ TFM_SVC_PSA_WAIT,
+ TFM_SVC_PSA_GET,
+ TFM_SVC_PSA_SET_RHANDLE,
+ TFM_SVC_PSA_READ,
+ TFM_SVC_PSA_SKIP,
+ TFM_SVC_PSA_WRITE,
+ TFM_SVC_PSA_REPLY,
+ TFM_SVC_PSA_NOTIFY,
+ TFM_SVC_PSA_CLEAR,
+ TFM_SVC_PSA_EOI,
#endif
} tfm_svc_number_t;
diff --git a/test/test_services/tfm_ipc_test/ipc_test_service.c b/test/test_services/tfm_ipc_test/ipc_test_service.c
index 5d0af44..85ca0fb 100644
--- a/test/test_services/tfm_ipc_test/ipc_test_service.c
+++ b/test/test_services/tfm_ipc_test/ipc_test_service.c
@@ -9,7 +9,6 @@
#include <stdio.h>
#include "psa_client.h"
#include "psa_service.h"
-#include "secure_fw/core/ipc/tfm_thread.h"
#include "secure_fw/core/secure_utilities.h"
#include "secure_fw/core/tfm_secure_api.h"
#include "tfm_api.h"
@@ -58,7 +57,7 @@
}
/* Test thread */
-static void *ipc_test_partition_main(void *param)
+void *ipc_test_partition_main(void *param)
{
uint32_t signals = 0;
psa_msg_t msg;
@@ -98,5 +97,3 @@
return NULL;
}
-
-REGISTER_TFM_THREAD(ipc_test_partition_main, (void *)0x1, 1024);