Core: Clear FP status before SPM initialization
Float point (FP) is forbidden during SPM initialization, clear it
before handler mode SPM initialization. And return the generic
EXC_RETURN for subsequent thread scheduling.
The usage of FP is still valid before SPM initialization and
the subsequent thread execution, just do not happen during SPM
initialization.
Change-Id: I48d7bd0f140cb1c933cdd621d598446cb81eaee3
Signed-off-by: Ken Liu <ken.liu@arm.com>
diff --git a/secure_fw/core/arch/include/tfm_arch.h b/secure_fw/core/arch/include/tfm_arch.h
index eb5f387..c65eb21 100644
--- a/secure_fw/core/arch/include/tfm_arch.h
+++ b/secure_fw/core/arch/include/tfm_arch.h
@@ -97,4 +97,9 @@
*/
void tfm_arch_prioritize_secure_exception(void);
+/*
+ * Clear float point status.
+ */
+void tfm_arch_clear_fp_status(void);
+
#endif
diff --git a/secure_fw/core/arch/tfm_arch_v6m_v7m.c b/secure_fw/core/arch/tfm_arch_v6m_v7m.c
index 494c14f..5cb111d 100644
--- a/secure_fw/core/arch/tfm_arch_v6m_v7m.c
+++ b/secure_fw/core/arch/tfm_arch_v6m_v7m.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -137,3 +137,22 @@
void tfm_arch_prioritize_secure_exception(void)
{
}
+
+/* There is no FPCA in v6m */
+#ifndef __ARM_ARCH_6M__
+__attribute__((naked, noinline)) void tfm_arch_clear_fp_status(void)
+{
+ __ASM volatile(
+ ".syntax unified \n"
+ "mrs r0, control \n"
+ "bics r0, r0, #4 \n"
+ "msr control, r0 \n"
+ "isb \n"
+ "bx lr \n"
+ );
+}
+#else
+void tfm_arch_clear_fp_status(void)
+{
+}
+#endif
diff --git a/secure_fw/core/arch/tfm_arch_v8m_base.c b/secure_fw/core/arch/tfm_arch_v8m_base.c
index 764955f..d04d498 100644
--- a/secure_fw/core/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/core/arch/tfm_arch_v8m_base.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -234,3 +234,8 @@
VECTKEY |
(AIRCR & ~SCB_AIRCR_VECTKEY_Msk);
}
+
+/* There is no FPCA in baseline. */
+void tfm_arch_clear_fp_status(void)
+{
+}
diff --git a/secure_fw/core/arch/tfm_arch_v8m_main.c b/secure_fw/core/arch/tfm_arch_v8m_main.c
index 3bd69bd..503e9c1 100644
--- a/secure_fw/core/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/core/arch/tfm_arch_v8m_main.c
@@ -224,3 +224,15 @@
VECTKEY |
(AIRCR & ~SCB_AIRCR_VECTKEY_Msk);
}
+
+__attribute__((naked, noinline)) void tfm_arch_clear_fp_status(void)
+{
+ __ASM volatile(
+ ".syntax unified \n"
+ "mrs r0, control \n"
+ "bics r0, r0, #4 \n"
+ "msr control, r0 \n"
+ "isb \n"
+ "bx lr \n"
+ );
+}
diff --git a/secure_fw/core/tfm_core_svcalls_ipc.c b/secure_fw/core/tfm_core_svcalls_ipc.c
index 0d66752..5d7e317 100644
--- a/secure_fw/core/tfm_core_svcalls_ipc.c
+++ b/secure_fw/core/tfm_core_svcalls_ipc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -7,6 +7,7 @@
#include <string.h>
#include "tfm_api.h"
+#include "tfm_arch.h"
#include "tfm_internal.h"
#include "core/tfm_core_svc.h"
#include "tfm_utils.h"
@@ -35,7 +36,8 @@
}
switch (svc_number) {
case TFM_SVC_HANDLER_MODE:
- tfm_spm_init();
+ tfm_arch_clear_fp_status();
+ exc_return = tfm_spm_init();
break;
case TFM_SVC_GET_BOOT_DATA:
tfm_core_get_boot_data_handler(svc_args);
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index d7d0e7d..fbcda09 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -681,8 +681,11 @@
* \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.
*/
-void tfm_spm_init(void);
+uint32_t tfm_spm_init(void);
#endif /* ifdef(TFM_PSA_API) */
diff --git a/secure_fw/spm/spm_api_ipc.c b/secure_fw/spm/spm_api_ipc.c
index dc27023..38ab043 100644
--- a/secure_fw/spm/spm_api_ipc.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -510,7 +510,7 @@
/********************** SPM functions for thread mode ************************/
-void tfm_spm_init(void)
+uint32_t tfm_spm_init(void)
{
uint32_t i, j, num;
struct spm_partition_desc_t *partition;
@@ -615,6 +615,8 @@
* the scheduler that the current thread is non-secure entry thread.
*/
tfm_thrd_start_scheduler(p_ns_entry_thread);
+
+ return p_ns_entry_thread->state_ctx.ctxb.lr;
}
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb)