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