Core: Move spm header files to 'spm' folder
- Move 'spm_xxx.h' to 'spm' folder, they should belong to 'spm'.
- Fix and simplify inclusion of header file.
- Fix format and typo error.
Change-Id: I129c6626ddffbbdba0e7edc27e9307f0d6ea9b79
Signed-off-by: Mingyang Sun <mingyang.sun@arm.com>
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_base.c b/secure_fw/spm/arch/tfm_arch_v8m_base.c
index 00c4fca..0c5d834 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/spm/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_api.h"
+#include "spm_api.h"
#include "tfm/tfm_core_svc.h"
#if !defined(__ARM_ARCH_8M_BASE__)
diff --git a/secure_fw/spm/arch/tfm_arch_v8m_main.c b/secure_fw/spm/arch/tfm_arch_v8m_main.c
index f975a66..be268ec 100644
--- a/secure_fw/spm/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/spm/arch/tfm_arch_v8m_main.c
@@ -13,7 +13,7 @@
#include "tfm_memory_utils.h"
#include "tfm_core_utils.h"
#include "tfm_secure_api.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm/tfm_core_svc.h"
#if !defined(__ARM_ARCH_8M_MAIN__) && !defined(__ARM_ARCH_8_1M_MAIN__)
diff --git a/secure_fw/spm/include/spm_api.h b/secure_fw/spm/include/spm_api.h
new file mode 100644
index 0000000..92e1409
--- /dev/null
+++ b/secure_fw/spm/include/spm_api.h
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPM_API_H__
+#define __SPM_API_H__
+
+/* This file contains the apis exported by the SPM to tfm core */
+#include "tfm_api.h"
+#include "spm_partition_defs.h"
+#include "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"
+#include "tfm_thread.h"
+#endif
+
+#define SPM_INVALID_PARTITION_IDX (~0U)
+
+/* Privileged definitions for partition thread mode */
+#define TFM_PARTITION_PRIVILEGED_MODE 1
+#define TFM_PARTITION_UNPRIVILEGED_MODE 0
+
+enum spm_err_t {
+ SPM_ERR_OK = 0,
+ SPM_ERR_PARTITION_DB_NOT_INIT,
+ SPM_ERR_PARTITION_ALREADY_ACTIVE,
+ SPM_ERR_PARTITION_NOT_AVAILABLE,
+ SPM_ERR_INVALID_PARAMETER,
+ SPM_ERR_INVALID_CONFIG,
+};
+
+#define SPM_PARTITION_STATE_UNINIT 0
+#define SPM_PARTITION_STATE_IDLE 1
+#define SPM_PARTITION_STATE_RUNNING 2
+#define SPM_PARTITION_STATE_HANDLING_IRQ 3
+#define SPM_PARTITION_STATE_SUSPENDED 4
+#define SPM_PARTITION_STATE_BLOCKED 5
+#define SPM_PARTITION_STATE_CLOSED 6
+
+#define SPM_PART_FLAG_APP_ROT 0x01
+#define SPM_PART_FLAG_PSA_ROT 0x02
+#define SPM_PART_FLAG_IPC 0x04
+
+#define TFM_HANDLE_STATUS_IDLE 0
+#define TFM_HANDLE_STATUS_ACTIVE 1
+#define TFM_HANDLE_STATUS_CONNECT_ERROR 2
+
+#ifndef TFM_PSA_API
+/**
+ * \brief Holds the iovec parameters that are passed to a service
+ *
+ * \note The size of the structure is (and have to be) multiple of 8 bytes
+ */
+struct iovec_args_t {
+ psa_invec in_vec[PSA_MAX_IOVEC]; /*!< Array of psa_invec objects */
+ size_t in_len; /*!< Number psa_invec objects in in_vec
+ */
+ psa_outvec out_vec[PSA_MAX_IOVEC]; /*!< Array of psa_outvec objects */
+ size_t out_len; /*!< Number psa_outvec objects in out_vec
+ */
+};
+
+/* The size of this struct must be multiple of 4 bytes as it is stacked to an
+ * uint32_t[] array
+ */
+struct interrupted_ctx_stack_frame_t {
+ uint32_t partition_state;
+};
+
+/* The size of this struct must be multiple of 4 bytes as it is stacked to an
+ * uint32_t[] array
+ */
+struct handler_ctx_stack_frame_t {
+ uint32_t partition_state;
+ uint32_t caller_partition_idx;
+};
+#endif /* !define(TFM_PSA_API) */
+
+/**
+ * \brief Runtime context information of a partition
+ */
+struct spm_partition_runtime_data_t {
+#ifdef TFM_PSA_API
+ uint32_t signals; /* Service signals had been triggered*/
+ struct tfm_event_t signal_evnt; /* Event signal */
+ struct tfm_list_node_t service_list;/* Service list */
+ struct tfm_core_thread_t sp_thrd; /* Thread object */
+ uint32_t assigned_signals; /* All assigned signals */
+#else /* TFM_PSA_API */
+ uint32_t partition_state;
+ uint32_t caller_partition_idx;
+ int32_t caller_client_id;
+ uint32_t stack_ptr;
+ uint32_t lr;
+ struct iovec_args_t iovec_args;
+ psa_outvec *orig_outvec;
+ uint32_t *ctx_stack_ptr;
+#endif /* TFM_PSA_API */
+ uint32_t signal_mask; /*
+ * Service signal mask passed by
+ * psa_wait()
+ */
+};
+
+#ifdef TFM_PSA_API
+
+#define TFM_VERSION_POLICY_RELAXED 0
+#define TFM_VERSION_POLICY_STRICT 1
+
+#define TFM_CONN_HANDLE_MAX_NUM 16
+
+/* RoT connection handle list */
+struct tfm_conn_handle_t {
+ void *rhandle; /* Reverse handle value */
+ uint32_t status; /*
+ * Status of handle, three valid
+ * options:
+ * TFM_HANDLE_STATUS_ACTIVE,
+ * TFM_HANDLE_STATUS_IDLE and
+ * TFM_HANDLE_STATUS_CONNECT_ERROR
+ */
+ int32_t client_id; /*
+ * Partition ID of the sender of the
+ * message:
+ * - secure partition id;
+ * - non secure client endpoint id.
+ */
+ struct tfm_msg_body_t internal_msg; /* Internal message for message queue */
+ struct tfm_spm_service_t *service; /* RoT service pointer */
+ 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 version; /* Service version */
+ uint32_t version_policy; /* Service version policy */
+};
+
+/* RoT Service data */
+struct tfm_spm_service_t {
+ const 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 */
+};
+#endif /* ifdef(TFM_PSA_API) */
+
+/*********************** common definitions ***********************/
+
+/**
+ * \brief Returns the index of the partition with the given partition ID.
+ *
+ * \param[in] partition_id Partition id
+ *
+ * \return the partition idx if partition_id is valid,
+ * \ref SPM_INVALID_PARTITION_IDX othervise
+ */
+uint32_t get_partition_idx(uint32_t partition_id);
+
+/**
+ * \brief Get the id of the partition for its index from the db
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \return Partition ID for that partition
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
+
+/**
+ * \brief Get the flags associated with a partition
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \return Flags associated with the partition
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
+
+/**
+ * \brief Initialize partition database
+ *
+ * \return Error code \ref spm_err_t
+ */
+enum spm_err_t tfm_spm_db_init(void);
+
+/**
+ * \brief Change the privilege mode for partition thread mode.
+ *
+ * \param[in] privileged Privileged mode,
+ * \ref TFM_PARTITION_PRIVILEGED_MODE
+ * and \ref TFM_PARTITION_UNPRIVILEGED_MODE
+ *
+ * \note Barrier instructions are not called by this function, and if
+ * it is called in thread mode, it might be necessary to call
+ * them after this function returns.
+ */
+void tfm_spm_partition_change_privilege(uint32_t privileged);
+
+/**
+ * \brief Get the current partition mode.
+ *
+ * \param[in] partition_flags Flags 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_flags);
+
+/**
+ * \brief Handle an SPM request by a secure service
+ * \param[in] svc_ctx The stacked SVC context
+ */
+void tfm_spm_request_handler(const struct tfm_state_context_t *svc_ctx);
+
+/*********************** library definitions ***********************/
+
+#ifndef TFM_PSA_API
+/**
+ * \brief Save interrupted partition context on ctx stack
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note This function doesn't whether the ctx stack overflows.
+ */
+void tfm_spm_partition_push_interrupted_ctx(uint32_t partition_idx);
+
+/**
+ * \brief Restores interrupted partition context on ctx stack
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note This function doesn't whether the ctx stack underflows.
+ */
+void tfm_spm_partition_pop_interrupted_ctx(uint32_t partition_idx);
+
+/**
+ * \brief Save handler partition context on ctx stack
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note This function doesn't whether the ctx stack overflows.
+ */
+void tfm_spm_partition_push_handler_ctx(uint32_t partition_idx);
+
+/**
+ * \brief Restores handler partition context on ctx stack
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note This function doesn't whether the ctx stack underflows.
+ */
+void tfm_spm_partition_pop_handler_ctx(uint32_t partition_idx);
+
+/**
+ * \brief Get the current runtime data of a partition
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \return The runtime data of the specified partition
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+const struct spm_partition_runtime_data_t *
+ tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
+
+/**
+ * \brief Returns the index of the partition that has running state
+ *
+ * \return The index of the partition with the running state, if there is any
+ * set. 0 otherwise.
+ */
+uint32_t tfm_spm_partition_get_running_partition_idx(void);
+
+/**
+ * \brief Save stack pointer and link register for partition in database
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] stack_ptr Stack pointer to be stored
+ * \param[in] lr Link register to be stored
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+void tfm_spm_partition_store_context(uint32_t partition_idx,
+ uint32_t stack_ptr, uint32_t lr);
+
+/**
+ * \brief Set the current state of a partition
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] state The state to be set
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note The state has to have the value set of \ref spm_part_state_t.
+ */
+void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
+
+/**
+ * \brief Set the caller partition index for a given partition
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] caller_partition_idx The index of the caller partition
+ *
+ * \note This function doesn't check if any of the partition_idxs are valid.
+ */
+void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
+ uint32_t caller_partition_idx);
+
+/**
+ * \brief Set the caller client ID for a given partition
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] caller_client_id The ID of the calling client
+ *
+ * \note This function doesn't check if any of the partition_idxs are valid.
+ */
+void tfm_spm_partition_set_caller_client_id(uint32_t partition_idx,
+ int32_t caller_client_id);
+
+
+/**
+ * \brief Set the iovec parameters for the partition
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] args The arguments of the secure function
+ *
+ * args is expected to be of type int32_t[4] where:
+ * args[0] is in_vec
+ * args[1] is in_len
+ * args[2] is out_vec
+ * args[3] is out_len
+ *
+ * \return Error code \ref spm_err_t
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ * \note This function assumes that the iovecs that are passed in args are
+ * valid, and does no sanity check on them at all.
+ */
+enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
+ const int32_t *args);
+
+/**
+ * \brief Execute partition init function
+ *
+ * \return Error code \ref spm_err_t
+ */
+enum spm_err_t tfm_spm_partition_init(void);
+
+/**
+ * \brief Clears the context info from the database for a partition.
+ *
+ * \param[in] partition_idx Partition index
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
+
+/**
+ * \brief Set the signal mask for a given partition
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] signal_mask The signal mask to be set for the partition
+ *
+ * \note This function doesn't check if any of the partition_idxs are valid.
+ */
+void tfm_spm_partition_set_signal_mask(uint32_t partition_idx,
+ uint32_t signal_mask);
+
+/**
+ * \brief Signal that secure partition initialisation is finished
+ */
+void tfm_spm_secure_api_init_done(void);
+
+/**
+ * \brief Called if veneer is running in thread mode
+ */
+uint32_t tfm_spm_partition_request_svc_handler(
+ const uint32_t *svc_args, uint32_t lr);
+
+/**
+ * \brief Called when secure service returns
+ */
+uint32_t tfm_spm_partition_return_handler(uint32_t lr);
+
+/**
+ * \brief Called by secure service to check if client is secure
+ */
+void tfm_spm_validate_secure_caller_handler(uint32_t *svc_args);
+
+/**
+ * \brief Stores caller's client id in state context
+ */
+void tfm_spm_get_caller_client_id_handler(uint32_t *svc_args);
+
+/**
+ * \brief Checks if a secure service's access to a memory location is permitted
+ */
+void tfm_spm_memory_permission_check_handler(uint32_t *svc_args);
+
+/**
+ * \brief Check whether a buffer is ok for writing to by the privileged API
+ * function.
+ *
+ * This function checks whether the caller partition owns the buffer, can write
+ * to it, and the buffer has proper alignment.
+ *
+ * \param[in] partition_idx Partition index
+ * \param[in] start_addr The start address of the buffer
+ * \param[in] len The length of the buffer
+ * \param[in] alignment The expected alignment (in bits)
+ *
+ * \return 1 if the check passes, 0 otherwise.
+ *
+ * \note For a 0 long buffer the check fails.
+ */
+int32_t tfm_spm_check_buffer_access(uint32_t partition_idx,
+ void *start_addr,
+ size_t len,
+ uint32_t alignment);
+
+/**
+ * \brief Handle deprivileged request
+ */
+extern uint32_t tfm_spm_depriv_req_handler(uint32_t *svc_args,
+ uint32_t excReturn);
+
+/**
+ * \brief Handle request to return to privileged
+ */
+uint32_t tfm_spm_depriv_return_handler(uint32_t *irq_svc_args, uint32_t lr);
+
+/**
+ * \brief Handle IRQ enable request
+ */
+void tfm_spm_enable_irq_handler(uint32_t *svc_args);
+
+/**
+ * \brief Handle IRQ disable request
+ */
+void tfm_spm_disable_irq_handler(uint32_t *svc_args);
+
+/**
+ * \brief Handle signal wait request
+ */
+void tfm_spm_psa_wait(uint32_t *svc_args);
+
+/**
+ * \brief Handle request to record IRQ processed
+ */
+void tfm_spm_psa_eoi(uint32_t *svc_args);
+#endif /* !defined(TFM_PSA_API) */
+
+#ifdef TFM_PSA_API
+/*************************** IPC definitions **************************/
+
+/**
+ * \brief Get the running partition ID.
+ *
+ * \return Returns the partition ID
+ */
+uint32_t tfm_spm_partition_get_running_partition_id(void);
+
+/******************** Service handle management functions ********************/
+
+/**
+ * \brief Create connection handle for client connect
+ *
+ * \param[in] service Target service context pointer
+ * \param[in] client_id Partition ID of the sender of the message
+ *
+ * \retval NULL Create failed
+ * \retval "Not NULL" Service handle created
+ */
+struct tfm_conn_handle_t *tfm_spm_create_conn_handle(
+ struct tfm_spm_service_t *service,
+ int32_t client_id);
+
+/**
+ * \brief Validate connection handle for client connect
+ *
+ * \param[in] conn_handle Handle to be validated
+ * \param[in] client_id Partition ID of the sender of the message
+ *
+ * \retval IPC_SUCCESS Success
+ * \retval IPC_ERROR_GENERIC Invalid handle
+ */
+int32_t tfm_spm_validate_conn_handle(
+ const struct tfm_conn_handle_t *conn_handle,
+ int32_t client_id);
+
+/******************** 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 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);
+
+/************************ Message functions **********************************/
+
+/**
+ * \brief Get message context by connect handle.
+ *
+ * \param[in] conn_handle Service connect handle.
+ *
+ * \return The message body context pointer
+ * \ref msg_body_t structures
+ */
+struct tfm_msg_body_t *
+ tfm_spm_get_msg_buffer_from_conn_handle(struct tfm_conn_handle_t *conn_handle);
+
+/**
+ * \brief Fill the message for PSA client call.
+ *
+ * \param[in] msg Service Message Queue buffer pointer
+ * \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] client_id Partition ID of the sender of the message
+ * \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
+ */
+void tfm_spm_fill_msg(struct tfm_msg_body_t *msg,
+ struct tfm_spm_service_t *service,
+ struct tfm_conn_handle_t *handle,
+ int32_t type, int32_t client_id,
+ psa_invec *invec, size_t in_len,
+ psa_outvec *outvec, size_t out_len,
+ psa_outvec *caller_outvec);
+
+/**
+ * \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 version according to
+ * version policy
+ *
+ * \param[in] service Target service context pointer, which can be get
+ * by partition management functions
+ * \param[in] version Client support 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 version);
+
+/**
+ * \brief Check the client access authorization
+ *
+ * \param[in] sid Target RoT Service identity
+ * \param[in] service Target service context pointer, which can be get
+ * by partition management functions
+ * \param[in] ns_caller Whether from NS caller
+ *
+ * \retval IPC_SUCCESS Success
+ * \retval IPC_ERROR_GENERIC Authorization check failed
+ */
+int32_t tfm_spm_check_authorization(uint32_t sid,
+ struct tfm_spm_service_t *service,
+ bool ns_caller);
+
+/**
+ * \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(const void *buffer, size_t len, bool ns_caller,
+ enum tfm_memory_access_e access,
+ uint32_t privileged);
+
+/*
+ * PendSV specified function.
+ *
+ * Parameters :
+ * p_actx - Architecture 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_arch_ctx_t *p_actx);
+
+/**
+ * \brief SPM initialization implementation
+ *
+ * \details This function must be called under handler mode.
+ * \retval This function returns an EXC_RETURN value. Other
+ * faults would panic the execution and never
+ * returned.
+ */
+uint32_t tfm_spm_init(void);
+
+/*
+ * \brief This function get the current PSA RoT lifecycle state.
+ *
+ * \return state The current security lifecycle state of the PSA
+ * RoT. The PSA state and implementation state are
+ * encoded as follows:
+ * \arg state[15:8] – PSA lifecycle state
+ * \arg state[7:0] – IMPLEMENTATION DEFINED state
+ */
+uint32_t tfm_spm_get_lifecycle_state(void);
+
+/* 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_spm_psa_framework_version(void);
+
+/**
+ * \brief SVC handler for \ref psa_version.
+ *
+ * \param[in] args Include all input arguments: sid.
+ * \param[in] ns_caller If 'true', 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 version of the implemented RoT Service.
+ */
+uint32_t tfm_spm_psa_version(uint32_t *args, bool ns_caller);
+
+/**
+ * \brief SVC handler for \ref psa_connect.
+ *
+ * \param[in] args Include all input arguments:
+ * sid, version.
+ * \param[in] ns_caller If 'true', call from non-secure client.
+ * Or 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_psa_connect(uint32_t *args, bool 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 'true', call from non-secure client.
+ * Or from secure client.
+ * \param[in] lr EXC_RETURN value of the SVC.
+ *
+ * \retval >=0 RoT Service-specific status value.
+ * \retval <0 RoT Service-specific error code.
+ * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
+ * RoT Service. The call is a PROGRAMMER ERROR if
+ * one or more of the following are true:
+ * \arg An invalid handle was passed.
+ * \arg The connection is already handling a request.
+ * \arg type < 0.
+ * \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_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr);
+
+/**
+ * \brief SVC handler for \ref psa_close.
+ *
+ * \param[in] args Include all input arguments: handle.
+ * \param[in] ns_caller If 'true', 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_spm_psa_close(uint32_t *args, bool ns_caller);
+
+/* Svcall 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.
+ */
+psa_signal_t tfm_spm_psa_wait(uint32_t *args);
+
+/**
+ * \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_ERROR_DOES_NOT_EXIST 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 an RoT Service.
+ * \arg The RoT Service signal is not currently
+ * asserted.
+ * \arg The msg pointer provided is not a valid memory
+ * reference.
+ */
+psa_status_t tfm_spm_psa_get(uint32_t *args);
+
+/**
+ * \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.
+ */
+void tfm_spm_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 request
+ * 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.
+ */
+size_t tfm_spm_psa_read(uint32_t *args);
+
+/**
+ * \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 request
+ * message.
+ * \arg invec_idx is equal to or greater than
+ * \ref PSA_MAX_IOVEC.
+ */
+size_t tfm_spm_psa_skip(uint32_t *args);
+
+/**
+ * \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 request
+ * 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.
+ */
+void tfm_spm_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.
+ */
+void tfm_spm_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.
+ */
+void tfm_spm_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.
+ */
+void tfm_spm_psa_clear(void);
+
+/**
+ * \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.
+ */
+void tfm_spm_psa_eoi(uint32_t *args);
+
+/**
+ * \brief SVC handler of enabling irq_line of the specified irq_signal.
+ *
+ * \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.
+ */
+void tfm_spm_enable_irq(uint32_t *args);
+
+/**
+ * \brief SVC handler of disabling irq_line of the specified irq_signal.
+ *
+ * \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.
+ */
+void tfm_spm_disable_irq(uint32_t *args);
+
+/**
+ * \brief Validate the whether NS caller re-enter.
+ *
+ * \param[in] p_cur_sp Pointer to current partition.
+ * \param[in] p_ctx Pointer to current stack context.
+ * \param[in] exc_return EXC_RETURN value.
+ * \param[in] ns_caller If 'true', call from non-secure client.
+ * Or from secure client.
+ *
+ * \retval void Success.
+ */
+void tfm_spm_validate_caller(struct spm_partition_desc_t *p_cur_sp,
+ uint32_t *p_ctx, uint32_t exc_return,
+ bool ns_caller);
+
+/**
+ * \brief Terminate execution within the calling Secure Partition and will not
+ * return.
+ *
+ * \retval "Does not return"
+ */
+void tfm_spm_psa_panic(void);
+
+/**
+ * \brief Converts a user handle into a corresponded handle instance.
+ */
+struct tfm_conn_handle_t *tfm_spm_to_handle_instance(psa_handle_t user_handle);
+
+#endif /* defined(TFM_PSA_API) */
+
+#endif /*__SPM_API_H__ */
diff --git a/secure_fw/spm/include/spm_db.h b/secure_fw/spm/include/spm_db.h
new file mode 100644
index 0000000..912b438
--- /dev/null
+++ b/secure_fw/spm/include/spm_db.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPM_DB_H__
+#define __SPM_DB_H__
+
+#include <stdint.h>
+#include "target_cfg.h"
+#ifdef TFM_PSA_API
+#include "tfm_spm_hal.h"
+#endif
+
+struct spm_partition_desc_t;
+struct spm_partition_db_t;
+
+typedef void(*sp_entry_point)(void);
+
+#define TFM_PARTITION_TYPE_APP "APPLICATION-ROT"
+#define TFM_PARTITION_TYPE_PSA "PSA-ROT"
+
+#ifdef TFM_PSA_API
+#define TFM_PRIORITY_LOW THRD_PRIOR_LOWEST
+#define TFM_PRIORITY_NORMAL THRD_PRIOR_MEDIUM
+#define TFM_PRIORITY_HIGH THRD_PRIOR_HIGHEST
+#else
+#define TFM_PRIORITY_LOW 0xFF
+#define TFM_PRIORITY_NORMAL 0x7F
+#define TFM_PRIORITY_HIGH 0
+#endif
+
+#define TFM_PRIORITY(LEVEL) TFM_PRIORITY_##LEVEL
+
+/**
+ * Holds the fields of the partition DB used by the SPM code. The values of
+ * these fields are calculated at compile time, and set during initialisation
+ * phase.
+ */
+struct spm_partition_static_data_t {
+#ifdef TFM_PSA_API
+ uint32_t psa_framework_version;
+#endif /* defined(TFM_PSA_API) */
+ uint32_t partition_id;
+ uint32_t partition_flags;
+ uint32_t partition_priority;
+ sp_entry_point partition_init;
+ uint32_t dependencies_num;
+ int32_t *p_dependencies;
+};
+
+/**
+ * Holds the fields that define a partition for SPM. The fields are further
+ * divided to structures, to keep the related fields close to each other.
+ */
+struct spm_partition_desc_t {
+ struct spm_partition_runtime_data_t runtime_data;
+ const struct spm_partition_static_data_t *static_data;
+ /** A list of platform_data pointers */
+ const struct tfm_spm_partition_platform_data_t **platform_data_list;
+#ifdef TFM_PSA_API
+ const struct tfm_spm_partition_memory_data_t *memory_data;
+#endif
+};
+
+struct spm_partition_db_t {
+ uint32_t is_init;
+ uint32_t partition_count;
+#ifndef TFM_PSA_API
+ uint32_t running_partition_idx;
+#endif /* !defined(TFM_PSA_API) */
+ struct spm_partition_desc_t *partitions;
+};
+
+#ifdef TFM_PSA_API
+#define PART_REGION_ADDR(partition, region) \
+ (uint32_t)®ION_NAME(Image$$, partition, region)
+#endif
+
+#endif /* __SPM_DB_H__ */
diff --git a/secure_fw/spm/include/spm_partition_defs.h b/secure_fw/spm/include/spm_partition_defs.h
new file mode 100644
index 0000000..4e32baf
--- /dev/null
+++ b/secure_fw/spm/include/spm_partition_defs.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPM_PARTITION_DEFS_H__
+#define __SPM_PARTITION_DEFS_H__
+
+/* FixMe: allocations to be settled.
+ * 8 bits reserved by TFM for secure partition Id in this prototype
+ */
+#define TFM_SP_BASE 256
+
+/* A reserved partition ID that is used for uninitialised data */
+#define INVALID_PARTITION_ID (~0U)
+
+/* ***** partition ID-s internal to the TFM ***** */
+#define TFM_INTERNAL_PARTITIONS (2)
+
+/* From the SPM point of view the non secure processing environment is handled
+ * as a special secure partition. This simplifies the context switch
+ * operations.
+ */
+#define TFM_SP_NON_SECURE_ID (0)
+/* A dummy partition for TFM_SP_CORE is created to handle secure partition
+ * calls done directly from the core, before NS execution started.
+ */
+#define TFM_SP_CORE_ID (1)
+
+#include "psa_manifest/pid.h"
+
+/* This limit is only used to define the size of the database reserved for
+ * partitions. There's no requirement that it match the number of partitions
+ * that get registered in a specific build
+ */
+#define SPM_MAX_PARTITIONS (TFM_MAX_USER_PARTITIONS + TFM_INTERNAL_PARTITIONS)
+
+#endif /* __SPM_PARTITION_DEFS_H__ */
diff --git a/secure_fw/spm/init/tfm_boot_data.c b/secure_fw/spm/init/tfm_boot_data.c
index d8e021c..ee4466e 100644
--- a/secure_fw/spm/init/tfm_boot_data.c
+++ b/secure_fw/spm/init/tfm_boot_data.c
@@ -12,8 +12,8 @@
#include "tfm_internal.h"
#include "tfm_api.h"
#include "tfm_core_utils.h"
-#include "tfm/spm_api.h"
-#include "tfm/spm_partition_defs.h"
+#include "spm_api.h"
+#include "spm_partition_defs.h"
#ifdef TFM_PSA_API
#include "tfm_internal_defines.h"
#include "tfm_utils.h"
@@ -22,7 +22,7 @@
#include "tfm_wait.h"
#include "tfm_message_queue.h"
#include "tfm_spm_hal.h"
-#include "tfm/spm_db.h"
+#include "spm_db.h"
#endif
/*!
diff --git a/secure_fw/spm/init/tfm_core.c b/secure_fw/spm/init/tfm_core.c
index d4df240..729f183 100644
--- a/secure_fw/spm/init/tfm_core.c
+++ b/secure_fw/spm/init/tfm_core.c
@@ -13,7 +13,7 @@
#include "tfm_spm_hal.h"
#include "tfm_version.h"
#include "log/tfm_log.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
/*
* Avoids the semihosting issue
diff --git a/secure_fw/spm/model_func/spm_func.c b/secure_fw/spm/model_func/spm_func.c
index 9f040b8..65c63b5 100644
--- a/secure_fw/spm/model_func/spm_func.c
+++ b/secure_fw/spm/model_func/spm_func.c
@@ -18,8 +18,8 @@
#include "tfm_peripherals_def.h"
#include "tfm_secure_api.h"
#include "tfm_spm_hal.h"
-#include "tfm/spm_api.h"
-#include "tfm/spm_db.h"
+#include "spm_api.h"
+#include "spm_db.h"
#include "region_defs.h"
#include "region.h"
#include "tfm/tfm_spm_services_api.h"
diff --git a/secure_fw/spm/model_func/tfm_core_svcalls_func.c b/secure_fw/spm/model_func/tfm_core_svcalls_func.c
index 9af7104..afa5c57 100644
--- a/secure_fw/spm/model_func/tfm_core_svcalls_func.c
+++ b/secure_fw/spm/model_func/tfm_core_svcalls_func.c
@@ -11,8 +11,8 @@
#include "tfm/tfm_core_svc.h"
#include "tfm_secure_api.h"
#include "region_defs.h"
-#include "tfm/spm_api.h"
-#include "tfm/spm_partition_defs.h"
+#include "spm_api.h"
+#include "spm_partition_defs.h"
#include "tfm_api.h"
#include "tfm_internal.h"
#include "tfm_memory_utils.h"
diff --git a/secure_fw/spm/model_func/tfm_spm_db_func.inc b/secure_fw/spm/model_func/tfm_spm_db_func.inc
index 6b5c42e..54f2ddb 100644
--- a/secure_fw/spm/model_func/tfm_spm_db_func.inc
+++ b/secure_fw/spm/model_func/tfm_spm_db_func.inc
@@ -10,7 +10,7 @@
#ifndef __TFM_SPM_DB_FUNC_INC__
#define __TFM_SPM_DB_FUNC_INC__
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "psa_manifest/sid.h"
/**************************************************************************/
diff --git a/secure_fw/spm/model_func/tfm_spm_db_func.inc.template b/secure_fw/spm/model_func/tfm_spm_db_func.inc.template
index 55bcce5..8f424b8 100644
--- a/secure_fw/spm/model_func/tfm_spm_db_func.inc.template
+++ b/secure_fw/spm/model_func/tfm_spm_db_func.inc.template
@@ -10,7 +10,7 @@
#ifndef __TFM_SPM_DB_FUNC_INC__
#define __TFM_SPM_DB_FUNC_INC__
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "psa_manifest/sid.h"
{# Produce a build error if heap_size is presented in the manifest, because of the dynamic memory allocation is not supported now. #}
diff --git a/secure_fw/spm/model_func/tfm_veneers.c b/secure_fw/spm/model_func/tfm_veneers.c
index a7a11c5..b58fca5 100644
--- a/secure_fw/spm/model_func/tfm_veneers.c
+++ b/secure_fw/spm/model_func/tfm_veneers.c
@@ -8,7 +8,7 @@
/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
#include "tfm_secure_api.h"
-#include "tfm/spm_partition_defs.h"
+#include "spm_partition_defs.h"
#ifdef TFM_PARTITION_PROTECTED_STORAGE
/******** TFM_SP_PS ********/
diff --git a/secure_fw/spm/model_func/tfm_veneers.c.template b/secure_fw/spm/model_func/tfm_veneers.c.template
index f6b482e..b518164 100644
--- a/secure_fw/spm/model_func/tfm_veneers.c.template
+++ b/secure_fw/spm/model_func/tfm_veneers.c.template
@@ -8,7 +8,7 @@
{{utilities.donotedit_warning}}
#include "tfm_secure_api.h"
-#include "tfm/spm_partition_defs.h"
+#include "spm_partition_defs.h"
{% for manifest in manifests %}
{% if manifest.attr.conditional %}
diff --git a/secure_fw/spm/model_ipc/spm_ipc.c b/secure_fw/spm/model_ipc/spm_ipc.c
index ea1a368..21f1bc6 100644
--- a/secure_fw/spm/model_ipc/spm_ipc.c
+++ b/secure_fw/spm/model_ipc/spm_ipc.c
@@ -20,9 +20,9 @@
#include "tfm_api.h"
#include "tfm_secure_api.h"
#include "tfm_memory_utils.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm_peripherals_def.h"
-#include "tfm/spm_db.h"
+#include "spm_db.h"
#include "tfm_core_utils.h"
#include "spm_psa_client_call.h"
#include "tfm_rpc.h"
diff --git a/secure_fw/spm/model_ipc/spm_psa_client_call.c b/secure_fw/spm/model_ipc/spm_psa_client_call.c
index 58aae56..bf5171e 100644
--- a/secure_fw/spm/model_ipc/spm_psa_client_call.c
+++ b/secure_fw/spm/model_ipc/spm_psa_client_call.c
@@ -6,7 +6,7 @@
*/
#include "psa/service.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm_core_utils.h"
#include "tfm_internal_defines.h"
#include "tfm_memory_utils.h"
diff --git a/secure_fw/spm/model_ipc/tfm_core_svcalls_ipc.c b/secure_fw/spm/model_ipc/tfm_core_svcalls_ipc.c
index 2c07bf4..2db4233 100644
--- a/secure_fw/spm/model_ipc/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/model_ipc/tfm_core_svcalls_ipc.c
@@ -7,8 +7,8 @@
#include <string.h>
#include "region.h"
-#include "tfm/spm_api.h"
-#include "tfm/spm_db.h"
+#include "spm_api.h"
+#include "spm_db.h"
#include "tfm_api.h"
#include "tfm_arch.h"
#include "tfm_core_trustzone.h"
diff --git a/secure_fw/spm/model_ipc/tfm_multi_core_mem_check.c b/secure_fw/spm/model_ipc/tfm_multi_core_mem_check.c
index ff97cf5..55e8e57 100644
--- a/secure_fw/spm/model_ipc/tfm_multi_core_mem_check.c
+++ b/secure_fw/spm/model_ipc/tfm_multi_core_mem_check.c
@@ -9,7 +9,7 @@
#include "tfm_spm_hal.h"
#include "region_defs.h"
#include "secure_utilities.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm_internal.h"
#include "tfm_multi_core.h"
#include "tfm_secure_api.h"
diff --git a/secure_fw/spm/model_ipc/tfm_rpc.c b/secure_fw/spm/model_ipc/tfm_rpc.c
index 073e4f4..f2778aa 100644
--- a/secure_fw/spm/model_ipc/tfm_rpc.c
+++ b/secure_fw/spm/model_ipc/tfm_rpc.c
@@ -5,7 +5,7 @@
*
*/
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "spm_psa_client_call.h"
#include "tfm_rpc.h"
#include "tfm_utils.h"
diff --git a/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc b/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc
index 8618458..0102970 100644
--- a/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc
+++ b/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc
@@ -10,7 +10,7 @@
#ifndef __TFM_SPM_DB_IPC_INC__
#define __TFM_SPM_DB_IPC_INC__
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "psa_manifest/sid.h"
/**************************************************************************/
diff --git a/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc.template b/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc.template
index 4fcd0fb..86390df 100644
--- a/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc.template
+++ b/secure_fw/spm/model_ipc/tfm_spm_db_ipc.inc.template
@@ -10,7 +10,7 @@
#ifndef __TFM_SPM_DB_IPC_INC__
#define __TFM_SPM_DB_IPC_INC__
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "psa_manifest/sid.h"
{# Produce a build error if heap_size is presented in the manifest, because of the dynamic memory allocation is not supported now. #}
diff --git a/secure_fw/spm/model_ipc/tfm_thread.c b/secure_fw/spm/model_ipc/tfm_thread.c
index 1d66e25..74af5a9 100644
--- a/secure_fw/spm/model_ipc/tfm_thread.c
+++ b/secure_fw/spm/model_ipc/tfm_thread.c
@@ -10,7 +10,7 @@
#include "tfm_utils.h"
#include "tfm_memory_utils.h"
#include "tfm/tfm_core_svc.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm_core_utils.h"
/* Force ZERO in case ZI(bss) clear is missing */
diff --git a/secure_fw/spm/runtime/spm_api.c b/secure_fw/spm/runtime/spm_api.c
index 5ff1dc3..22db2ec 100644
--- a/secure_fw/spm/runtime/spm_api.c
+++ b/secure_fw/spm/runtime/spm_api.c
@@ -7,8 +7,8 @@
/* All the APIs defined in this file are common for library and IPC model. */
-#include "tfm/spm_api.h"
-#include "tfm/spm_db.h"
+#include "spm_api.h"
+#include "spm_db.h"
/* Extern SPM variable */
extern struct spm_partition_db_t g_spm_partition_db;
diff --git a/secure_fw/spm/runtime/tfm_core_mem_check.c b/secure_fw/spm/runtime/tfm_core_mem_check.c
index 17ab074..d0983cb 100644
--- a/secure_fw/spm/runtime/tfm_core_mem_check.c
+++ b/secure_fw/spm/runtime/tfm_core_mem_check.c
@@ -7,7 +7,7 @@
#include <arm_cmse.h>
#include "region_defs.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "tfm_api.h"
/**
diff --git a/secure_fw/spm/runtime/tfm_spm_services.c b/secure_fw/spm/runtime/tfm_spm_services.c
index fc3f038..25c6514 100644
--- a/secure_fw/spm/runtime/tfm_spm_services.c
+++ b/secure_fw/spm/runtime/tfm_spm_services.c
@@ -11,7 +11,7 @@
#include "tfm_secure_api.h"
#include "tfm_internal.h"
#include "tfm/tfm_spm_services_api.h"
-#include "tfm/spm_api.h"
+#include "spm_api.h"
#include "psa/service.h"
#ifndef TFM_PSA_API