mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00
Demonstrate model for routing IRQs to EL3
This patch provides an option to specify a interrupt routing model where non-secure interrupts (IRQs) are routed to EL3 instead of S-EL1. When such an interrupt occurs, the TSPD arranges a return to the normal world after saving any necessary context. The interrupt routing model to route IRQs to EL3 is enabled only during STD SMC processing. Thus the pre-emption of S-EL1 is disabled during Fast SMC and Secure Interrupt processing. A new build option TSPD_ROUTE_NS_INT_EL3 is introduced to change the non secure interrupt target execution level to EL3. Fixes ARM-software/tf-issues#225 Change-Id: Ia1e779fbbb6d627091e665c73fa6315637cfdd32
This commit is contained in:
parent
07ddb33a8e
commit
f4f1ae777b
7 changed files with 219 additions and 17 deletions
|
@ -158,6 +158,45 @@ int32_t set_routing_model(uint32_t type, uint32_t flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* This function disables the routing model of interrupt 'type' from the
|
||||||
|
* specified 'security_state' on the local core. The disable is in effect
|
||||||
|
* till the core powers down or till the next enable for that interrupt
|
||||||
|
* type.
|
||||||
|
*****************************************************************************/
|
||||||
|
int disable_intr_rm_local(uint32_t type, uint32_t security_state)
|
||||||
|
{
|
||||||
|
uint32_t bit_pos, flag;
|
||||||
|
|
||||||
|
assert(intr_type_descs[type].handler);
|
||||||
|
|
||||||
|
flag = get_interrupt_rm_flag(INTR_DEFAULT_RM, security_state);
|
||||||
|
|
||||||
|
bit_pos = plat_interrupt_type_to_line(type, security_state);
|
||||||
|
cm_write_scr_el3_bit(security_state, bit_pos, flag);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* This function enables the routing model of interrupt 'type' from the
|
||||||
|
* specified 'security_state' on the local core.
|
||||||
|
*****************************************************************************/
|
||||||
|
int enable_intr_rm_local(uint32_t type, uint32_t security_state)
|
||||||
|
{
|
||||||
|
uint32_t bit_pos, flag;
|
||||||
|
|
||||||
|
assert(intr_type_descs[type].handler);
|
||||||
|
|
||||||
|
flag = get_interrupt_rm_flag(intr_type_descs[type].flags,
|
||||||
|
security_state);
|
||||||
|
|
||||||
|
bit_pos = plat_interrupt_type_to_line(type, security_state);
|
||||||
|
cm_write_scr_el3_bit(security_state, bit_pos, flag);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This function registers a handler for the 'type' of interrupt specified. It
|
* This function registers a handler for the 'type' of interrupt specified. It
|
||||||
* also validates the routing model specified in the 'flags' for this type of
|
* also validates the routing model specified in the 'flags' for this type of
|
||||||
|
|
|
@ -251,6 +251,11 @@ performed.
|
||||||
(Coherent memory region is included) or 0 (Coherent memory region is
|
(Coherent memory region is included) or 0 (Coherent memory region is
|
||||||
excluded). Default is 1.
|
excluded). Default is 1.
|
||||||
|
|
||||||
|
* `TSPD_ROUTE_IRQ_TO_EL3`: A non zero value enables the routing model
|
||||||
|
for non-secure interrupts in which they are routed to EL3 (TSPD). The
|
||||||
|
default model (when the value is 0) is to route non-secure interrupts
|
||||||
|
to S-EL1 (TSP).
|
||||||
|
|
||||||
#### FVP specific build options
|
#### FVP specific build options
|
||||||
|
|
||||||
* `FVP_TSP_RAM_LOCATION`: location of the TSP binary. Options:
|
* `FVP_TSP_RAM_LOCATION`: location of the TSP binary. Options:
|
||||||
|
|
|
@ -63,7 +63,8 @@
|
||||||
#define INTR_NS_VALID_RM0 0x0
|
#define INTR_NS_VALID_RM0 0x0
|
||||||
/* Routed to EL1/EL2 from NS and to EL3 from Secure */
|
/* Routed to EL1/EL2 from NS and to EL3 from Secure */
|
||||||
#define INTR_NS_VALID_RM1 0x1
|
#define INTR_NS_VALID_RM1 0x1
|
||||||
|
/* This is the default routing model */
|
||||||
|
#define INTR_DEFAULT_RM 0x0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constants for the _individual_ routing model bits in the 'flags' field for
|
* Constants for the _individual_ routing model bits in the 'flags' field for
|
||||||
|
@ -123,6 +124,8 @@ int32_t register_interrupt_type_handler(uint32_t type,
|
||||||
interrupt_type_handler_t handler,
|
interrupt_type_handler_t handler,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
interrupt_type_handler_t get_interrupt_type_handler(uint32_t interrupt_type);
|
interrupt_type_handler_t get_interrupt_type_handler(uint32_t interrupt_type);
|
||||||
|
int disable_intr_rm_local(uint32_t type, uint32_t security_state);
|
||||||
|
int enable_intr_rm_local(uint32_t type, uint32_t security_state);
|
||||||
|
|
||||||
#endif /*__ASSEMBLY__*/
|
#endif /*__ASSEMBLY__*/
|
||||||
#endif /* __INTERRUPT_MGMT_H__ */
|
#endif /* __INTERRUPT_MGMT_H__ */
|
||||||
|
|
|
@ -52,3 +52,10 @@ include ${BL32_ROOT}/tsp.mk
|
||||||
|
|
||||||
# Let the top-level Makefile know that we intend to build the SP from source
|
# Let the top-level Makefile know that we intend to build the SP from source
|
||||||
NEED_BL32 := yes
|
NEED_BL32 := yes
|
||||||
|
|
||||||
|
# Flag used to enable routing of non-secure interrupts to EL3 when they are
|
||||||
|
# generated while the code is executing in S-EL1/0.
|
||||||
|
TSPD_ROUTE_IRQ_TO_EL3 := 0
|
||||||
|
|
||||||
|
$(eval $(call assert_boolean,TSPD_ROUTE_IRQ_TO_EL3))
|
||||||
|
$(eval $(call add_define,TSPD_ROUTE_IRQ_TO_EL3))
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <runtime_svc.h>
|
#include <runtime_svc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
#include <tsp.h>
|
#include <tsp.h>
|
||||||
#include <uuid.h>
|
#include <uuid.h>
|
||||||
#include "tspd_private.h"
|
#include "tspd_private.h"
|
||||||
|
@ -71,6 +72,24 @@ DEFINE_SVC_UUID(tsp_uuid,
|
||||||
|
|
||||||
int32_t tspd_init(void);
|
int32_t tspd_init(void);
|
||||||
|
|
||||||
|
uint64_t tspd_handle_sp_preemption(void *handle)
|
||||||
|
{
|
||||||
|
cpu_context_t *ns_cpu_context;
|
||||||
|
assert(handle == cm_get_context(SECURE));
|
||||||
|
cm_el1_sysregs_context_save(SECURE);
|
||||||
|
/* Get a reference to the non-secure context */
|
||||||
|
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||||
|
assert(ns_cpu_context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore non-secure state. The secure system
|
||||||
|
* register context will be saved when required.
|
||||||
|
*/
|
||||||
|
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||||
|
cm_set_next_eret_context(NON_SECURE);
|
||||||
|
|
||||||
|
SMC_RET1(ns_cpu_context, SMC_PREEMPTED);
|
||||||
|
}
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This function is the handler registered for S-EL1 interrupts by the TSPD. It
|
* This function is the handler registered for S-EL1 interrupts by the TSPD. It
|
||||||
* validates the interrupt and upon success arranges entry into the TSP at
|
* validates the interrupt and upon success arranges entry into the TSP at
|
||||||
|
@ -120,11 +139,16 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
|
||||||
CTX_SPSR_EL3);
|
CTX_SPSR_EL3);
|
||||||
tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
|
tsp_ctx->saved_elr_el3 = SMC_GET_EL3(&tsp_ctx->cpu_ctx,
|
||||||
CTX_ELR_EL3);
|
CTX_ELR_EL3);
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*Need to save the previously interrupted secure context */
|
||||||
|
memcpy(&tsp_ctx->sp_ctx, &tsp_ctx->cpu_ctx, TSPD_SP_CTX_SIZE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cm_el1_sysregs_context_restore(SECURE);
|
cm_el1_sysregs_context_restore(SECURE);
|
||||||
cm_set_elr_spsr_el3(SECURE, (uint64_t) &tsp_vectors->fiq_entry,
|
cm_set_elr_spsr_el3(SECURE, (uint64_t) &tsp_vectors->fiq_entry,
|
||||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||||
|
|
||||||
cm_set_next_eret_context(SECURE);
|
cm_set_next_eret_context(SECURE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -137,6 +161,34 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
|
||||||
SMC_RET2(&tsp_ctx->cpu_ctx, TSP_HANDLE_FIQ_AND_RETURN, read_elr_el3());
|
SMC_RET2(&tsp_ctx->cpu_ctx, TSP_HANDLE_FIQ_AND_RETURN, read_elr_el3());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function is the handler registered for S-EL1 interrupts by the TSPD. It
|
||||||
|
* validates the interrupt and upon success arranges entry into the TSP at
|
||||||
|
* 'tsp_fiq_entry()' for handling the interrupt.
|
||||||
|
******************************************************************************/
|
||||||
|
static uint64_t tspd_ns_interrupt_handler(uint32_t id,
|
||||||
|
uint32_t flags,
|
||||||
|
void *handle,
|
||||||
|
void *cookie)
|
||||||
|
{
|
||||||
|
/* Check the security state when the exception was generated */
|
||||||
|
assert(get_interrupt_src_ss(flags) == SECURE);
|
||||||
|
|
||||||
|
#if IMF_READ_INTERRUPT_ID
|
||||||
|
/* Check the security status of the interrupt */
|
||||||
|
assert(plat_ic_get_interrupt_type(id) == INTR_TYPE_NS);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Disable the routing of NS interrupts from secure world to EL3 while
|
||||||
|
* interrupted on this core.
|
||||||
|
*/
|
||||||
|
disable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
|
||||||
|
return tspd_handle_sp_preemption(handle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
|
* Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
|
||||||
* (aarch32/aarch64) if not already known and initialises the context for entry
|
* (aarch32/aarch64) if not already known and initialises the context for entry
|
||||||
|
@ -270,21 +322,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
if (ns)
|
if (ns)
|
||||||
SMC_RET1(handle, SMC_UNK);
|
SMC_RET1(handle, SMC_UNK);
|
||||||
|
|
||||||
assert(handle == cm_get_context(SECURE));
|
return tspd_handle_sp_preemption(handle);
|
||||||
cm_el1_sysregs_context_save(SECURE);
|
|
||||||
/* Get a reference to the non-secure context */
|
|
||||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
|
||||||
assert(ns_cpu_context);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Restore non-secure state. There is no need to save the
|
|
||||||
* secure system register context since the TSP was supposed
|
|
||||||
* to preserve it during S-EL1 interrupt handling.
|
|
||||||
*/
|
|
||||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
|
||||||
cm_set_next_eret_context(NON_SECURE);
|
|
||||||
|
|
||||||
SMC_RET1(ns_cpu_context, SMC_PREEMPTED);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function ID is used only by the TSP to indicate that it has
|
* This function ID is used only by the TSP to indicate that it has
|
||||||
|
@ -308,6 +346,14 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
SMC_SET_EL3(&tsp_ctx->cpu_ctx,
|
SMC_SET_EL3(&tsp_ctx->cpu_ctx,
|
||||||
CTX_ELR_EL3,
|
CTX_ELR_EL3,
|
||||||
tsp_ctx->saved_elr_el3);
|
tsp_ctx->saved_elr_el3);
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Need to restore the previously interrupted
|
||||||
|
* secure context.
|
||||||
|
*/
|
||||||
|
memcpy(&tsp_ctx->cpu_ctx, &tsp_ctx->sp_ctx,
|
||||||
|
TSPD_SP_CTX_SIZE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a reference to the non-secure context */
|
/* Get a reference to the non-secure context */
|
||||||
|
@ -389,6 +435,28 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
flags);
|
flags);
|
||||||
if (rc)
|
if (rc)
|
||||||
panic();
|
panic();
|
||||||
|
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Register an interrupt handler for NS interrupts when
|
||||||
|
* generated during code executing in secure state are
|
||||||
|
* routed to EL3.
|
||||||
|
*/
|
||||||
|
flags = 0;
|
||||||
|
set_interrupt_rm_flag(flags, SECURE);
|
||||||
|
|
||||||
|
rc = register_interrupt_type_handler(INTR_TYPE_NS,
|
||||||
|
tspd_ns_interrupt_handler,
|
||||||
|
flags);
|
||||||
|
if (rc)
|
||||||
|
panic();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the interrupt NS locally since it will be enabled globally
|
||||||
|
* within cm_init_context.
|
||||||
|
*/
|
||||||
|
disable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,6 +575,13 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
set_std_smc_active_flag(tsp_ctx->state);
|
set_std_smc_active_flag(tsp_ctx->state);
|
||||||
cm_set_elr_el3(SECURE, (uint64_t)
|
cm_set_elr_el3(SECURE, (uint64_t)
|
||||||
&tsp_vectors->std_smc_entry);
|
&tsp_vectors->std_smc_entry);
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Enable the routing of NS interrupts to EL3
|
||||||
|
* during STD SMC processing on this core.
|
||||||
|
*/
|
||||||
|
enable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cm_el1_sysregs_context_restore(SECURE);
|
cm_el1_sysregs_context_restore(SECURE);
|
||||||
|
@ -529,8 +604,18 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
/* Restore non-secure state */
|
/* Restore non-secure state */
|
||||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||||
cm_set_next_eret_context(NON_SECURE);
|
cm_set_next_eret_context(NON_SECURE);
|
||||||
if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_STD)
|
if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_STD) {
|
||||||
clr_std_smc_active_flag(tsp_ctx->state);
|
clr_std_smc_active_flag(tsp_ctx->state);
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Disable the routing of NS interrupts to EL3
|
||||||
|
* after STD SMC processing is finished on this
|
||||||
|
* core.
|
||||||
|
*/
|
||||||
|
disable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
SMC_RET3(ns_cpu_context, x1, x2, x3);
|
SMC_RET3(ns_cpu_context, x1, x2, x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +649,15 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
|
||||||
* We are done stashing the non-secure context. Ask the
|
* We are done stashing the non-secure context. Ask the
|
||||||
* secure payload to do the work now.
|
* secure payload to do the work now.
|
||||||
*/
|
*/
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Enable the routing of NS interrupts to EL3 during resumption
|
||||||
|
* of STD SMC call on this core.
|
||||||
|
*/
|
||||||
|
enable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* We just need to return to the preempted point in
|
/* We just need to return to the preempted point in
|
||||||
* TSP and the execution will resume as normal.
|
* TSP and the execution will resume as normal.
|
||||||
|
|
|
@ -133,6 +133,14 @@ static void tspd_cpu_on_finish_handler(uint64_t unused)
|
||||||
/* Initialise this cpu's secure context */
|
/* Initialise this cpu's secure context */
|
||||||
cm_init_context(mpidr, &tsp_on_entrypoint);
|
cm_init_context(mpidr, &tsp_on_entrypoint);
|
||||||
|
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
/*
|
||||||
|
* Disable the NS interrupt locally since it will be enabled globally
|
||||||
|
* within cm_init_context.
|
||||||
|
*/
|
||||||
|
disable_intr_rm_local(INTR_TYPE_NS, SECURE);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enter the TSP */
|
/* Enter the TSP */
|
||||||
rc = tspd_synchronous_sp_entry(tsp_ctx);
|
rc = tspd_synchronous_sp_entry(tsp_ctx);
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,34 @@
|
||||||
#define TSPD_C_RT_CTX_SIZE 0x60
|
#define TSPD_C_RT_CTX_SIZE 0x60
|
||||||
#define TSPD_C_RT_CTX_ENTRIES (TSPD_C_RT_CTX_SIZE >> DWORD_SHIFT)
|
#define TSPD_C_RT_CTX_ENTRIES (TSPD_C_RT_CTX_SIZE >> DWORD_SHIFT)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Constants that allow assembler code to preserve caller-saved registers of the
|
||||||
|
* SP context while performing a TSP preemption.
|
||||||
|
* Note: These offsets have to match with the offsets for the corresponding
|
||||||
|
* registers in cpu_context as we are using memcpy to copy the values from
|
||||||
|
* cpu_context to sp_ctx.
|
||||||
|
******************************************************************************/
|
||||||
|
#define TSPD_SP_CTX_X0 0x0
|
||||||
|
#define TSPD_SP_CTX_X1 0x8
|
||||||
|
#define TSPD_SP_CTX_X2 0x10
|
||||||
|
#define TSPD_SP_CTX_X3 0x18
|
||||||
|
#define TSPD_SP_CTX_X4 0x20
|
||||||
|
#define TSPD_SP_CTX_X5 0x28
|
||||||
|
#define TSPD_SP_CTX_X6 0x30
|
||||||
|
#define TSPD_SP_CTX_X7 0x38
|
||||||
|
#define TSPD_SP_CTX_X8 0x40
|
||||||
|
#define TSPD_SP_CTX_X9 0x48
|
||||||
|
#define TSPD_SP_CTX_X10 0x50
|
||||||
|
#define TSPD_SP_CTX_X11 0x58
|
||||||
|
#define TSPD_SP_CTX_X12 0x60
|
||||||
|
#define TSPD_SP_CTX_X13 0x68
|
||||||
|
#define TSPD_SP_CTX_X14 0x70
|
||||||
|
#define TSPD_SP_CTX_X15 0x78
|
||||||
|
#define TSPD_SP_CTX_X16 0x80
|
||||||
|
#define TSPD_SP_CTX_X17 0x88
|
||||||
|
#define TSPD_SP_CTX_SIZE 0x90
|
||||||
|
#define TSPD_SP_CTX_ENTRIES (TSPD_SP_CTX_SIZE >> DWORD_SHIFT)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <cassert.h>
|
#include <cassert.h>
|
||||||
|
@ -142,6 +170,17 @@ DEFINE_REG_STRUCT(c_rt_regs, TSPD_C_RT_CTX_ENTRIES);
|
||||||
CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \
|
CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \
|
||||||
assert_spd_c_rt_regs_size_mismatch);
|
assert_spd_c_rt_regs_size_mismatch);
|
||||||
|
|
||||||
|
/* SEL1 Secure payload (SP) caller saved register context structure. */
|
||||||
|
DEFINE_REG_STRUCT(sp_ctx_regs, TSPD_SP_CTX_ENTRIES);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile time assertion to ensure that both the compiler and linker
|
||||||
|
* have the same double word aligned view of the size of the C runtime
|
||||||
|
* register context.
|
||||||
|
*/
|
||||||
|
CASSERT(TSPD_SP_CTX_SIZE == sizeof(sp_ctx_regs_t), \
|
||||||
|
assert_spd_sp_regs_size_mismatch);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Structure which helps the SPD to maintain the per-cpu state of the SP.
|
* Structure which helps the SPD to maintain the per-cpu state of the SP.
|
||||||
* 'saved_spsr_el3' - temporary copy to allow FIQ handling when the TSP has been
|
* 'saved_spsr_el3' - temporary copy to allow FIQ handling when the TSP has been
|
||||||
|
@ -155,6 +194,10 @@ CASSERT(TSPD_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \
|
||||||
* 'cpu_ctx' - space to maintain SP architectural state
|
* 'cpu_ctx' - space to maintain SP architectural state
|
||||||
* 'saved_tsp_args' - space to store arguments for TSP arithmetic operations
|
* 'saved_tsp_args' - space to store arguments for TSP arithmetic operations
|
||||||
* which will queried using the TSP_GET_ARGS SMC by TSP.
|
* which will queried using the TSP_GET_ARGS SMC by TSP.
|
||||||
|
* 'sp_ctx' - space to save the SEL1 Secure Payload(SP) caller saved
|
||||||
|
* register context after it has been preempted by an EL3
|
||||||
|
* routed NS interrupt and when a Secure Interrupt is taken
|
||||||
|
* to SP.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
typedef struct tsp_context {
|
typedef struct tsp_context {
|
||||||
uint64_t saved_elr_el3;
|
uint64_t saved_elr_el3;
|
||||||
|
@ -164,6 +207,9 @@ typedef struct tsp_context {
|
||||||
uint64_t c_rt_ctx;
|
uint64_t c_rt_ctx;
|
||||||
cpu_context_t cpu_ctx;
|
cpu_context_t cpu_ctx;
|
||||||
uint64_t saved_tsp_args[TSP_NUM_ARGS];
|
uint64_t saved_tsp_args[TSP_NUM_ARGS];
|
||||||
|
#if TSPD_ROUTE_IRQ_TO_EL3
|
||||||
|
sp_ctx_regs_t sp_ctx;
|
||||||
|
#endif
|
||||||
} tsp_context_t;
|
} tsp_context_t;
|
||||||
|
|
||||||
/* Helper macros to store and retrieve tsp args from tsp_context */
|
/* Helper macros to store and retrieve tsp args from tsp_context */
|
||||||
|
|
Loading…
Add table
Reference in a new issue