Core: Move spm code of IPC model to spm_api_ipc.c

- Moves API functions from tfm_spm.c to spm_api_ipc.c.
- Moves content from tfm_spm.h to spm_api.h.
- Removes tfm_spm.c and tfm_spm.h.

Change-Id: Idb333ec2e97e02206d6431dcbf13051aa4b108d0
Signed-off-by: Mingyang Sun <mingyang.sun@arm.com>
diff --git a/secure_fw/core/arch/tfm_arch_v8m_base.c b/secure_fw/core/arch/tfm_arch_v8m_base.c
index 6aa969a..cddcc2b 100644
--- a/secure_fw/core/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/core/arch/tfm_arch_v8m_base.c
@@ -10,7 +10,7 @@
 #include "secure_utilities.h"
 #include "tfm_arch.h"
 #include "tfm_secure_api.h"
-#include "tfm_spm.h"
+#include "spm_api.h"
 #include "tfm_svc.h"
 
 #if !defined(__ARM_ARCH_8M_BASE__)
diff --git a/secure_fw/core/arch/tfm_arch_v8m_main.c b/secure_fw/core/arch/tfm_arch_v8m_main.c
index 3035d3c..a241ef3 100644
--- a/secure_fw/core/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/core/arch/tfm_arch_v8m_main.c
@@ -12,7 +12,7 @@
 #include "tfm_arch.h"
 #include "tfm_memory_utils.h"
 #include "tfm_secure_api.h"
-#include "tfm_spm.h"
+#include "spm_api.h"
 #include "tfm_svc.h"
 
 #if !defined(__ARM_ARCH_8M_MAIN__)
diff --git a/secure_fw/core/ipc/CMakeLists.inc b/secure_fw/core/ipc/CMakeLists.inc
index e369a42..c2e385a 100644
--- a/secure_fw/core/ipc/CMakeLists.inc
+++ b/secure_fw/core/ipc/CMakeLists.inc
@@ -40,7 +40,6 @@
 			"${SS_IPC_DIR}/tfm_wait.c"
 			"${SS_IPC_DIR}/tfm_message_queue.c"
 			"${SS_IPC_DIR}/tfm_pools.c"
-			"${SS_IPC_DIR}/tfm_spm.c"
 			"${SS_IPC_DIR}/../tfm_core.c"
 			"${SS_IPC_DIR}/../tfm_secure_api.c"
 			"${SS_IPC_DIR}/../tfm_spm_services.c"
diff --git a/secure_fw/core/ipc/include/tfm_spm.h b/secure_fw/core/ipc/include/tfm_spm.h
deleted file mode 100644
index 18d532c..0000000
--- a/secure_fw/core/ipc/include/tfm_spm.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-#ifndef __TFM_SPM_H__
-#define __TFM_SPM_H__
-
-#include <stdbool.h>
-#include "tfm_list.h"
-#include "tfm_message_queue.h"
-#include "tfm_secure_api.h"
-
-#define TFM_SPM_MAX_ROT_SERV_NUM        48
-#define TFM_VERSION_POLICY_RELAXED      0
-#define TFM_VERSION_POLICY_STRICT       1
-
-#define TFM_CONN_HANDLE_MAX_NUM         32
-
-/* RoT connection handle list */
-struct tfm_conn_handle_t {
-    psa_handle_t handle;            /* Handle value                         */
-    void *rhandle;                  /* Reverse handle value                 */
-    struct tfm_list_node_t list;    /* list node                            */
-};
-
-/* Service database defined by manifest */
-struct tfm_spm_service_db_t {
-    char *name;                     /* Service name                          */
-    uint32_t partition_id;          /* Partition ID which service belong to  */
-    psa_signal_t signal;            /* Service signal                        */
-    uint32_t sid;                   /* Service identifier                    */
-    bool non_secure_client;         /* If can be called by non secure client */
-    uint32_t minor_version;         /* Minor version                         */
-    uint32_t minor_policy;          /* Minor version policy                  */
-};
-
-/* RoT Service data */
-struct tfm_spm_service_t {
-    struct tfm_spm_service_db_t *service_db; /* Service database pointer     */
-    struct spm_partition_desc_t *partition;  /*
-                                              * Point to secure partition
-                                              * data
-                                              */
-    struct tfm_list_node_t handle_list;      /* Service handle list          */
-    struct tfm_msg_queue_t msg_queue;        /* Message queue                */
-    struct tfm_list_node_t list;             /* For list operation           */
-};
-
-/*************************** Extended SPM functions **************************/
-
-/**
- * \brief   Get the running partition ID.
- *
- * \return  Returns the partition ID
- */
-uint32_t tfm_spm_partition_get_running_partition_id_ext(void);
-
-/**
- * \brief                   Get the current partition mode.
- *
- * \param[in] partition_idx                 Index of current partition
- *
- * \retval TFM_PARTITION_PRIVILEGED_MODE    Privileged mode
- * \retval TFM_PARTITION_UNPRIVILEGED_MODE  Unprivileged mode
- */
-uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx);
-
-/******************** Service handle management functions ********************/
-
-/**
- * \brief                   Create connection handle for client connect
- *
- * \param[in] service       Target service context pointer
- *
- * \retval PSA_NULL_HANDLE  Create failed \ref PSA_NULL_HANDLE
- * \retval >0               Service handle created, \ref psa_handle_t
- */
-psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service);
-
-/**
- * \brief                   Free connection handle which not used anymore.
- *
- * \param[in] service       Target service context pointer
- * \param[in] conn_handle   Connection handle created by
- *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
- *
- * \retval IPC_SUCCESS      Success
- * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
- * \retval "Does not return"  Panic for not find service by handle
- */
-int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service,
-                                 psa_handle_t conn_handle);
-
-/**
- * \brief                   Set reverse handle value for connection.
- *
- * \param[in] service       Target service context pointer
- * \param[in] conn_handle   Connection handle created by
- *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
- * \param[in] rhandle       rhandle need to save
- *
- * \retval IPC_SUCCESS      Success
- * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
- * \retval "Does not return"  Panic for not find handle node
- */
-int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service,
-                            psa_handle_t conn_handle,
-                            void *rhandle);
-
-/**
- * \brief                   Get reverse handle value from connection hanlde.
- *
- * \param[in] service       Target service context pointer
- * \param[in] conn_handle   Connection handle created by
- *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
- *
- * \retval void *           Success
- * \retval "Does not return"  Panic for those:
- *                              service pointer are NULL
- *                              hanlde is \ref PSA_NULL_HANDLE
- *                              handle node does not be found
- */
-void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service,
-                          psa_handle_t conn_handle);
-
-/******************** Partition management functions *************************/
-
-/**
- * \brief                   Get current running partition context.
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       Return the parttion context pointer
- *                          \ref spm_partition_desc_t structures
- */
-struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
-
-/**
- * \brief                   Get the service context by signal.
- *
- * \param[in] partition     Partition context pointer
- *                          \ref spm_partition_desc_t structures
- * \param[in] signal        Signal associated with inputs to the Secure
- *                          Partition, \ref psa_signal_t
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       Target service context pointer,
- *                          \ref tfm_spm_service_t structures
- */
-struct tfm_spm_service_t *
-    tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
-                                  psa_signal_t signal);
-
-/**
- * \brief                   Get the service context by service ID.
- *
- * \param[in] sid           RoT Service identity
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       Target service context pointer,
- *                          \ref tfm_spm_service_t structures
- */
-struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
-
-/**
- * \brief                   Get the service context by connection handle.
- *
- * \param[in] conn_handle   Connection handle created by
- *                          tfm_spm_create_conn_handle()
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       Target service context pointer,
- *                          \ref tfm_spm_service_t structures
- */
-struct tfm_spm_service_t *
-    tfm_spm_get_service_by_handle(psa_handle_t conn_handle);
-
-/**
- * \brief                   Get the partition context by partition ID.
- *
- * \param[in] partition_id  Partition identity
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       Target partition context pointer,
- *                          \ref spm_partition_desc_t structures
- */
-struct spm_partition_desc_t *
-    tfm_spm_get_partition_by_id(int32_t partition_id);
-
-/************************ Message functions **********************************/
-
-/**
- * \brief                   Get message context by message handle.
- *
- * \param[in] msg_handle    Message handle which is a reference generated
- *                          by the SPM to a specific message.
- *
- * \return                  The message body context pointer
- *                          \ref tfm_msg_body_t structures
- */
-struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle);
-
-/**
- * \brief                   Create a message for PSA client call.
- *
- * \param[in] service       Target service context pointer, which can be
- *                          obtained by partition management functions
- * \prarm[in] handle        Connect handle return by psa_connect().
- * \param[in] type          Message type, one of the following values:
- *                            \ref PSA_IPC_CONNECT
- *                            >= 0
- *                            \ref PSA_IPC_DISCONNECT
- *                          positive.
- * \param[in] ns_caller     Whether from NS caller
- * \param[in] invec         Array of input \ref psa_invec structures
- * \param[in] in_len        Number of input \ref psa_invec structures
- * \param[in] outvec        Array of output \ref psa_outvec structures
- * \param[in] out_len       Number of output \ref psa_outvec structures
- * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
- *
- * \retval NULL             Failed
- * \retval "Not NULL"       New message body pointer \ref tfm_msg_body_t
- *                          structures
- */
-struct tfm_msg_body_t *tfm_spm_create_msg(struct tfm_spm_service_t *service,
-                                          psa_handle_t handle,
-                                          int32_t type, int32_t ns_caller,
-                                          psa_invec *invec, size_t in_len,
-                                          psa_outvec *outvec, size_t out_len,
-                                          psa_outvec *caller_outvec);
-
-/**
- * \brief                   Free message which unused anymore
- *
- * \param[in] msg           Message pointer which want to free
- *                          \ref tfm_msg_body_t structures
- *
- * \retval void             Success
- * \retval "Does not return" Failed
- */
-void tfm_spm_free_msg(struct tfm_msg_body_t *msg);
-
-/**
- * \brief                   Send message and wake up the SP who is waiting on
- *                          message queue, block the current thread and
- *                          scheduler triggered
- *
- * \param[in] service       Target service context pointer, which can be
- *                          obtained by partition management functions
- * \param[in] msg           message created by tfm_spm_create_msg()
- *                          \ref tfm_msg_body_t structures
- *
- * \retval IPC_SUCCESS      Success
- * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
- * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
- */
-int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
-                           struct tfm_msg_body_t *msg);
-
-/**
- * \brief                   Check the client minor version according to
- *                          version policy
- *
- * \param[in] service       Target service context pointer, which can be get
- *                          by partition management functions
- * \param[in] minor_version Client support minor version
- *
- * \retval IPC_SUCCESS      Success
- * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
- * \retval IPC_ERROR_VERSION Check failed
- */
-int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
-                                     uint32_t minor_version);
-
-/**
- * \brief                      Check the memory reference is valid.
- *
- * \param[in] buffer           Pointer of memory reference
- * \param[in] len              Length of memory reference in bytes
- * \param[in] ns_caller        From non-secure caller
- * \param[in] access           Type of access specified by the
- *                             \ref tfm_memory_access_e
- * \param[in] privileged       Privileged mode or unprivileged mode:
- *                             \ref TFM_PARTITION_UNPRIVILEGED_MODE
- *                             \ref TFM_PARTITION_PRIVILEGED_MODE
- *
- * \retval IPC_SUCCESS               Success
- * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
- * \retval IPC_ERROR_MEMORY_CHECK    Check failed
- */
-int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
-                         enum tfm_memory_access_e access,
-                         uint32_t privileged);
-
-/* This function should be called before schedule function */
-void tfm_spm_init(void);
-
-/*
- * PendSV specified function.
- *
- * Parameters :
- *  ctxb        -    State context storage pointer
- *
- * Notes:
- *  This is a staging API. Scheduler should be called in SPM finally and
- *  this function will be obsoleted later.
- */
-void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
-
-#endif
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index 463c19b..e507057 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -16,7 +16,6 @@
 #include "tfm_utils.h"
 #include "tfm_internal_defines.h"
 #include "tfm_message_queue.h"
-#include "tfm_spm.h"
 #include "tfm_spm_hal.h"
 #include "tfm_irq_list.h"
 #include "tfm_api.h"
diff --git a/secure_fw/core/tfm_boot_data.c b/secure_fw/core/tfm_boot_data.c
index a325f43..4fce3fc 100644
--- a/secure_fw/core/tfm_boot_data.c
+++ b/secure_fw/core/tfm_boot_data.c
@@ -19,7 +19,6 @@
 #include "tfm_thread.h"
 #include "tfm_wait.h"
 #include "tfm_message_queue.h"
-#include "tfm_spm.h"
 #include "tfm_spm_hal.h"
 #include "spm_db.h"
 #endif
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index d56e5c9..abfa6b1 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -24,7 +24,6 @@
 #include "tfm_thread.h"
 #include "tfm_wait.h"
 #include "tfm_message_queue.h"
-#include "tfm_spm.h"
 #endif
 
 /*
diff --git a/secure_fw/spm/CMakeLists.inc b/secure_fw/spm/CMakeLists.inc
index ef9094b..696feb4 100644
--- a/secure_fw/spm/CMakeLists.inc
+++ b/secure_fw/spm/CMakeLists.inc
@@ -26,6 +26,9 @@
 
 set (SS_SPM_C_SRC "${SS_SPM_DIR}/spm_api.c")
 
+if(TFM_PSA_API)
+	list(APPEND SS_SPM_C_SRC "${SS_SPM_DIR}/spm_api_ipc.c")
+endif()
 
 #Append all our source files to global lists.
 list(APPEND ALL_SRC_C ${SS_SPM_C_SRC})
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index 3a3b2f8..36f4afd 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -10,7 +10,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "spm_api.h"
-#include "platform/include/tfm_spm_hal.h"
+#include "tfm_spm_hal.h"
 #include "tfm_memory_utils.h"
 #include "spm_db.h"
 #include "tfm_internal.h"
@@ -222,7 +222,6 @@
 #endif
     runtime_data->ctx_stack_ptr +=
             sizeof(struct interrupted_ctx_stack_frame_t) / sizeof(uint32_t);
-
 }
 
 void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx)
@@ -273,9 +272,8 @@
     tfm_spm_partition_set_state(partition_idx, stack_frame->partition_state);
     stack_frame->partition_state = 0;
     tfm_spm_partition_set_caller_partition_idx(
-                              partition_idx, stack_frame->caller_partition_idx);
+                            partition_idx, stack_frame->caller_partition_idx);
     stack_frame->caller_partition_idx = 0;
-
 }
 
 #endif /* !defined(TFM_PSA_API) */
