Commit 6e346fe2 authored by johpow01's avatar johpow01 Committed by Mark Dykes
Browse files

feat(RME): Run BL2 in root world



This patch enables BL2 to run in root world (EL3) which is
needed as per the security model of RME-enabled systems.
Signed-off-by: default avatarJohn Powell <john.powell@arm.com>
Change-Id: I53ace51e326fcdd44d44c791a7cb9ffaa20ed3f5
parent 156ed4ce
......@@ -93,3 +93,34 @@ void bl1_prepare_next_image(unsigned int image_id)
print_entry_point_info(next_bl_ep);
}
#if ENABLE_RME
/*******************************************************************************
* This function prepares the entry point information to run BL2 in Root world
* i.e. EL3. It then jumps into BL2 using this entry point information.
******************************************************************************/
void bl1_prepare_for_bl2_in_root(void)
{
image_desc_t *bl2_desc;
entry_point_info_t *bl2_ep_info;
/* Get the image descriptor. */
bl2_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
assert(bl2_desc != NULL);
/* Get the entry point info. */
bl2_ep_info = &bl2_desc->ep_info;
bl2_ep_info->spsr = (uint32_t)SPSR_64(MODE_EL3, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
/* Indicate that image is in execution state. */
bl2_desc->state = IMAGE_STATE_EXECUTED;
/* Print debug info and flush the console before running BL2. */
print_entry_point_info(bl2_ep_info);
console_flush();
bl1_run_bl2_in_root(bl2_ep_info);
}
#endif /* ENABLE_RME */
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <common/bl_common.h>
#include <el3_common_macros.S>
.globl bl1_entrypoint
.globl bl1_run_bl2_in_root
/* -----------------------------------------------------
......@@ -68,3 +70,43 @@ func bl1_entrypoint
*/
b el3_exit
endfunc bl1_entrypoint
/* -----------------------------------------------------
* void bl1_run_bl2_in_root(entry_point_info_t *ep_info);
* This function runs BL2 in root/EL3 when RME is enabled.
* -----------------------------------------------------
*/
#if ENABLE_RME
func bl1_run_bl2_in_root
mov x20,x0
/* ---------------------------------------------
* MMU needs to be disabled because BL2 executes
* in EL3. It will initialize the address space
* according to its own requirements.
* ---------------------------------------------
*/
bl disable_mmu_icache_el3
tlbi alle3
#if ENABLE_PAUTH
/* ---------------------------------------------
* Disable pointer authentication before jumping
* to next boot image.
* ---------------------------------------------
*/
bl pauth_disable_el3
#endif /* ENABLE_PAUTH */
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
msr elr_el3, x0
msr spsr_el3, x1
ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
exception_return
endfunc bl1_run_bl2_in_root
#endif /* ENABLE_RME */
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -142,10 +142,18 @@ void bl1_main(void)
* We currently interpret any image id other than
* BL2_IMAGE_ID as the start of firmware update.
*/
if (image_id == BL2_IMAGE_ID)
if (image_id == BL2_IMAGE_ID) {
bl1_load_bl2();
else
#if ENABLE_RME
/* Run BL2 in root if RME is enabled. */
assert(get_armv9_2_feat_rme_support() != 0U);
bl1_prepare_for_bl2_in_root();
#endif /* ENABLE_RME */
} else {
NOTICE("BL1-FWU: *******FWU Process Started*******\n");
}
bl1_prepare_next_image(image_id);
......
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -18,6 +18,8 @@ void bl1_arch_setup(void);
void bl1_arch_next_el_setup(void);
void bl1_prepare_next_image(unsigned int image_id);
void bl1_prepare_for_bl2_in_root(void);
void bl1_run_bl2_in_root(entry_point_info_t *ep_info);
u_register_t bl1_fwu_smc_handler(unsigned int smc_fid,
u_register_t x1,
......
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -21,6 +21,23 @@
#define FIXUP_SIZE ((BL2_LIMIT) - (BL2_BASE))
#endif
/*
* Notes on ENABLE_RME build option
*
* The purpose of the BL2_IN_EL3 build option is to allow BL2 to
* essentially function as BL1 in systems that don't use a TFA boot ROM.
* For the purposes of RME, we use a normal BL1 image but we also want
* to run BL2 in EL3/root as normally as possible, so rather than use the
* special bl2_el3_setup function here we use the standard bl2_setup and we
* don't need reset or mailbox initialization code seen in the
* el3_entrypoint_common macro. This functionality could be split off into its
* own file if more separation between code paths is desired.
*
* See https://trustedfirmware-a.readthedocs.io/en/latest/design/
* firmware-design.html?highlight=BL2_AT_EL3
* #running-bl2-at-el3-execution-level
*/
func bl2_entrypoint
/* Save arguments x0-x3 from previous Boot loader */
mov x20, x0
......@@ -28,6 +45,18 @@ func bl2_entrypoint
mov x22, x2
mov x23, x3
#if ENABLE_RME
/* RME support is enabled. */
el3_entrypoint_common \
_init_sctlr=0 \
_warm_boot_mailbox=0 \
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=1 \
_exception_vectors=bl2_el3_exceptions \
_pie_fixup_size=FIXUP_SIZE
#else /* ENABLE_RME */
/* RME support is disabled. */
el3_entrypoint_common \
_init_sctlr=1 \
_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
......@@ -36,6 +65,7 @@ func bl2_entrypoint
_init_c_runtime=1 \
_exception_vectors=bl2_el3_exceptions \
_pie_fixup_size=FIXUP_SIZE
#endif /* ENABLE_RME */
/* ---------------------------------------------
* Restore parameters of boot rom
......@@ -50,7 +80,13 @@ func bl2_entrypoint
* Perform BL2 setup
* ---------------------------------------------
*/
#if ENABLE_RME
/* RME is a special case, use normal bl2_setup. */
bl bl2_setup
#else
/* Otherwise, use the normal bl2 in el3 setup function. */
bl bl2_el3_setup
#endif /* ENABLE_RME */
#if ENABLE_PAUTH
/* ---------------------------------------------
......
......@@ -25,7 +25,11 @@ SECTIONS
#if SEPARATE_CODE_AND_RODATA
.text . : {
__TEXT_START__ = .;
#if ENABLE_RME
*bl2_el3_entrypoint.o(.text*)
#else /* ENABLE_RME */
*bl2_entrypoint.o(.text*)
#endif /* ENABLE_RME */
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
......
#
# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
......@@ -15,11 +15,21 @@ ifeq (${ARCH},aarch64)
BL2_SOURCES += common/aarch64/early_exceptions.S
endif
ifeq (${BL2_AT_EL3},0)
ifeq (${ENABLE_RME},1)
include lib/gpt/gpt.mk
# Using RME, run BL2 at EL3
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
${GPT_LIB_SRCS}
BL2_LINKERFILE := bl2/bl2.ld.S
else ifeq (${BL2_AT_EL3},0)
# Normal operation, no RME, no BL2 at EL3
BL2_SOURCES += bl2/${ARCH}/bl2_entrypoint.S
BL2_LINKERFILE := bl2/bl2.ld.S
else
# BL2 at EL3, no RME
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
lib/cpus/${ARCH}/cpu_helpers.S \
......
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -28,18 +28,18 @@
#define NEXT_IMAGE "BL32"
#endif
#if !BL2_AT_EL3
#if BL2_AT_EL3
/*******************************************************************************
* Setup function for BL2.
* Setup function for BL2 when BL2_AT_EL3=1
******************************************************************************/
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
u_register_t arg3)
{
/* Perform early platform-specific setup */
bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
/* Perform late platform-specific setup */
bl2_plat_arch_setup();
bl2_el3_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
......@@ -49,19 +49,18 @@ void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
}
#else /* if BL2_AT_EL3 */
#else /* BL2_AT_EL3 */
/*******************************************************************************
* Setup function for BL2 when BL2_AT_EL3=1.
* Setup function for BL2. This function is used when ENABLE_RME=1
******************************************************************************/
void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
u_register_t arg3)
{
/* Perform early platform-specific setup */
bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
/* Perform late platform-specific setup */
bl2_el3_plat_arch_setup();
bl2_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
......@@ -110,7 +109,7 @@ void bl2_main(void)
measured_boot_finish();
#endif /* MEASURED_BOOT */
#if !BL2_AT_EL3
#if !BL2_AT_EL3 && !ENABLE_RME
#ifndef __aarch64__
/*
* For AArch32 state BL1 and BL2 share the MMU setup.
......
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -87,6 +87,13 @@
* do so.
*/
orr x0, x0, #(SCR_API_BIT | SCR_APK_BIT)
#endif
#if ENABLE_RME
/*
* Current RME-enabled model does not run in R-EL2 unless EEL2 is enabled.
* EL3 cannot access ICC_SRE_EL2 either.
*/
orr x0, x0, #SCR_EEL2_BIT
#endif
msr scr_el3, x0
......@@ -324,6 +331,7 @@
msr vbar_el3, x0
isb
#if !(defined(IMAGE_BL2) && ENABLE_RME)
/* ---------------------------------------------------------------------
* It is a cold boot.
* Perform any processor specific actions upon reset e.g. cache, TLB
......@@ -331,6 +339,7 @@
* ---------------------------------------------------------------------
*/
bl reset_handler
#endif
el3_arch_init_common
......@@ -373,7 +382,8 @@
* ---------------------------------------------------------------------
*/
.if \_init_c_runtime
#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_INV_DCACHE)
#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
((BL2_AT_EL3 && BL2_INV_DCACHE) || ENABLE_RME))
/* -------------------------------------------------------------
* Invalidate the RW memory used by the BL31 image. This
* includes the data and NOBITS sections. This is done to
......
......@@ -15,6 +15,7 @@
.globl zero_normalmem
.globl zeromem
.globl memcpy16
.globl tlbi_by_pa
.globl disable_mmu_el1
.globl disable_mmu_el3
......@@ -162,7 +163,8 @@ func zeromem_dczva
* Check for M bit (MMU enabled) of the current SCTLR_EL(1|3)
* register value and panic if the MMU is disabled.
*/
#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
(BL2_AT_EL3 || ENABLE_RME))
mrs tmp1, sctlr_el3
#else
mrs tmp1, sctlr_el1
......@@ -592,3 +594,24 @@ func fixup_gdt_reloc
b.lo 1b
ret
endfunc fixup_gdt_reloc
func tlbi_by_pa
// @TODO The following code invalidates the entire TLB cache. Replace it with
// "tlbi by pa" instruction once it is made available by the model.
tlbi alle3is
mrs x1, scr_el3
mov_imm x2, SCR_NS_BIT | SCR_NSE_BIT
orr x0, x1, x2
msr scr_el3, x0
tlbi alle2is
tlbi alle1is
orr x0, x1, #SCR_NS_BIT
msr scr_el3, x0
tlbi alle2is
tlbi alle1is
msr scr_el3, x1
dsb sy
ret
endfunc tlbi_by_pa
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -21,7 +21,7 @@
# define BL_STRING "BL31"
#elif !defined(__arch64__) && defined(IMAGE_BL32)
# define BL_STRING "BL32"
#elif defined(IMAGE_BL2) && BL2_AT_EL3
#elif defined(IMAGE_BL2) && (BL2_AT_EL3 || ENABLE_RME)
# define BL_STRING "BL2"
#else
# error This image should not be printing errata status
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment