bl32: add secure interrupt handling in AArch32 sp_min

Add support for a minimal secure interrupt service in sp_min for
the AArch32 implementation. Hard code that only FIQs are handled.

Introduce bolean build directive SP_MIN_WITH_SECURE_FIQ to enable
FIQ handling from SP_MIN.

Configure SCR[FIQ] and SCR[FW] from generic code for both cold and
warm boots to handle FIQ in secure state from monitor.

Since SP_MIN architecture, FIQ are always trapped when system executes
in non secure state. Hence discard relay of the secure/non-secure
state in the FIQ handler.

Change-Id: I1f7d1dc7b21f6f90011b7f3fcd921e455592f5e7
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
This commit is contained in:
Etienne Carriere 2017-08-09 15:48:53 +02:00
parent 2f860c7815
commit 71816096da
6 changed files with 91 additions and 1 deletions

View File

@ -18,6 +18,17 @@
.globl sp_min_entrypoint
.globl sp_min_warm_entrypoint
.macro route_fiq_to_sp_min reg
/* -----------------------------------------------------
* FIQs are secure interrupts trapped by Monitor and non
* secure is not allowed to mask the FIQs.
* -----------------------------------------------------
*/
ldcopr \reg, SCR
orr \reg, \reg, #SCR_FIQ_BIT
bic \reg, \reg, #SCR_FW_BIT
stcopr \reg, SCR
.endm
vector_base sp_min_vector_table
b sp_min_entrypoint
@ -27,7 +38,7 @@ vector_base sp_min_vector_table
b plat_panic_handler /* Data abort */
b plat_panic_handler /* Reserved */
b plat_panic_handler /* IRQ */
b plat_panic_handler /* FIQ */
b handle_fiq /* FIQ */
/*
@ -92,6 +103,10 @@ func sp_min_entrypoint
mov r1, #0
#endif /* RESET_TO_SP_MIN */
#if SP_MIN_WITH_SECURE_FIQ
route_fiq_to_sp_min r4
#endif
bl sp_min_early_platform_setup
bl sp_min_plat_arch_setup
@ -165,6 +180,44 @@ func handle_smc
b sp_min_exit
endfunc handle_smc
/*
* Secure Interrupts handling function for SP_MIN.
*/
func handle_fiq
#if !SP_MIN_WITH_SECURE_FIQ
b plat_panic_handler
#else
/* FIQ has a +4 offset for lr compared to preferred return address */
sub lr, lr, #4
/* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
str lr, [sp, #SMC_CTX_LR_MON]
smcc_save_gp_mode_regs
/*
* AArch32 architectures need to clear the exclusive access when
* entering Monitor mode.
*/
clrex
/* load run-time stack */
mov r2, sp
ldr sp, [r2, #SMC_CTX_SP_MON]
/* Switch to Secure Mode */
ldr r0, [r2, #SMC_CTX_SCR]
bic r0, #SCR_NS_BIT
stcopr r0, SCR
isb
push {r2, r3}
bl sp_min_fiq
pop {r0, r3}
b sp_min_exit
#endif
endfunc handle_fiq
/*
* The Warm boot entrypoint for SP_MIN.
*/
@ -213,6 +266,10 @@ func sp_min_warm_entrypoint
mov r0, #DISABLE_DCACHE
bl bl32_plat_enable_mmu
#if SP_MIN_WITH_SECURE_FIQ
route_fiq_to_sp_min r0
#endif
#if HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY
ldcopr r0, SCTLR
orr r0, r0, #SCTLR_C_BIT

View File

@ -37,3 +37,9 @@ endif
RESET_TO_SP_MIN := 0
$(eval $(call add_define,RESET_TO_SP_MIN))
$(eval $(call assert_boolean,RESET_TO_SP_MIN))
# Flag to allow SP_MIN to handle FIQ interrupts in monitor mode. The platform
# port is free to override this value. It is default disabled.
SP_MIN_WITH_SECURE_FIQ ?= 0
$(eval $(call add_define,SP_MIN_WITH_SECURE_FIQ))
$(eval $(call assert_boolean,SP_MIN_WITH_SECURE_FIQ))

View File

@ -207,3 +207,19 @@ void sp_min_warm_boot(void)
copy_cpu_ctx_to_smc_stx(get_regs_ctx(cm_get_context(NON_SECURE)),
next_smc_ctx);
}
#if SP_MIN_WITH_SECURE_FIQ
/******************************************************************************
* This function is invoked on secure interrupts. By construction of the
* SP_MIN, secure interrupts can only be handled when core executes in non
* secure state.
*****************************************************************************/
void sp_min_fiq(void)
{
uint32_t id;
id = plat_ic_acknowledge_interrupt();
sp_min_plat_fiq_handler(id);
plat_ic_end_of_interrupt(id);
}
#endif /* SP_MIN_WITH_SECURE_FIQ */

View File

@ -10,5 +10,6 @@
void sp_min_warm_entrypoint(void);
void sp_min_main(void);
void sp_min_warm_boot(void);
void sp_min_fiq(void);
#endif /* __SP_MIN_H__ */

View File

@ -521,6 +521,13 @@ Common build options
firmware images have been loaded in memory, and the MMU and caches are
turned off. Refer to the "Debugging options" section for more details.
- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
secure interrupts (caught through the FIQ line). Platforms can enable
this directive if they need to handle such interruption. When enabled,
the FIQ are handled in monitor mode and non secure world is not allowed
to mask these events. Platforms that enable FIQ handling in SP_MIN shall
implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
Boot feature. When set to '1', BL1 and BL2 images include support to load
and verify the certificates and images in a FIP, and BL1 includes support

View File

@ -17,4 +17,7 @@ void sp_min_plat_runtime_setup(void);
void sp_min_plat_arch_setup(void);
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
/* Platforms that enable SP_MIN_WITH_SECURE_FIQ shall implement this api */
void sp_min_plat_fiq_handler(uint32_t id);
#endif /* __PLATFORM_SP_MIN_H__ */