From 1e7545accd0452d943347e386ac5cefc67162169 Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Thu, 18 Jan 2024 22:32:52 +0000 Subject: [PATCH 1/3] refactor(arm): rename L0/L1 GPT base macros In accordance with common naming conventions, macros specifying the base address of a region typically use the prefix "BASE" combined with the region name, rather than "ADDR_BASE." Currently, the macros defining the base addresses for L0 and L1 GPT tables within `arm_def.h` are named "ARM_L0_GPT_ADDR_BASE" and "ARM_L1_GPT_ADDR_BASE" respectively. To adhere to the established naming convention, rename these macros as "ARM_L1_GPT_BASE" and "ARM_L0_GPT_BASE" respectively. Signed-off-by: Rohit Mathew Change-Id: Ibd50a58a1f63ba97d2df141f41a21a89ef97d6fb --- include/plat/arm/common/arm_def.h | 12 ++++++------ include/plat/arm/common/arm_pas_def.h | 2 +- plat/arm/common/arm_bl2_setup.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 54b184d86..c3a88e7cb 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -150,10 +150,10 @@ MEASURED_BOOT #endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */ #if ENABLE_RME -#define ARM_L1_GPT_ADDR_BASE (ARM_DRAM1_BASE + \ +#define ARM_L1_GPT_BASE (ARM_DRAM1_BASE + \ ARM_DRAM1_SIZE - \ ARM_L1_GPT_SIZE) -#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \ +#define ARM_L1_GPT_END (ARM_L1_GPT_BASE + \ ARM_L1_GPT_SIZE - 1U) #define ARM_REALM_BASE (ARM_EL3_RMM_SHARED_BASE - \ @@ -343,7 +343,7 @@ MEASURED_BOOT #define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \ - ARM_L1_GPT_ADDR_BASE, \ + ARM_L1_GPT_BASE, \ ARM_L1_GPT_SIZE, \ MT_MEMORY | MT_RW | EL3_PAS) @@ -422,7 +422,7 @@ MEASURED_BOOT * Map L0_GPT with read and write permissions */ #if ENABLE_RME -#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE, \ +#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_BASE, \ ARM_L0_GPT_SIZE, \ MT_MEMORY | MT_RW | MT_ROOT) #endif @@ -533,8 +533,8 @@ MEASURED_BOOT * configuration memory, 4KB aligned. */ #define ARM_L0_GPT_SIZE (PAGE_SIZE) -#define ARM_L0_GPT_ADDR_BASE (ARM_FW_CONFIGS_LIMIT) -#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE) +#define ARM_L0_GPT_BASE (ARM_FW_CONFIGS_LIMIT) +#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE) #else #define ARM_L0_GPT_SIZE U(0) #endif diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h index fba8d2c70..797792b10 100644 --- a/include/plat/arm/common/arm_pas_def.h +++ b/include/plat/arm/common/arm_pas_def.h @@ -107,7 +107,7 @@ ARM_EL3_TZC_DRAM1_SIZE, \ GPT_GPI_ROOT) -#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \ +#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_BASE, \ ARM_L1_GPT_SIZE, \ GPT_GPI_ROOT) diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 3e8109e6b..c545f5890 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -151,7 +151,7 @@ static void arm_bl2_plat_gpt_setup(void) }; /* Initialize entire protected space to GPT_GPI_ANY. */ - if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE, + if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_BASE, ARM_L0_GPT_SIZE) < 0) { ERROR("gpt_init_l0_tables() failed!\n"); panic(); @@ -159,7 +159,7 @@ static void arm_bl2_plat_gpt_setup(void) /* Carve out defined PAS ranges. */ if (gpt_init_pas_l1_tables(GPCCR_PGS_4K, - ARM_L1_GPT_ADDR_BASE, + ARM_L1_GPT_BASE, ARM_L1_GPT_SIZE, pas_regions, (unsigned int)(sizeof(pas_regions) / From 86e4859a05614b40ff3cf38f8bd4efc856c546fe Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Wed, 20 Dec 2023 17:29:18 +0000 Subject: [PATCH 2/3] feat(arm): retrieve GPT related data from platform For RME-enabled platforms, initializing L0 and L1 tables and enabling GPC checks is necessary. For systems using BL2 to load firmware images, the GPT initialization has to be done in BL2 prior to the image load. The common Arm platform code currently implements this in the "arm_bl2_plat_gpt_setup" function, relying on the FVP platform's specifications (PAS definitions, GPCCR_PPS, and GPCCR_PGS). Different Arm platforms may have distinct PAS definitions, GPCCR_PPS, GPCCR_PGS, L0/L1 base, and size. To accommodate these variations, introduce the "plat_arm_get_gpt_info" API. Platforms must implement this API to provide the necessary data for GPT setup on RME-enabled platforms. It is essential to note that these additions are relevant to platforms under the plat/arm hierarchy that will reuse the "arm_bl2_plat_gpt_setup" function. As a result of these new additions, migrate data related to the FVP platform to its source and header files. Signed-off-by: Rohit Mathew Change-Id: I4f4c8894c1cda0adc1f83e7439eb372e923f6147 --- .../granule-protection-tables-design.rst | 4 +- include/plat/arm/common/plat_arm.h | 16 ++++++- plat/arm/board/fvp/fvp_bl2_setup.c | 36 +++++++++++++++- plat/arm/board/fvp/fvp_common.c | 3 +- .../arm/board/fvp/include/fvp_pas_def.h | 10 ++--- plat/arm/common/arm_bl2_setup.c | 43 ++++++++----------- 6 files changed, 77 insertions(+), 35 deletions(-) rename include/plat/arm/common/arm_pas_def.h => plat/arm/board/fvp/include/fvp_pas_def.h (96%) diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst index 07637dd58..7a4ffcf0b 100644 --- a/docs/components/granule-protection-tables-design.rst +++ b/docs/components/granule-protection-tables-design.rst @@ -80,8 +80,8 @@ structure used by the granule transition service which will be covered more below. In the reference implementation for FVP models, you can find an example of PAS -region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table -creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and +region definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``. +Table creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and runtime initialization API calls can be seen in ``plat/arm/common/arm_bl31_setup.c``. diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 0fb06a662..97f544630 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,17 @@ typedef struct arm_tzc_regions_info { unsigned int nsaid_permissions; } arm_tzc_regions_info_t; +typedef struct arm_gpt_info { + pas_region_t *pas_region_base; + unsigned int pas_region_count; + uintptr_t l0_base; + uintptr_t l1_base; + size_t l0_size; + size_t l1_size; + gpccr_pps_e pps; + gpccr_pgs_e pgs; +} arm_gpt_info_t; + /******************************************************************************* * Default mapping definition of the TrustZone Controller for ARM standard * platforms. @@ -362,6 +374,8 @@ int plat_arm_get_alt_image_source( unsigned int plat_arm_calc_core_pos(u_register_t mpidr); const mmap_region_t *plat_arm_get_mmap(void); +const arm_gpt_info_t *plat_arm_get_gpt_info(void); + /* Allow platform to override psci_pm_ops during runtime */ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops); diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index ebd52664b..97d000e7f 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,32 @@ static struct transfer_list_header *ns_tl __unused; +#if ENABLE_RME +/* + * The GPT library might modify the gpt regions structure to optimize + * the layout, so the array cannot be constant. + */ +static pas_region_t pas_regions[] = { + ARM_PAS_KERNEL, + ARM_PAS_SECURE, + ARM_PAS_REALM, + ARM_PAS_EL3_DRAM, + ARM_PAS_GPTS, + ARM_PAS_KERNEL_1 +}; + +static const arm_gpt_info_t arm_gpt_info = { + .pas_region_base = pas_regions, + .pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions), + .l0_base = (uintptr_t)ARM_L0_GPT_BASE, + .l1_base = (uintptr_t)ARM_L1_GPT_BASE, + .l0_size = (size_t)ARM_L0_GPT_SIZE, + .l1_size = (size_t)ARM_L1_GPT_SIZE, + .pps = GPCCR_PPS_64GB, + .pgs = GPCCR_PGS_4K +}; +#endif + void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); @@ -41,6 +68,13 @@ void bl2_platform_setup(void) fvp_timer_init(); } +#if ENABLE_RME +const arm_gpt_info_t *plat_arm_get_gpt_info(void) +{ + return &arm_gpt_info; +} +#endif /* ENABLE_RME */ + /******************************************************************************* * This function returns the list of executable images ******************************************************************************/ diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index c40a3ced3..beae242ea 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,7 +24,6 @@ #endif #include -#include #include #include diff --git a/include/plat/arm/common/arm_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h similarity index 96% rename from include/plat/arm/common/arm_pas_def.h rename to plat/arm/board/fvp/include/fvp_pas_def.h index 797792b10..468438724 100644 --- a/include/plat/arm/common/arm_pas_def.h +++ b/plat/arm/board/fvp/include/fvp_pas_def.h @@ -1,13 +1,13 @@ /* - * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef ARM_PAS_DEF_H -#define ARM_PAS_DEF_H +#ifndef FVP_PAS_DEF_H +#define FVP_PAS_DEF_H #include -#include +#include /***************************************************************************** * PAS regions used to initialize the Granule Protection Table (GPT) @@ -114,4 +114,4 @@ /* GPT Configuration options */ #define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS -#endif /* ARM_PAS_DEF_H */ +#endif /* FVP_PAS_DEF_H */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index c545f5890..3ef561a92 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,9 +23,6 @@ #include #endif #include -#if ENABLE_RME -#include -#endif #include #include @@ -135,35 +132,33 @@ void bl2_platform_setup(void) } #if ENABLE_RME -static void arm_bl2_plat_gpt_setup(void) +static void arm_bl2_gpt_setup(void) { /* - * The GPT library might modify the gpt regions structure to optimize - * the layout, so the array cannot be constant. + * It is to be noted that any Arm platform that reuses arm_bl2_gpt_setup + * must implement plat_arm_get_gpt_info within its platform code */ - pas_region_t pas_regions[] = { - ARM_PAS_KERNEL, - ARM_PAS_SECURE, - ARM_PAS_REALM, - ARM_PAS_EL3_DRAM, - ARM_PAS_GPTS, - ARM_PAS_KERNEL_1 - }; + const arm_gpt_info_t *arm_gpt_info = + plat_arm_get_gpt_info(); + + if (arm_gpt_info == NULL) { + ERROR("arm_gpt_info not initialized!!\n"); + panic(); + } /* Initialize entire protected space to GPT_GPI_ANY. */ - if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_BASE, - ARM_L0_GPT_SIZE) < 0) { + if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base, + arm_gpt_info->l0_size) < 0) { ERROR("gpt_init_l0_tables() failed!\n"); panic(); } /* Carve out defined PAS ranges. */ - if (gpt_init_pas_l1_tables(GPCCR_PGS_4K, - ARM_L1_GPT_BASE, - ARM_L1_GPT_SIZE, - pas_regions, - (unsigned int)(sizeof(pas_regions) / - sizeof(pas_region_t))) < 0) { + if (gpt_init_pas_l1_tables(arm_gpt_info->pgs, + arm_gpt_info->l1_base, + arm_gpt_info->l1_size, + arm_gpt_info->pas_region_base, + arm_gpt_info->pas_region_count) < 0) { ERROR("gpt_init_pas_l1_tables() failed!\n"); panic(); } @@ -216,7 +211,7 @@ void arm_bl2_plat_arch_setup(void) enable_mmu_el3(0); /* Initialise and enable granule protection after MMU. */ - arm_bl2_plat_gpt_setup(); + arm_bl2_gpt_setup(); #else enable_mmu_el1(0); #endif From 341df6af6eb911ffd175e129f61fc59efcf9fcea Mon Sep 17 00:00:00 2001 From: Rohit Mathew Date: Sun, 21 Jan 2024 22:49:08 +0000 Subject: [PATCH 3/3] feat(arm): move GPT setup to common BL source As of now, GPT setup is being handled from BL2 for plat/arm platforms. However, for platforms having a separate entity to load firmware images, it is possible for BL31 to setup the GPT. In order to address this concern, move the GPT setup implementation from arm_bl2_setup.c file to arm_common.c. Additionally, rename the API from arm_bl2_gpt_setup to arm_gpt_setup to make it boot stage agnostic. Signed-off-by: Rohit Mathew Change-Id: I35d17a179c8746945c69db37fd23d763a7774ddc --- .../granule-protection-tables-design.rst | 2 +- include/plat/arm/common/plat_arm.h | 1 + plat/arm/common/arm_bl2_setup.c | 42 +------------------ plat/arm/common/arm_common.c | 42 ++++++++++++++++++- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst index 7a4ffcf0b..9d85bef82 100644 --- a/docs/components/granule-protection-tables-design.rst +++ b/docs/components/granule-protection-tables-design.rst @@ -81,7 +81,7 @@ below. In the reference implementation for FVP models, you can find an example of PAS region definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``. -Table creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and +Table creation API calls can be found in ``plat/arm/common/arm_common.c`` and runtime initialization API calls can be seen in ``plat/arm/common/arm_bl31_setup.c``. diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 97f544630..4c425a70c 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -375,6 +375,7 @@ unsigned int plat_arm_calc_core_pos(u_register_t mpidr); const mmap_region_t *plat_arm_get_mmap(void); const arm_gpt_info_t *plat_arm_get_gpt_info(void); +void arm_gpt_setup(void); /* Allow platform to override psci_pm_ops during runtime */ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops); diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 3ef561a92..30d064791 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -131,46 +131,6 @@ void bl2_platform_setup(void) arm_bl2_platform_setup(); } -#if ENABLE_RME -static void arm_bl2_gpt_setup(void) -{ - /* - * It is to be noted that any Arm platform that reuses arm_bl2_gpt_setup - * must implement plat_arm_get_gpt_info within its platform code - */ - const arm_gpt_info_t *arm_gpt_info = - plat_arm_get_gpt_info(); - - if (arm_gpt_info == NULL) { - ERROR("arm_gpt_info not initialized!!\n"); - panic(); - } - - /* Initialize entire protected space to GPT_GPI_ANY. */ - if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base, - arm_gpt_info->l0_size) < 0) { - ERROR("gpt_init_l0_tables() failed!\n"); - panic(); - } - - /* Carve out defined PAS ranges. */ - if (gpt_init_pas_l1_tables(arm_gpt_info->pgs, - arm_gpt_info->l1_base, - arm_gpt_info->l1_size, - arm_gpt_info->pas_region_base, - arm_gpt_info->pas_region_count) < 0) { - ERROR("gpt_init_pas_l1_tables() failed!\n"); - panic(); - } - - INFO("Enabling Granule Protection Checks\n"); - if (gpt_enable() < 0) { - ERROR("gpt_enable() failed!\n"); - panic(); - } -} -#endif /* ENABLE_RME */ - /******************************************************************************* * Perform the very early platform specific architectural setup here. * When RME is enabled the secure environment is initialised before @@ -211,7 +171,7 @@ void arm_bl2_plat_arch_setup(void) enable_mmu_el3(0); /* Initialise and enable granule protection after MMU. */ - arm_bl2_gpt_setup(); + arm_gpt_setup(); #else enable_mmu_el1(0); #endif diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index fc681149e..21cc39ccf 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -241,3 +241,43 @@ const mmap_region_t *plat_get_addr_mmap(void) { return plat_arm_mmap; } + +#if ENABLE_RME +void arm_gpt_setup(void) +{ + /* + * It is to be noted that any Arm platform that reuses arm_gpt_setup + * must implement plat_arm_get_gpt_info within its platform code + */ + const arm_gpt_info_t *arm_gpt_info = + plat_arm_get_gpt_info(); + + if (arm_gpt_info == NULL) { + ERROR("arm_gpt_info not initialized!!\n"); + panic(); + } + + /* Initialize entire protected space to GPT_GPI_ANY. */ + if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base, + arm_gpt_info->l0_size) < 0) { + ERROR("gpt_init_l0_tables() failed!\n"); + panic(); + } + + /* Carve out defined PAS ranges. */ + if (gpt_init_pas_l1_tables(arm_gpt_info->pgs, + arm_gpt_info->l1_base, + arm_gpt_info->l1_size, + arm_gpt_info->pas_region_base, + arm_gpt_info->pas_region_count) < 0) { + ERROR("gpt_init_pas_l1_tables() failed!\n"); + panic(); + } + + INFO("Enabling Granule Protection Checks\n"); + if (gpt_enable() < 0) { + ERROR("gpt_enable() failed!\n"); + panic(); + } +} +#endif /* ENABLE_RME */