From 4693ff7225faadc5ad1bcd1c2fb3fbbb8fe1aed0 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 8 Jul 2021 17:13:09 -0500 Subject: feat(rme): add Realm security state definition FEAT_RME introduces two additional security states, Root and Realm security states. This patch adds Realm security state awareness to SMCCC helpers and entry point info structure. Signed-off-by: Zelalem Aweke Change-Id: I9cdefcc1aa71259b2de46e5fb62b28d658fa59bd --- include/lib/smccc.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'include/lib') diff --git a/include/lib/smccc.h b/include/lib/smccc.h index deaeb1d1d..1a39f24c7 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -108,9 +108,24 @@ #define SMC_ARCH_CALL_NOT_REQUIRED -2 #define SMC_ARCH_CALL_INVAL_PARAM -3 -/* Various flags passed to SMC handlers */ +/* + * Various flags passed to SMC handlers + * + * Bit 5 and bit 0 of the flag are used to + * determine the source security state as + * follows: + * --------------------------------- + * Bit 5 | Bit 0 | Security state + * --------------------------------- + * 0 0 SMC_FROM_SECURE + * 0 1 SMC_FROM_NON_SECURE + * 1 1 SMC_FROM_REALM + */ + #define SMC_FROM_SECURE (U(0) << 0) #define SMC_FROM_NON_SECURE (U(1) << 0) +#define SMC_FROM_REALM U(0x21) +#define SMC_FROM_MASK U(0x21) #ifndef __ASSEMBLER__ @@ -118,8 +133,18 @@ #include +#if ENABLE_RME +#define is_caller_non_secure(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_NON_SECURE) +#define is_caller_secure(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_SECURE) +#define is_caller_realm(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_REALM) +#define caller_sec_state(_f) ((_f) & SMC_FROM_MASK) +#else /* ENABLE_RME */ #define is_caller_non_secure(_f) (((_f) & SMC_FROM_NON_SECURE) != U(0)) #define is_caller_secure(_f) (!is_caller_non_secure(_f)) +#endif /* ENABLE_RME */ /* The macro below is used to identify a Standard Service SMC call */ #define is_std_svc_call(_fid) (GET_SMC_OEN(_fid) == OEN_STD_START) -- cgit v1.2.3 From 362182386bafbda9e6671be921fa30cc20610d30 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 8 Jul 2021 17:23:04 -0500 Subject: feat(rme): add xlat table library changes for FEAT_RME FEAT_RME adds a new bit (NSE) in the translation table descriptor to determine the Physical Address Space (PAS) of an EL3 stage 1 translation according to the following mapping: TTD.NSE TTD.NS | PAS ================================= 0 0 | Secure 0 1 | Non-secure 1 0 | Root 1 1 | Realm This patch adds modifications to version 2 of the translation table library accordingly. Bits 4 and 5 in mmap attribute are used to determine the PAS. Signed-off-by: Zelalem Aweke Change-Id: I82790f6900b7a1ab9494c732eac7b9808a388103 --- include/lib/xlat_tables/xlat_tables.h | 9 ++++++++- include/lib/xlat_tables/xlat_tables_defs.h | 3 ++- include/lib/xlat_tables/xlat_tables_v2.h | 30 ++++++++++++++++++++++-------- 3 files changed, 32 insertions(+), 10 deletions(-) (limited to 'include/lib') diff --git a/include/lib/xlat_tables/xlat_tables.h b/include/lib/xlat_tables/xlat_tables.h index 082bb5e45..a15696976 100644 --- a/include/lib/xlat_tables/xlat_tables.h +++ b/include/lib/xlat_tables/xlat_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -72,6 +72,13 @@ #define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) #define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) +/* Memory type for EL3 regions */ +#if ENABLE_RME +#error FEAT_RME requires version 2 of the Translation Tables Library +#else +#define EL3_PAS MT_SECURE +#endif + /* * Structure for specifying a single region of memory. */ diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index 579d8d89c..2d0949b51 100644 --- a/include/lib/xlat_tables/xlat_tables_defs.h +++ b/include/lib/xlat_tables/xlat_tables_defs.h @@ -1,5 +1,5 @@ /* - * 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 */ @@ -142,6 +142,7 @@ #define AP_NO_ACCESS_UNPRIVILEGED (AP1_NO_ACCESS_UNPRIVILEGED << 4) #define AP_ONE_VA_RANGE_RES1 (AP1_RES1 << 4) #define NS (U(0x1) << 3) +#define EL3_S1_NSE (U(0x1) << 9) #define ATTR_NON_CACHEABLE_INDEX ULL(0x2) #define ATTR_DEVICE_INDEX ULL(0x1) #define ATTR_IWBWA_OWBWA_NTR_INDEX ULL(0x0) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 359b9839a..69ad02764 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -1,5 +1,5 @@ /* - * 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 */ @@ -60,17 +60,22 @@ #define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK) /* Access permissions (RO/RW) */ #define MT_PERM_SHIFT U(3) -/* Security state (SECURE/NS) */ -#define MT_SEC_SHIFT U(4) + +/* Physical address space (SECURE/NS/Root/Realm) */ +#define MT_PAS_SHIFT U(4) +#define MT_PAS_MASK (U(3) << MT_PAS_SHIFT) +#define MT_PAS(_attr) ((_attr) & MT_PAS_MASK) + /* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ -#define MT_EXECUTE_SHIFT U(5) +#define MT_EXECUTE_SHIFT U(6) /* In the EL1&0 translation regime, User (EL0) or Privileged (EL1). */ -#define MT_USER_SHIFT U(6) +#define MT_USER_SHIFT U(7) /* Shareability attribute for the memory region */ -#define MT_SHAREABILITY_SHIFT U(7) +#define MT_SHAREABILITY_SHIFT U(8) #define MT_SHAREABILITY_MASK (U(3) << MT_SHAREABILITY_SHIFT) #define MT_SHAREABILITY(_attr) ((_attr) & MT_SHAREABILITY_MASK) + /* All other bits are reserved */ /* @@ -91,8 +96,10 @@ #define MT_RO (U(0) << MT_PERM_SHIFT) #define MT_RW (U(1) << MT_PERM_SHIFT) -#define MT_SECURE (U(0) << MT_SEC_SHIFT) -#define MT_NS (U(1) << MT_SEC_SHIFT) +#define MT_SECURE (U(0) << MT_PAS_SHIFT) +#define MT_NS (U(1) << MT_PAS_SHIFT) +#define MT_ROOT (U(2) << MT_PAS_SHIFT) +#define MT_REALM (U(3) << MT_PAS_SHIFT) /* * Access permissions for instruction execution are only relevant for normal @@ -149,6 +156,13 @@ typedef struct mmap_region { #define EL3_REGIME 3 #define EL_REGIME_INVALID -1 +/* Memory type for EL3 regions. With RME, EL3 is in ROOT PAS */ +#if ENABLE_RME +#define EL3_PAS MT_ROOT +#else +#define EL3_PAS MT_SECURE +#endif /* ENABLE_RME */ + /* * Declare the translation context type. * Its definition is private. -- cgit v1.2.3 From c5ea4f8a6679131010636eb524d2a15b709d0196 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 17:54:30 -0500 Subject: feat(rme): add context management changes for FEAT_RME This patch adds a new context for realm world and realm world awareness in context management. Signed-off-by: Zelalem Aweke Signed-off-by: Subhasish Ghosh Change-Id: Ic17469393603e789d7adc025880346bc3d6233d7 --- include/lib/el3_runtime/aarch64/context.h | 13 +++--- include/lib/el3_runtime/cpu_data.h | 73 ++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 19 deletions(-) (limited to 'include/lib') diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index c3f41179f..698e20876 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -405,13 +405,12 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); = (uint64_t) (val)) /* - * Top-level context structure which is used by EL3 firmware to - * preserve the state of a core at EL1 in one of the two security - * states and save enough EL3 meta data to be able to return to that - * EL and security state. The context management library will be used - * to ensure that SP_EL3 always points to an instance of this - * structure at exception entry and exit. Each instance will - * correspond to either the secure or the non-secure state. + * Top-level context structure which is used by EL3 firmware to preserve + * the state of a core at the next lower EL in a given security state and + * save enough EL3 meta data to be able to return to that EL and security + * state. The context management library will be used to ensure that + * SP_EL3 always points to an instance of this structure at exception + * entry and exit. */ typedef struct cpu_context { gp_regs_t gpregs_ctx; diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h index 3d57a5c59..2c7b61967 100644 --- a/include/lib/el3_runtime/cpu_data.h +++ b/include/lib/el3_runtime/cpu_data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,16 +19,25 @@ /* 8-bytes aligned size of psci_cpu_data structure */ #define PSCI_CPU_DATA_SIZE_ALIGNED ((PSCI_CPU_DATA_SIZE + 7) & ~7) +#if ENABLE_RME +/* Size of cpu_context array */ +#define CPU_DATA_CONTEXT_NUM 3 /* Offset of cpu_ops_ptr, size 8 bytes */ +#define CPU_DATA_CPU_OPS_PTR 0x18 +#else /* ENABLE_RME */ +#define CPU_DATA_CONTEXT_NUM 2 #define CPU_DATA_CPU_OPS_PTR 0x10 +#endif /* ENABLE_RME */ #if ENABLE_PAUTH /* 8-bytes aligned offset of apiakey[2], size 16 bytes */ -#define CPU_DATA_APIAKEY_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED) -#define CPU_DATA_CRASH_BUF_OFFSET (CPU_DATA_APIAKEY_OFFSET + 0x10) -#else -#define CPU_DATA_CRASH_BUF_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED) -#endif /* ENABLE_PAUTH */ +#define CPU_DATA_APIAKEY_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \ + + CPU_DATA_CPU_OPS_PTR) +#define CPU_DATA_CRASH_BUF_OFFSET (0x10 + CPU_DATA_APIAKEY_OFFSET) +#else /* ENABLE_PAUTH */ +#define CPU_DATA_CRASH_BUF_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \ + + CPU_DATA_CPU_OPS_PTR) +#endif /* ENABLE_PAUTH */ /* need enough space in crash buffer to save 8 registers */ #define CPU_DATA_CRASH_BUF_SIZE 64 @@ -65,11 +74,14 @@ #ifndef __ASSEMBLER__ +#include +#include + #include #include #include + #include -#include /* Offsets for the cpu_data structure */ #define CPU_DATA_PSCI_LOCK_OFFSET __builtin_offsetof\ @@ -80,27 +92,34 @@ (cpu_data_t, platform_cpu_data) #endif +typedef enum context_pas { + CPU_CONTEXT_SECURE = 0, + CPU_CONTEXT_NS, +#if ENABLE_RME + CPU_CONTEXT_REALM, +#endif + CPU_CONTEXT_NUM +} context_pas_t; + /******************************************************************************* * Function & variable prototypes ******************************************************************************/ /******************************************************************************* * Cache of frequently used per-cpu data: - * Pointers to non-secure and secure security state contexts + * Pointers to non-secure, realm, and secure security state contexts * Address of the crash stack * It is aligned to the cache line boundary to allow efficient concurrent * manipulation of these pointers on different cpus * - * TODO: Add other commonly used variables to this (tf_issues#90) - * * The data structure and the _cpu_data accessors should not be used directly * by components that have per-cpu members. The member access macros should be * used for this. ******************************************************************************/ typedef struct cpu_data { #ifdef __aarch64__ - void *cpu_context[2]; -#endif + void *cpu_context[CPU_DATA_CONTEXT_NUM]; +#endif /* __aarch64__ */ uintptr_t cpu_ops_ptr; struct psci_cpu_data psci_svc_cpu_data; #if ENABLE_PAUTH @@ -122,6 +141,11 @@ typedef struct cpu_data { extern cpu_data_t percpu_data[PLATFORM_CORE_COUNT]; +#ifdef __aarch64__ +CASSERT(CPU_DATA_CONTEXT_NUM == CPU_CONTEXT_NUM, + assert_cpu_data_context_num_mismatch); +#endif + #if ENABLE_PAUTH CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof (cpu_data_t, apiakey), @@ -160,6 +184,31 @@ static inline struct cpu_data *_cpu_data(void) struct cpu_data *_cpu_data(void); #endif +/* + * Returns the index of the cpu_context array for the given security state. + * All accesses to cpu_context should be through this helper to make sure + * an access is not out-of-bounds. The function assumes security_state is + * valid. + */ +static inline context_pas_t get_cpu_context_index(uint32_t security_state) +{ + if (security_state == SECURE) { + return CPU_CONTEXT_SECURE; + } else { +#if ENABLE_RME + if (security_state == NON_SECURE) { + return CPU_CONTEXT_NS; + } else { + assert(security_state == REALM); + return CPU_CONTEXT_REALM; + } +#else + assert(security_state == NON_SECURE); + return CPU_CONTEXT_NS; +#endif + } +} + /************************************************************************** * APIs for initialising and accessing per-cpu data *************************************************************************/ -- cgit v1.2.3 From 1839012d5b5d431f7ec307230eae9890a5fe7477 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Tue, 13 Jul 2021 14:05:20 -0500 Subject: feat(rme): add GPT Library This patch introduces the Granule Protection Table (GPT) library code. This implementation will be updated later to be more flexible, as the current implementation is very rigid. Signed-off-by: Zelalem Aweke Change-Id: I3af824a28c6e9a5d36459c0c51d2d9bebfba1505 --- include/lib/gpt/gpt.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++ include/lib/gpt/gpt_defs.h | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 include/lib/gpt/gpt.h create mode 100644 include/lib/gpt/gpt_defs.h (limited to 'include/lib') diff --git a/include/lib/gpt/gpt.h b/include/lib/gpt/gpt.h new file mode 100644 index 000000000..89d30177d --- /dev/null +++ b/include/lib/gpt/gpt.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_H +#define GPT_H + +#include + +#include + +#include "gpt_defs.h" + +#define GPT_DESC_ATTRS(_type, _gpi) \ + ((((_type) & PAS_REG_DESC_TYPE_MASK) \ + << PAS_REG_DESC_TYPE_SHIFT) | \ + (((_gpi) & PAS_REG_GPI_MASK) \ + << PAS_REG_GPI_SHIFT)) + +/* + * Macro to create a GPT entry for this PAS range either as a L0 block + * descriptor or L1 table descriptor depending upon the size of the range. + */ +#define MAP_GPT_REGION(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_ANY, (_gpi)), \ + } + +/* + * Special macro to create a L1 table descriptor at L0 for a 1GB region as + * opposed to creating a block mapping by default. + */ +#define MAP_GPT_REGION_TBL(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, (_gpi)), \ + } + +/* + * Structure for specifying a Granule range and its properties + */ +typedef struct pas_region { + unsigned long long base_pa; /**< Base address for PAS. */ + size_t size; /**< Size of the PAS. */ + unsigned int attrs; /**< PAS GPI and entry type. */ +} pas_region_t; + +/* + * Structure to initialise the Granule Protection Tables. + */ +typedef struct gpt_init_params { + unsigned int pgs; /**< Address Width of Phisical Granule Size. */ + unsigned int pps; /**< Protected Physical Address Size. */ + unsigned int l0gptsz; /**< Granule size on L0 table entry. */ + pas_region_t *pas_regions; /**< PAS regions to protect. */ + unsigned int pas_count; /**< Number of PAS regions to initialise. */ + uintptr_t l0_mem_base; /**< L0 Table base address. */ + size_t l0_mem_size; /**< Size of memory reserved for L0 tables. */ + uintptr_t l1_mem_base; /**< L1 Table base address. */ + size_t l1_mem_size; /**< Size of memory reserved for L1 tables. */ +} gpt_init_params_t; + +/** @brief Initialise the Granule Protection tables. + */ +int gpt_init(gpt_init_params_t *params); + +/** @brief Enable the Granule Protection Checks. + */ +void gpt_enable(void); + +/** @brief Disable the Granule Protection Checks. + */ +void gpt_disable(void); + +/** @brief Transition a granule between security states. + */ +int gpt_transition_pas(uint64_t pa, + unsigned int src_sec_state, + unsigned int target_pas); + +#endif /* GPT_H */ diff --git a/include/lib/gpt/gpt_defs.h b/include/lib/gpt/gpt_defs.h new file mode 100644 index 000000000..6122a126f --- /dev/null +++ b/include/lib/gpt/gpt_defs.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_DEFS_H +#define GPT_DEFS_H + +#include +#include + +#include "gpt.h" + +/* GPI values */ +#define GPI_NO_ACCESS U(0x0) +#define GPI_SECURE U(0x8) +#define GPI_NS U(0x9) +#define GPI_ROOT U(0xa) +#define GPI_REALM U(0xb) +#define GPI_ANY U(0xf) +#define GPI_VAL_MASK ULL(0xf) + +/* GPT descriptor bit definitions */ +#define GPT_L1_INDEX_MASK ULL(0xf) +#define GPT_L1_INDEX_SHIFT ULL(0x0) + +#define GPT_TBL_DESC ULL(0x3) +#define GPT_BLK_DESC ULL(0x1) + +#define GPT_TBL_DESC_ADDR_SHIFT ULL(12) +#define GPT_TBL_DESC_ADDR_MASK (((ULL(1) << \ + (51 - GPT_TBL_DESC_ADDR_SHIFT)) - 1) \ + << GPT_TBL_DESC_ADDR_SHIFT) + +#define GPT_BLOCK_DESC_GPI_VAL_SHIFT ULL(4) + +/* Each descriptor is 8 bytes long. */ +#define GPT_DESC_SIZE ULL(8) + +#define PPS_MAX_VAL PSTCR_EL3_PPS_4PB +#define PPS_NUM_1GB_ENTRIES ULL(1024) +#define PGS_4K_1GB_L1_TABLE_SZ (U(2) << 17) + +/* 2 << LOG2_8K = Bytes in 8K */ +#define LOG2_8K U(13) + +#define GPT_L1_SIZE ULL(0x40000) /* 256K */ +#define SZ_1G (ULL(0x1) << 30) /* 1GB */ + +#define GPT_MIN_PGS_SHIFT U(12) /* 4K */ + +#define L1_GPT_INDEX_MASK U(0x3fffffff) +#define GPT_GRAN_DESC_NUM_GPIS U(4) + +#define PAS_REG_GPI_SHIFT U(0) +#define PAS_REG_GPI_MASK U(0xf) + +/* .attrs field definitions */ +#define PAS_REG_DESC_TYPE_ANY U(0) +#define PAS_REG_DESC_TYPE_BLK U(1) +#define PAS_REG_DESC_TYPE_TBL U(2) +#define PAS_REG_DESC_TYPE_SHIFT U(4) +#define PAS_REG_DESC_TYPE_MASK U(0x3) +#define PAS_REG_DESC_TYPE(_attrs) (((_attrs) \ + >> PAS_REG_DESC_TYPE_SHIFT) \ + & PAS_REG_DESC_TYPE_MASK) + +#define PAS_REG_GPI(_attrs) (((_attrs) \ + >> PAS_REG_GPI_SHIFT) \ + & PAS_REG_GPI_MASK) + +#define SZ_1G_MASK (SZ_1G - U(1)) +#define IS_1GB_ALIGNED(addr) (((addr) & SZ_1G_MASK) == U(0)) + +#endif /* GPT_DEFS */ -- cgit v1.2.3 From f19dc624a17c9df6aa444e33568b1f70ff4e9341 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 16 Jun 2021 17:57:28 -0500 Subject: refactor(gpt): productize and refactor GPT library This patch updates and refactors the GPT library and fixes bugs. - Support all combinations of PGS, PPS, and L0GPTSZ parameters. - PPS and PGS are set at runtime, L0GPTSZ is read from GPCCR_EL3. - Use compiler definitions to simplify code. - Renaming functions to better suit intended uses. - MMU enabled before GPT APIs called. - Add comments to make function usage more clear in GPT library. - Added _rme suffix to file names to differentiate better from the GPT file system code. - Renamed gpt_defs.h to gpt_rme_private.h to better separate private and public code. - Renamed gpt_core.c to gpt_rme.c to better conform to TF-A precedent. Signed-off-by: John Powell Change-Id: I4cbb23b0f81e697baa9fb23ba458aa3f7d1ed919 --- include/lib/gpt/gpt.h | 86 ------------- include/lib/gpt/gpt_defs.h | 76 ------------ include/lib/gpt_rme/gpt_rme.h | 276 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+), 162 deletions(-) delete mode 100644 include/lib/gpt/gpt.h delete mode 100644 include/lib/gpt/gpt_defs.h create mode 100644 include/lib/gpt_rme/gpt_rme.h (limited to 'include/lib') diff --git a/include/lib/gpt/gpt.h b/include/lib/gpt/gpt.h deleted file mode 100644 index 89d30177d..000000000 --- a/include/lib/gpt/gpt.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GPT_H -#define GPT_H - -#include - -#include - -#include "gpt_defs.h" - -#define GPT_DESC_ATTRS(_type, _gpi) \ - ((((_type) & PAS_REG_DESC_TYPE_MASK) \ - << PAS_REG_DESC_TYPE_SHIFT) | \ - (((_gpi) & PAS_REG_GPI_MASK) \ - << PAS_REG_GPI_SHIFT)) - -/* - * Macro to create a GPT entry for this PAS range either as a L0 block - * descriptor or L1 table descriptor depending upon the size of the range. - */ -#define MAP_GPT_REGION(_pa, _sz, _gpi) \ - { \ - .base_pa = (_pa), \ - .size = (_sz), \ - .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_ANY, (_gpi)), \ - } - -/* - * Special macro to create a L1 table descriptor at L0 for a 1GB region as - * opposed to creating a block mapping by default. - */ -#define MAP_GPT_REGION_TBL(_pa, _sz, _gpi) \ - { \ - .base_pa = (_pa), \ - .size = (_sz), \ - .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, (_gpi)), \ - } - -/* - * Structure for specifying a Granule range and its properties - */ -typedef struct pas_region { - unsigned long long base_pa; /**< Base address for PAS. */ - size_t size; /**< Size of the PAS. */ - unsigned int attrs; /**< PAS GPI and entry type. */ -} pas_region_t; - -/* - * Structure to initialise the Granule Protection Tables. - */ -typedef struct gpt_init_params { - unsigned int pgs; /**< Address Width of Phisical Granule Size. */ - unsigned int pps; /**< Protected Physical Address Size. */ - unsigned int l0gptsz; /**< Granule size on L0 table entry. */ - pas_region_t *pas_regions; /**< PAS regions to protect. */ - unsigned int pas_count; /**< Number of PAS regions to initialise. */ - uintptr_t l0_mem_base; /**< L0 Table base address. */ - size_t l0_mem_size; /**< Size of memory reserved for L0 tables. */ - uintptr_t l1_mem_base; /**< L1 Table base address. */ - size_t l1_mem_size; /**< Size of memory reserved for L1 tables. */ -} gpt_init_params_t; - -/** @brief Initialise the Granule Protection tables. - */ -int gpt_init(gpt_init_params_t *params); - -/** @brief Enable the Granule Protection Checks. - */ -void gpt_enable(void); - -/** @brief Disable the Granule Protection Checks. - */ -void gpt_disable(void); - -/** @brief Transition a granule between security states. - */ -int gpt_transition_pas(uint64_t pa, - unsigned int src_sec_state, - unsigned int target_pas); - -#endif /* GPT_H */ diff --git a/include/lib/gpt/gpt_defs.h b/include/lib/gpt/gpt_defs.h deleted file mode 100644 index 6122a126f..000000000 --- a/include/lib/gpt/gpt_defs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GPT_DEFS_H -#define GPT_DEFS_H - -#include -#include - -#include "gpt.h" - -/* GPI values */ -#define GPI_NO_ACCESS U(0x0) -#define GPI_SECURE U(0x8) -#define GPI_NS U(0x9) -#define GPI_ROOT U(0xa) -#define GPI_REALM U(0xb) -#define GPI_ANY U(0xf) -#define GPI_VAL_MASK ULL(0xf) - -/* GPT descriptor bit definitions */ -#define GPT_L1_INDEX_MASK ULL(0xf) -#define GPT_L1_INDEX_SHIFT ULL(0x0) - -#define GPT_TBL_DESC ULL(0x3) -#define GPT_BLK_DESC ULL(0x1) - -#define GPT_TBL_DESC_ADDR_SHIFT ULL(12) -#define GPT_TBL_DESC_ADDR_MASK (((ULL(1) << \ - (51 - GPT_TBL_DESC_ADDR_SHIFT)) - 1) \ - << GPT_TBL_DESC_ADDR_SHIFT) - -#define GPT_BLOCK_DESC_GPI_VAL_SHIFT ULL(4) - -/* Each descriptor is 8 bytes long. */ -#define GPT_DESC_SIZE ULL(8) - -#define PPS_MAX_VAL PSTCR_EL3_PPS_4PB -#define PPS_NUM_1GB_ENTRIES ULL(1024) -#define PGS_4K_1GB_L1_TABLE_SZ (U(2) << 17) - -/* 2 << LOG2_8K = Bytes in 8K */ -#define LOG2_8K U(13) - -#define GPT_L1_SIZE ULL(0x40000) /* 256K */ -#define SZ_1G (ULL(0x1) << 30) /* 1GB */ - -#define GPT_MIN_PGS_SHIFT U(12) /* 4K */ - -#define L1_GPT_INDEX_MASK U(0x3fffffff) -#define GPT_GRAN_DESC_NUM_GPIS U(4) - -#define PAS_REG_GPI_SHIFT U(0) -#define PAS_REG_GPI_MASK U(0xf) - -/* .attrs field definitions */ -#define PAS_REG_DESC_TYPE_ANY U(0) -#define PAS_REG_DESC_TYPE_BLK U(1) -#define PAS_REG_DESC_TYPE_TBL U(2) -#define PAS_REG_DESC_TYPE_SHIFT U(4) -#define PAS_REG_DESC_TYPE_MASK U(0x3) -#define PAS_REG_DESC_TYPE(_attrs) (((_attrs) \ - >> PAS_REG_DESC_TYPE_SHIFT) \ - & PAS_REG_DESC_TYPE_MASK) - -#define PAS_REG_GPI(_attrs) (((_attrs) \ - >> PAS_REG_GPI_SHIFT) \ - & PAS_REG_GPI_MASK) - -#define SZ_1G_MASK (SZ_1G - U(1)) -#define IS_1GB_ALIGNED(addr) (((addr) & SZ_1G_MASK) == U(0)) - -#endif /* GPT_DEFS */ diff --git a/include/lib/gpt_rme/gpt_rme.h b/include/lib/gpt_rme/gpt_rme.h new file mode 100644 index 000000000..379b91562 --- /dev/null +++ b/include/lib/gpt_rme/gpt_rme.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_RME_H +#define GPT_RME_H + +#include + +#include + +/******************************************************************************/ +/* GPT helper macros and definitions */ +/******************************************************************************/ + +/* + * Structure for specifying a mapping range and it's properties. This should not + * be manually initialized, using the MAP_GPT_REGION_x macros is recommended as + * to avoid potential incompatibilities in the future. + */ +typedef struct pas_region { + uintptr_t base_pa; /* Base address for PAS. */ + size_t size; /* Size of the PAS. */ + unsigned int attrs; /* PAS GPI and entry type. */ +} pas_region_t; + +/* GPT GPI definitions */ +#define GPT_GPI_NO_ACCESS U(0x0) +#define GPT_GPI_SECURE U(0x8) +#define GPT_GPI_NS U(0x9) +#define GPT_GPI_ROOT U(0xA) +#define GPT_GPI_REALM U(0xB) +#define GPT_GPI_ANY U(0xF) +#define GPT_GPI_VAL_MASK UL(0xF) + +/* PAS attribute GPI definitions. */ +#define GPT_PAS_ATTR_GPI_SHIFT U(0) +#define GPT_PAS_ATTR_GPI_MASK U(0xF) +#define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \ + >> GPT_PAS_ATTR_GPI_SHIFT) \ + & GPT_PAS_ATTR_GPI_MASK) + +/* PAS attribute mapping type definitions */ +#define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0) +#define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1) +#define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4) +#define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1) +#define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \ + >> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \ + & GPT_PAS_ATTR_MAP_TYPE_MASK) + +/* + * Macro to initialize the attributes field in the pas_region_t structure. + * [31:5] Reserved + * [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions) + * [3:0] PAS GPI type (GPT_GPI_x definitions) + */ +#define GPT_PAS_ATTR(_type, _gpi) \ + ((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \ + << GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \ + (((_gpi) & GPT_PAS_ATTR_GPI_MASK) \ + << GPT_PAS_ATTR_GPI_SHIFT)) + +/* + * Macro to create a GPT entry for this PAS range as a block descriptor. If this + * region does not fit the requirements for a block descriptor then GPT + * initialization will fail. + */ +#define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \ + } + +/* + * Macro to create a GPT entry for this PAS range as a table descriptor. If this + * region does not fit the requirements for a table descriptor then GPT + * initialization will fail. + */ +#define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \ + } + +/******************************************************************************/ +/* GPT register field definitions */ +/******************************************************************************/ + +/* + * Least significant address bits protected by each entry in level 0 GPT. This + * field is read-only. + */ +#define GPCCR_L0GPTSZ_SHIFT U(20) +#define GPCCR_L0GPTSZ_MASK U(0xF) + +typedef enum { + GPCCR_L0GPTSZ_30BITS = U(0x0), + GPCCR_L0GPTSZ_34BITS = U(0x4), + GPCCR_L0GPTSZ_36BITS = U(0x6), + GPCCR_L0GPTSZ_39BITS = U(0x9) +} gpccr_l0gptsz_e; + +/* Granule protection check priority bit definitions */ +#define GPCCR_GPCP_SHIFT U(17) +#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) + +/* Granule protection check bit definitions */ +#define GPCCR_GPC_SHIFT U(16) +#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) + +/* Physical granule size bit definitions */ +#define GPCCR_PGS_SHIFT U(14) +#define GPCCR_PGS_MASK U(0x3) +#define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) + +typedef enum { + GPCCR_PGS_4K = U(0x0), + GPCCR_PGS_64K = U(0x1), + GPCCR_PGS_16K = U(0x2) +} gpccr_pgs_e; + +/* GPT fetch shareability attribute bit definitions */ +#define GPCCR_SH_SHIFT U(12) +#define GPCCR_SH_MASK U(0x3) +#define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) + +typedef enum { + GPCCR_SH_NS = U(0x0), + GPCCR_SH_OS = U(0x2), + GPCCR_SH_IS = U(0x3) +} gpccr_sh_e; + +/* GPT fetch outer cacheability attribute bit definitions */ +#define GPCCR_ORGN_SHIFT U(10) +#define GPCCR_ORGN_MASK U(0x3) +#define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) + +typedef enum { + GPCCR_ORGN_NC = U(0x0), + GPCCR_ORGN_WB_RA_WA = U(0x1), + GPCCR_ORGN_WT_RA_NWA = U(0x2), + GPCCR_ORGN_WB_RA_NWA = U(0x3) +} gpccr_orgn_e; + +/* GPT fetch inner cacheability attribute bit definitions */ +#define GPCCR_IRGN_SHIFT U(8) +#define GPCCR_IRGN_MASK U(0x3) +#define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) + +typedef enum { + GPCCR_IRGN_NC = U(0x0), + GPCCR_IRGN_WB_RA_WA = U(0x1), + GPCCR_IRGN_WT_RA_NWA = U(0x2), + GPCCR_IRGN_WB_RA_NWA = U(0x3) +} gpccr_irgn_e; + +/* Protected physical address size bit definitions */ +#define GPCCR_PPS_SHIFT U(0) +#define GPCCR_PPS_MASK U(0x7) +#define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) + +typedef enum { + GPCCR_PPS_4GB = U(0x0), + GPCCR_PPS_64GB = U(0x1), + GPCCR_PPS_1TB = U(0x2), + GPCCR_PPS_4TB = U(0x3), + GPCCR_PPS_16TB = U(0x4), + GPCCR_PPS_256TB = U(0x5), + GPCCR_PPS_4PB = U(0x6) +} gpccr_pps_e; + +/* Base Address for the GPT bit definitions */ +#define GPTBR_BADDR_SHIFT U(0) +#define GPTBR_BADDR_VAL_SHIFT U(12) +#define GPTBR_BADDR_MASK ULL(0xffffffffff) + +/******************************************************************************/ +/* GPT public APIs */ +/******************************************************************************/ + +/* + * Public API that initializes the entire protected space to GPT_GPI_ANY using + * the L0 tables (block descriptors). Ideally, this function is invoked prior + * to DDR discovery and initialization. The MMU must be initialized before + * calling this function. + * + * Parameters + * pps PPS value to use for table generation + * l0_mem_base Base address of L0 tables in memory. + * l0_mem_size Total size of memory available for L0 tables. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_l0_tables(gpccr_pps_e pps, + uintptr_t l0_mem_base, + size_t l0_mem_size); + +/* + * Public API that carves out PAS regions from the L0 tables and builds any L1 + * tables that are needed. This function ideally is run after DDR discovery and + * initialization. The L0 tables must have already been initialized to GPI_ANY + * when this function is called. + * + * Parameters + * pgs PGS value to use for table generation. + * l1_mem_base Base address of memory used for L1 tables. + * l1_mem_size Total size of memory available for L1 tables. + * *pas_regions Pointer to PAS regions structure array. + * pas_count Total number of PAS regions. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, + uintptr_t l1_mem_base, + size_t l1_mem_size, + pas_region_t *pas_regions, + unsigned int pas_count); + +/* + * Public API to initialize the runtime gpt_config structure based on the values + * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization + * typically happens in a bootloader stage prior to setting up the EL3 runtime + * environment for the granule transition service so this function detects the + * initialization from a previous stage. Granule protection checks must be + * enabled already or this function will return an error. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_runtime_init(void); + +/* + * Public API to enable granule protection checks once the tables have all been + * initialized. This function is called at first initialization and then again + * later during warm boots of CPU cores. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_enable(void); + +/* + * Public API to disable granule protection checks. + */ +void gpt_disable(void); + +/* + * This function is the core of the granule transition service. When a granule + * transition request occurs it is routed to this function where the request is + * validated then fulfilled if possible. + * + * TODO: implement support for transitioning multiple granules at once. + * + * Parameters + * base: Base address of the region to transition, must be aligned to granule + * size. + * size: Size of region to transition, must be aligned to granule size. + * src_sec_state: Security state of the caller. + * target_pas: Target PAS of the specified memory region. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_transition_pas(uint64_t base, + size_t size, + unsigned int src_sec_state, + unsigned int target_pas); + +#endif /* GPT_RME_H */ -- cgit v1.2.3