AArch32: Add `TRUSTED_BOARD_BOOT` support
authordp-arm <dimitris.papastamos@arm.com>
Wed, 15 Feb 2017 11:07:55 +0000 (11:07 +0000)
committerdp-arm <dimitris.papastamos@arm.com>
Mon, 15 May 2017 15:34:27 +0000 (16:34 +0100)
This patch adds `TRUSTED_BOARD_BOOT` support for AArch32 mode.

To build this patch the "mbedtls/include/mbedtls/bignum.h"
needs to be modified to remove `#define MBEDTLS_HAVE_UDBL`
when `MBEDTLS_HAVE_INT32` is defined. This is a workaround
for "https://github.com/ARMmbed/mbedtls/issues/708"

NOTE: TBBR support on Juno AArch32 is not currently supported.

Change-Id: I86d80e30b9139adc4d9663f112801ece42deafcf
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
Co-Authored-By: Yatharth Kochar <yatharth.kochar@arm.com>
Makefile
bl1/aarch32/bl1_entrypoint.S
bl1/aarch32/bl1_exceptions.S
bl1/bl1_fwu.c
bl1/bl1_main.c
include/plat/arm/common/arm_def.h
make_helpers/tbbr/tbbr_tools.mk
plat/arm/board/fvp/platform.mk

index a263c4eb30bd5b8ae1435ee4fbf66c5f7e046dba..78860b374f3926cc8a1c421236769c424659221c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -261,6 +261,25 @@ endif
 # This can be overridden by the platform.
 include lib/cpus/cpu-ops.mk
 
