SPM: Add First-Level Interrupt Handling implementation
Change-Id: I5cc6d63f9864c5ea35e7a5236a736799d727855e
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
index fc41394..c63e3cc 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
@@ -8,6 +8,7 @@
#include <inttypes.h>
#include "tfm_hal_device_header.h"
#include "tfm_arch.h"
+#include "svc_num.h"
#include "exception_info.h"
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && \
@@ -86,18 +87,60 @@
}
#if defined(__ICCARM__)
-uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return);
+uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
+ uint32_t *psp);
#pragma required = tfm_core_svc_handler
#endif
__attribute__((naked)) void SVC_Handler(void)
{
__ASM volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
"MRS r0, MSP \n"
- "MRS r1, PSP \n"
- "MOV r2, lr \n"
+ "MOV r1, lr \n"
+ "MRS r2, PSP \n"
+ "SUB sp, #8 \n" /* For FLIH PID and signal */
+ "PUSH {r1, r2} \n" /* Orig_exc_return, PSP */
"BL tfm_core_svc_handler \n"
- "BX r0 \n"
+ "MOV lr, r0 \n"
+ "LDR r1, [sp] \n" /* Original EXC_RETURN */
+ "MOVS r2, #8 \n"
+ "ANDS r0, r2 \n" /* Mode bit */
+ "ANDS r1, r2 \n"
+ "SUBS r0, r1 \n" /* Compare EXC_RETURN values */
+ "BGT to_flih_func \n"
+ "BLT from_flih_func \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
+ "to_flih_func: \n"
+ "PUSH {r4-r7} \n"
+ "MOV r4, r8 \n"
+ "MOV r5, r9 \n"
+ "MOV r6, r10 \n"
+ "MOV r7, r11 \n"
+ "PUSH {r4-r7} \n"
+ "LDR r4, =0xFEF5EDA5 \n" /* clear r4-r11 */
+ "MOV r5, r4 \n"
+ "MOV r6, r4 \n"
+ "MOV r7, r4 \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r4 \n"
+ "MOV r10, r4 \n"
+ "MOV r11, r4 \n"
+ "PUSH {r4, r5} \n" /* Seal stack before EXC_RET */
+ "BX lr \n"
+ "from_flih_func: \n"
+ "ADD sp, #24 \n"
+ "POP {r4-r7} \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r5 \n"
+ "MOV r10, r6 \n"
+ "MOV r11, r7 \n"
+ "POP {r4-r7} \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
);
}
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
index 66d50d8..015ae73 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
@@ -118,18 +118,60 @@
}
#if defined(__ICCARM__)
-uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return);
+uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
+ uint32_t *psp);
#pragma required = tfm_core_svc_handler
#endif
__attribute__((naked)) void SVC_Handler(void)
{
__ASM volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
"MRS r0, MSP \n"
- "MRS r1, PSP \n"
- "MOV r2, lr \n"
+ "MOV r1, lr \n"
+ "MRS r2, PSP \n"
+ "SUB sp, #8 \n" /* For FLIH PID and signal */
+ "PUSH {r1, r2} \n" /* Orig_exc_return, PSP */
"BL tfm_core_svc_handler \n"
- "BX r0 \n"
+ "MOV lr, r0 \n"
+ "LDR r1, [sp] \n" /* Original EXC_RETURN */
+ "MOVS r2, #8 \n"
+ "ANDS r0, r2 \n" /* Mode bit */
+ "ANDS r1, r2 \n"
+ "SUBS r0, r1 \n" /* Compare EXC_RETURN values */
+ "BGT to_flih_func \n"
+ "BLT from_flih_func \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
+ "to_flih_func: \n"
+ "PUSH {r4-r7} \n"
+ "MOV r4, r8 \n"
+ "MOV r5, r9 \n"
+ "MOV r6, r10 \n"
+ "MOV r7, r11 \n"
+ "PUSH {r4-r7} \n"
+ "LDR r4, =0xFEF5EDA5 \n" /* clear r4-r11 */
+ "MOV r5, r4 \n"
+ "MOV r6, r4 \n"
+ "MOV r7, r4 \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r4 \n"
+ "MOV r10, r4 \n"
+ "MOV r11, r4 \n"
+ "PUSH {r4, r5} \n" /* Seal stack before EXC_RET */
+ "BX lr \n"
+ "from_flih_func: \n"
+ "ADD sp, #24 \n"
+ "POP {r4-r7} \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r5 \n"
+ "MOV r10, r6 \n"
+ "MOV r11, r7 \n"
+ "POP {r4-r7} \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
);
}
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
index b96c8cc..33fda0c 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
@@ -97,7 +97,8 @@
}
#if defined(__ICCARM__)
-uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return);
+uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
+ uint32_t *psp);
#pragma required = tfm_core_svc_handler
#endif
@@ -105,10 +106,37 @@
{
__ASM volatile(
"MRS r0, MSP \n"
- "MRS r1, PSP \n"
- "MOV r2, lr \n"
- "BL tfm_core_svc_handler \n"
- "BX r0 \n"
+ "MOV r1, lr \n"
+ "MRS r2, PSP \n"
+ "SUB sp, #8 \n" /* For FLIH PID and signal */
+ "PUSH {r1, r2} \n" /* Orig_exc_return, PSP */
+ "BL tfm_core_svc_handler \n" /* New EXC_RET returned */
+ "MOV lr, r0 \n"
+ "LDR r1, [sp] \n" /* Original EXC_RETURN */
+ "AND r0, #8 \n" /* Mode bit */
+ "AND r1, #8 \n"
+ "SUBS r0, r1 \n" /* Compare EXC_RETURN values */
+ "BGT to_flih_func \n"
+ "BLT from_flih_func \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
+ "to_flih_func: \n"
+ "PUSH {r4-r11} \n"
+ "LDR r4, =0xFEF5EDA5 \n" /* clear r4-r11 */
+ "MOV r5, r4 \n"
+ "MOV r6, r4 \n"
+ "MOV r7, r4 \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r4 \n"
+ "MOV r10, r4 \n"
+ "MOV r11, r4 \n"
+ "PUSH {r4, r5} \n" /* Seal stack before EXC_RET */
+ "BX lr \n"
+ "from_flih_func: \n"
+ "ADD sp, #24 \n"
+ "POP {r4-r11} \n"
+ "ADD sp, #16 \n"
+ "BX lr \n"
);
}
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 384aa36..2db3dce 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -45,8 +45,10 @@
TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t),
TFM_CONN_HANDLE_MAX_NUM);
-void tfm_set_irq_signal(uint32_t partition_id, psa_signal_t signal,
- uint32_t irq_line);
+void spm_interrupt_handler(struct partition_load_info_t *p_ldinf,
+ psa_signal_t signal,
+ uint32_t irq_line,
+ psa_flih_func flih_func);
#include "tfm_secure_irq_handlers_ipc.inc"
@@ -323,7 +325,7 @@
* \retval "Not NULL" Target partition context pointer,
* \ref partition_t structures
*/
-static struct partition_t *tfm_spm_get_partition_by_id(int32_t partition_id)
+struct partition_t *tfm_spm_get_partition_by_id(int32_t partition_id)
{
struct partition_t *p_part;
@@ -876,25 +878,53 @@
}
}
-/**
- * \brief Sets signal to partition for Second-Level Interrupt Handling mode IRQ
- *
- * \param[in] partition_id The ID of the partition which handles this IRQ
- * \param[in] signal The signal associated with this IRQ
- * \param[in] irq_line The number of the IRQ line
- *
- * \retval void Success.
- * \retval "Does not return" Partition ID is invalid
- */
-void tfm_set_irq_signal(uint32_t partition_id, psa_signal_t signal,
- uint32_t irq_line)
+__attribute__((naked))
+static void tfm_flih_deprivileged_handling(uint32_t p_ldinf,
+ psa_flih_func flih_func,
+ psa_signal_t signal)
{
- __disable_irq();
+ __ASM volatile("SVC %0 \n"
+ "BX LR \n"
+ : : "I" (TFM_SVC_PREPARE_DEPRIV_FLIH));
+}
- tfm_spm_hal_disable_irq(irq_line);
- notify_with_signal(partition_id, signal);
+void spm_interrupt_handler(struct partition_load_info_t *p_ldinf,
+ psa_signal_t signal,
+ uint32_t irq_line,
+ psa_flih_func flih_func)
+{
+ uint32_t pid;
+ psa_flih_result_t flih_result;
- __enable_irq();
+ pid = p_ldinf->pid;
+
+ if (flih_func == NULL) {
+ /* SLIH Model Handling */
+ __disable_irq();
+ tfm_spm_hal_disable_irq(irq_line);
+ notify_with_signal(pid, signal);
+ __enable_irq();
+ return;
+ }
+
+ /* FLIH Model Handling */
+ if (tfm_spm_partition_get_privileged_mode(p_ldinf->flags) ==
+ TFM_PARTITION_PRIVILEGED_MODE) {
+ flih_result = flih_func();
+ if (flih_result == PSA_FLIH_SIGNAL) {
+ __disable_irq();
+ notify_with_signal(pid, signal);
+ __enable_irq();
+ } else if (flih_result != PSA_FLIH_NO_SIGNAL) {
+ /*
+ * Nothing needed to do for PSA_FLIH_NO_SIGNAL
+ * But if the flih_result is invalid, should panic.
+ */
+ tfm_core_panic();
+ }
+ } else {
+ tfm_flih_deprivileged_handling((uint32_t)p_ldinf, flih_func, signal);
+ }
}
struct irq_load_info_t *get_irq_info_for_signal(
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index d8fd3c7..43b836b 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -211,6 +211,18 @@
struct tfm_msg_body_t *tfm_spm_get_msg_by_signal(struct partition_t *partition,
psa_signal_t signal);
+
+/**
+ * \brief Get partition by Partition ID.
+ *
+ * \param[in] partition_id The Partition ID of the partition to get
+ *
+ * \retval NULL Failed
+ * \retval "Not NULL" Return the parttion context pointer
+ * \ref partition_t structures
+ */
+struct partition_t *tfm_spm_get_partition_by_id(int32_t partition_id);
+
/**
* \brief Get current running partition context.
*
diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
index e02753a..7ca5cfc 100644
--- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
@@ -6,11 +6,13 @@
*/
#include <string.h>
+#include "load/partition_defs.h"
#include "region.h"
#include "spm_ipc.h"
#include "tfm_api.h"
#include "tfm_arch.h"
#include "tfm_core_trustzone.h"
+#include "tfm_core_utils.h"
#include "tfm_svcalls.h"
#include "utilities.h"
#include "svc_num.h"
@@ -30,6 +32,13 @@
uint32_t *ctx, uint32_t lr);
#endif
+struct tfm_svc_flih_ctx_t {
+ uint32_t exc_ret; /* EXC_RETURN payload at SVC entry */
+ uint32_t psp; /* PSP value at SVC entry */
+ const struct partition_load_info_t *p_ldinf;/* Load info of IRQ Partition */
+ uint32_t signal; /* The IRQ signal */
+};
+
static int32_t SVC_Handler_IPC(uint8_t svc_num, uint32_t *ctx,
uint32_t lr)
{
@@ -128,10 +137,115 @@
return PSA_SUCCESS;
}
-uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return)
+extern void tfm_flih_func_return(psa_flih_result_t result);
+
+/*
+ * Prepare execution context for deprivileged FLIH functions
+ * svc_args: IRQ owner Partition load info, flih_func, signal
+ */
+uint32_t tfm_flih_prepare_depriv_flih(uintptr_t ctx, uint32_t *svc_args)
+{
+ struct tfm_core_thread_t *irq_sp_thread;
+ struct partition_t *irq_sp, *curr_sp;
+ struct tfm_state_context_t *p_stat_ctx;
+ struct tfm_svc_flih_ctx_t *flih_ctx;
+
+ irq_sp = tfm_spm_get_partition_by_id(
+ ((struct partition_load_info_t *)svc_args[0])->pid);
+
+ if (!irq_sp) {
+ tfm_core_panic();
+ }
+ irq_sp_thread = &irq_sp->sp_thread;
+
+ curr_sp = TO_CONTAINER(tfm_core_thrd_get_curr(),
+ struct partition_t,
+ sp_thread);
+
+ flih_ctx = (struct tfm_svc_flih_ctx_t *)ctx;
+ flih_ctx->signal = svc_args[2];
+ flih_ctx->p_ldinf = curr_sp->p_ldinf;
+
+ if (curr_sp == irq_sp) {
+ /*
+ * Either the Partition Thread or FLIH Function within the same
+ * Partition was preempted.
+ */
+ p_stat_ctx = (struct tfm_state_context_t *)flih_ctx->psp;
+ } else {
+ p_stat_ctx = (struct tfm_state_context_t *)irq_sp_thread->arch_ctx.sp;
+ tfm_core_thrd_set_curr(irq_sp_thread);
+ tfm_set_up_isolation_boundary(irq_sp);
+ tfm_arch_set_psplim(irq_sp_thread->stk_btm);
+ }
+
+ p_stat_ctx--;
+ if ((uintptr_t)p_stat_ctx < irq_sp_thread->stk_btm) {
+ tfm_core_panic();
+ }
+ spm_memset(p_stat_ctx, 0, sizeof(struct tfm_state_context_t));
+
+ p_stat_ctx->ra = (uint32_t)svc_args[1];
+ p_stat_ctx->lr = (uint32_t)tfm_flih_func_return;
+ p_stat_ctx->xpsr = XPSR_T32;
+
+ __set_PSP((uint32_t)p_stat_ctx);
+
+ return EXC_RETURN_THREAD_S_PSP;
+}
+
+/* Go back to ISR from FLIH functions */
+uint32_t tfm_flih_return_to_isr(uintptr_t ctx, psa_flih_result_t result)
+{
+ struct partition_t *curr_sp, *prev_sp;
+ struct tfm_svc_flih_ctx_t *flih_ctx;
+ uint32_t msp_top =
+ (uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit);
+
+ /* Skip one tfm_svc_flih_ctx_t + 8 words (R4- R11) + seals (2 words) */
+ flih_ctx = (struct tfm_svc_flih_ctx_t *)
+ (ctx + sizeof(struct tfm_svc_flih_ctx_t) + 10 * sizeof(uint32_t));
+ if ((uint32_t)flih_ctx > msp_top - TFM_STACK_SEALED_SIZE) {
+ tfm_core_panic();
+ }
+
+ curr_sp = TO_CONTAINER(tfm_core_thrd_get_curr(),
+ struct partition_t,
+ sp_thread);
+
+ prev_sp = tfm_spm_get_partition_by_id(flih_ctx->p_ldinf->pid);
+ if (!prev_sp) {
+ tfm_core_panic();
+ }
+
+ if (curr_sp != prev_sp) {
+ tfm_set_up_isolation_boundary(prev_sp);
+ tfm_core_thrd_set_curr(&(prev_sp->sp_thread));
+ tfm_arch_set_psplim(prev_sp->sp_thread.stk_btm);
+ }
+
+ __set_PSP(flih_ctx->psp);
+
+ if (result == PSA_FLIH_SIGNAL) {
+ notify_with_signal(curr_sp->p_ldinf->pid, flih_ctx->signal);
+ } else if (result != PSA_FLIH_NO_SIGNAL) {
+ /*
+ * Nothing needed to do for PSA_FLIH_NO_SIGNAL
+ * But if the flih_result is invalid, should panic.
+ */
+ tfm_core_panic();
+ }
+
+ return flih_ctx->exc_ret;
+}
+
+uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
+ uint32_t *psp)
{
uint8_t svc_number = TFM_SVC_PSA_FRAMEWORK_VERSION;
uint32_t *svc_args = msp;
+ uintptr_t flih_ctx =
+ (uintptr_t)((uint32_t)msp - sizeof(struct tfm_svc_flih_ctx_t));
if ((exc_return & EXC_RETURN_MODE) && (exc_return & EXC_RETURN_SPSEL)) {
/* Use PSP when both EXC_RETURN.MODE and EXC_RETURN.SPSEL are set */
@@ -171,6 +285,12 @@
case TFM_SVC_GET_BOOT_DATA:
tfm_core_get_boot_data_handler(svc_args);
break;
+ case TFM_SVC_PREPARE_DEPRIV_FLIH:
+ exc_return = tfm_flih_prepare_depriv_flih(flih_ctx, svc_args);
+ break;
+ case TFM_SVC_FLIH_FUNC_RETURN:
+ exc_return = tfm_flih_return_to_isr(flih_ctx, svc_args[0]);
+ break;
default:
if (((uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit)
- (uint32_t)msp) > TFM_STACK_SEALED_SIZE) {
diff --git a/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template b/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
index f5faa43..d7b9fde 100644
--- a/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
+++ b/secure_fw/spm/cmsis_psa/tfm_secure_irq_handlers_ipc.inc.template
@@ -14,6 +14,7 @@
#ifdef {{partition.attr.conditional}}
{% endif %}
#include "{{partition.header_file}}"
+extern struct partition_{{partition.manifest.name|lower}}_load_info_t {{partition.manifest.name|lower}}_load;
{% for irq in partition.manifest.irqs %}
{% set irq_data = namespace() %}
{% if partition.manifest.psa_framework_version == 1.0 %}
@@ -31,15 +32,15 @@
{
{% if irq.source %}
{% if partition.manifest.psa_framework_version == 1.1 and irq.handling == "FLIH" %}
-#error "FLIH is not supported yet!"
+ {% set irq_data.flih = irq.name|lower + "_flih" %}
{% else %}
- tfm_set_irq_signal({{partition.manifest.name}}, {{irq_data.signal}}, {{irq.source}});
+ {% set irq_data.flih = "NULL" %}
{% endif %}
+ spm_interrupt_handler((struct partition_load_info_t *)&{{partition.manifest.name|lower}}_load, {{irq_data.signal}}, {{irq.source}}, {{irq_data.flih}});
{% else %}
#error "Interrupt source isn't provided for 'irqs' in partition {{partition.manifest.name}}"
{% endif %}
}
-
{% endfor %}
{% if partition.attr.conditional %}
#endif /* {{partition.attr.conditional}} */
diff --git a/secure_fw/spm/cmsis_psa/tfm_svcalls.h b/secure_fw/spm/cmsis_psa/tfm_svcalls.h
index d3b374f..5d7f964 100644
--- a/secure_fw/spm/cmsis_psa/tfm_svcalls.h
+++ b/secure_fw/spm/cmsis_psa/tfm_svcalls.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -13,11 +13,12 @@
* \brief The C source of SVCall handlers
*
* \param[in] msp MSP at SVCall entry.
- * \param[in] psp PSP at SVCall entry.
* \param[in] exc_return EXC_RETURN value of the SVC.
- *
+ * \param[in] psp PSP at SVCall entry.
+
* \returns EXC_RETURN value indicates where to return.
*/
-uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t *psp, uint32_t exc_return);
+uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
+ uint32_t *psp);
#endif
diff --git a/secure_fw/spm/cmsis_psa/tfm_thread.c b/secure_fw/spm/cmsis_psa/tfm_thread.c
index 43a128a..ef371a1 100644
--- a/secure_fw/spm/cmsis_psa/tfm_thread.c
+++ b/secure_fw/spm/cmsis_psa/tfm_thread.c
@@ -44,6 +44,15 @@
return CURR_THRD;
}
+void tfm_core_thrd_set_curr(struct tfm_core_thread_t *pth)
+{
+ if (!pth) {
+ tfm_core_panic();
+ }
+
+ CURR_THRD = pth;
+}
+
/* Insert a new thread into list by descending priority (Highest at head) */
static void insert_by_prior(struct tfm_core_thread_t **head,
struct tfm_core_thread_t *node)
@@ -73,6 +82,7 @@
pth->param = param;
pth->stk_btm = stk_btm;
pth->stk_top = stk_top;
+ pth->flih_ctx = stk_top;
}
uint32_t tfm_core_thrd_start(struct tfm_core_thread_t *pth)
@@ -155,6 +165,8 @@
spm_memcpy(&prev->arch_ctx, p_actx, sizeof(*p_actx));
spm_memcpy(p_actx, &next->arch_ctx, sizeof(next->arch_ctx));
+ prev->flih_ctx = prev->arch_ctx.sp;
+
/* Update current thread indicator */
CURR_THRD = next;
}
diff --git a/secure_fw/spm/cmsis_psa/tfm_thread.h b/secure_fw/spm/cmsis_psa/tfm_thread.h
index 3841f94..76a274f 100644
--- a/secure_fw/spm/cmsis_psa/tfm_thread.h
+++ b/secure_fw/spm/cmsis_psa/tfm_thread.h
@@ -45,6 +45,7 @@
void *param; /* entry parameter */
uintptr_t stk_btm; /* stack bottom (lower address) */
uintptr_t stk_top; /* stack top (higher address)*/
+ uintptr_t flih_ctx; /* FLIH context pointer */
uint32_t prior; /* priority */
uint32_t state; /* state */
@@ -175,6 +176,18 @@
struct tfm_core_thread_t *tfm_core_thrd_get_curr(void);
/*
+ * Set the current running thread
+ * Note:
+ * This API is intended to update the current thread in FLIH handling.
+ * So that in nested FLIH interrupts, the handler knows which isolation
+ * boundary was preempted.
+ * Although the CURR_THRD is updated, it does not mean the running Partition
+ * thread is changed. It could also be the FLIH function which runs with the
+ * same isolation boundary of the CURR_THRD.
+ */
+void tfm_core_thrd_set_curr(struct tfm_core_thread_t *pth);
+
+/*
* Get next thread to run in list.
*
* Return :
diff --git a/secure_fw/spm/include/interface/svc_num.h b/secure_fw/spm/include/interface/svc_num.h
index 955d7bf..7a3c3c5 100644
--- a/secure_fw/spm/include/interface/svc_num.h
+++ b/secure_fw/spm/include/interface/svc_num.h
@@ -42,6 +42,7 @@
#define TFM_SVC_SPM_REQUEST (0x40)
#define TFM_SVC_GET_BOOT_DATA (0x41)
#define TFM_SVC_SPM_INIT (0x42)
+#define TFM_SVC_FLIH_FUNC_RETURN (0x43)
#define TFM_SVC_THREAD_NUMBER_END (0x7F)
#if (TFM_SPM_LOG_LEVEL > TFM_SPM_LOG_LEVEL_SILENCE)
#define TFM_SVC_OUTPUT_UNPRIV_STRING (TFM_SVC_THREAD_NUMBER_END)
@@ -50,5 +51,6 @@
#define TFM_SVC_HANDLER_NUMBER_START (0x80)
/********************* SVC for interrupt handling *****************************/
+#define TFM_SVC_PREPARE_DEPRIV_FLIH (0x80)
#endif /* __SVC_NUM_H__ */
diff --git a/secure_fw/spm/include/spm_partition_defs.h b/secure_fw/spm/include/spm_partition_defs.h
index c811cb6..252f99c 100644
--- a/secure_fw/spm/include/spm_partition_defs.h
+++ b/secure_fw/spm/include/spm_partition_defs.h
@@ -31,6 +31,7 @@
#define TFM_SP_CORE_ID (1)
#include "psa_manifest/pid.h"
+#include "psa/service.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
@@ -39,5 +40,6 @@
#define SPM_MAX_PARTITIONS (TFM_MAX_USER_PARTITIONS + TFM_INTERNAL_PARTITIONS)
typedef void(*sp_entry_point)(void);
+typedef psa_flih_result_t (*psa_flih_func)(void);
#endif /* __SPM_PARTITION_DEFS_H__ */