1 /* 2 * Copyright (c) 2022-2026, 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 /* 37 * Lookup table used to speed up granule transitions by associating GPIs and 38 * relevant information such as descriptors, NSE fields, and transition 39 * policies. 40 */ 41 typedef struct { 42 uint64_t desc; 43 uint8_t nse; 44 uint8_t nse2; 45 uint16_t policy[3]; 46 } gpi_lookup_t; 47 48 /* GPT GPI definitions */ 49 #define GPT_GPI_NO_ACCESS U(0x0) 50 #define GPT_GPI_SA U(0x4) 51 #define GPT_GPI_NSP U(0x5) 52 #define GPT_GPI_SECURE U(0x8) 53 #define GPT_GPI_NS U(0x9) 54 #define GPT_GPI_ROOT U(0xA) 55 #define GPT_GPI_REALM U(0xB) 56 #define GPT_GPI_NSO U(0xD) 57 #define GPT_GPI_ANY U(0xF) 58 #define GPT_GPI_VAL_MASK UL(0xF) 59 60 #define GPT_NSE_SECURE U(0b00) 61 #define GPT_NSE_ROOT U(0b01) 62 #define GPT_NSE_NS U(0b10) 63 #define GPT_NSE_REALM U(0b11) 64 65 #define GPT_NSE_SHIFT U(62) 66 67 #define GPT_NSE2_SA U(0b001) 68 #define GPT_NSE2_NSP U(0b101) 69 70 #define GPT_NSE2_SHIFT U(61) 71 72 /* PAS attribute GPI definitions. */ 73 #define GPT_PAS_ATTR_GPI_SHIFT U(0) 74 #define GPT_PAS_ATTR_GPI_MASK U(0xF) 75 #define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \ 76 >> GPT_PAS_ATTR_GPI_SHIFT) \ 77 & GPT_PAS_ATTR_GPI_MASK) 78 79 /* PAS attribute mapping type definitions */ 80 #define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0) 81 #define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1) 82 #define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4) 83 #define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1) 84 #define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \ 85 >> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \ 86 & GPT_PAS_ATTR_MAP_TYPE_MASK) 87 88 /* 89 * Macro to initialize the attributes field in the pas_region_t structure. 90 * [31:5] Reserved 91 * [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions) 92 * [3:0] PAS GPI type (GPT_GPI_x definitions) 93 */ 94 #define GPT_PAS_ATTR(_type, _gpi) \ 95 ((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \ 96 << GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \ 97 (((_gpi) & GPT_PAS_ATTR_GPI_MASK) \ 98 << GPT_PAS_ATTR_GPI_SHIFT)) 99 100 /* 101 * Macro to create a GPT entry for this PAS range as a block descriptor. If this 102 * region does not fit the requirements for a block descriptor then GPT 103 * initialization will fail. 104 */ 105 #define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \ 106 { \ 107 .base_pa = (_pa), \ 108 .size = (_sz), \ 109 .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \ 110 } 111 112 /* 113 * Macro to create a GPT entry for this PAS range as a table descriptor. If this 114 * region does not fit the requirements for a table descriptor then GPT 115 * initialization will fail. 116 */ 117 #define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \ 118 { \ 119 .base_pa = (_pa), \ 120 .size = (_sz), \ 121 .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \ 122 } 123 124 /******************************************************************************/ 125 /* GPT register field definitions */ 126 /******************************************************************************/ 127 128 /* NSO bit definitions */ 129 #define GPCCR_NSO_SHIFT U(19) 130 #define GPCCR_NSO_BIT (ULL(1) << GPCCR_NSO_SHIFT) 131 132 /* SA bit definitions */ 133 #define GPCCR_NSP_SHIFT U(26) 134 #define GPCCR_NSP_BIT (ULL(1) << GPCCR_NSP_SHIFT) 135 136 /* SA bit definitions */ 137 #define GPCCR_SA_SHIFT U(25) 138 #define GPCCR_SA_BIT (ULL(1) << GPCCR_SA_SHIFT) 139 140 /* 141 * Least significant address bits protected by each entry in level 0 GPT. This 142 * field is read-only. 143 */ 144 #define GPCCR_L0GPTSZ_SHIFT U(20) 145 #define GPCCR_L0GPTSZ_MASK U(0xF) 146 147 typedef enum { 148 GPCCR_L0GPTSZ_30BITS = U(0x0), 149 GPCCR_L0GPTSZ_34BITS = U(0x4), 150 GPCCR_L0GPTSZ_36BITS = U(0x6), 151 GPCCR_L0GPTSZ_39BITS = U(0x9) 152 } gpccr_l0gptsz_e; 153 154 /* Granule protection check priority bit definitions */ 155 #define GPCCR_GPCP_SHIFT U(17) 156 #define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) 157 158 /* Granule protection check bit definitions */ 159 #define GPCCR_GPC_SHIFT U(16) 160 #define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) 161 162 /* Physical granule size bit definitions */ 163 #define GPCCR_PGS_SHIFT U(14) 164 #define GPCCR_PGS_MASK U(0x3) 165 #define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) 166 167 typedef enum { 168 GPCCR_PGS_4K = U(0x0), 169 GPCCR_PGS_64K = U(0x1), 170 GPCCR_PGS_16K = U(0x2) 171 } gpccr_pgs_e; 172 173 /* GPT fetch shareability attribute bit definitions */ 174 #define GPCCR_SH_SHIFT U(12) 175 #define GPCCR_SH_MASK U(0x3) 176 #define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) 177 178 typedef enum { 179 GPCCR_SH_NS = U(0x0), 180 GPCCR_SH_OS = U(0x2), 181 GPCCR_SH_IS = U(0x3) 182 } gpccr_sh_e; 183 184 /* GPT fetch outer cacheability attribute bit definitions */ 185 #define GPCCR_ORGN_SHIFT U(10) 186 #define GPCCR_ORGN_MASK U(0x3) 187 #define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) 188 189 typedef enum { 190 GPCCR_ORGN_NC = U(0x0), 191 GPCCR_ORGN_WB_RA_WA = U(0x1), 192 GPCCR_ORGN_WT_RA_NWA = U(0x2), 193 GPCCR_ORGN_WB_RA_NWA = U(0x3) 194 } gpccr_orgn_e; 195 196 /* GPT fetch inner cacheability attribute bit definitions */ 197 #define GPCCR_IRGN_SHIFT U(8) 198 #define GPCCR_IRGN_MASK U(0x3) 199 #define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) 200 201 typedef enum { 202 GPCCR_IRGN_NC = U(0x0), 203 GPCCR_IRGN_WB_RA_WA = U(0x1), 204 GPCCR_IRGN_WT_RA_NWA = U(0x2), 205 GPCCR_IRGN_WB_RA_NWA = U(0x3) 206 } gpccr_irgn_e; 207 208 /* Protected physical address size bit definitions */ 209 #define GPCCR_PPS_SHIFT U(0) 210 #define GPCCR_PPS_MASK U(0x7) 211 #define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) 212 213 typedef enum { 214 GPCCR_PPS_4GB = U(0x0), 215 GPCCR_PPS_64GB = U(0x1), 216 GPCCR_PPS_1TB = U(0x2), 217 GPCCR_PPS_4TB = U(0x3), 218 GPCCR_PPS_16TB = U(0x4), 219 GPCCR_PPS_256TB = U(0x5), 220 GPCCR_PPS_4PB = U(0x6) 221 } gpccr_pps_e; 222 223 /* Base Address for the GPT bit definitions */ 224 #define GPTBR_BADDR_SHIFT U(0) 225 #define GPTBR_BADDR_VAL_SHIFT U(12) 226 #define GPTBR_BADDR_MASK ULL(0xffffffffff) 227 228 /******************************************************************************/ 229 /* GPT public APIs */ 230 /******************************************************************************/ 231 232 /* 233 * Public API that initializes the entire protected space to GPT_GPI_ANY using 234 * the L0 tables (block descriptors). Ideally, this function is invoked prior 235 * to DDR discovery and initialization. The MMU must be initialized before 236 * calling this function. 237 * 238 * Parameters 239 * pps PPS value to use for table generation 240 * l0_mem_base Base address of L0 tables in memory. 241 * l0_mem_size Total size of memory available for L0 tables. 242 * 243 * Return 244 * Negative Linux error code in the event of a failure, 0 for success. 245 */ 246 int gpt_init_l0_tables(gpccr_pps_e pps, 247 uintptr_t l0_mem_base, 248 size_t l0_mem_size); 249 250 /* 251 * Public API that carves out PAS regions from the L0 tables and builds any L1 252 * tables that are needed. This function ideally is run after DDR discovery and 253 * initialization. The L0 tables must have already been initialized to GPI_ANY 254 * when this function is called. 255 * 256 * Parameters 257 * pgs PGS value to use for table generation. 258 * l1_mem_base Base address of memory used for L1 tables. 259 * l1_mem_size Total size of memory available for L1 tables. 260 * *pas_regions Pointer to PAS regions structure array. 261 * pas_count Total number of PAS regions. 262 * 263 * Return 264 * Negative Linux error code in the event of a failure, 0 for success. 265 */ 266 int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, 267 uintptr_t l1_mem_base, 268 size_t l1_mem_size, 269 pas_region_t *pas_regions, 270 unsigned int pas_count); 271 272 /* 273 * Public API to initialize the runtime gpt_config structure based on the values 274 * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization 275 * typically happens in a bootloader stage prior to setting up the EL3 runtime 276 * environment for the granule transition service so this function detects the 277 * initialization from a previous stage. Granule protection checks must be 278 * enabled already or this function will return an error. 279 * 280 * Parameters 281 * l1_bitlocks_base Base address of memory for L1 tables bitlocks. 282 * l1_bitlocks_size Total size of memory available for L1 tables bitlocks. 283 * 284 * Return 285 * Negative Linux error code in the event of a failure, 0 for success. 286 */ 287 int gpt_runtime_init(uintptr_t l1_bitlocks_base, size_t l1_bitlocks_size); 288 289 /* 290 * Public API to enable granule protection checks once the tables have all been 291 * initialized. This function is called at first initialization and then again 292 * later during warm boots of CPU cores. 293 * 294 * Return 295 * Negative Linux error code in the event of a failure, 0 for success. 296 */ 297 int gpt_enable(void); 298 299 /* 300 * This function is the core of the granule transition service, including both 301 * delegate and undelegate operations. When a granule transition request occurs 302 * it is routed to this function which will determine if it is valid and fulfill 303 * it. 304 * 305 * Parameters 306 * base Base address of the first granule to transition, aligned 307 * to granule size. 308 * *granule_count Pointer to a variable containing the number of granules 309 * to be transitioned. This value will be overwritten with 310 * the number of granules actually transitioned once this 311 * function returns. It is possible to return an error part 312 * way through the process and have a non-zero number of 313 * granules transitioned. TODO is this acceptable? 314 * target_gpi GPI to transition the granules to. 315 * src_sec_state Security state of the requesting entity. This will be 316 * combined with target_gpi to determine whether a 317 * transition is allowed. 318 */ 319 int gpt_transition_pas(uint64_t base, uint64_t *granule_count, 320 uint8_t target_gpi, uint8_t src_sec_state); 321 322 #endif /* GPT_RME_H */ 323