@@ -305,7 +303,6 @@
 
     return tfm_spm_hal_partition_sandbox_config(&(part->memory_data),
                                                 part->platform_data);
-
 }
 
 enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index adc57f2..6b8164b 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -12,9 +12,12 @@
 #include "tfm_api.h"
 #include "spm_partition_defs.h"
 #include "secure_fw/core/tfm_secure_api.h"
+#include <stdbool.h>
 #ifdef TFM_PSA_API
 #include "tfm_list.h"
 #include "tfm_wait.h"
+#include "tfm_message_queue.h"
+#include "tfm_secure_api.h"
 #endif
 
 #define SPM_INVALID_PARTITION_IDX     (~0U)
@@ -422,4 +425,301 @@
  */
 void tfm_spm_partition_change_privilege(uint32_t privileged);
 
+#ifdef TFM_PSA_API
+
+#define TFM_SPM_MAX_ROT_SERV_NUM        48
+#define TFM_VERSION_POLICY_RELAXED      0
+#define TFM_VERSION_POLICY_STRICT       1
+
+#define TFM_CONN_HANDLE_MAX_NUM         32
+
+/* RoT connection handle list */
+struct tfm_conn_handle_t {
+    psa_handle_t handle;            /* Handle value                         */
+    void *rhandle;                  /* Reverse handle value                 */
+    struct tfm_list_node_t list;    /* list node                            */
+};
+
+/* Service database defined by manifest */
+struct tfm_spm_service_db_t {
+    char *name;                     /* Service name                          */
+    uint32_t partition_id;          /* Partition ID which service belong to  */
+    psa_signal_t signal;            /* Service signal                        */
+    uint32_t sid;                   /* Service identifier                    */
+    bool non_secure_client;         /* If can be called by non secure client */
+    uint32_t minor_version;         /* Minor version                         */
+    uint32_t minor_policy;          /* Minor version policy                  */
+};
+
+/* RoT Service data */
+struct tfm_spm_service_t {
+    struct tfm_spm_service_db_t *service_db; /* Service database pointer     */
+    struct spm_partition_desc_t *partition;  /*
+                                              * Point to secure partition
+                                              * data
+                                              */
+    struct tfm_list_node_t handle_list;      /* Service handle list          */
+    struct tfm_msg_queue_t msg_queue;        /* Message queue                */
+    struct tfm_list_node_t list;             /* For list operation           */
+};
+
+/*************************** Extended SPM functions **************************/
+
+/**
+ * \brief   Get the running partition ID.
+ *
+ * \return  Returns the partition ID
+ */
+uint32_t tfm_spm_partition_get_running_partition_id(void);
+
+/**
+ * \brief                   Get the current partition mode.
+ *
+ * \param[in] partition_idx                 Index of current partition
+ *
+ * \retval TFM_PARTITION_PRIVILEGED_MODE    Privileged mode
+ * \retval TFM_PARTITION_UNPRIVILEGED_MODE  Unprivileged mode
+ */
+uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx);
+
+/******************** Service handle management functions ********************/
+
+/**
+ * \brief                   Create connection handle for client connect
+ *
+ * \param[in] service       Target service context pointer
+ *
+ * \retval PSA_NULL_HANDLE  Create failed \ref PSA_NULL_HANDLE
+ * \retval >0               Service handle created, \ref psa_handle_t
+ */
+psa_handle_t tfm_spm_create_conn_handle(struct tfm_spm_service_t *service);
+
+/**
+ * \brief                   Free connection handle which not used anymore.
+ *
+ * \param[in] service       Target service context pointer
+ * \param[in] conn_handle   Connection handle created by
+ *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
+ *
+ * \retval IPC_SUCCESS      Success
+ * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
+ * \retval "Does not return"  Panic for not find service by handle
+ */
+int32_t tfm_spm_free_conn_handle(struct tfm_spm_service_t *service,
+                                 psa_handle_t conn_handle);
+
+/**
+ * \brief                   Set reverse handle value for connection.
+ *
+ * \param[in] service       Target service context pointer
+ * \param[in] conn_handle   Connection handle created by
+ *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
+ * \param[in] rhandle       rhandle need to save
+ *
+ * \retval IPC_SUCCESS      Success
+ * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
+ * \retval "Does not return"  Panic for not find handle node
+ */
+int32_t tfm_spm_set_rhandle(struct tfm_spm_service_t *service,
+                            psa_handle_t conn_handle,
+                            void *rhandle);
+
+/**
+ * \brief                   Get reverse handle value from connection hanlde.
+ *
+ * \param[in] service       Target service context pointer
+ * \param[in] conn_handle   Connection handle created by
+ *                          tfm_spm_create_conn_handle(), \ref psa_handle_t
+ *
+ * \retval void *           Success
+ * \retval "Does not return"  Panic for those:
+ *                              service pointer are NULL
+ *                              hanlde is \ref PSA_NULL_HANDLE
+ *                              handle node does not be found
+ */
+void *tfm_spm_get_rhandle(struct tfm_spm_service_t *service,
+                          psa_handle_t conn_handle);
+
+/******************** Partition management functions *************************/
+
+/**
+ * \brief                   Get current running partition context.
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       Return the parttion context pointer
+ *                          \ref spm_partition_desc_t structures
+ */
+struct spm_partition_desc_t *tfm_spm_get_running_partition(void);
+
+/**
+ * \brief                   Get the service context by signal.
+ *
+ * \param[in] partition     Partition context pointer
+ *                          \ref spm_partition_desc_t structures
+ * \param[in] signal        Signal associated with inputs to the Secure
+ *                          Partition, \ref psa_signal_t
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       Target service context pointer,
+ *                          \ref tfm_spm_service_t structures
+ */
+struct tfm_spm_service_t *
+    tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
+                                  psa_signal_t signal);
+
+/**
+ * \brief                   Get the service context by service ID.
+ *
+ * \param[in] sid           RoT Service identity
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       Target service context pointer,
+ *                          \ref tfm_spm_service_t structures
+ */
+struct tfm_spm_service_t *tfm_spm_get_service_by_sid(uint32_t sid);
+
+/**
+ * \brief                   Get the service context by connection handle.
+ *
+ * \param[in] conn_handle   Connection handle created by
+ *                          tfm_spm_create_conn_handle()
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       Target service context pointer,
+ *                          \ref tfm_spm_service_t structures
+ */
+struct tfm_spm_service_t *
+    tfm_spm_get_service_by_handle(psa_handle_t conn_handle);
+
+/**
+ * \brief                   Get the partition context by partition ID.
+ *
+ * \param[in] partition_id  Partition identity
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       Target partition context pointer,
+ *                          \ref spm_partition_desc_t structures
+ */
+struct spm_partition_desc_t *
+    tfm_spm_get_partition_by_id(int32_t partition_id);
+
+/************************ Message functions **********************************/
+
+/**
+ * \brief                   Get message context by message handle.
+ *
+ * \param[in] msg_handle    Message handle which is a reference generated
+ *                          by the SPM to a specific message.
+ *
+ * \return                  The message body context pointer
+ *                          \ref tfm_msg_body_t structures
+ */
+struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle);
+
+/**
+ * \brief                   Create a message for PSA client call.
+ *
+ * \param[in] service       Target service context pointer, which can be
+ *                          obtained by partition management functions
+ * \prarm[in] handle        Connect handle return by psa_connect().
+ * \param[in] type          Message type, PSA_IPC_CONNECT, PSA_IPC_CALL or
+ *                          PSA_IPC_DISCONNECT
+ * \param[in] ns_caller     Whether from NS caller
+ * \param[in] invec         Array of input \ref psa_invec structures
+ * \param[in] in_len        Number of input \ref psa_invec structures
+ * \param[in] outvec        Array of output \ref psa_outvec structures
+ * \param[in] out_len       Number of output \ref psa_outvec structures
+ * \param[in] caller_outvec Array of caller output \ref psa_outvec structures
+ *
+ * \retval NULL             Failed
+ * \retval "Not NULL"       New message body pointer \ref tfm_msg_body_t
+ *                          structures
+ */
+struct tfm_msg_body_t *tfm_spm_create_msg(struct tfm_spm_service_t *service,
+                                          psa_handle_t handle,
+                                          int32_t type, int32_t ns_caller,
+                                          psa_invec *invec, size_t in_len,
+                                          psa_outvec *outvec, size_t out_len,
+                                          psa_outvec *caller_outvec);
+
+/**
+ * \brief                   Free message which unused anymore
+ *
+ * \param[in] msg           Message pointer which want to free
+ *                          \ref tfm_msg_body_t structures
+ *
+ * \retval void             Success
+ * \retval "Does not return" Failed
+ */
+void tfm_spm_free_msg(struct tfm_msg_body_t *msg);
+
+/**
+ * \brief                   Send message and wake up the SP who is waiting on
+ *                          message queue, block the current thread and
+ *                          scheduler triggered
+ *
+ * \param[in] service       Target service context pointer, which can be
+ *                          obtained by partition management functions
+ * \param[in] msg           message created by tfm_spm_create_msg()
+ *                          \ref tfm_msg_body_t structures
+ *
+ * \retval IPC_SUCCESS      Success
+ * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
+ * \retval IPC_ERROR_GENERIC Failed to enqueue message to service message queue
+ */
+int32_t tfm_spm_send_event(struct tfm_spm_service_t *service,
+                           struct tfm_msg_body_t *msg);
+
+/**
+ * \brief                   Check the client minor version according to
+ *                          version policy
+ *
+ * \param[in] service       Target service context pointer, which can be get
+ *                          by partition management functions
+ * \param[in] minor_version Client support minor version
+ *
+ * \retval IPC_SUCCESS      Success
+ * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
+ * \retval IPC_ERROR_VERSION Check failed
+ */
+int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
+                                     uint32_t minor_version);
+
+/**
+ * \brief                      Check the memory reference is valid.
+ *
+ * \param[in] buffer           Pointer of memory reference
+ * \param[in] len              Length of memory reference in bytes
+ * \param[in] ns_caller        From non-secure caller
+ * \param[in] access           Type of access specified by the
+ *                             \ref tfm_memory_access_e
+ * \param[in] privileged       Privileged mode or unprivileged mode:
+ *                             \ref TFM_PARTITION_UNPRIVILEGED_MODE
+ *                             \ref TFM_PARTITION_PRIVILEGED_MODE
+ *
+ * \retval IPC_SUCCESS               Success
+ * \retval IPC_ERROR_BAD_PARAMETERS  Bad parameters input
+ * \retval IPC_ERROR_MEMORY_CHECK    Check failed
+ */
+int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
+                         enum tfm_memory_access_e access,
+                         uint32_t privileged);
+
+/* This function should be called before schedule function */
+void tfm_spm_init(void);
+
+/*
+ * PendSV specified function.
+ *
+ * Parameters :
+ *  ctxb        -    State context storage pointer
+ *
+ * Notes:
+ *  This is a staging API. Scheduler should be called in SPM finally and
+ *  this function will be obsoleted later.
+ */
+void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
+
+#endif /* ifdef(TFM_PSA_API) */
+
 #endif /*__SPM_API_H__ */
diff --git a/secure_fw/core/ipc/tfm_spm.c b/secure_fw/spm/spm_api_ipc.c
similarity index 94%
rename from secure_fw/core/ipc/tfm_spm.c
rename to secure_fw/spm/spm_api_ipc.c
index 0159190..595a1a2 100644
--- a/secure_fw/core/ipc/tfm_spm.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -11,7 +11,7 @@
 #include "psa/client.h"
 #include "psa/service.h"
 #include "tfm_utils.h"
-#include "platform/include/tfm_spm_hal.h"
+#include "tfm_spm_hal.h"
 #include "spm_api.h"
 #include "spm_db.h"
 #include "tfm_internal_defines.h"
@@ -19,7 +19,6 @@
 #include "tfm_message_queue.h"
 #include "tfm_list.h"
 #include "tfm_pools.h"
-#include "tfm_spm.h"
 #include "tfm_thread.h"
 #include "region_defs.h"
 #include "tfm_nspm.h"
@@ -30,6 +29,7 @@
 
 /* Extern secure lock variable */
 extern int32_t tfm_secure_lock;
+
 /* Pools */
 TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t),
                  TFM_CONN_HANDLE_MAX_NUM);
@@ -147,8 +147,8 @@
 
 /* Partition management functions */
 struct tfm_spm_service_t *
-tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
-                              psa_signal_t signal)
+    tfm_spm_get_service_by_signal(struct spm_partition_desc_t *partition,
+                                  psa_signal_t signal)
 {
     struct tfm_list_node_t *node, *head;
     struct tfm_spm_service_t *service;
@@ -179,8 +179,7 @@
     for (i = 0; i < g_spm_partition_db.partition_count; i++) {
         partition = &g_spm_partition_db.partitions[i];
         /* Skip partition without IPC flag */
-        if ((tfm_spm_partition_get_flags(partition->static_data.index) &
-             SPM_PART_FLAG_IPC) == 0) {
+        if ((tfm_spm_partition_get_flags(i) & SPM_PART_FLAG_IPC) == 0) {
             continue;
         }
 
@@ -213,8 +212,7 @@
     for (i = 0; i < g_spm_partition_db.partition_count; i++) {
         partition = &g_spm_partition_db.partitions[i];
         /* Skip partition without IPC flag */
-        if ((tfm_spm_partition_get_flags(partition->static_data.index) &
-             SPM_PART_FLAG_IPC) == 0) {
+        if ((tfm_spm_partition_get_flags(i) & SPM_PART_FLAG_IPC) == 0) {
             continue;
         }
 
@@ -253,7 +251,7 @@
 {
     uint32_t spid;
 
-    spid = tfm_spm_partition_get_running_partition_id_ext();
+    spid = tfm_spm_partition_get_running_partition_id();
 
     return tfm_spm_get_partition_by_id(spid);
 }
@@ -307,7 +305,7 @@
     }
 
     /* For condition 2: check if the partition ID is same */
-    partition_id = tfm_spm_partition_get_running_partition_id_ext();
+    partition_id = tfm_spm_partition_get_running_partition_id();
     if (partition_id != msg->service->partition->static_data.partition_id) {
         return NULL;
     }
@@ -350,7 +348,7 @@
     if (ns_caller) {
         msg->msg.client_id = tfm_nspm_get_current_client_id();
     } else {
-        msg->msg.client_id = tfm_spm_partition_get_running_partition_id_ext();
+        msg->msg.client_id = tfm_spm_partition_get_running_partition_id();
     }
 
     /* Copy contents */
@@ -410,7 +408,7 @@
 }
 
 /* SPM extend functions */
-uint32_t tfm_spm_partition_get_running_partition_id_ext(void)
+uint32_t tfm_spm_partition_get_running_partition_id(void)
 {
     struct tfm_thrd_ctx *pth = tfm_thrd_curr_thread();
     struct spm_partition_desc_t *partition;
@@ -421,19 +419,19 @@
 }
 
 static struct tfm_thrd_ctx *
-    tfm_spm_partition_get_thread_info_ext(uint32_t partition_idx)
+    tfm_spm_partition_get_thread_info(uint32_t partition_idx)
 {
     return &g_spm_partition_db.partitions[partition_idx].sp_thrd;
 }
 
 static tfm_thrd_func_t
-    tfm_spm_partition_get_init_func_ext(uint32_t partition_idx)
+    tfm_spm_partition_get_init_func(uint32_t partition_idx)
 {
     return (tfm_thrd_func_t)(g_spm_partition_db.partitions[partition_idx].
                              static_data.partition_init);
 }
 
-static uint32_t tfm_spm_partition_get_priority_ext(uint32_t partition_idx)
+static uint32_t tfm_spm_partition_get_priority(uint32_t partition_idx)
 {
     return g_spm_partition_db.partitions[partition_idx].static_data.
                     partition_priority;
@@ -513,18 +511,18 @@
         tfm_event_init(&partition->runtime_data.signal_evnt);
         tfm_list_init(&partition->runtime_data.service_list);
 
-        pth = tfm_spm_partition_get_thread_info_ext(i);
+        pth = tfm_spm_partition_get_thread_info(i);
         if (!pth) {
             tfm_panic();
         }
 
         tfm_thrd_init(pth,
-                      tfm_spm_partition_get_init_func_ext(i),
+                      tfm_spm_partition_get_init_func(i),
                       NULL,
                       (uint8_t *)tfm_spm_partition_get_stack_top(i),
                       (uint8_t *)tfm_spm_partition_get_stack_bottom(i));
 
-        pth->prior = tfm_spm_partition_get_priority_ext(i);
+        pth->prior = tfm_spm_partition_get_priority(i);
 
         /* Kick off */
         if (tfm_thrd_start(pth) != THRD_SUCCESS) {