Core: use secure partition context for its init
- set appropriate stack pointer for partition init
- move target-independent init code to TF-M core
- set unprivileged execution for init functions if
privilege handling is enabled
- fix naming convention bug related to spm_api.h
- fix header reference for partition ids
Change-Id: I56fe20a247ecde20047658d3227ae95257c95e0f
Signed-off-by: Miklos Balint <miklos.balint@arm.com>
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index f48e9fc..6b64ce1 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -6,7 +6,9 @@
*/
#include <stdio.h>
+#include "region_defs.h"
#include "tfm_core.h"
+#include "tfm_internal.h"
#include "target_cfg.h"
#include "uart_stdout.h"
#include "secure_utilities.h"
@@ -86,6 +88,25 @@
#endif
}
+void configure_ns_code(void)
+{
+ /* SCB_NS.VTOR points to the Non-secure vector table base address */
+ SCB_NS->VTOR = (NS_CODE_START);
+
+ /* Setups Main stack pointer of the non-secure code */
+ uint32_t ns_msp = *((uint32_t *)(NS_CODE_START));
+
+ __TZ_set_MSP_NS(ns_msp);
+
+ /* The entry contains address of the Reset_handler (CMSIS-CORE) function */
+ uint32_t entry_ptr = *((uint32_t *)(NS_CODE_START + 4));
+
+ /* Clears LSB of the function address to indicate the function-call
+ * will perform the switch from secure to non-secure
+ */
+ ns_entry = (nsfptr_t) (entry_ptr & (~0x1));
+}
+
int32_t tfm_core_init(void)
{
/* Enables fault handlers */
@@ -130,20 +151,25 @@
tfm_spm_db_init();
#if TFM_LVL != 1
- tfm_spm_mpu_init();
-#endif
- if (tfm_spm_partition_init() != SPM_ERR_OK) {
- /* Certain systems might refuse to boot altogether if partitions fail
- * to initialize. This is a placeholder for such an error handler
- */
+ if (tfm_spm_mpu_init() != SPM_ERR_OK) {
+ ERROR_MSG("Failed to set up initial MPU configuration! Halting.");
+ while (1) {
+ ;
+ }
}
-
+#endif
tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING);
extern uint32_t Stack_Mem[];
__set_PSPLIM((uint32_t)Stack_Mem);
+ if (tfm_spm_partition_init() != SPM_ERR_OK) {
+ /* Certain systems might refuse to boot altogether if partitions fail
+ * to initialize. This is a placeholder for such an error handler
+ */
+ }
+
#ifdef TEST_FRAMEWORK_S
start_integ_test();
#endif
@@ -153,22 +179,6 @@
LOG_MSG("Jumping to non-secure code...");
#endif
-#if TFM_LVL != 1
- /* FixMe: partition MPU regions need to be overloaded for snippet of
- * code jumping to NS to work in unprivileged thread mode
- */
-#ifdef UNPRIV_JUMP_TO_NS
- /* Initialization is done, set thread mode to unprivileged. */
- CONTROL_Type ctrl;
-
- ctrl.w = __get_CONTROL();
- ctrl.b.nPRIV = 1;
- __set_CONTROL(ctrl.w);
- __DSB();
- __ISB();
-#endif
-#endif
-
/* We close the TFM_SP_CORE_ID partition, because its only purpose is
* to be able to pass the state checks for the tests started from secure.
*/
diff --git a/secure_fw/core/tfm_internal.h b/secure_fw/core/tfm_internal.h
new file mode 100644
index 0000000..a25bde6
--- /dev/null
+++ b/secure_fw/core/tfm_internal.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_INTERNAL_H__
+#define __TFM_INTERNAL_H__
+
+/*
+ * This function pointer is meant to only hold non secure function pointers.
+ * It will be turned into a non-secure one (LSB cleared) before being called
+ * whatever happens anyway (unless cast to another function pointer type).
+ * Registers will be cleared before branching so that no information leaks
+ * from secure to non-secure world.
+ */
+typedef void __attribute__((cmse_nonsecure_call)) (*nsfptr_t) (void);
+
+extern nsfptr_t ns_entry;
+
+void tfm_secure_api_init_done(void);
+
+/**
+ * \brief Jumps to non-secure code.
+ */
+void jump_to_ns_code(void);
+
+#endif /* __TFM_INTERNAL_H__ */
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index f691743..eb0d0b2 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -39,6 +39,7 @@
* to SPE
*/
static int32_t tfm_secure_lock;
+static int32_t tfm_secure_api_init = 1;
static uint32_t *prepare_partition_ctx(
struct tfm_sfn_req_s *desc_ptr, uint32_t *dst)
@@ -57,7 +58,7 @@
while (i > 0) {
i--;
- *(--dst) = desc_ptr->args[i];
+ *(--dst) = (uint32_t)desc_ptr->args[i];
}
return dst;
}
@@ -72,7 +73,9 @@
uint32_t psp;
uint32_t partition_psp, partition_psplim;
uint32_t partition_state;
+ uint32_t partition_flags;
+ /* Check partition idx validity */
if (caller_partition_idx == SPM_INVALID_PARTITION_IDX) {
return TFM_SECURE_LOCK_FAILED;
}
@@ -80,94 +83,112 @@
caller_flags = tfm_spm_partition_get_flags(caller_partition_idx);
/* Check partition state consistency */
- if (((caller_flags&SPM_PART_FLAG_SECURE) != 0) == (!desc_ptr->ns_caller)) {
- partition_idx = get_partition_idx(desc_ptr->ss_id);
- psp = __get_PSP();
- curr_part_data = tfm_spm_partition_get_runtime_data(partition_idx);
- partition_state = curr_part_data->partition_state;
-
- if (partition_state == SPM_PARTITION_STATE_RUNNING ||
- partition_state == SPM_PARTITION_STATE_SUSPENDED ||
- partition_state == SPM_PARTITION_STATE_BLOCKED) {
- /* Recursion is not permitted! */
- return TFM_ERROR_PARTITION_NON_REENTRANT;
- } else if (partition_state != SPM_PARTITION_STATE_IDLE) {
- /* The partition to be called is not in a proper state */
- return TFM_SECURE_LOCK_FAILED;
- }
-
-#if TFM_LVL == 1
- /* Prepare switch to shared secure partition stack */
- partition_psp =
- (uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
- partition_psplim =
- (uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
-#else
- if (caller_flags&SPM_PART_FLAG_SECURE) {
- /* Store the caller PSP in case we are doing a partition to
- * partition call
- */
- tfm_spm_partition_set_stack(caller_partition_idx, psp);
- }
- partition_psp = curr_part_data->stack_ptr;
- partition_psplim = tfm_spm_partition_get_stack_bottom(partition_idx);
-#endif
- /* Stack the context for the partition call */
- tfm_spm_partition_set_orig_psp(partition_idx, psp);
- tfm_spm_partition_set_orig_psplim(partition_idx, __get_PSPLIM());
- tfm_spm_partition_set_orig_lr(partition_idx, lr);
- tfm_spm_partition_set_caller_partition_id(partition_idx,
- caller_partition_idx);
-
-#if (TFM_LVL != 1) && (TFM_LVL != 2)
- /* Dynamic partition partitioning is only done is TFM level 3 */
- if (caller_flags&SPM_PART_FLAG_SECURE) {
- /* In a partition to partition call, deconfigure the
- * caller partition
- */
- tfm_spm_partition_sandbox_deconfig(caller_partition_idx);
- }
-
- /* Configure partition execution environment */
- tfm_spm_partition_sandbox_config(partition_idx);
-#endif
-
- /* Default share to scratch area in case of partition to partition calls
- * this way partitions always get default access to input buffers
- */
- /* FixMe: return value/error handling TBD */
- tfm_spm_partition_set_share(partition_idx, desc_ptr->ns_caller ?
- TFM_BUFFER_SHARE_NS_CODE : TFM_BUFFER_SHARE_SCRATCH);
-
-#if TFM_LVL == 1
- /* In level one, only switch context and return from exception if in
- * handler mode
- */
- if (desc_ptr->exc_num != EXC_NUM_THREAD_MODE) {
- /* Prepare the partition context, update stack ptr */
- psp = (uint32_t)prepare_partition_ctx(
- desc_ptr, (uint32_t *)partition_psp);
- __set_PSP(psp);
- __set_PSPLIM(partition_psplim);
- }
-#else
- /* Prepare the partition context, update stack ptr */
- psp = (uint32_t)prepare_partition_ctx(desc_ptr,
- (uint32_t *)partition_psp);
- __set_PSP(psp);
- __set_PSPLIM(partition_psplim);
-#endif
-
- tfm_spm_partition_set_state(caller_partition_idx,
- SPM_PARTITION_STATE_BLOCKED);
- tfm_spm_partition_set_state(partition_idx, SPM_PARTITION_STATE_RUNNING);
- tfm_secure_lock++;
-
- return TFM_SUCCESS;
- } else {
- /* Secure partition stacking limit exceeded */
+ if (((caller_flags&SPM_PART_FLAG_SECURE) != 0) != (!desc_ptr->ns_caller)) {
+ /* Partition state inconsistency detected */
return TFM_SECURE_LOCK_FAILED;
}
+
+ partition_idx = get_partition_idx(desc_ptr->sp_id);
+ psp = __get_PSP();
+
+ curr_part_data = tfm_spm_partition_get_runtime_data(partition_idx);
+ partition_state = curr_part_data->partition_state;
+ partition_flags = tfm_spm_partition_get_flags(partition_idx);
+
+ if ((tfm_secure_api_init) &&
+ (tfm_spm_partition_get_partition_id(caller_partition_idx)
+ == TFM_SP_CORE_ID) &&
+ (partition_state == SPM_PARTITION_STATE_UNINIT)) {
+#if TFM_LVL != 1
+ /* Make thread mode unprivileged while untrusted partition init is
+ * executed
+ */
+ if ((partition_flags & SPM_PART_FLAG_TRUSTED) == 0) {
+ CONTROL_Type ctrl;
+
+ ctrl.w = __get_CONTROL();
+ ctrl.b.nPRIV = 1;
+ __set_CONTROL(ctrl.w);
+ __DSB();
+ __ISB();
+ }
+#endif
+ } else if (partition_state == SPM_PARTITION_STATE_RUNNING ||
+ partition_state == SPM_PARTITION_STATE_SUSPENDED ||
+ partition_state == SPM_PARTITION_STATE_BLOCKED) {
+ /* Recursion is not permitted! */
+ return TFM_ERROR_PARTITION_NON_REENTRANT;
+ } else if (partition_state != SPM_PARTITION_STATE_IDLE) {
+ /* The partition to be called is not in a proper state */
+ return TFM_SECURE_LOCK_FAILED;
+ }
+
+#if TFM_LVL == 1
+ /* Prepare switch to shared secure partition stack */
+ partition_psp =
+ (uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
+ partition_psplim =
+ (uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
+#else
+ if (caller_flags&SPM_PART_FLAG_SECURE) {
+ /* Store the caller PSP in case we are doing a partition to
+ * partition call
+ */
+ tfm_spm_partition_set_stack(caller_partition_idx, psp);
+ }
+ partition_psp = curr_part_data->stack_ptr;
+ partition_psplim = tfm_spm_partition_get_stack_bottom(partition_idx);
+#endif
+ /* Stack the context for the partition call */
+ tfm_spm_partition_set_orig_psp(partition_idx, psp);
+ tfm_spm_partition_set_orig_psplim(partition_idx, __get_PSPLIM());
+ tfm_spm_partition_set_orig_lr(partition_idx, lr);
+ tfm_spm_partition_set_caller_partition_idx(partition_idx,
+ caller_partition_idx);
+
+#if (TFM_LVL != 1) && (TFM_LVL != 2)
+ /* Dynamic partitioning is only done is TFM level 3 */
+ tfm_spm_partition_sandbox_deconfig(caller_partition_idx);
+
+ /* Configure partition execution environment */
+ if (tfm_spm_partition_sandbox_config(partition_idx) != SPM_ERR_OK) {
+ ERROR_MSG("Failed to configure sandbox for partition!");
+ tfm_secure_api_error_handler();
+ }
+#endif
+
+ /* Default share to scratch area in case of partition to partition calls
+ * this way partitions always get default access to input buffers
+ */
+ /* FixMe: return value/error handling TBD */
+ tfm_spm_partition_set_share(partition_idx, desc_ptr->ns_caller ?
+ TFM_BUFFER_SHARE_NS_CODE : TFM_BUFFER_SHARE_SCRATCH);
+
+#if TFM_LVL == 1
+ /* In level one, only switch context and return from exception if in
+ * handler mode
+ */
+ if ((desc_ptr->exc_num != EXC_NUM_THREAD_MODE) || (tfm_secure_api_init)) {
+ /* Prepare the partition context, update stack ptr */
+ psp = (uint32_t)prepare_partition_ctx(
+ desc_ptr, (uint32_t *)partition_psp);
+ __set_PSP(psp);
+ __set_PSPLIM(partition_psplim);
+ }
+#else
+ /* Prepare the partition context, update stack ptr */
+ psp = (uint32_t)prepare_partition_ctx(desc_ptr,
+ (uint32_t *)partition_psp);
+ __set_PSP(psp);
+ __set_PSPLIM(partition_psplim);
+#endif
+
+ tfm_spm_partition_set_state(caller_partition_idx,
+ SPM_PARTITION_STATE_BLOCKED);
+ tfm_spm_partition_set_state(partition_idx, SPM_PARTITION_STATE_RUNNING);
+ tfm_secure_lock++;
+
+ return TFM_SUCCESS;
}
static int32_t tfm_pop_lock(uint32_t *lr_ptr)
@@ -175,6 +196,7 @@
uint32_t current_partition_idx =
tfm_spm_partition_get_running_partition_idx();
const struct spm_partition_runtime_data_t *curr_part_data;
+ uint32_t current_partition_flags;
uint32_t return_partition_idx;
uint32_t return_partition_flags;
#if TFM_LVL != 1
@@ -193,26 +215,50 @@
}
return_partition_flags = tfm_spm_partition_get_flags(return_partition_idx);
+ current_partition_flags = tfm_spm_partition_get_flags(
+ current_partition_idx);
tfm_secure_lock--;
#if (TFM_LVL != 1) && (TFM_LVL != 2)
/* Deconfigure completed partition environment */
tfm_spm_partition_sandbox_deconfig(current_partition_idx);
- if (return_partition_flags&SPM_PART_FLAG_SECURE) {
- /* Configure the caller partition environment in case this was a
- * partition to partition call
+ if (tfm_secure_api_init) {
+ /* Restore privilege for thread mode during TF-M init. This is only
+ * have to be done if the partition is not trusted.
*/
- tfm_spm_partition_sandbox_config(return_partition_idx);
- /* Restore share status */
- tfm_spm_partition_set_share(return_partition_idx,
- tfm_spm_partition_get_runtime_data(return_partition_idx)->share);
+ if ((current_partition_flags & SPM_PART_FLAG_TRUSTED) == 0) {
+ CONTROL_Type ctrl;
+
+ ctrl.w = __get_CONTROL();
+ ctrl.b.nPRIV = 0;
+ __set_CONTROL(ctrl.w);
+ __DSB();
+ __ISB();
+ }
+ } else {
+ /* Configure the caller partition environment in case this was a
+ * partition to partition call and returning to untrusted partition
+ */
+ if (tfm_spm_partition_sandbox_config(return_partition_idx)
+ != SPM_ERR_OK) {
+ ERROR_MSG("Failed to configure sandbox for partition!");
+ tfm_secure_api_error_handler();
+ }
+ if (return_partition_flags&SPM_PART_FLAG_SECURE) {
+ /* Restore share status */
+ tfm_spm_partition_set_share(
+ return_partition_idx,
+ tfm_spm_partition_get_runtime_data(
+ return_partition_idx)->share);
+ }
}
#endif
#if TFM_LVL == 1
- if (!(return_partition_flags&SPM_PART_FLAG_SECURE)) {
+ if (!(return_partition_flags&SPM_PART_FLAG_SECURE) ||
+ (tfm_secure_api_init)) {
/* In TFM level 1 context restore is only done when
- * returning to NS
+ * returning to NS or after initialization
*/
/* Restore caller PSP and LR ptr */
__set_PSP(curr_part_data->orig_psp);
@@ -237,6 +283,8 @@
tfm_spm_partition_set_state(current_partition_idx,
SPM_PARTITION_STATE_IDLE);
+ tfm_spm_partition_set_caller_partition_idx(current_partition_idx,
+ SPM_INVALID_PARTITION_IDX);
tfm_spm_partition_set_state(return_partition_idx,
SPM_PARTITION_STATE_RUNNING);
@@ -254,7 +302,7 @@
static int32_t tfm_check_sfn_req_integrity(struct tfm_sfn_req_s *desc_ptr)
{
if ((desc_ptr == NULL) ||
- (desc_ptr->ss_id == 0) ||
+ (desc_ptr->sp_id == 0) ||
(desc_ptr->sfn == NULL)) {
/* invalid parameter */
return TFM_ERROR_INVALID_PARAMETER;
@@ -403,13 +451,24 @@
extern void return_from_sfn(void);
+void tfm_secure_api_init_done(void)
+{
+ tfm_secure_api_init = 0;
+#if TFM_LVL != 1
+ if (tfm_spm_partition_sandbox_config(TFM_SP_NON_SECURE_ID) != SPM_ERR_OK) {
+ ERROR_MSG("Failed to configure sandbox for partition!");
+ tfm_secure_api_error_handler();
+ }
+#endif
+}
+
static int32_t tfm_core_call_sfn(struct tfm_sfn_req_s *desc_ptr)
{
#if TFM_LVL == 1
- if (desc_ptr->exc_num == EXC_NUM_THREAD_MODE) {
+ if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) {
/* Secure partition to secure partition call in TFM level 1 */
int32_t res;
- uint32_t *args = desc_ptr->args;
+ int32_t *args = desc_ptr->args;
int32_t retVal = desc_ptr->sfn(args[0], args[1], args[2], args[3]);
/* return handler should restore original exc_return value... */
res = tfm_pop_lock(NULL);
diff --git a/secure_fw/core/tfm_secure_api.h b/secure_fw/core/tfm_secure_api.h
index 5504e0b..02fda8d 100644
--- a/secure_fw/core/tfm_secure_api.h
+++ b/secure_fw/core/tfm_secure_api.h
@@ -43,10 +43,12 @@
extern void tfm_secure_api_error_handler(void);
+typedef int32_t(*sfn_t)(int32_t, int32_t, int32_t, int32_t);
+
struct tfm_sfn_req_s {
- uint32_t ss_id;
- int32_t (*sfn)(int32_t, int32_t, int32_t, int32_t);
- uint32_t *args;
+ uint32_t sp_id;
+ sfn_t sfn;
+ int32_t *args;
uint32_t exc_num;
int32_t ns_caller : 1;
};
@@ -91,10 +93,10 @@
int32_t tfm_core_partition_request(uint32_t id, void *fn,
int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4)
{
- uint32_t args[4] = {arg1, arg2, arg3, arg4};
+ int32_t args[4] = {arg1, arg2, arg3, arg4};
struct tfm_sfn_req_s desc, *desc_ptr = &desc;
- desc.ss_id = id;
+ desc.sp_id = id;
desc.sfn = fn;
desc.args = args;
desc.ns_caller = cmse_nonsecure_caller();
diff --git a/secure_fw/core/tfm_unpriv_api.c b/secure_fw/core/tfm_unpriv_api.c
index 8c531ff..a3761de 100644
--- a/secure_fw/core/tfm_unpriv_api.c
+++ b/secure_fw/core/tfm_unpriv_api.c
@@ -5,11 +5,33 @@
*
*/
+#include <arm_cmse.h>
+
#include "tfm_svc.h"
#include "tfm_secure_api.h"
+#include "tfm_internal.h"
uint8_t *tfm_scratch_area;
int32_t tfm_scratch_area_size;
+nsfptr_t ns_entry;
+
+void jump_to_ns_code(void)
+{
+#if TFM_LVL != 1
+ /* Initialization is done, set thread mode to unprivileged. */
+ CONTROL_Type ctrl;
+
+ ctrl.w = __get_CONTROL();
+ ctrl.b.nPRIV = 1;
+ __set_CONTROL(ctrl.w);
+#endif
+ /* All changes made to memory will be effective after this point */
+ __DSB();
+ __ISB();
+
+ /* Calls the non-secure Reset_Handler to jump to the non-secure binary */
+ ns_entry();
+}
__attribute__((naked)) void tfm_core_partition_return_svc(void)
{
diff --git a/secure_fw/ns_callable/tfm_sst_veneers.c b/secure_fw/ns_callable/tfm_sst_veneers.c
index d95bc0b..76fa9a7 100644
--- a/secure_fw/ns_callable/tfm_sst_veneers.c
+++ b/secure_fw/ns_callable/tfm_sst_veneers.c
@@ -9,7 +9,7 @@
#include "secure_fw/services/secure_storage/sst_asset_management.h"
#include "tfm_secure_api.h"
#include "tfm_api.h"
-#include "secure_fw/spm/spm_api.h"
+#include "secure_fw/spm/spm_partition_defs.h"
__tfm_secure_gateway_attributes__
enum tfm_sst_err_t tfm_sst_veneer_get_handle(uint32_t app_id,
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index 40d054d..e83c62e 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -11,6 +11,7 @@
#include <string.h>
#include "spm_api.h"
#include "spm_db.h"
+#include "tfm_internal.h"
#include "tfm_api.h"
#include "mpu_armv8m_drv.h"
#include "region_defs.h"
@@ -89,6 +90,10 @@
*/
/* For the non secure Execution environment */
+#if TFM_LVL != 1
+ extern uint32_t Stack_Mem[];
+ extern uint32_t Stack_top[];
+#endif
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
return SPM_ERR_INVALID_CONFIG;
}
@@ -96,6 +101,16 @@
g_spm_partition_db.partition_count]);
part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
part_ptr->static_data.partition_flags = 0;
+
+#if TFM_LVL != 1
+ part_ptr->static_data.stack_bottom = (uint32_t)Stack_Mem;
+ part_ptr->static_data.stack_top = (uint32_t)Stack_top;
+ /* Since RW, ZI and stack are configured as one MPU region, configure
+ * RW start address to Stack_Mem to get RW access to stack
+ */
+ part_ptr->static_data.rw_start = (uint32_t)Stack_Mem;
+#endif
+
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
++g_spm_partition_db.partition_count;
@@ -140,7 +155,9 @@
region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
/* TFM Core unprivileged code region */
region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_CODE;
@@ -151,7 +168,9 @@
region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
/* TFM Core unprivileged data region */
region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA;
@@ -162,7 +181,9 @@
region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
/* TFM Core unprivileged non-secure data region */
region_cfg.region_nr = MPU_REGION_NS_DATA;
@@ -171,7 +192,9 @@
region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
mpu_armv8m_enable(&dev_mpu_s, 1, 1);
@@ -234,14 +257,12 @@
enum spm_err_t tfm_spm_partition_init(void)
{
struct spm_partition_desc_t *part;
+ struct tfm_sfn_req_s desc, *desc_ptr = &desc;
+ int32_t args[4] = {0};
int32_t fail_cnt = 0;
uint32_t idx;
/* Call the init function for each partition */
- /* FixMe: This implementation only fits level 1 isolation.
- * On higher levels MPU (and PPC) configuration need to be in place to have
- * proper isolation during init.
- */
for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
part = &g_spm_partition_db.partitions[idx];
if (part->static_data.periph_start) {
@@ -250,8 +271,22 @@
}
if (part->static_data.partition_init == NULL) {
tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
+ tfm_spm_partition_set_caller_partition_idx(idx,
+ SPM_INVALID_PARTITION_IDX);
} else {
- int32_t ret = part->static_data.partition_init();
+ int32_t ret;
+
+ desc.args = args;
+ desc.exc_num = EXC_NUM_THREAD_MODE;
+ desc.ns_caller = 0;
+ desc.sfn = (sfn_t)part->static_data.partition_init;
+ desc.sp_id = part->static_data.partition_id;
+ __ASM("MOV r0, %1\n"
+ "SVC %2\n"
+ "MOV %0, r0\n"
+ : "=r" (ret)
+ : "r" (desc_ptr), "I" (TFM_SVC_SFN_REQUEST)
+ : "r0");
if (ret == TFM_SUCCESS) {
tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
@@ -262,6 +297,8 @@
}
}
+ tfm_secure_api_init_done();
+
if (fail_cnt == 0) {
return SPM_ERR_OK;
} else {
@@ -290,15 +327,20 @@
/* Configure Regions */
- /* RO region*/
- region_cfg.region_nr = PARTITION_REGION_RO;
- region_cfg.region_base = part->static_data.ro_start;
- region_cfg.region_limit = part->static_data.ro_limit;
- region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
- region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
- region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
+ if (part->static_data.ro_start) {
+ /* RO region*/
+ region_cfg.region_nr = PARTITION_REGION_RO;
+ region_cfg.region_base = part->static_data.ro_start;
+ region_cfg.region_limit = part->static_data.ro_limit;
+ region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
+ region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg)
+ != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
+ }
/* RW, ZI and stack as one region*/
region_cfg.region_nr = PARTITION_REGION_RW_STACK;
@@ -308,7 +350,9 @@
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
if (part->static_data.periph_start) {
/* Peripheral */
@@ -318,7 +362,10 @@
region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg);
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg)
+ != MPU_ARMV8M_OK) {
+ return SPM_ERR_INVALID_CONFIG;
+ }
ppc_en_secure_unpriv(part->static_data.periph_ppc_bank,
part->static_data.periph_ppc_loc);
@@ -326,21 +373,6 @@
mpu_armv8m_enable(&dev_mpu_s, 1, 1);
-#ifndef UNPRIV_JUMP_TO_NS
- /* FixMe: if jump_to_ns_code() from unprivileged is solved,
- * this code can be removed
- */
- /* Initialization is done, set thread mode to unprivileged.
- */
- CONTROL_Type ctrl;
-
- ctrl.w = __get_CONTROL();
- ctrl.b.nPRIV = 1;
- __set_CONTROL(ctrl.w);
- __DSB();
- __ISB();
-#endif
-
return SPM_ERR_OK;
}
@@ -350,19 +382,6 @@
* SPM partition for that partition
*/
-#ifndef UNPRIV_JUMP_TO_NS
- /* FixMe: if jump_to_ns_code() from unprivileged is solved,
- * this code can be removed
- */
- CONTROL_Type ctrl;
-
- ctrl.w = __get_CONTROL();
- ctrl.b.nPRIV = 0;
- __set_CONTROL(ctrl.w);
- __DSB();
- __ISB();
-#endif
-
struct spm_partition_desc_t *part;
part = &g_spm_partition_db.partitions[partition_idx];
@@ -428,8 +447,8 @@
}
}
-void tfm_spm_partition_set_caller_partition_id(uint32_t partition_idx,
- uint32_t caller_partition_idx)
+void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
+ uint32_t caller_partition_idx)
{
g_spm_partition_db.partitions[partition_idx].runtime_data.
caller_partition_idx = caller_partition_idx;
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index c36288f..5e15044 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -170,15 +170,15 @@
void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
/**
- * \brief Set the caller partition Id for a given partition
+ * \brief Set the caller partition index for a given partition
*
* \param[in] partition_idx Partition index
- * \param[in] caller_partition_id The Id of the caller partition
+ * \param[in] caller_partition_idx The index of the caller partition
*
- * \note This function doesn't check if any of the partition_ids is valid.
+ * \note This function doesn't check if any of the partition_idxs are valid.
*/
-void tfm_spm_partition_set_caller_partition_id(uint32_t partition_idx,
- uint32_t caller_partition_id);
+void tfm_spm_partition_set_caller_partition_idx(uint32_t partition_idx,
+ uint32_t caller_partition_idx);
/**
* \brief Set the original PSP value of a partition