+ifeq (${ARCH},aarch32)
+NEED_BL32 := yes
+
+################################################################################
+# Build `AARCH32_SP` as BL32 image for AArch32
+################################################################################
+ifneq (${AARCH32_SP},none)
+# We expect to locate an sp.mk under the specified AARCH32_SP directory
+AARCH32_SP_MAKE        :=      $(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
+
+ifeq (${AARCH32_SP_MAKE},)
+  $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
+endif
+
+$(info Including ${AARCH32_SP_MAKE})
+include ${AARCH32_SP_MAKE}
+endif
+
+endif
 
 ################################################################################
 # Check incompatible options
@@ -285,15 +304,11 @@ ifeq (${NEED_BL33},yes)
         endif
 endif
 
+# For AArch32, LOAD_IMAGE_V2 must be enabled.
 ifeq (${ARCH},aarch32)
-    # For AArch32, LOAD_IMAGE_V2 must be enabled.
     ifeq (${LOAD_IMAGE_V2}, 0)
         $(error "For AArch32, LOAD_IMAGE_V2 must be enabled.")
     endif
-    # TRUSTED_BOARD_BOOT is currently not supported for AArch32.
-    ifeq (${TRUSTED_BOARD_BOOT},1)
-        $(error "TRUSTED_BOARD_BOOT is currently not supported for AArch32")
-    endif
 endif
 
 # When building for systems with hardware-assisted coherency, there's no need to
@@ -398,26 +413,6 @@ endif
 endif
 endif
 
-ifeq (${ARCH},aarch32)
-NEED_BL32 := yes
-
-################################################################################
-# Build `AARCH32_SP` as BL32 image for AArch32
-################################################################################
-ifneq (${AARCH32_SP},none)
-# We expect to locate an sp.mk under the specified AARCH32_SP directory
-AARCH32_SP_MAKE        :=      $(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
-
-ifeq (${AARCH32_SP_MAKE},)
-  $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
-endif
-
-$(info Including ${AARCH32_SP_MAKE})
-include ${AARCH32_SP_MAKE}
-endif
-
-endif
-
 ################################################################################
 # Build options checks
 ################################################################################
index e3d915fb4318d8b60f301ec78bb880646ef154e5..39ebcf73d99bc49ecc905ece0eb25274ef30d533 100644 (file)
@@ -71,9 +71,21 @@ func bl1_entrypoint
         */
 
        /*
-        * MMU needs to be disabled because both BL1 and BL2 execute
+        * Get the smc_context for next BL image,
+        * program the gp/system registers and save it in `r4`.
+        */
+       bl      smc_get_next_ctx
+       mov     r4, r0
+
+       /* Only turn-off MMU if going to secure world */
+       ldr     r5, [r4, #SMC_CTX_SCR]
+       tst     r5, #SCR_NS_BIT
+       bne     skip_mmu_off
+
+       /*
+        * MMU needs to be disabled because both BL1 and BL2/BL2U execute
         * in PL1, and therefore share the same address space.
-        * BL2 will initialize the address space according to its
+        * BL2/BL2U will initialize the address space according to its
         * own requirement.
         */
        bl      disable_mmu_icache_secure
@@ -81,11 +93,8 @@ func bl1_entrypoint
        dsb     sy
        isb
 
-       /*
-        * Get the smc_context for next BL image,
-        * program the gp/system registers and exit
-        * secure monitor mode
-        */
-       bl      smc_get_next_ctx
+skip_mmu_off:
+       /* Restore smc_context from `r4` and exit secure monitor mode. */
+       mov     r0, r4
        monitor_exit
 endfunc bl1_entrypoint
index de7ddc557c4a0acd6620d6de9ab78f9d553c0b3e..f73db4022d97e93cb30797fff2c2e3b1736717e4 100644 (file)
@@ -8,11 +8,18 @@
 #include <asm_macros.S>
 #include <bl1.h>
 #include <bl_common.h>
+#include <context.h>
+#include <smcc_helpers.h>
+#include <smcc_macros.S>
+#include <xlat_tables.h>
 
        .globl  bl1_aarch32_smc_handler
 
 
 func bl1_aarch32_smc_handler
+       /* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
+       str     lr, [sp, #SMC_CTX_LR_MON]
+
        /* ------------------------------------------------
         * SMC in BL1 is handled assuming that the MMU is
         * turned off by BL2.
@@ -20,12 +27,12 @@ func bl1_aarch32_smc_handler
         */
 
        /* ----------------------------------------------
-        * Only RUN_IMAGE SMC is supported.
+        * Detect if this is a RUN_IMAGE or other SMC.
         * ----------------------------------------------
         */
-       mov     r8, #BL1_SMC_RUN_IMAGE
-       cmp     r8, r0
-       blne    report_exception
+       mov     lr, #BL1_SMC_RUN_IMAGE
+       cmp     lr, r0
+       bne     smc_handler
 
        /* ------------------------------------------------
         * Make sure only Secure world reaches here.
@@ -70,3 +77,76 @@ debug_loop:
        ldm     r8, {r0, r1, r2, r3}
        eret
 endfunc bl1_aarch32_smc_handler
+
+       /* -----------------------------------------------------
+        * Save Secure/Normal world context and jump to
+        * BL1 SMC handler.
+        * -----------------------------------------------------
+        */
+func smc_handler
+       /* -----------------------------------------------------
+        * Save the GP registers.
+        * -----------------------------------------------------
+        */
+       smcc_save_gp_mode_regs
+
+       /*
+        * `sp` still points to `smc_ctx_t`. Save it to a register
+        * and restore the C runtime stack pointer to `sp`.
+        */
+       mov     r6, sp
+       ldr     sp, [r6, #SMC_CTX_SP_MON]
+
+       ldr     r0, [r6, #SMC_CTX_SCR]
+       and     r7, r0, #SCR_NS_BIT             /* flags */
+
+       /* Switch to Secure Mode */
+       bic     r0, #SCR_NS_BIT
+       stcopr  r0, SCR
+       isb
+
+       /* If caller is from Secure world then turn on the MMU */
+       tst     r7, #SCR_NS_BIT
+       bne     skip_mmu_on
+
+       /* Turn on the MMU */
+       mov     r0, #DISABLE_DCACHE
+       bl      enable_mmu_secure
+
+       /* Enable the data cache. */
+       ldcopr  r9, SCTLR
+       orr     r9, r9, #SCTLR_C_BIT
+       stcopr  r9, SCTLR
+       isb
+
+skip_mmu_on:
+       /* Prepare arguments for BL1 SMC wrapper. */
+       ldr     r0, [r6, #SMC_CTX_GPREG_R0]     /* smc_fid */
+       mov     r1, #0                          /* cookie */
+       mov     r2, r6                          /* handle */
+       mov     r3, r7                          /* flags */
+       bl      bl1_smc_wrapper
+
+       /* Get the smc_context for next BL image */
+       bl      smc_get_next_ctx
+       mov     r4, r0
+
+       /* Only turn-off MMU if going to secure world */
+       ldr     r5, [r4, #SMC_CTX_SCR]
+       tst     r5, #SCR_NS_BIT
+       bne     skip_mmu_off
+
+       /* Disable the MMU */
+       bl      disable_mmu_icache_secure
+       stcopr  r0, TLBIALL
+       dsb     sy
+       isb
+
+skip_mmu_off:
+       /* -----------------------------------------------------
+        * Do the transition to next BL image.
+        * -----------------------------------------------------
+        */
+       mov     r0, r4
+       monitor_exit
+endfunc smc_handler
index b0985320e7fbc0eff2a5853559f75fc003d4c3ed..ace364d422a1367998ced9be3f0022255f6617a2 100644 (file)
@@ -47,6 +47,8 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved);
  */
 static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
 
+void cm_set_next_context(void *cpu_context);
+
 /*******************************************************************************
  * Top level handler for servicing FWU SMCs.
  ******************************************************************************/
@@ -364,8 +366,10 @@ static int bl1_fwu_image_execute(unsigned int image_id,
 
        INFO("BL1-FWU: Executing Secure image\n");
 
+#ifdef AARCH64
        /* Save NS-EL1 system registers. */
        cm_el1_sysregs_context_save(NON_SECURE);
+#endif
 
        /* Prepare the image for execution. */
        bl1_prepare_next_image(image_id);
@@ -373,7 +377,11 @@ static int bl1_fwu_image_execute(unsigned int image_id,
        /* Update the secure image id. */
        sec_exec_image_id = image_id;
 
+#ifdef AARCH64
        *handle = cm_get_context(SECURE);
+#else
+       *handle = smc_get_ctx(SECURE);
+#endif
        return 0;
 }
 
@@ -419,6 +427,10 @@ static register_t bl1_fwu_image_resume(register_t image_param,
                resume_sec_state = SECURE;
        }
 
+       INFO("BL1-FWU: Resuming %s world context\n",
+               (resume_sec_state == SECURE) ? "secure" : "normal");
+
+#ifdef AARCH64
        /* Save the EL1 system registers of calling world. */
        cm_el1_sysregs_context_save(caller_sec_state);
 
@@ -428,10 +440,16 @@ static register_t bl1_fwu_image_resume(register_t image_param,
        /* Update the next context. */
        cm_set_next_eret_context(resume_sec_state);
 
-       INFO("BL1-FWU: Resuming %s world context\n",
-               (resume_sec_state == SECURE) ? "secure" : "normal");
-
        *handle = cm_get_context(resume_sec_state);
+#else
+       /* Update the next context. */
+       cm_set_next_context(cm_get_context(resume_sec_state));
+
+       /* Prepare the smc context for the next BL image. */
+       smc_set_next_ctx(resume_sec_state);
+
+       *handle = smc_get_ctx(resume_sec_state);
+#endif
        return image_param;
 }
 
@@ -461,6 +479,8 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags)
        image_desc->state = IMAGE_STATE_RESET;
        sec_exec_image_id = INVALID_IMAGE_ID;
 
+       INFO("BL1-FWU: Resuming Normal world context\n");
+#ifdef AARCH64
        /*
         * Secure world is done so no need to save the context.
         * Just restore the Non-Secure context.
@@ -470,9 +490,16 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags)
        /* Update the next context. */
        cm_set_next_eret_context(NON_SECURE);
 
-       INFO("BL1-FWU: Resuming Normal world context\n");
-
        *handle = cm_get_context(NON_SECURE);
+#else
+       /* Update the next context. */
+       cm_set_next_context(cm_get_context(NON_SECURE));
+
+       /* Prepare the smc context for the next BL image. */
+       smc_set_next_ctx(NON_SECURE);
+
+       *handle = smc_get_ctx(NON_SECURE);
+#endif
        return 0;
 }
 
index 71ece00dd97e9fdd50603dd1fc575ea9527ff431..fa4f3a4c0c27cc90e9eda8cd3e7e6819a191ec54 100644 (file)
@@ -279,3 +279,20 @@ register_t bl1_smc_handler(unsigned int smc_fid,
        WARN("Unimplemented BL1 SMC Call: 0x%x \n", smc_fid);
        SMC_RET1(handle, SMC_UNK);
 }
+
+/*******************************************************************************
+ * BL1 SMC wrapper.  This function is only used in AArch32 mode to ensure ABI
+ * compliance when invoking bl1_smc_handler.
+ ******************************************************************************/
+register_t bl1_smc_wrapper(uint32_t smc_fid,
+       void *cookie,
+       void *handle,
+       unsigned int flags)
+{
+       register_t x1, x2, x3, x4;
+
+       assert(handle);
+
+       get_smc_params_from_ctx(handle, x1, x2, x3, x4);
+       return bl1_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
index 7a42c98a18199af2bc9acb18bb05ffec9c1f88ef..23e78678e7e09ab6c5ef96d39cf0eaeb209258d6 100644 (file)
 /*******************************************************************************
  * BL2 specific defines.
  ******************************************************************************/
-#if ARM_BL31_IN_DRAM
+#if ARM_BL31_IN_DRAM || defined(AARCH32)
 /*
- * BL31 is loaded in the DRAM.
+ * For AArch32 BL31 is not applicable.
+ * For AArch64 BL31 is loaded in the DRAM.
  * Put BL2 just below BL1.
  */
 #define BL2_BASE                       (BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
index 4912c90dd0cbc671422835bf44ce2e8746016b94..610ccb883fd0fbfbe4ac6f7d927b73b7bcb02a54 100644 (file)
@@ -75,6 +75,7 @@ ifneq (${SCP_BL2},)
     $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_key.crt,--scp-fw-key-cert))
 endif
 
+ifeq (${ARCH},aarch64)
 # Add the BL31 CoT (key cert + img cert + image)
 $(if ${BL31},$(eval $(call CERT_ADD_CMD_OPT,${BL31},--soc-fw,true)),\
              $(eval $(call CERT_ADD_CMD_OPT,$(call IMG_BIN,31),--soc-fw,true)))
@@ -83,6 +84,7 @@ $(eval $(call CERT_ADD_CMD_OPT,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
 $(eval $(call CERT_ADD_CMD_OPT,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
+endif
 
 # Add the BL32 CoT (key cert + img cert + image)
 ifeq (${NEED_BL32},yes)
index afcb4b53d1e2ebe0ebeb53f0d5e533f9e617e43e..6a759c5a7285bb4294096177be5fc0edd36d6a4d 100644 (file)
@@ -137,5 +137,9 @@ ifneq (${ENABLE_STACK_PROTECTOR},0)
 PLAT_BL_COMMON_SOURCES +=      plat/arm/board/fvp/fvp_stack_protector.c
 endif
 
+ifeq (${ARCH},aarch32)
+    NEED_BL32 := yes
+endif
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk