1 /* 2 * Copyright (c) 2022-2025, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef GPT_RME_H 8 #define GPT_RME_H 9 10 #include <stdint.h> 11 #include <lib/spinlock.h> 12 13 /******************************************************************************/ 14 /* GPT helper macros and definitions */ 15 /******************************************************************************/ 16 17 #if (RME_GPT_BITLOCK_BLOCK != 0) 18 #define LOCK_SIZE sizeof(((bitlock_t *)NULL)->lock) 19 #define LOCK_TYPE typeof(((bitlock_t *)NULL)->lock) 20 #define LOCK_BITS (LOCK_SIZE * UL(8)) 21 22 CASSERT((UL(1) == LOCK_SIZE), assert_bitlock_type_not_uint8_t); 23 #endif /* RME_GPT_BITLOCK_BLOCK */ 24 25 /* 26 * Structure for specifying a mapping range and it's properties. This should not 27 * be manually initialized, using the MAP_GPT_REGION_x macros is recommended as 28 * to avoid potential incompatibilities in the future. 29 */ 30 typedef struct pas_region { 31 uintptr_t base_pa; /* Base address for PAS. */ 32 size_t size; /* Size of the PAS. */ 33 unsigned int attrs; /* PAS GPI and entry type. */ 34 } pas_region_t; 35 36 /* GPT GPI definitions */ 37 #define GPT_GPI_NO_ACCESS U(0x0) 38 #define GPT_GPI_SECURE U(0x8) 39 #define GPT_GPI_NS U(0x9) 40 #define GPT_GPI_ROOT U(0xA) 41 #define GPT_GPI_REALM U(0xB) 42 #define GPT_GPI_NSO U(0xD) 43 #define GPT_GPI_ANY U(0xF) 44 #define GPT_GPI_VAL_MASK UL(0xF) 45 46 #define GPT_NSE_SECURE U(0b00) 47 #define GPT_NSE_ROOT U(0b01) 48 #define GPT_NSE_NS U(0b10) 49 #define GPT_NSE_REALM U(0b11) 50 51 #define GPT_NSE_SHIFT U(62) 52 53 /* PAS attribute GPI definitions. */ 54 #define GPT_PAS_ATTR_GPI_SHIFT U(0) 55 #define GPT_PAS_ATTR_GPI_MASK U(0xF) 56 #define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \ 57 >> GPT_PAS_ATTR_GPI_SHIFT) \ 58 & GPT_PAS_ATTR_GPI_MASK) 59 60 /* PAS attribute mapping type definitions */ 61 #define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0) 62 #define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1) 63 #define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4) 64 #define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1) 65 #define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \ 66 >> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \ 67 & GPT_PAS_ATTR_MAP_TYPE_MASK) 68 69 /* 70 * Macro to initialize the attributes field in the pas_region_t structure. 71 * [31:5] Reserved 72 * [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions) 73 * [3:0] PAS GPI type (GPT_GPI_x definitions) 74 */ 75 #define GPT_PAS_ATTR(_type, _gpi) \ 76 ((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \ 77 << GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \ 78 (((_gpi) & GPT_PAS_ATTR_GPI_MASK) \ 79 << GPT_PAS_ATTR_GPI_SHIFT)) 80 81 /* 82 * Macro to create a GPT entry for this PAS range as a block descriptor. If this 83 * region does not fit the requirements for a block descriptor then GPT 84 * initialization will fail. 85 */ 86 #define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \ 87 { \ 88 .base_pa = (_pa), \ 89 .size = (_sz), \ 90 .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \ 91 } 92 93 /* 94 * Macro to create a GPT entry for this PAS range as a table descriptor. If this 95 * region does not fit the requirements for a table descriptor then GPT 96 * initialization will fail. 97 */ 98 #define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \ 99 { \ 100 .base_pa = (_pa), \ 101 .size = (_sz), \ 102 .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \ 103 } 104 105 /******************************************************************************/ 106 /* GPT register field definitions */ 107 /******************************************************************************/ 108 109 /* NSO bit definitions */ 110 #define GPCCR_NSO_SHIFT U(19) 111 #define GPCCR_NSO_BIT (ULL(1) << GPCCR_NSO_SHIFT) 112 113 /* 114 * Least significant address bits protected by each entry in level 0 GPT. This 115 * field is read-only. 116 */ 117 #define GPCCR_L0GPTSZ_SHIFT U(20) 118 #define GPCCR_L0GPTSZ_MASK U(0xF) 119 120 typedef enum { 121 GPCCR_L0GPTSZ_30BITS = U(0x0), 122 GPCCR_L0GPTSZ_34BITS = U(0x4), 123 GPCCR_L0GPTSZ_36BITS = U(0x6), 124 GPCCR_L0GPTSZ_39BITS = U(0x9) 125 } gpccr_l0gptsz_e; 126 127 /* Granule protection check priority bit definitions */ 128 #define GPCCR_GPCP_SHIFT U(17) 129 #define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) 130 131 /* Granule protection check bit definitions */ 132 #define GPCCR_GPC_SHIFT U(16) 133 #define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) 134 135 /* Physical granule size bit definitions */ 136 #define GPCCR_PGS_SHIFT U(14) 137 #define GPCCR_PGS_MASK U(0x3) 138 #define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) 139 140 typedef enum { 141 GPCCR_PGS_4K = U(0x0), 142 GPCCR_PGS_64K = U(0x1), 143 GPCCR_PGS_16K = U(0x2) 144 } gpccr_pgs_e; 145 146 /* GPT fetch shareability attribute bit definitions */ 147 #define GPCCR_SH_SHIFT U(12) 148 #define GPCCR_SH_MASK U(0x3) 149 #define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) 150 151 typedef enum { 152 GPCCR_SH_NS = U(0x0), 153 GPCCR_SH_OS = U(0x2), 154 GPCCR_SH_IS = U(0x3) 155 } gpccr_sh_e; 156 157 /* GPT fetch outer cacheability attribute bit definitions */ 158 #define GPCCR_ORGN_SHIFT U(10) 159 #define GPCCR_ORGN_MASK U(0x3) 160 #define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) 161 162 typedef enum { 163 GPCCR_ORGN_NC = U(0x0), 164 GPCCR_ORGN_WB_RA_WA = U(0x1), 165 GPCCR_ORGN_WT_RA_NWA = U(0x2), 166 GPCCR_ORGN_WB_RA_NWA = U(0x3) 167 } gpccr_orgn_e; 168 169 /* GPT fetch inner cacheability attribute bit definitions */ 170 #define GPCCR_IRGN_SHIFT U(8) 171 #define GPCCR_IRGN_MASK U(0x3) 172 #define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) 173 174 typedef enum { 175 GPCCR_IRGN_NC = U(0x0), 176 GPCCR_IRGN_WB_RA_WA = U(0x1), 177 GPCCR_IRGN_WT_RA_NWA = U(0x2), 178 GPCCR_IRGN_WB_RA_NWA = U(0x3) 179 } gpccr_irgn_e; 180 181 /* Protected physical address size bit definitions */ 182 #define GPCCR_PPS_SHIFT U(0) 183 #define GPCCR_PPS_MASK U(0x7) 184 #define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) 185 186 typedef enum { 187 GPCCR_PPS_4GB = U(0x0), 188 GPCCR_PPS_64GB = U(0x1), 189 GPCCR_PPS_1TB = U(0x2), 190 GPCCR_PPS_4TB = U(0x3), 191 GPCCR_PPS_16TB = U(0x4), 192 GPCCR_PPS_256TB = U(0x5), 193 GPCCR_PPS_4PB = U(0x6) 194 } gpccr_pps_e; 195 196 /* Base Address for the GPT bit definitions */ 197 #define GPTBR_BADDR_SHIFT U(0) 198 #define GPTBR_BADDR_VAL_SHIFT U(12) 199 #define GPTBR_BADDR_MASK ULL(0xffffffffff) 200 201 /******************************************************************************/ 202 /* GPT public APIs */ 203 /******************************************************************************/ 204 205 /* 206 * Public API that initializes the entire protected space to GPT_GPI_ANY using 207 * the L0 tables (block descriptors). Ideally, this function is invoked prior 208 * to DDR discovery and initialization. The MMU must be initialized before 209 * calling this function. 210 * 211 * Parameters 212 * pps PPS value to use for table generation 213 * l0_mem_base Base address of L0 tables in memory. 214 * l0_mem_size Total size of memory available for L0 tables. 215 * 216 * Return 217 * Negative Linux error code in the event of a failure, 0 for success. 218 */ 219 int gpt_init_l0_tables(gpccr_pps_e pps, 220 uintptr_t l0_mem_base, 221 size_t l0_mem_size); 222 223 /* 224 * Public API that carves out PAS regions from the L0 tables and builds any L1 225 * tables that are needed. This function ideally is run after DDR discovery and 226 * initialization. The L0 tables must have already been initialized to GPI_ANY 227 * when this function is called. 228 * 229 * Parameters 230 * pgs PGS value to use for table generation. 231 * l1_mem_base Base address of memory used for L1 tables. 232 * l1_mem_size Total size of memory available for L1 tables. 233 * *pas_regions Pointer to PAS regions structure array. 234 * pas_count Total number of PAS regions. 235 * 236 * Return 237 * Negative Linux error code in the event of a failure, 0 for success. 238 */ 239 int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, 240 uintptr_t l1_mem_base, 241 size_t l1_mem_size, 242 pas_region_t *pas_regions, 243 unsigned int pas_count); 244 245 /* 246 * Public API to initialize the runtime gpt_config structure based on the values 247 * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization 248 * typically happens in a bootloader stage prior to setting up the EL3 runtime 249 * environment for the granule transition service so this function detects the 250 * initialization from a previous stage. Granule protection checks must be 251 * enabled already or this function will return an error. 252 * 253 * Parameters 254 * l1_bitlocks_base Base address of memory for L1 tables bitlocks. 255 * l1_bitlocks_size Total size of memory available for L1 tables bitlocks. 256 * 257 * Return 258 * Negative Linux error code in the event of a failure, 0 for success. 259 */ 260 int gpt_runtime_init(uintptr_t l1_bitlocks_base, size_t l1_bitlocks_size); 261 262 /* 263 * Public API to enable granule protection checks once the tables have all been 264 * initialized. This function is called at first initialization and then again 265 * later during warm boots of CPU cores. 266 * 267 * Return 268 * Negative Linux error code in the event of a failure, 0 for success. 269 */ 270 int gpt_enable(void); 271 272 /* 273 * Public API to disable granule protection checks. 274 */ 275 void gpt_disable(void); 276 277 /* 278 * This function is the core of the granule transition service. When a granule 279 * transition request occurs it is routed to this function where the request is 280 * validated then fulfilled if possible. 281 * 282 * TODO: implement support for transitioning multiple granules at once. 283 * 284 * Parameters 285 * base: Base address of the region to transition, must be aligned to granule 286 * size. 287 * size: Size of region to transition, must be aligned to granule size. 288 * src_sec_state: Security state of the originating SMC invoking the API. 289 * 290 * Return 291 * Negative Linux error code in the event of a failure, 0 for success. 292 */ 293 int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state); 294 int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state); 295 296 #endif /* GPT_RME_H */ 297