SPM: Move psa client call apis into 'spm/common'
PSA client APIs implementation is pure logic which belongs
to the 'spm/common'.
Change-Id: Ia327971e918d0cc997cdcbcd16f9ca8ce10206a6
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/CMakeLists.inc b/secure_fw/spm/cmsis_psa/CMakeLists.inc
index 637bf5d..ea24393 100644
--- a/secure_fw/spm/cmsis_psa/CMakeLists.inc
+++ b/secure_fw/spm/cmsis_psa/CMakeLists.inc
@@ -34,12 +34,12 @@
set(SFW_SPM_COMMON_DIR "${SFW_SPM_DIR}/common")
set (SFW_IPC_SPM_SRC
+ "${SFW_SPM_COMMON_DIR}/spm_psa_client_call.c"
"${SFW_SPM_COMMON_DIR}/tfm_boot_data.c"
"${SFW_SPM_COMMON_DIR}/tfm_core_utils.c"
"${SFW_SPM_COMMON_DIR}/utilities.c"
"${SFW_IPC_SPM_DIR}/main.c"
"${SFW_IPC_SPM_DIR}/spm_ipc.c"
- "${SFW_IPC_SPM_DIR}/spm_psa_client_call.c"
"${SFW_IPC_SPM_DIR}/tfm_core_svcalls_ipc.c"
"${SFW_IPC_SPM_DIR}/tfm_pools.c"
"${SFW_IPC_SPM_DIR}/tfm_thread.c"
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index c823812..5abbe24 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -22,7 +22,7 @@
#include "spm_ipc.h"
#include "tfm_peripherals_def.h"
#include "tfm_core_utils.h"
-#include "spm_psa_client_call.h"
+#include "common/spm_psa_client_call.h"
#include "tfm_rpc.h"
#include "tfm_core_trustzone.h"
#include "tfm_core_mem_check.h"
diff --git a/secure_fw/spm/cmsis_psa/spm_psa_client_call.c b/secure_fw/spm/cmsis_psa/spm_psa_client_call.c
deleted file mode 100644
index 4f93746..0000000
--- a/secure_fw/spm/cmsis_psa/spm_psa_client_call.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "psa/service.h"
-#include "spm_ipc.h"
-#include "tfm_core_utils.h"
-#include "tfm_internal_defines.h"
-#include "tfm_memory_utils.h"
-#include "spm_psa_client_call.h"
-#include "utilities.h"
-#include "tfm_wait.h"
-#include "tfm_nspm.h"
-
-uint32_t tfm_spm_client_psa_framework_version(void)
-{
- return PSA_FRAMEWORK_VERSION;
-}
-
-uint32_t tfm_spm_client_psa_version(uint32_t sid, bool ns_caller)
-{
- struct tfm_spm_service_t *service;
-
- /*
- * It should return PSA_VERSION_NONE if the RoT Service is not
- * implemented.
- */
- service = tfm_spm_get_service_by_sid(sid);
- if (!service) {
- return PSA_VERSION_NONE;
- }
-
- /*
- * It should return PSA_VERSION_NONE if the caller is not authorized
- * to access the RoT Service.
- */
- if (tfm_spm_check_authorization(sid, service, ns_caller) != IPC_SUCCESS) {
- return PSA_VERSION_NONE;
- }
-
- return service->service_db->version;
-}
-
-psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version,
- bool ns_caller)
-{
- struct tfm_spm_service_t *service;
- struct tfm_msg_body_t *msg;
- struct tfm_conn_handle_t *connect_handle;
- int32_t client_id;
- psa_handle_t handle;
-
- /* It is a fatal error if the RoT Service does not exist on the platform */
- service = tfm_spm_get_service_by_sid(sid);
- if (!service) {
- tfm_core_panic();
- }
-
- if (ns_caller) {
- client_id = tfm_nspm_get_current_client_id();
- } else {
- client_id = tfm_spm_partition_get_running_partition_id();
- }
-
- /*
- * It is a fatal error if the caller is not authorized to access the RoT
- * Service.
- */
- if (tfm_spm_check_authorization(sid, service, ns_caller) != IPC_SUCCESS) {
- tfm_core_panic();
- }
-
- /*
- * Create connection handle here since it is possible to return the error
- * code to client when creation fails.
- */
- connect_handle = tfm_spm_create_conn_handle(service, client_id);
- if (!connect_handle) {
- return PSA_ERROR_CONNECTION_BUSY;
- }
-
- /*
- * It is a fatal error if the version of the RoT Service requested is not
- * supported on the platform.
- */
- if (tfm_spm_check_client_version(service, version) != IPC_SUCCESS) {
- tfm_core_panic();
- }
-
- msg = tfm_spm_get_msg_buffer_from_conn_handle(connect_handle);
- if (!msg) {
- /* Have no enough resource to create message */
- return PSA_ERROR_CONNECTION_BUSY;
- }
-
- handle = tfm_spm_to_user_handle(connect_handle);
- /* No input or output needed for connect message */
- tfm_spm_fill_msg(msg, service, handle, PSA_IPC_CONNECT,
- client_id, NULL, 0, NULL, 0, NULL);
-
- /*
- * Send message and wake up the SP who is waiting on message queue,
- * and scheduler triggered
- */
- tfm_spm_send_event(service, msg);
-
- return PSA_SUCCESS;
-}
-
-psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type,
- const psa_invec *inptr, size_t in_num,
- psa_outvec *outptr, size_t out_num,
- bool ns_caller, uint32_t privileged)
-{
- psa_invec invecs[PSA_MAX_IOVEC];
- psa_outvec outvecs[PSA_MAX_IOVEC];
- struct tfm_conn_handle_t *conn_handle;
- struct tfm_spm_service_t *service;
- struct tfm_msg_body_t *msg;
- int i, j;
- int32_t client_id;
-
- /* It is a fatal error if in_len + out_len > PSA_MAX_IOVEC. */
- if ((in_num > PSA_MAX_IOVEC) ||
- (out_num > PSA_MAX_IOVEC) ||
- (in_num + out_num > PSA_MAX_IOVEC)) {
- tfm_core_panic();
- }
-
- if (ns_caller) {
- client_id = tfm_nspm_get_current_client_id();
- } else {
- client_id = tfm_spm_partition_get_running_partition_id();
- }
-
- conn_handle = tfm_spm_to_handle_instance(handle);
- /* It is a fatal error if an invalid handle was passed. */
- if (tfm_spm_validate_conn_handle(conn_handle, client_id) != IPC_SUCCESS) {
- tfm_core_panic();
- }
- service = conn_handle->service;
- if (!service) {
- /* FixMe: Need to implement one mechanism to resolve this failure. */
- tfm_core_panic();
- }
-
- /* It is a fatal error if the connection is currently handling a request. */
- if (conn_handle->status == TFM_HANDLE_STATUS_ACTIVE) {
- tfm_core_panic();
- }
-
- /*
- * Return PSA_ERROR_PROGRAMMER_ERROR immediately for the connection
- * has been terminated by the RoT Service.
- */
- if (conn_handle->status == TFM_HANDLE_STATUS_CONNECT_ERROR) {
- return PSA_ERROR_PROGRAMMER_ERROR;
- }
-
- /*
- * Read client invecs from the wrap input vector. It is a fatal error
- * if the memory reference for the wrap input vector is invalid or not
- * readable.
- */
- if (tfm_memory_check(inptr, in_num * sizeof(psa_invec), ns_caller,
- TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
- tfm_core_panic();
- }
-
- /*
- * Read client outvecs from the wrap output vector and will update the
- * actual length later. It is a fatal error if the memory reference for
- * the wrap output vector is invalid or not read-write.
- */
- if (tfm_memory_check(outptr, out_num * sizeof(psa_outvec), ns_caller,
- TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
- tfm_core_panic();
- }
-
- spm_memset(invecs, 0, sizeof(invecs));
- spm_memset(outvecs, 0, sizeof(outvecs));
-
- /* Copy the address out to avoid TOCTOU attacks. */
- spm_memcpy(invecs, inptr, in_num * sizeof(psa_invec));
- spm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
-
- /*
- * For client input vector, it is a fatal error if the provided payload
- * memory reference was invalid or not readable.
- */
- for (i = 0; i < in_num; i++) {
- if (tfm_memory_check(invecs[i].base, invecs[i].len, ns_caller,
- TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
- tfm_core_panic();
- }
- }
-
- /*
- * Clients must never overlap input parameters because of the risk of a
- * double-fetch inconsistency.
- * Overflow is checked in tfm_memory_check functions.
- */
- for (i = 0; i + 1 < in_num; i++) {
- for (j = i+1; j < in_num; j++) {
- if (!((char *) invecs[j].base + invecs[j].len <=
- (char *) invecs[i].base ||
- (char *) invecs[j].base >=
- (char *) invecs[i].base + invecs[i].len)) {
- tfm_core_panic();
- }
- }
- }
-
- /*
- * For client output vector, it is a fatal error if the provided payload
- * memory reference was invalid or not read-write.
- */
- for (i = 0; i < out_num; i++) {
- if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
- ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
- tfm_core_panic();
- }
- }
-
- /*
- * FixMe: Need to check if the message is unrecognized by the RoT
- * Service or incorrectly formatted.
- */
- msg = tfm_spm_get_msg_buffer_from_conn_handle(conn_handle);
- if (!msg) {
- /* FixMe: Need to implement one mechanism to resolve this failure. */
- tfm_core_panic();
- }
-
- tfm_spm_fill_msg(msg, service, handle, type, client_id,
- invecs, in_num, outvecs, out_num, outptr);
-
- /*
- * Send message and wake up the SP who is waiting on message queue,
- * and scheduler triggered
- */
- if (tfm_spm_send_event(service, msg) != IPC_SUCCESS) {
- /* FixMe: Need to refine failure process here. */
- tfm_core_panic();
- }
- return PSA_SUCCESS;
-}
-
-void tfm_spm_client_psa_close(psa_handle_t handle, bool ns_caller)
-{
- struct tfm_spm_service_t *service;
- struct tfm_msg_body_t *msg;
- struct tfm_conn_handle_t *conn_handle;
- int32_t client_id;
-
- /* It will have no effect if called with the NULL handle */
- if (handle == PSA_NULL_HANDLE) {
- return;
- }
-
- if (ns_caller) {
- client_id = tfm_nspm_get_current_client_id();
- } else {
- client_id = tfm_spm_partition_get_running_partition_id();
- }
-
- conn_handle = tfm_spm_to_handle_instance(handle);
- /*
- * It is a fatal error if an invalid handle was provided that is not the
- * null handle.
- */
- if (tfm_spm_validate_conn_handle(conn_handle, client_id) != IPC_SUCCESS) {
- tfm_core_panic();
- }
- service = conn_handle->service;
- if (!service) {
- /* FixMe: Need to implement one mechanism to resolve this failure. */
- tfm_core_panic();
- }
-
- msg = tfm_spm_get_msg_buffer_from_conn_handle(conn_handle);
- if (!msg) {
- /* FixMe: Need to implement one mechanism to resolve this failure. */
- tfm_core_panic();
- }
-
- /* It is a fatal error if the connection is currently handling a request. */
- if (conn_handle->status == TFM_HANDLE_STATUS_ACTIVE) {
- tfm_core_panic();
- }
-
- /* No input or output needed for close message */
- tfm_spm_fill_msg(msg, service, handle, PSA_IPC_DISCONNECT, client_id,
- NULL, 0, NULL, 0, NULL);
-
- /*
- * Send message and wake up the SP who is waiting on message queue,
- * and scheduler triggered
- */
- tfm_spm_send_event(service, msg);
-}
diff --git a/secure_fw/spm/cmsis_psa/spm_psa_client_call.h b/secure_fw/spm/cmsis_psa/spm_psa_client_call.h
deleted file mode 100644
index ae2a5d2..0000000
--- a/secure_fw/spm/cmsis_psa/spm_psa_client_call.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __TFM_PSA_CLIENT_CALL_H__
-#define __TFM_PSA_CLIENT_CALL_H__
-
-#include <stdint.h>
-#include <stdbool.h>
-#include "psa/client.h"
-
-/* Common handlers for PSA client calls */
-
-/**
- * \brief handler for \ref psa_framework_version.
- *
- * \return version The version of the PSA Framework implementation
- * that is providing the runtime services.
- */
-uint32_t tfm_spm_client_psa_framework_version(void);
-
-/**
- * \brief handler for \ref psa_version.
- *
- * \param[in] sid RoT Service identity.
- * \param[in] ns_caller If 'true', call from non-secure client.
- * Otherwise 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 version of the implemented RoT Service.
- */
-uint32_t tfm_spm_client_psa_version(uint32_t sid, bool ns_caller);
-
-/**
- * \brief handler for \ref psa_connect.
- *
- * \param[in] sid RoT Service identity.
- * \param[in] version The version of the RoT Service.
- * \param[in] ns_caller If 'true', call from non-secure client.
- * Otherwise from secure client.
- *
- * \retval PSA_SUCCESS Success.
- * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
- * connection.
- * \retval PSA_ERROR_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_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version,
- bool ns_caller);
-
-/**
- * \brief handler for \ref psa_call.
- *
- * \param[in] handle Service handle to the established connection,
- * \ref psa_handle_t
- * \param[in] type The request type.
- * Must be zero( \ref PSA_IPC_CALL) or positive.
- * \param[in] inptr Array of input psa_invec structures.
- * \ref psa_invec
- * \param[in] in_num Number of input psa_invec structures.
- * \ref psa_invec
- * \param[in] outptr Array of output psa_outvec structures.
- * \ref psa_outvec
- * \param[in] out_num Number of outut psa_outvec structures.
- * \ref psa_outvec
- * \param[in] ns_caller If 'true', call from non-secure client.
- * Otherwise from secure client.
- * \param[in] privileged Privileged mode or unprivileged mode:
- * \ref TFM_PARTITION_UNPRIVILEGED_MODE
- * \ref TFM_PARTITION_PRIVILEGED_MODE
- *
- * \retval PSA_SUCCESS Success.
- * \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_num + out_num > PSA_MAX_IOVEC.
- * \arg The message is unrecognized by the RoT
- * Service or incorrectly formatted.
- */
-psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type,
- const psa_invec *inptr, size_t in_num,
- psa_outvec *outptr, size_t out_num,
- bool ns_caller, uint32_t privileged);
-
-/**
- * \brief handler for \ref psa_close.
- *
- * \param[in] handle Service handle to the connection to be closed,
- * \ref psa_handle_t
- * \param[in] ns_caller If 'true', call from non-secure client.
- * Otherwise 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_spm_client_psa_close(psa_handle_t handle, bool ns_caller);
-
-#endif
diff --git a/secure_fw/spm/cmsis_psa/tfm_rpc.c b/secure_fw/spm/cmsis_psa/tfm_rpc.c
index 402b055..08b4bd4 100644
--- a/secure_fw/spm/cmsis_psa/tfm_rpc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_rpc.c
@@ -6,7 +6,7 @@
*/
#include "spm_ipc.h"
-#include "spm_psa_client_call.h"
+#include "common/spm_psa_client_call.h"
#include "tfm_rpc.h"
#include "utilities.h"