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>
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index b3fccde..d868c53 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -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 @@
 	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 @@
 	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
 
@@ -166,6 +181,44 @@
 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.
  */
 func sp_min_warm_entrypoint
@@ -213,6 +266,10 @@
 	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