Interface: Interface provided to NS side

These files provide a reference interface mplementation for integration
with OS running on the NS side. This has been tested to work with
RTX scheduler.
Modifications may be required while integrating other OS.

Change-Id: I4845584465c5df0bc574de31564a0789154c0dd5
Signed-off-by: Ashutosh Singh <ashutosh.singh@arm.com>
Co-Authored-By: Marc Moreno Berengue <marc.morenoberengue@arm.com>
Co-Authored-By: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
new file mode 100644
index 0000000..d911f0c
--- /dev/null
+++ b/interface/include/tfm_api.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_API_H__
+#define __TFM_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* FixMe: sort out DEBUG compile option and limit return value options
+ * on external interfaces */
+/* Note:
+ * TFM will only return values recognized and parsed by TFM core.
+ * Service return codes are not automatically passed on to REE.
+ * Any non-zero return value is interpreted as an error that may trigger
+ * TEE error handling flow.
+ */
+enum tfm_status_e
+{
+    TFM_SUCCESS = 0,
+    TFM_SERVICE_PENDED,
+    TFM_SERVICE_BUSY,
+    TFM_ERROR_SERVICE_ALREADY_PENDED,
+    TFM_ERROR_SECURE_DOMAIN_LOCKED,
+    TFM_ERROR_INVALID_PARAMETER,
+    TFM_ERROR_SERVICE_NON_REENTRANT,
+    TFM_ERROR_NS_THREAD_MODE_CALL,
+    TFM_ERROR_INVALID_EXC_MODE,
+    TFM_SECURE_LOCK_FAILED,
+    TFM_SECURE_UNLOCK_FAILED,
+    TFM_ERROR_GENERIC = 0x1F,
+    TFM_SERVICE_SPECIFIC_ERROR_MIN,
+};
+
+//==================== Secure function declarations ==========================//
+
+/* Placeholder for secure function declarations defined by TF-M in the future */
+
+//================ End Secure function declarations ==========================//
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_API_H__ */
diff --git a/interface/include/tfm_id_mngr.h b/interface/include/tfm_id_mngr.h
new file mode 100644
index 0000000..dafe133
--- /dev/null
+++ b/interface/include/tfm_id_mngr.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_ID_MNGR_H__
+#define __TFM_ID_MNGR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/**
+ * \brief Gets SST current application ID
+ *
+ * \return Returns the SST current application ID
+ */
+uint32_t tfm_sst_get_cur_id(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_ID_MNGR_H__ */
diff --git a/interface/include/tfm_ns_lock.h b/interface/include/tfm_ns_lock.h
new file mode 100644
index 0000000..7361aac
--- /dev/null
+++ b/interface/include/tfm_ns_lock.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_NS_LOCK_H__
+#define __TFM_NS_LOCK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_ns_svc.h"
+
+/**
+ * \brief NS world, NS lock based dispatcher
+ *
+ * \details To be called from the SVC wrapper API interface
+ */
+uint32_t tfm_ns_lock_svc_dispatch(enum tfm_svc_num svc_num,
+                                  uint32_t arg0,
+                                  uint32_t arg1,
+                                  uint32_t arg2,
+                                  uint32_t arg3);
+
+/**
+ * \brief NS world, Init NS lock
+ *
+ * \details Needs to be called during non-secure app init
+ *          to initialize the TFM NS lock object
+ */
+uint32_t tfm_ns_lock_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_LOCK_H__ */
diff --git a/interface/include/tfm_ns_svc.h b/interface/include/tfm_ns_svc.h
new file mode 100644
index 0000000..e83b076
--- /dev/null
+++ b/interface/include/tfm_ns_svc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+#include <cmsis_compiler.h>
+
+#ifndef __TFM_NS_SVC_H__
+#define __TFM_NS_SVC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Macro to encode an svc instruction
+ *
+ */
+#define SVC(code) __ASM("svc %0" : : "I" (code))
+
+/**
+ * \brief Numbers associated to each SVC available
+ *
+ * \details Start from 1 as 0 is reserved by RTX
+ */
+enum tfm_svc_num {
+    SVC_INVALID = 0,
+
+/* SVC API for SST */
+    SVC_TFM_SST_GET_HANDLE,
+    SVC_TFM_SST_CREATE,
+    SVC_TFM_SST_GET_ATTRIBUTES,
+    SVC_TFM_SST_READ,
+    SVC_TFM_SST_WRITE,
+    SVC_TFM_SST_DELETE,
+
+#if defined(CORE_TEST_INTERACTIVE)
+    SVC_SECURE_DECREMENT_NS_LOCK_1,
+    SVC_SECURE_DECREMENT_NS_LOCK_2,
+#endif /* CORE_TEST_INTERACTIVE */
+
+#if defined(CORE_TEST_SERVICES)
+    SVC_TFM_CORE_TEST,
+    SVC_TFM_CORE_TEST_MULTIPLE_CALLS,
+#endif /* CORE_TEST_SERVICES */
+
+    /* add all the new entries above this line */
+    SVC_TFM_MAX,
+};
+
+/* number of user SVC functions */
+#define USER_SVC_COUNT (SVC_TFM_MAX - 1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_SVC_H__ */
diff --git a/interface/include/tfm_sst_api.h b/interface/include/tfm_sst_api.h
new file mode 100644
index 0000000..3cdb64e
--- /dev/null
+++ b/interface/include/tfm_sst_api.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_API__
+#define __TFM_SST_API__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Gets handler for the given asset UUID. If an asset is deleted, the
+ *        linked asset handle reference is no longer valid and will give
+ *        TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in]  asset_uuid  Asset UUID
+ * \param[out] hdl         Pointer to store the asset's handler
+ *
+ * \return Returns TFM_SST_ERR_SUCCESS if asset is found. Otherwise, error code
+ *         as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_get_handle(uint16_t asset_uuid,
+                                      uint32_t* hdl);
+
+/**
+ * \brief Allocates space for the asset, referenced by asset handler,
+ *        without setting any data in the asset.
+ *
+ * \param[in] asset_uuid  Asset UUID
+ *
+ * \return Returns an TFM_SST_ERR_SUCCESS if asset is created correctly.
+ *         Otherwise, error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t  tfm_sst_create(uint16_t asset_uuid);
+
+/**
+ * \brief Gets asset's attributes referenced by asset handler.
+ *        Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in]  asset_handle   Asset handler
+ * \param[out] attrib_struct  Pointer to store the asset's attribute
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_get_attributes(uint32_t asset_handle,
+                                          struct tfm_sst_attribs_t* attrib_struct);
+
+/**
+ * \brief Reads asset's data from asset referenced by asset handler.
+ *
+ * \param[in]  asset_handle   Asset handler
+ * \param[out] data           Pointer to data vector \ref tfm_sst_buf_t to store
+ *                            data, size and offset
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_read(uint32_t asset_handle,
+                                struct tfm_sst_buf_t* data);
+
+/**
+ * \brief Writes data into an asset referenced by asset handler.
+ *
+ * \param[in] asset_handle   Asset handler
+ * \param[in] data           Pointer to data vector \ref tfm_sst_buf_t which
+ *                           contains the data to write
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_write(uint32_t asset_handle,
+                                 struct tfm_sst_buf_t* data);
+
+/**
+ * \brief Deletes the asset referenced by the asset handler.
+ *
+ * \param[in] asset_handle  Asset handler
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_delete(uint32_t asset_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_API__ */
diff --git a/interface/include/tfm_sst_defs.h b/interface/include/tfm_sst_defs.h
new file mode 100644
index 0000000..75e2a16
--- /dev/null
+++ b/interface/include/tfm_sst_defs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_DEFS_H__
+#define __TFM_SST_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <limits.h>
+#include "tfm_api.h"
+
+/* FIXME: the secure APP ID should not be share with the non-secure code
+ *        as it is revealing information about secure code implementation.
+ */
+#define S_APP_ID 0xF0000000
+
+/* FIXME:
+ * Very descriptive error codes can leak implementation
+ * information to caller and may allow exploitation
+ * of implementation weaknesses by malicious actors.
+ * Potential approaches-
+ * a. Just return generic error for any kind of failure
+ *
+ * OR
+ *
+ * b. Non-secure callers get the generic failure, the
+ *    secure side callers get a bit more detailed error
+ *    codes.
+ */
+
+/* The return value is shared with the TFM service status value. The SST return
+ * codes shouldn't overlap with predefined TFM status values.
+ */
+#define TFM_SST_ERR_OFFSET (TFM_SERVICE_SPECIFIC_ERROR_MIN)
+
+enum tfm_sst_err_t {
+    TFM_SST_ERR_SUCCESS = 0,
+    TFM_SST_ERR_ASSET_NOT_PREPARED = TFM_SST_ERR_OFFSET,
+    TFM_SST_ERR_ASSET_NOT_FOUND,
+    TFM_SST_ERR_PARAM_ERROR,
+    TFM_SST_ERR_INVALID_HANDLE,
+    TFM_SST_ERR_STORAGE_SYSTEM_FULL,
+    TFM_SST_ERR_SYSTEM_ERROR,
+    /* Following entry is only to ensure the error code of int size */
+    TFM_SST_ERR_FORCE_INT_SIZE = INT_MAX
+};
+
+struct tfm_sst_attribs_t {
+    uint32_t size_current; /*!< The current size of the asset */
+    uint32_t size_max;     /*!< The maximum size of the asset in bytes */
+};
+
+/* Structure to store data information to read/write from/to asset */
+struct tfm_sst_buf_t {
+    uint8_t* data;   /*!< Address of input/output data */
+    uint32_t size;   /*!< Size of input/output data */
+    uint32_t offset; /*!< Offset within asset */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_DEFS_H__ */
diff --git a/interface/include/tfm_sst_svc_handler.h b/interface/include/tfm_sst_svc_handler.h
new file mode 100644
index 0000000..808c0ea
--- /dev/null
+++ b/interface/include/tfm_sst_svc_handler.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_SVC_HANDLER_H__
+#define __TFM_SST_SVC_HANDLER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_sst_defs.h"
+
+/**
+ * \brief SVC funtion to get handler for the given asset UUID. If an asset is
+ *        deleted, the linked asset handle reference is no longer valid and
+ *        will give TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in]  asset_uuid  Asset UUID
+ * \param[out] hdl         Pointer to store the asset's handler
+ *
+ * \return Returns TFM_SST_ERR_SUCCESS if asset is found. Otherwise, error code
+ *         as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_get_handle(uint16_t asset_uuid,
+                                          uint32_t* hdl);
+
+/**
+ * \brief SVC funtion to allocate space for the asset, referenced by asset
+ *        handler, without setting any data in the asset.
+ *
+ * \param[in] asset_uuid  Asset UUID
+ *
+ * \return Returns an TFM_SST_ERR_SUCCESS if asset is created correctly.
+ *         Otherwise, error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_create(uint16_t asset_uuid);
+
+/**
+ * \brief SVC funtion to get asset's attributes referenced by asset handler.
+ *        Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in]  asset_handle   Asset handler
+ * \param[out] attrib_struct  Pointer to store asset's attribute
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_get_attributes(uint32_t asset_handle,
+                                       struct tfm_sst_attribs_t* attrib_struct);
+
+/**
+ * \brief SVC funtion to read asset's data from asset referenced by asset
+ *        handler.
+ *
+ * \param[in]  asset_handle  Asset handler
+ * \param[out] data          Pointer to data vector \ref tfm_sst_buf_t to store
+ *                           data, size and offset
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_read(uint32_t asset_handle,
+                                    struct tfm_sst_buf_t* data);
+
+/**
+ * \brief SVC funtion to write data into an asset referenced by asset handler.
+ *
+ * \param[in] asset_handle   Asset handler
+ * \param[in] data           Pointer to data vector \ref tfm_sst_buf_t which
+ *                           contains the data to write
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_write(uint32_t asset_handle,
+                                     struct tfm_sst_buf_t* data);
+
+/**
+ * \brief SVC funtion to delete the asset referenced by the asset handler.
+ *
+ * \param[in] asset_handle  Asset handler
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+enum tfm_sst_err_t tfm_sst_svc_delete(uint32_t asset_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_SVC_HANDLER_H__ */
diff --git a/interface/include/tfm_sst_veneers.h b/interface/include/tfm_sst_veneers.h
new file mode 100644
index 0000000..791bbb0
--- /dev/null
+++ b/interface/include/tfm_sst_veneers.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_VENEERS_H__
+#define __TFM_SST_VENEERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_sst_defs.h"
+
+#define __cmse_secure_gateway \
+        __attribute__((cmse_nonsecure_entry, noinline, section("SFN")))
+
+/**
+ * \brief Gets handler for the given asset uuid. If an asset is deleted, the
+ *        linked asset handle reference is no longer valid and will give
+ *        TFM_SST_ERR_ASSET_REF_INVALID if used.
+ *
+ * \param[in]  app_id      Application ID
+ * \param[in]  asset_uuid  Asset UUID
+ * \param[out] hdl         Handle to be returned
+ *
+ * \return Returns asset handle. If asset is not found, it returns
+ *         TFM_SST_ERR_ASSET_NOT_FOUND. If SST area is not prepared, it returns
+ *         TFM_SST_ERR_ASSET_NOT_PREPARED.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_get_handle(uint32_t app_id,
+                                             uint16_t asset_uuid,
+                                             uint32_t *hdl)
+__cmse_secure_gateway;
+
+/**
+ * \brief Allocates space for the asset, referenced by asset handler,
+ *        without setting any data in the asset.
+ *
+ * \param[in] app_id      Application ID
+ * \param[in] asset_uuid  Asset UUID
+ *
+ * \return Returns an asset handle. If SST area is not prepared, it returns
+ *         TFM_SST_ERR_ASSET_NOT_PREPARED. If SST area is full, it returns
+ *         TFM_SST_ERR_STORAGE_SYSTEM_FULL. If application id doesn't have the
+ *         write rights, it returns TFM_SST_ERR_PERMS_NOT_ALLOWED.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_create(uint32_t app_id, uint16_t asset_uuid)
+__cmse_secure_gateway;
+
+/**
+ * \brief Gets asset's attributes referenced by asset handler.
+ *        Uses cached metadata to return the size and write offset of an asset.
+ *
+ * \param[in]  app_id         Application ID
+ * \param[in]  asset_handle   Asset handler
+ * \param[out] attrib_struct  Pointer to asset attribute struct
+ *
+ * \return Returns error code as specified in \ref tfm_sst_err_t
+ */
+extern enum tfm_sst_err_t tfm_sst_veneer_get_attributes(
+                                        uint32_t app_id,
+                                        uint32_t asset_handle,
+                                        struct tfm_sst_attribs_t *attrib_struct)
+__cmse_secure_gateway;
+
+/**
+ * \brief Reads asset's data from asset referenced by asset handler.
+ *
+ * \param[in]     app_id         Application ID
+ * \param[in]     asset_handle   Asset handler
+ * \param[in/out] data           Pointer to data vector \ref tfm_sst_buf_t to
+ *                               store data, size and offset
+ *
+ * \return Returns the number of bytes written or a castable \ref tfm_sst_err_t
+ *         value
+ */
+enum tfm_sst_err_t tfm_sst_veneer_read(uint32_t app_id,
+                                       uint32_t asset_handle,
+                                       struct tfm_sst_buf_t *data)
+__cmse_secure_gateway;
+
+/**
+ * \brief Writes data into an asset referenced by asset handler.
+ *
+ * \param[in] app_id         Application ID
+ * \param[in] asset_handle   Asset handler
+ * \param[in] data           Pointer to data vector \ref tfm_sst_buf_t which
+ *                           contains the data to write
+ *
+ * \return Returns the number of bytes written or a castable \ref tfm_sst_err_t
+ *         value
+ */
+enum tfm_sst_err_t tfm_sst_veneer_write(uint32_t app_id,
+                                        uint32_t asset_handle,
+                                        struct tfm_sst_buf_t *data)
+__cmse_secure_gateway;
+
+/**
+ * \brief Deletes the asset referenced by the asset handler.
+ *
+ * \param[in] app_id        Application ID
+ * \param[in] asset_handle  Asset handler
+ *
+ * \return Returns TFM_SST_ERR_PERMS_NOT_ALLOWED if the asset can't be deleted
+ *         to by this app ID. Returns TFM_SST_ERR_ASSET_REF_INVALID, if asset
+ *         no longer exists. Otherwise, TFM_SST_ERR_SUCCESS.
+ */
+enum tfm_sst_err_t tfm_sst_veneer_delete(uint32_t app_id,
+                                         uint32_t asset_handle)
+__cmse_secure_gateway;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_VENEERS_H__ */
diff --git a/interface/src/tfm_id_mngr_dummy.c b/interface/src/tfm_id_mngr_dummy.c
new file mode 100644
index 0000000..c882c8a
--- /dev/null
+++ b/interface/src/tfm_id_mngr_dummy.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* FIXME: this TFM ID manager is only a stub implementation. It is system
+ * integrators responsibility to define a way of identifying the app id and
+ * based on their non secure side of the threat model. The secure side only
+ * checks if this is an ID belonging to NS side entities. The secure side
+ * doesn't make any attempt to challenge the app id value, this is left for NS
+ * side privileged code to implement.
+ */
+
+#include "tfm_id_mngr.h"
+
+#include <string.h>
+#include "cmsis_os2.h"
+
+#define INVALID_APP_ID  0
+
+/* FIXME: following two functions are meant to be internally
+ * available to RTX. The header file containing prototype of
+ * these functions has complex header inclusion which leads
+ * to compiler specific paths in CMSIS, which currently doesn't have
+ * clang variant. To simplify this, following functions are directly
+ * declared here (as opposed to header inclusion). After clear
+ * separation of S and NS builds this will require to be revisited
+ */
+extern osThreadId_t svcRtxThreadGetId(void);
+extern const char *svcRtxThreadGetName(osThreadId_t thread_id);
+
+/* Translation table pair between OS threads and SST app IDs */
+struct thread_sst_appid_pair {
+    const char* t_name;  /*!< Task/Thread name */
+    uint32_t    app_id;  /*!< Application ID used in assets definition */
+};
+
+static struct thread_sst_appid_pair sst_ns_policy_table[] =
+{
+    {"Thread_A", 9},
+    {"Thread_B", 10},
+    {"Thread_C", 11},
+};
+
+static const char* get_active_task_name(void)
+{
+    const char* thread_name;
+
+    thread_name = svcRtxThreadGetName(svcRtxThreadGetId());
+
+    return thread_name;
+}
+
+uint32_t tfm_sst_get_cur_id(void)
+{
+    uint32_t i;
+    static uint32_t sst_table_size = (sizeof(sst_ns_policy_table) /
+                                      sizeof(sst_ns_policy_table[0]));
+    const char* p_thread_name;
+
+    p_thread_name = get_active_task_name();
+
+    for (i = 0; i < sst_table_size; i++) {
+        if (strcmp(sst_ns_policy_table[i].t_name, p_thread_name) == 0) {
+                return sst_ns_policy_table[i].app_id;
+        }
+    }
+
+    return INVALID_APP_ID;
+}
diff --git a/interface/src/tfm_ns_lock_rtx.c b/interface/src/tfm_ns_lock_rtx.c
new file mode 100644
index 0000000..cf5fd6d
--- /dev/null
+++ b/interface/src/tfm_ns_lock_rtx.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cmsis.h"
+#include "cmsis_os2.h"
+
+#include "tfm_api.h"
+#include "tfm_ns_svc.h"
+
+/**
+ * \brief struct ns_lock_state type
+ */
+struct ns_lock_state
+{
+    bool        init;
+    osMutexId_t id;
+};
+
+/**
+ * \brief ns_lock status
+ */
+static struct ns_lock_state ns_lock = {.init=false, .id=NULL};
+
+/**
+ * \brief Mutex properties, NS lock
+ */
+static const osMutexAttr_t ns_lock_attrib = {
+    .name = "ns_lock",
+    .attr_bits = osMutexPrioInherit
+};
+
+/**
+ * \def NUM_SVC_DISPATCHERS
+ *
+ */
+#define NUM_SVC_DISPATCHERS (6)
+
+/**
+ * \brief Naked functions associated to each
+ *        SVC needed
+ */
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_GET_HANDLE(uint32_t arg0, uint32_t arg1,
+                                                uint32_t arg2, uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_GET_HANDLE);
+    __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_CREATE(uint32_t arg0, uint32_t arg1,
+                                                uint32_t arg2, uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_CREATE);
+    __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_GET_ATTRIBUTES(uint32_t arg0,uint32_t arg1,
+                                                    uint32_t arg2,uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_GET_ATTRIBUTES);
+    __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_READ(uint32_t arg0, uint32_t arg1,
+                                              uint32_t arg2, uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_READ);
+    __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_WRITE(uint32_t arg0, uint32_t arg1,
+                                               uint32_t arg2, uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_WRITE);
+    __ASM("BX LR");
+}
+
+__attribute__((naked))
+static uint32_t tfm_svc_dispatch_SST_DELETE(uint32_t arg0, uint32_t arg1,
+                                                uint32_t arg2, uint32_t arg3)
+{
+    SVC(SVC_TFM_SST_DELETE);
+    __ASM("BX LR");
+}
+
+/**
+ * \brief Array with function pointers to the
+ *        naked functions. Entry 0 is treated
+*         as invalid
+ */
+static void *tfm_svc_dispatch_functions[NUM_SVC_DISPATCHERS+1] = {
+    (void *) NULL, /* SVC_INVALID */
+    (void *) tfm_svc_dispatch_SST_GET_HANDLE,
+    (void *) tfm_svc_dispatch_SST_CREATE,
+    (void *) tfm_svc_dispatch_SST_GET_ATTRIBUTES,
+    (void *) tfm_svc_dispatch_SST_READ,
+    (void *) tfm_svc_dispatch_SST_WRITE,
+    (void *) tfm_svc_dispatch_SST_DELETE
+};
+
+/**
+ * \brief NS world, NS lock based dispatcher
+ */
+uint32_t tfm_ns_lock_svc_dispatch(enum tfm_svc_num svc_num,
+                                  uint32_t arg0,
+                                  uint32_t arg1,
+                                  uint32_t arg2,
+                                  uint32_t arg3)
+{
+    uint32_t result;
+    uint32_t (*tfm_svc_dispatch_function_p)(uint32_t, uint32_t,
+                                                uint32_t, uint32_t);
+
+    /* Check the NS lock has been initialized */
+    if (ns_lock.init == false) {
+        return TFM_ERROR_GENERIC;
+    }
+
+    /* Validate the SVC number requested */
+    if ((svc_num > SVC_INVALID) && (svc_num < (NUM_SVC_DISPATCHERS+1))) {
+        tfm_svc_dispatch_function_p = tfm_svc_dispatch_functions[svc_num];
+
+        /* TFM request protected by NS lock */
+        osMutexAcquire(ns_lock.id,osWaitForever);
+        result = (*tfm_svc_dispatch_function_p)(arg0, arg1, arg2, arg3);
+        osMutexRelease(ns_lock.id);
+
+        return result;
+    }
+    else {
+        return TFM_ERROR_GENERIC;
+    }
+}
+
+/**
+ * \brief NS world, Init NS lock
+ */
+uint32_t tfm_ns_lock_init()
+{
+    if (ns_lock.init == false) {
+        ns_lock.id = osMutexNew(&ns_lock_attrib);
+        ns_lock.init = true;
+        return TFM_SUCCESS;
+    }
+    else {
+        return TFM_ERROR_GENERIC;
+    }
+}
diff --git a/interface/src/tfm_sst_api.c b/interface/src/tfm_sst_api.c
new file mode 100644
index 0000000..fb13ed0
--- /dev/null
+++ b/interface/src/tfm_sst_api.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_sst_defs.h"
+#include "tfm_ns_lock.h"
+
+enum tfm_sst_err_t tfm_sst_get_handle(uint16_t asset_uuid, uint32_t* hdl)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_GET_HANDLE,
+                                    (uint32_t)asset_uuid,
+                                    (uint32_t)hdl,
+                                    0,
+                                    0);
+}
+
+enum tfm_sst_err_t tfm_sst_create(uint16_t asset_uuid)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_CREATE,
+                                    (uint32_t) asset_uuid,
+                                    0,
+                                    0,
+                                    0);
+}
+
+enum tfm_sst_err_t tfm_sst_get_attributes(uint32_t asset_handle,
+                                        struct tfm_sst_attribs_t* attrib_struct)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_GET_ATTRIBUTES,
+                                    (uint32_t)asset_handle,
+                                    (uint32_t)attrib_struct,
+                                    0,
+                                    0);
+}
+
+enum tfm_sst_err_t tfm_sst_read(uint32_t asset_handle, struct tfm_sst_buf_t* data)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_READ,
+                                    (uint32_t)asset_handle,
+                                    (uint32_t)data,
+                                    0,
+                                    0);
+}
+
+enum tfm_sst_err_t tfm_sst_write(uint32_t asset_handle, struct tfm_sst_buf_t* data)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_WRITE,
+                                    (uint32_t)asset_handle,
+                                    (uint32_t)data,
+                                    0,
+                                    0);
+}
+
+enum tfm_sst_err_t tfm_sst_delete(uint32_t asset_handle)
+{
+    return tfm_ns_lock_svc_dispatch(SVC_TFM_SST_DELETE,
+                                    (uint32_t)asset_handle,
+                                    0,
+                                    0,
+                                    0);
+}
diff --git a/interface/src/tfm_sst_svc_handler.c b/interface/src/tfm_sst_svc_handler.c
new file mode 100644
index 0000000..c10432e
--- /dev/null
+++ b/interface/src/tfm_sst_svc_handler.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+#include "tfm_ns_svc.h"
+#include "tfm_sst_veneers.h"
+#include "tfm_id_mngr.h"
+
+/* SVC function implementations */
+enum tfm_sst_err_t tfm_sst_svc_get_handle(uint16_t asset_uuid,
+                                          uint32_t* hdl)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_get_handle(app_id, asset_uuid, hdl);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_create(uint16_t asset_uuid)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_create(app_id, asset_uuid);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_get_attributes(uint32_t asset_handle,
+                                        struct tfm_sst_attribs_t* attrib_struct)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_get_attributes(app_id, asset_handle, attrib_struct);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_read(uint32_t asset_handle,
+                                    struct tfm_sst_buf_t* data)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_read(app_id, asset_handle, data);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_write(uint32_t asset_handle,
+                                     struct tfm_sst_buf_t* data)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_write(app_id, asset_handle, data);
+}
+
+enum tfm_sst_err_t tfm_sst_svc_delete(uint32_t asset_handle)
+{
+    uint32_t app_id;
+
+    app_id = tfm_sst_get_cur_id();
+
+    return tfm_sst_veneer_delete(app_id, asset_handle);
+}