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