From deb4b3a63e3a52f2e9823865a1932f6289ccb7ac Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Tue, 13 Jul 2021 17:19:54 -0500 Subject: [PATCH] feat(plat/arm): add GPT initialization code for Arm platforms When RME is enabled, during configuration of the TrustZone controller, Root regions are initially configured as Secure regions, and Realm regions as Non-secure regions. Then later these regions are configured as Root and Realm regions respectively in the GPT. According to the RME architecture reference manual, Root firmware must ensure that Granule Protection Check is enabled before enabling any stage of translation. Therefore initializations are done as follows when RME is enabled : Initialize/enable the TrustZone controller (plat_arm_security_setup) --> Initialize/enable GPC (arm_bl2_plat_gpt_setup) --> enable MMU (enable_mmu_el3) Signed-off-by: Zelalem Aweke Change-Id: I91094e8259079437bee02de1f65edb9ad51e43cf --- include/plat/arm/common/arm_pas_def.h | 5 +++ plat/arm/common/arm_bl2_setup.c | 60 ++++++++++++++++++++++++++- plat/arm/common/arm_bl31_setup.c | 24 +++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h index a8ebee3f1..d268ce613 100644 --- a/include/plat/arm/common/arm_pas_def.h +++ b/include/plat/arm/common/arm_pas_def.h @@ -87,4 +87,9 @@ ARM_L1_GPT_SIZE, \ GPI_ROOT) +/* GPT Configuration options */ +#define PLATFORM_PGS GPCCR_PGS_4K +#define PLATFORM_PPS GPCCR_PPS_4GB +#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS + #endif /* ARM_PAS_DEF_H */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 758a061b8..ef372068a 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -17,10 +18,12 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif #include +#include #include #include @@ -111,8 +114,10 @@ void bl2_plat_preload_setup(void) */ void arm_bl2_platform_setup(void) { +#if !ENABLE_RME /* Initialize the secure environment */ plat_arm_security_setup(); +#endif #if defined(PLAT_ARM_MEM_PROT_ADDR) arm_nor_psci_do_static_mem_protect(); @@ -124,9 +129,47 @@ void bl2_platform_setup(void) arm_bl2_platform_setup(); } +#if ENABLE_RME +static void arm_bl2_plat_gpt_setup(void) +{ + /* + * The GPT library might modify the gpt regions structure to optimize + * the layout, so the array cannot be constant. + */ + pas_region_t pas_regions[] = { + ARM_PAS_GPI_ANY, + ARM_PAS_KERNEL, + ARM_PAS_TZC, + ARM_PAS_REALM, + ARM_PAS_EL3_DRAM, + ARM_PAS_GPTS + }; + + gpt_init_params_t gpt_params = { + PLATFORM_PGS, + PLATFORM_PPS, + PLATFORM_L0GPTSZ, + pas_regions, + (unsigned int)(sizeof(pas_regions)/sizeof(pas_region_t)), + ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, + ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE + }; + + /* Initialise the global granule tables */ + INFO("Enabling Granule Protection Checks\n"); + if (gpt_init(&gpt_params) < 0) { + panic(); + } + + gpt_enable(); +} +#endif /* ENABLE_RME */ + /******************************************************************************* - * Perform the very early platform specific architectural setup here. At the - * moment this is only initializes the mmu in a quick and dirty way. + * Perform the very early platform specific architectural setup here. + * When RME is enabled the secure environment is initialised before + * initialising and enabling Granule Protection. + * This function initialises the MMU in a quick and dirty way. ******************************************************************************/ void arm_bl2_plat_arch_setup(void) { @@ -155,10 +198,23 @@ void arm_bl2_plat_arch_setup(void) {0} }; +#if ENABLE_RME + /* Initialise the secure environment */ + plat_arm_security_setup(); + + /* Initialise and enable Granule Protection */ + arm_bl2_plat_gpt_setup(); +#endif setup_page_tables(bl_regions, plat_arm_get_mmap()); #ifdef __aarch64__ +#if ENABLE_RME + /* BL2 runs in EL3 when RME enabled. */ + assert(get_armv9_2_feat_rme_support() != 0U); + enable_mmu_el3(0); +#else enable_mmu_el1(0); +#endif #else enable_mmu_svc_mon(0); #endif diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index d2bacd3fa..d76031282 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -229,6 +231,28 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi */ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; #endif + +#if ENABLE_RME + /* + * Initialise Granule Protection library and enable GPC + * for the primary processor. The tables were initialised + * in BL2, so there is no need to provide any PAS here. + */ + gpt_init_params_t gpt_params = { + PLATFORM_PGS, + PLATFORM_PPS, + PLATFORM_L0GPTSZ, + NULL, + 0U, + ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, + ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE + }; + + /* Initialise the global granule tables. */ + if (gpt_init(&gpt_params) < 0) { + panic(); + } +#endif /* ENABLE_RME */ } void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,