mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 13:53:54 +00:00
feat(gpt): add support for large GPT mappings
This patch adds support for large GPT mappings using Contiguous descriptors. The maximum size of supported contiguous block in MB is defined in RME_GPT_MAX_BLOCK build parameter and takes values 0, 2, 32 and 512 and by default set to 2 in make_helpers/defaults.mk. Setting RME_GPT_MAX_BLOCK value to 0 disables use of Contiguous descriptors. Function gpt_tlbi_by_pa_ll() and its declaration are removed from lib/aarch64/misc_helpers.S and include/arch/aarch64/arch_helpers.h, because the GPT library now uses tlbirpalos_xxx() functions. Change-Id: Ia9a59bde1741c5666b4ca1de9324e6dfd6f734eb Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
This commit is contained in:
parent
85ea97f972
commit
ec0088bbab
9 changed files with 960 additions and 238 deletions
1
Makefile
1
Makefile
|
@ -1331,6 +1331,7 @@ $(eval $(call add_defines,\
|
|||
PSCI_EXTENDED_STATE_ID \
|
||||
PSCI_OS_INIT_MODE \
|
||||
RESET_TO_BL31 \
|
||||
RME_GPT_MAX_BLOCK \
|
||||
SEPARATE_CODE_AND_RODATA \
|
||||
SEPARATE_BL2_NOLOAD_REGION \
|
||||
SEPARATE_NOBITS_REGION \
|
||||
|
|
|
@ -812,6 +812,11 @@ Common build options
|
|||
instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
|
||||
entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
|
||||
|
||||
- ``RME_GPT_MAX_BLOCK``: Numeric value in MB to define maximum size of
|
||||
supported contiguous blocks in GPT Library. This parameter can take the
|
||||
values 0, 2, 32 and 512. Setting this value to 0 disables use of Contigious
|
||||
descriptors. Default value is 2.
|
||||
|
||||
- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
|
||||
file that contains the ROT private key in PEM format or a PKCS11 URI and
|
||||
enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is
|
||||
|
|
|
@ -807,15 +807,6 @@ static inline void tlbirpalos_512m(uintptr_t addr)
|
|||
TLBIRPALOS(addr, TLBI_SZ_512M);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate TLBs of GPT entries by Physical address, last level.
|
||||
*
|
||||
* @pa: the starting address for the range
|
||||
* of invalidation
|
||||
* @size: size of the range of invalidation
|
||||
*/
|
||||
void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
|
||||
|
||||
/* Previously defined accessor functions with incomplete register names */
|
||||
|
||||
#define read_current_el() read_CurrentEl()
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -15,7 +15,6 @@
|
|||
.globl zero_normalmem
|
||||
.globl zeromem
|
||||
.globl memcpy16
|
||||
.globl gpt_tlbi_by_pa_ll
|
||||
|
||||
.globl disable_mmu_el1
|
||||
.globl disable_mmu_el3
|
||||
|
@ -594,20 +593,3 @@ func fixup_gdt_reloc
|
|||
b.lo 1b
|
||||
ret
|
||||
endfunc fixup_gdt_reloc
|
||||
|
||||
/*
|
||||
* TODO: Currently only supports size of 4KB,
|
||||
* support other sizes as well.
|
||||
*/
|
||||
func gpt_tlbi_by_pa_ll
|
||||
#if ENABLE_ASSERTIONS
|
||||
cmp x1, #PAGE_SIZE_4KB
|
||||
ASM_ASSERT(eq)
|
||||
tst x0, #(PAGE_SIZE_MASK)
|
||||
ASM_ASSERT(eq)
|
||||
#endif
|
||||
lsr x0, x0, #FOUR_KB_SHIFT /* 4KB size encoding is zero */
|
||||
sys #6, c8, c4, #7, x0 /* TLBI RPALOS, <Xt> */
|
||||
dsb sy
|
||||
ret
|
||||
endfunc gpt_tlbi_by_pa_ll
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,13 @@
|
|||
#
|
||||
# Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Process RME_GPT_MAX_BLOCK value
|
||||
ifeq ($(filter 0 2 32 512, ${RME_GPT_MAX_BLOCK}),)
|
||||
$(error "Invalid value for RME_GPT_MAX_BLOCK: ${RME_GPT_MAX_BLOCK}")
|
||||
endif
|
||||
|
||||
GPT_LIB_SRCS := $(addprefix lib/gpt_rme/, \
|
||||
gpt_rme.c)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <arch.h>
|
||||
#include <lib/gpt_rme/gpt_rme.h>
|
||||
#include <lib/spinlock.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -19,7 +20,7 @@
|
|||
#define GPT_L0_TYPE_MASK UL(0xF)
|
||||
#define GPT_L0_TYPE_SHIFT U(0)
|
||||
|
||||
/* For now, we don't support contiguous descriptors, only table and block */
|
||||
/* GPT level 0 table and block descriptors */
|
||||
#define GPT_L0_TYPE_TBL_DESC UL(3)
|
||||
#define GPT_L0_TYPE_BLK_DESC UL(1)
|
||||
|
||||
|
@ -29,29 +30,63 @@
|
|||
#define GPT_L0_BLK_DESC_GPI_MASK UL(0xF)
|
||||
#define GPT_L0_BLK_DESC_GPI_SHIFT U(4)
|
||||
|
||||
/* GPT level 1 descriptor bit definitions */
|
||||
/* GPT level 1 Contiguous descriptor */
|
||||
#define GPT_L1_TYPE_CONT_DESC_MASK UL(0xF)
|
||||
#define GPT_L1_TYPE_CONT_DESC UL(1)
|
||||
|
||||
/* GPT level 1 Contiguous descriptor definitions */
|
||||
#define GPT_L1_CONTIG_2MB UL(1)
|
||||
#define GPT_L1_CONTIG_32MB UL(2)
|
||||
#define GPT_L1_CONTIG_512MB UL(3)
|
||||
|
||||
#define GPT_L1_CONT_DESC_GPI_SHIFT U(4)
|
||||
#define GPT_L1_CONT_DESC_GPI_MASK UL(0xF)
|
||||
#define GPT_L1_CONT_DESC_CONTIG_SHIFT U(8)
|
||||
#define GPT_L1_CONT_DESC_CONTIG_MASK UL(3)
|
||||
|
||||
/* GPT level 1 Granules descriptor bit definitions */
|
||||
#define GPT_L1_GRAN_DESC_GPI_MASK UL(0xF)
|
||||
|
||||
/* L1 Contiguous descriptors templates */
|
||||
#define GPT_L1_CONT_DESC_2MB \
|
||||
(GPT_L1_TYPE_CONT_DESC | \
|
||||
(GPT_L1_CONTIG_2MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
|
||||
#define GPT_L1_CONT_DESC_32MB \
|
||||
(GPT_L1_TYPE_CONT_DESC | \
|
||||
(GPT_L1_CONTIG_32MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
|
||||
#define GPT_L1_CONT_DESC_512MB \
|
||||
(GPT_L1_TYPE_CONT_DESC | \
|
||||
(GPT_L1_CONTIG_512MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
|
||||
|
||||
/* Create L1 Contiguous descriptor from GPI and template */
|
||||
#define GPT_L1_GPI_CONT_DESC(_gpi, _desc) \
|
||||
((_desc) | ((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
|
||||
|
||||
/* Create L1 Contiguous descriptor from Granules descriptor and size */
|
||||
#define GPT_L1_CONT_DESC(_desc, _size) \
|
||||
(GPT_L1_CONT_DESC_##_size | \
|
||||
(((_desc) & GPT_L1_GRAN_DESC_GPI_MASK) << \
|
||||
GPT_L1_CONT_DESC_GPI_SHIFT))
|
||||
|
||||
/* Create L1 Contiguous descriptor from GPI and size */
|
||||
#define GPT_L1_CONT_DESC_SIZE(_gpi, _size) \
|
||||
(GPT_L1_CONT_DESC_##_size | \
|
||||
(((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
|
||||
|
||||
#define GPT_L1_GPI_BYTE(_gpi) (uint64_t)((_gpi) | ((_gpi) << 4))
|
||||
#define GPT_L1_GPI_HALF(_gpi) (GPT_L1_GPI_BYTE(_gpi) | (GPT_L1_GPI_BYTE(_gpi) << 8))
|
||||
#define GPT_L1_GPI_WORD(_gpi) (GPT_L1_GPI_HALF(_gpi) | (GPT_L1_GPI_HALF(_gpi) << 16))
|
||||
|
||||
/*
|
||||
* This macro fills out every GPI entry in a granules descriptor to the same
|
||||
* value.
|
||||
* This macro generates a Granules descriptor
|
||||
* with the same value for every GPI entry.
|
||||
*/
|
||||
#define GPT_BUILD_L1_DESC(_gpi) (((uint64_t)(_gpi) << 4*0) | \
|
||||
((uint64_t)(_gpi) << 4*1) | \
|
||||
((uint64_t)(_gpi) << 4*2) | \
|
||||
((uint64_t)(_gpi) << 4*3) | \
|
||||
((uint64_t)(_gpi) << 4*4) | \
|
||||
((uint64_t)(_gpi) << 4*5) | \
|
||||
((uint64_t)(_gpi) << 4*6) | \
|
||||
((uint64_t)(_gpi) << 4*7) | \
|
||||
((uint64_t)(_gpi) << 4*8) | \
|
||||
((uint64_t)(_gpi) << 4*9) | \
|
||||
((uint64_t)(_gpi) << 4*10) | \
|
||||
((uint64_t)(_gpi) << 4*11) | \
|
||||
((uint64_t)(_gpi) << 4*12) | \
|
||||
((uint64_t)(_gpi) << 4*13) | \
|
||||
((uint64_t)(_gpi) << 4*14) | \
|
||||
((uint64_t)(_gpi) << 4*15))
|
||||
#define GPT_BUILD_L1_DESC(_gpi) (GPT_L1_GPI_WORD(_gpi) | (GPT_L1_GPI_WORD(_gpi) << 32))
|
||||
|
||||
#define GPT_L1_SECURE_DESC GPT_BUILD_L1_DESC(GPT_GPI_SECURE)
|
||||
#define GPT_L1_NS_DESC GPT_BUILD_L1_DESC(GPT_GPI_NS)
|
||||
#define GPT_L1_REALM_DESC GPT_BUILD_L1_DESC(GPT_GPI_REALM)
|
||||
#define GPT_L1_ANY_DESC GPT_BUILD_L1_DESC(GPT_GPI_ANY)
|
||||
|
||||
/******************************************************************************/
|
||||
/* GPT platform configuration */
|
||||
|
@ -106,17 +141,44 @@ typedef enum {
|
|||
PGS_64KB_P = 16U
|
||||
} gpt_p_val_e;
|
||||
|
||||
#define LOCK_SIZE sizeof(((bitlock_t *)NULL)->lock)
|
||||
#define LOCK_TYPE typeof(((bitlock_t *)NULL)->lock)
|
||||
#define LOCK_BITS (LOCK_SIZE * 8U)
|
||||
|
||||
/*
|
||||
* Internal structure to retrieve the values from get_gpi_info();
|
||||
* Internal structure to retrieve the values from get_gpi_params();
|
||||
*/
|
||||
typedef struct gpi_info {
|
||||
typedef struct {
|
||||
uint64_t gpt_l1_desc;
|
||||
uint64_t *gpt_l1_addr;
|
||||
unsigned int idx;
|
||||
unsigned int gpi_shift;
|
||||
unsigned int gpi;
|
||||
bitlock_t *lock;
|
||||
LOCK_TYPE mask;
|
||||
} gpi_info_t;
|
||||
|
||||
/*
|
||||
* Look up structure for contiguous blocks and descriptors
|
||||
*/
|
||||
typedef struct {
|
||||
size_t size;
|
||||
unsigned int desc;
|
||||
} gpt_fill_lookup_t;
|
||||
|
||||
typedef void (*gpt_shatter_func)(uintptr_t base, const gpi_info_t *gpi_info,
|
||||
uint64_t l1_desc);
|
||||
typedef void (*gpt_tlbi_func)(uintptr_t base);
|
||||
|
||||
/*
|
||||
* Look-up structure for
|
||||
* invalidating TLBs of GPT entries by Physical address, last level.
|
||||
*/
|
||||
typedef struct {
|
||||
gpt_tlbi_func function;
|
||||
size_t mask;
|
||||
} gpt_tlbi_lookup_t;
|
||||
|
||||
/* Max valid value for PGS */
|
||||
#define GPT_PGS_MAX (2U)
|
||||
|
||||
|
@ -136,8 +198,8 @@ typedef struct gpi_info {
|
|||
* special case we'll get a negative width value which does not make sense and
|
||||
* would cause problems.
|
||||
*/
|
||||
#define GPT_L0_IDX_WIDTH(_t) (((_t) > GPT_S_VAL) ? \
|
||||
((_t) - GPT_S_VAL) : (0U))
|
||||
#define GPT_L0_IDX_WIDTH(_t) (((unsigned int)(_t) > GPT_S_VAL) ? \
|
||||
((unsigned int)(_t) - GPT_S_VAL) : (0U))
|
||||
|
||||
/* Bit shift for the L0 index field in a PA */
|
||||
#define GPT_L0_IDX_SHIFT (GPT_S_VAL)
|
||||
|
@ -173,10 +235,11 @@ typedef struct gpi_info {
|
|||
* the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ
|
||||
* (s) will result in a positive width value.
|
||||
*/
|
||||
#define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - ((_p) + 3U))
|
||||
#define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - \
|
||||
((unsigned int)(_p) + 3U))
|
||||
|
||||
/* Bit shift for the L1 index field */
|
||||
#define GPT_L1_IDX_SHIFT(_p) ((_p) + 4U)
|
||||
#define GPT_L1_IDX_SHIFT(_p) ((unsigned int)(_p) + 4U)
|
||||
|
||||
/*
|
||||
* Mask for the L1 index field, must be shifted.
|
||||
|
@ -196,7 +259,10 @@ typedef struct gpi_info {
|
|||
#define GPT_L1_GPI_IDX_MASK (0xF)
|
||||
|
||||
/* Total number of entries in each L1 table */
|
||||
#define GPT_L1_ENTRY_COUNT(_p) ((GPT_L1_IDX_MASK(_p)) + 1U)
|
||||
#define GPT_L1_ENTRY_COUNT(_p) ((GPT_L1_IDX_MASK(_p)) + 1UL)
|
||||
|
||||
/* Number of L1 entries in 2MB block */
|
||||
#define GPT_L1_ENTRY_COUNT_2MB(_p) (SZ_2M >> GPT_L1_IDX_SHIFT(_p))
|
||||
|
||||
/* Total size in bytes of each L1 table */
|
||||
#define GPT_L1_TABLE_SIZE(_p) ((GPT_L1_ENTRY_COUNT(_p)) << 3U)
|
||||
|
@ -206,10 +272,13 @@ typedef struct gpi_info {
|
|||
/******************************************************************************/
|
||||
|
||||
/* Protected space actual size in bytes */
|
||||
#define GPT_PPS_ACTUAL_SIZE(_t) (1UL << (_t))
|
||||
#define GPT_PPS_ACTUAL_SIZE(_t) (1UL << (unsigned int)(_t))
|
||||
|
||||
/* Granule actual size in bytes */
|
||||
#define GPT_PGS_ACTUAL_SIZE(_p) (1UL << (_p))
|
||||
#define GPT_PGS_ACTUAL_SIZE(_p) (1UL << (unsigned int)(_p))
|
||||
|
||||
/* Number of granules in 2MB block */
|
||||
#define GPT_PGS_COUNT_2MB(_p) (1UL << (21U - (unsigned int)(_p)))
|
||||
|
||||
/* L0 GPT region size in bytes */
|
||||
#define GPT_L0GPTSZ_ACTUAL_SIZE (1UL << GPT_S_VAL)
|
||||
|
@ -221,7 +290,8 @@ typedef struct gpi_info {
|
|||
* This definition is used to determine if a physical address lies on an L0
|
||||
* region boundary.
|
||||
*/
|
||||
#define GPT_IS_L0_ALIGNED(_pa) (((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0))
|
||||
#define GPT_IS_L0_ALIGNED(_pa) \
|
||||
(((_pa) & (GPT_L0_REGION_SIZE - UL(1))) == UL(0))
|
||||
|
||||
/* Get the type field from an L0 descriptor */
|
||||
#define GPT_L0_TYPE(_desc) (((_desc) >> GPT_L0_TYPE_SHIFT) & \
|
||||
|
@ -246,16 +316,43 @@ typedef struct gpi_info {
|
|||
(GPT_L0_TBL_DESC_L1ADDR_MASK << \
|
||||
GPT_L0_TBL_DESC_L1ADDR_SHIFT))))
|
||||
|
||||
/* Get the GPI from L1 Contiguous descriptor */
|
||||
#define GPT_L1_CONT_GPI(_desc) \
|
||||
(((_desc) >> GPT_L1_CONT_DESC_GPI_SHIFT) & GPT_L1_CONT_DESC_GPI_MASK)
|
||||
|
||||
/* Get the GPI from L1 Granules descriptor */
|
||||
#define GPT_L1_GRAN_GPI(_desc) ((_desc) & GPT_L1_GRAN_DESC_GPI_MASK)
|
||||
|
||||
/* Get the Contig from L1 Contiguous descriptor */
|
||||
#define GPT_L1_CONT_CONTIG(_desc) \
|
||||
(((_desc) >> GPT_L1_CONT_DESC_CONTIG_SHIFT) & \
|
||||
GPT_L1_CONT_DESC_CONTIG_MASK)
|
||||
|
||||
/* Get the index into the L1 table from a physical address */
|
||||
#define GPT_L1_IDX(_p, _pa) (((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \
|
||||
GPT_L1_IDX_MASK(_p))
|
||||
#define GPT_L1_IDX(_p, _pa) \
|
||||
(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & GPT_L1_IDX_MASK(_p))
|
||||
|
||||
/* Get the index of the GPI within an L1 table entry from a physical address */
|
||||
#define GPT_L1_GPI_IDX(_p, _pa) (((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \
|
||||
GPT_L1_GPI_IDX_MASK)
|
||||
#define GPT_L1_GPI_IDX(_p, _pa) \
|
||||
(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & GPT_L1_GPI_IDX_MASK)
|
||||
|
||||
/* Determine if an address is granule-aligned */
|
||||
#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \
|
||||
== U(0))
|
||||
#define GPT_IS_L1_ALIGNED(_p, _pa) \
|
||||
(((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - UL(1))) == UL(0))
|
||||
|
||||
/* Get aligned addresses */
|
||||
#define ALIGN_2MB(_addr) ((_addr) & ~(SZ_2M - 1UL))
|
||||
#define ALIGN_32MB(_addr) ((_addr) & ~(SZ_32M - 1UL))
|
||||
#define ALIGN_512MB(_addr) ((_addr) & ~(SZ_512M - 1UL))
|
||||
|
||||
/* Determine if region is contiguous */
|
||||
#define GPT_REGION_IS_CONT(_len, _addr, _size) \
|
||||
(((_len) >= (_size)) && (((_addr) & ((_size) - UL(1))) == UL(0)))
|
||||
|
||||
/* Get 32MB block number in 512MB block: 0-15 */
|
||||
#define GET_32MB_NUM(_addr) ((_addr >> 25) & 0xF)
|
||||
|
||||
/* Get 2MB block number in 32MB block: 0-15 */
|
||||
#define GET_2MB_NUM(_addr) ((_addr >> 21) & 0xF)
|
||||
|
||||
#endif /* GPT_RME_PRIVATE_H */
|
||||
|
|
|
@ -139,6 +139,9 @@ FW_ENC_STATUS := 0
|
|||
# For Chain of Trust
|
||||
GENERATE_COT := 0
|
||||
|
||||
# Default maximum size of GPT contiguous block
|
||||
RME_GPT_MAX_BLOCK := 2
|
||||
|
||||
# Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
|
||||
# default, they are for Secure EL1.
|
||||
GICV2_G0_FOR_EL3 := 0
|
||||
|
|
|
@ -24,7 +24,7 @@ FVP_GICR_REGION_PROTECTION := 0
|
|||
|
||||
FVP_DT_PREFIX := fvp-base-gicv3-psci
|
||||
|
||||
# Size (in kilobytes) of the Trusted SRAM region to utilize when building for
|
||||
# Size (in kilobytes) of the Trusted SRAM region to utilize when building for
|
||||
# the FVP platform. This option defaults to 256.
|
||||
FVP_TRUSTED_SRAM_SIZE := 256
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue