bl32: add secure interrupt handling in AArch32 sp_min
authorEtienne Carriere <etienne.carriere@st.com>
Wed, 9 Aug 2017 13:48:53 +0000 (15:48 +0200)
committerEtienne Carriere <etienne.carriere@st.com>
Wed, 9 Aug 2017 13:48:53 +0000 (15:48 +0200)
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>
bl32/sp_min/aarch32/entrypoint.S
bl32/sp_min/sp_min.mk
bl32/sp_min/sp_min_main.c
bl32/sp_min/sp_min_private.h
docs/user-guide.rst
include/bl32/sp_min/platform_sp_min.h

index b3fccdec4e8da23063cbab8c915450a10d705805..d868c53db156e88876f931f894982a20906e1e31 100644 (file)
        .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
index f6e58e97313376132dc480f72ae6704a340d967f..39588ce7d26587fc0acaa66d826f72a5d95a042b 100644 (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))
index 1c83cbe1a4f8b9ef6d11dba3b4b908f53c0ca906..06b0f33326fd48d7971a05e8eff6b1f5a78cb14a 100644 (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 */
index 97185b919112e0e7874b6ad4bdb3768f1fbe9e0b..1836af9850af27eb696cca38c3f73f39cc4d587c 100644 (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__ */
index ec8c2333ede7c9f404e2aec5659a74e318b72a7b..5b1ec17a2ee21b4648d7b816bc24f516a3ce10ad 100644 (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
index 70c5c14da0ee796e22e01dc01be1c75bc5672d22..6c7e0cc0ca598b0cc211349b9bf6ca0e354231cd 100644 (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__ */