Browse Source

AArch32: Add `TRUSTED_BOARD_BOOT` support

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>
pull/939/head
dp-arm 8 years ago
parent
commit
a440900803
  1. 45
      Makefile
  2. 25
      bl1/aarch32/bl1_entrypoint.S
  3. 88
      bl1/aarch32/bl1_exceptions.S
  4. 37
      bl1/bl1_fwu.c
  5. 17
      bl1/bl1_main.c
  6. 5
      include/plat/arm/common/arm_def.h
  7. 2
      make_helpers/tbbr/tbbr_tools.mk
  8. 4
      plat/arm/board/fvp/platform.mk

45
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
################################################################################

25
bl1/aarch32/bl1_entrypoint.S

@ -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

88
bl1/aarch32/bl1_exceptions.S

@ -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

37
bl1/bl1_fwu.c

@ -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;
}

17
bl1/bl1_main.c

@ -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);
}

5
include/plat/arm/common/arm_def.h

@ -224,9 +224,10 @@
/*******************************************************************************
* 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)

2
make_helpers/tbbr/tbbr_tools.mk

@ -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)

4
plat/arm/board/fvp/platform.mk

@ -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

Loading…
Cancel
Save