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