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"