Core: Add veneer for registering NS client id
Change-Id: I4b8d826ca1b7f07dcbc2e82e10bd11cee01da1fc
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/interface/include/tfm_api.h b/interface/include/tfm_api.h
index 64a9447..c450c7c 100644
--- a/interface/include/tfm_api.h
+++ b/interface/include/tfm_api.h
@@ -12,6 +12,8 @@
extern "C" {
#endif
+#include <stdint.h>
+
/* FixMe: sort out DEBUG compile option and limit return value options
* on external interfaces */
/* Note:
@@ -39,7 +41,17 @@
//==================== Secure function declarations ==========================//
-/* Placeholder for secure function declarations defined by TF-M in the future */
+/**
+ * \brief Assign client ID to the current TZ context
+ *
+ * \param[in] ns_client_id The client ID to be assigned to the current
+ * context
+ * \return TFM_SUCCESS if the client ID assigned successfully, an error code
+ * according to \ref tfm_status_e in case of error.
+ *
+ * \note This function have to be called from handler mode.
+ */
+enum tfm_status_e tfm_register_client_id (int32_t ns_client_id);
//================ End Secure function declarations ==========================//
diff --git a/secure_fw/core/tfm_nspm.c b/secure_fw/core/tfm_nspm.c
index 76ba608..e4e3a18 100644
--- a/secure_fw/core/tfm_nspm.c
+++ b/secure_fw/core/tfm_nspm.c
@@ -7,12 +7,18 @@
#include <stdio.h>
#include "secure_utilities.h"
+#include "tfm_api.h"
#ifndef TFM_MAX_NS_THREAD_COUNT
#define TFM_MAX_NS_THREAD_COUNT 8
#endif
#define INVALID_CLIENT_ID 0
+#define CLIENT_ID_RANGE_START ((int32_t)-1)
+
+#define INVALID_NS_CLIENT_IDX (-1)
+#define DEFAULT_NS_CLIENT_IDX 0
+
typedef uint32_t TZ_ModuleId_t;
typedef uint32_t TZ_MemoryId_t;
@@ -21,9 +27,19 @@
int32_t next_free_index;
} NsClientIdList[TFM_MAX_NS_THREAD_COUNT];
-static int32_t next_ns_client_id = -1;
static int32_t free_index = 0U;
-static int32_t active_ns_client = INVALID_CLIENT_ID;
+static int32_t active_ns_client_idx = INVALID_NS_CLIENT_IDX;
+
+static int get_next_ns_client_id()
+{
+ static int32_t next_ns_client_id = CLIENT_ID_RANGE_START;
+
+ if (next_ns_client_id > 0)
+ {
+ next_ns_client_id = CLIENT_ID_RANGE_START;
+ }
+ return next_ns_client_id--;
+}
void tfm_nspm_configure_clients(void)
{
@@ -31,10 +47,21 @@
/* Default to one NS client */
free_index = 1;
- NsClientIdList[0].ns_client_id = next_ns_client_id--;
+ NsClientIdList[0].ns_client_id = get_next_ns_client_id();
for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
}
+ active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
+}
+
+int32_t tfm_nspm_get_current_client_id()
+{
+ if (active_ns_client_idx == INVALID_NS_CLIENT_IDX)
+ {
+ return 0;
+ } else {
+ return NsClientIdList[active_ns_client_idx].ns_client_id;
+ }
}
/* TF-M implementation of the CMSIS TZ RTOS thread context management API */
@@ -53,15 +80,16 @@
}
/* NS RTOS supports TZ context management, override defaults */
+#ifdef PRINT_NSPM_DEBUG
LOG_MSG("NS RTOS initialized TZ RTOS context management");
- for (i = 0; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
+#endif /* PRINT_NSPM_DEBUG */
+ for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
NsClientIdList[i].next_free_index = i + 1;
}
/* Terminate list */
- NsClientIdList[i - 1].next_free_index = -1;
- free_index = 0;
+ NsClientIdList[i - 1].next_free_index = INVALID_NS_CLIENT_IDX;
/* Success */
return 1U;
}
@@ -90,9 +118,11 @@
/* TZ_MemoryId_t must be a positive integer */
tz_id = free_index + 1;
- NsClientIdList[free_index].ns_client_id = next_ns_client_id--;
+ NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
+#ifdef PRINT_NSPM_DEBUG
printf("TZ_AllocModuleContext_S called, returning id %d\r\n",
NsClientIdList[free_index].ns_client_id);
+#endif /* PRINT_NSPM_DEBUG */
free_index = NsClientIdList[free_index].next_free_index;
return tz_id;
@@ -125,11 +155,15 @@
return 0U;
}
+#ifdef PRINT_NSPM_DEBUG
printf("TZ_FreeModuleContext_S called for id %d\r\n",
NsClientIdList[index].ns_client_id);
- if (active_ns_client == NsClientIdList[index].ns_client_id) {
+#endif /* PRINT_NSPM_DEBUG */
+ if (active_ns_client_idx == index) {
+#ifdef PRINT_NSPM_DEBUG
printf("Freeing active NS client, NS inactive\r\n");
- active_ns_client = INVALID_CLIENT_ID;
+#endif /* PRINT_NSPM_DEBUG */
+ active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
}
NsClientIdList[index].ns_client_id = INVALID_CLIENT_ID;
NsClientIdList[index].next_free_index = free_index;
@@ -154,7 +188,9 @@
return 0U;
}
+#ifdef PRINT_NSPM_DEBUG
LOG_MSG("TZ_LoadContext_S called");
+#endif /* PRINT_NSPM_DEBUG */
if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
/* Invalid TZ_MemoryId_t */
return 0U;
@@ -167,9 +203,11 @@
return 0U;
}
- active_ns_client = NsClientIdList[index].ns_client_id;
+ active_ns_client_idx = index;
+#ifdef PRINT_NSPM_DEBUG
printf("TZ_LoadContext_S called for id %d\r\n",
NsClientIdList[index].ns_client_id);
+#endif /* PRINT_NSPM_DEBUG */
return 1U; // Success
}
@@ -189,7 +227,9 @@
return 0U;
}
+#ifdef PRINT_NSPM_DEBUG
LOG_MSG("TZ_StoreContext_S called");
+#endif /* PRINT_NSPM_DEBUG */
/* id corresponds to context being swapped out on NS side */
if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
/* Invalid TZ_MemoryId_t */
@@ -203,15 +243,54 @@
return 0U;
}
- if (active_ns_client != NsClientIdList[index].ns_client_id) {
+ if (active_ns_client_idx != index) {
+#ifdef PRINT_NSPM_DEBUG
printf("TZ_StoreContext_S called for id %d, active id: %d\r\n",
- NsClientIdList[index].ns_client_id, active_ns_client);
+ NsClientIdList[index].ns_client_id,
+ NsClientIdList[active_ns_client_idx].ns_client_id);
+#endif /* PRINT_NSPM_DEBUG */
return 0U;
}
+#ifdef PRINT_NSPM_DEBUG
printf("TZ_StoreContext_S called for id %d\r\n",
NsClientIdList[index].ns_client_id);
- active_ns_client = INVALID_CLIENT_ID;
+#endif /* PRINT_NSPM_DEBUG */
+ active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
return 1U; // Success
}
+
+__attribute__((cmse_nonsecure_entry))
+enum tfm_status_e tfm_register_client_id (int32_t ns_client_id)
+{
+ int current_client_id;
+
+ if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
+ /* This veneer should only be called by NS RTOS in handler mode */
+ return TFM_ERROR_NS_THREAD_MODE_CALL;
+ }
+
+ if (ns_client_id >= 0) {
+ /* The client ID is invalid */
+ return TFM_ERROR_INVALID_PARAMETER;
+ }
+
+ if (active_ns_client_idx < 0) {
+ /* No client is active */
+ return TFM_ERROR_GENERIC;
+ }
+
+ current_client_id = NsClientIdList[active_ns_client_idx].ns_client_id;
+ if (current_client_id >= 0 ) {
+ /* The client ID is invalid */
+ return TFM_ERROR_INVALID_PARAMETER;
+ }
+
+ NsClientIdList[active_ns_client_idx].ns_client_id = ns_client_id;
+#ifdef PRINT_NSPM_DEBUG
+ printf("tfm_register_client_id called with id %d\r\n", ns_client_id);
+#endif /* PRINT_NSPM_DEBUG */
+
+ return TFM_SUCCESS;
+}
diff --git a/secure_fw/core/tfm_nspm.h b/secure_fw/core/tfm_nspm.h
new file mode 100644
index 0000000..b485462
--- /dev/null
+++ b/secure_fw/core/tfm_nspm.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_NSPM_H__
+#define __TFM_NSPM_H__
+
+#include <stdint.h>
+
+/**
+ * \brief initialise the NS context database
+ */
+void tfm_nspm_configure_clients(void);
+
+/**
+ * \brief Get the client ID of the current NS client
+ *
+ * \return The client id of the current NS client. 0 (invalid client id) is
+ * returned in case of error.
+ */
+int32_t tfm_nspm_get_current_client_id(void);
+
+#endif /* __TFM_NSPM_H__ */
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index 7b96b11..ff68245 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -14,6 +14,7 @@
#include "spm_db_setup.h"
#include "tfm_internal.h"
#include "tfm_api.h"
+#include "tfm_nspm.h"
#include "secure_fw/core/tfm_core.h"
#include "platform_retarget.h"
#include "tfm_peripherals_def.h"
@@ -66,9 +67,6 @@
return SPM_INVALID_PARTITION_IDX;
}
-/* FixMe: this should be in a header */
-extern void tfm_nspm_configure_clients(void);
-
enum spm_err_t tfm_spm_db_init(void)
{
struct spm_partition_desc_t *part_ptr;