1*91f16700SchasingluluGranule Protection Tables Library 2*91f16700Schasinglulu================================= 3*91f16700Schasinglulu 4*91f16700SchasingluluThis document describes the design of the granule protection tables (GPT) 5*91f16700Schasinglululibrary used by Trusted Firmware-A (TF-A). This library provides the APIs needed 6*91f16700Schasingluluto initialize the GPTs based on a data structure containing information about 7*91f16700Schasingluluthe systems memory layout, configure the system registers to enable granule 8*91f16700Schasingluluprotection checks based on these tables, and transition granules between 9*91f16700Schasingluludifferent PAS (physical address spaces) at runtime. 10*91f16700Schasinglulu 11*91f16700SchasingluluArm CCA adds two new security states for a total of four: root, realm, secure, and 12*91f16700Schasinglulunon-secure. In addition to new security states, corresponding physical address 13*91f16700Schasingluluspaces have been added to control memory access for each state. The PAS access 14*91f16700Schasingluluallowed to each security state can be seen in the table below. 15*91f16700Schasinglulu 16*91f16700Schasinglulu.. list-table:: Security states and PAS access rights 17*91f16700Schasinglulu :widths: 25 25 25 25 25 18*91f16700Schasinglulu :header-rows: 1 19*91f16700Schasinglulu 20*91f16700Schasinglulu * - 21*91f16700Schasinglulu - Root state 22*91f16700Schasinglulu - Realm state 23*91f16700Schasinglulu - Secure state 24*91f16700Schasinglulu - Non-secure state 25*91f16700Schasinglulu * - Root PAS 26*91f16700Schasinglulu - yes 27*91f16700Schasinglulu - no 28*91f16700Schasinglulu - no 29*91f16700Schasinglulu - no 30*91f16700Schasinglulu * - Realm PAS 31*91f16700Schasinglulu - yes 32*91f16700Schasinglulu - yes 33*91f16700Schasinglulu - no 34*91f16700Schasinglulu - no 35*91f16700Schasinglulu * - Secure PAS 36*91f16700Schasinglulu - yes 37*91f16700Schasinglulu - no 38*91f16700Schasinglulu - yes 39*91f16700Schasinglulu - no 40*91f16700Schasinglulu * - Non-secure PAS 41*91f16700Schasinglulu - yes 42*91f16700Schasinglulu - yes 43*91f16700Schasinglulu - yes 44*91f16700Schasinglulu - yes 45*91f16700Schasinglulu 46*91f16700SchasingluluThe GPT can function as either a 1 level or 2 level lookup depending on how a 47*91f16700SchasingluluPAS region is configured. The first step is the level 0 table, each entry in the 48*91f16700Schasinglululevel 0 table controls access to a relatively large region in memory (block 49*91f16700Schasingluludescriptor), and the entire region can belong to a single PAS when a one step 50*91f16700Schasinglulumapping is used, or a level 0 entry can link to a level 1 table where relatively 51*91f16700Schasinglulusmall regions (granules) of memory can be assigned to different PAS with a 2 52*91f16700Schasinglulustep mapping. The type of mapping used for each PAS is determined by the user 53*91f16700Schasingluluwhen setting up the configuration structure. 54*91f16700Schasinglulu 55*91f16700SchasingluluDesign Concepts and Interfaces 56*91f16700Schasinglulu------------------------------ 57*91f16700Schasinglulu 58*91f16700SchasingluluThis section covers some important concepts and data structures used in the GPT 59*91f16700Schasinglululibrary. 60*91f16700Schasinglulu 61*91f16700SchasingluluThere are three main parameters that determine how the tables are organized and 62*91f16700Schasinglulufunction: the PPS (protected physical space) which is the total amount of 63*91f16700Schasingluluprotected physical address space in the system, PGS (physical granule size) 64*91f16700Schasingluluwhich is how large each level 1 granule is, and L0GPTSZ (level 0 GPT size) which 65*91f16700Schasingluludetermines how much physical memory is governed by each level 0 entry. A granule 66*91f16700Schasingluluis the smallest unit of memory that can be independently assigned to a PAS. 67*91f16700Schasinglulu 68*91f16700SchasingluluL0GPTSZ is determined by the hardware and is read from the GPCCR_EL3 register. 69*91f16700SchasingluluPPS and PGS are passed into the APIs at runtime and can be determined in 70*91f16700Schasingluluwhatever way is best for a given platform, either through some algorithm or hard 71*91f16700Schasinglulucoded in the firmware. 72*91f16700Schasinglulu 73*91f16700SchasingluluGPT setup is split into two parts: table creation and runtime initialization. In 74*91f16700Schasingluluthe table creation step, a data structure containing information about the 75*91f16700Schasingluludesired PAS regions is passed into the library which validates the mappings, 76*91f16700Schasinglulucreates the tables in memory, and enables granule protection checks. In the 77*91f16700Schasingluluruntime initialization step, the runtime firmware locates the existing tables in 78*91f16700Schasinglulumemory using the GPT register configuration and saves important data to a 79*91f16700Schasinglulustructure used by the granule transition service which will be covered more 80*91f16700Schasinglulubelow. 81*91f16700Schasinglulu 82*91f16700SchasingluluIn the reference implementation for FVP models, you can find an example of PAS 83*91f16700Schasingluluregion definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table 84*91f16700Schasinglulucreation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and 85*91f16700Schasingluluruntime initialization API calls can be seen in 86*91f16700Schasinglulu``plat/arm/common/arm_bl31_setup.c``. 87*91f16700Schasinglulu 88*91f16700SchasingluluDefining PAS regions 89*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~ 90*91f16700Schasinglulu 91*91f16700SchasingluluA ``pas_region_t`` structure is a way to represent a physical address space and 92*91f16700Schasingluluits attributes that can be used by the GPT library to initialize the tables. 93*91f16700Schasinglulu 94*91f16700SchasingluluThis structure is composed of the following: 95*91f16700Schasinglulu 96*91f16700Schasinglulu#. The base physical address 97*91f16700Schasinglulu#. The region size 98*91f16700Schasinglulu#. The desired attributes of this memory region (mapping type, PAS type) 99*91f16700Schasinglulu 100*91f16700SchasingluluSee the ``pas_region_t`` type in ``include/lib/gpt_rme/gpt_rme.h``. 101*91f16700Schasinglulu 102*91f16700SchasingluluThe programmer should provide the API with an array containing ``pas_region_t`` 103*91f16700Schasinglulustructures, then the library will check the desired memory access layout for 104*91f16700Schasingluluvalidity and create tables to implement it. 105*91f16700Schasinglulu 106*91f16700Schasinglulu``pas_region_t`` is a public type, however it is recommended that the macros 107*91f16700Schasinglulu``GPT_MAP_REGION_BLOCK`` and ``GPT_MAP_REGION_GRANULE`` be used to populate 108*91f16700Schasingluluthese structures instead of doing it manually to reduce the risk of future 109*91f16700Schasinglulucompatibility issues. These macros take the base physical address, region size, 110*91f16700Schasingluluand PAS type as arguments to generate the pas_region_t structure. As the names 111*91f16700Schasingluluimply, ``GPT_MAP_REGION_BLOCK`` creates a region using only L0 mapping while 112*91f16700Schasinglulu``GPT_MAP_REGION_GRANULE`` creates a region using L0 and L1 mappings. 113*91f16700Schasinglulu 114*91f16700SchasingluluLevel 0 and Level 1 Tables 115*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~ 116*91f16700Schasinglulu 117*91f16700SchasingluluThe GPT initialization APIs require memory to be passed in for the tables to be 118*91f16700Schasingluluconstructed, ``gpt_init_l0_tables`` takes a memory address and size for building 119*91f16700Schasingluluthe level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for 120*91f16700Schasinglulubuilding the level 1 tables which are linked from level 0 descriptors. The 121*91f16700Schasinglulutables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place 122*91f16700Schasingluluits level 0 table in SRAM and its level 1 table(s) in DRAM. 123*91f16700Schasinglulu 124*91f16700SchasingluluGranule Transition Service 125*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~ 126*91f16700Schasinglulu 127*91f16700SchasingluluThe Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE 128*91f16700Schasingluluownership to be changed using SMC calls. Non-secure granules can be transitioned 129*91f16700Schasingluluto either realm or secure space, and realm and secure granules can be 130*91f16700Schasinglulutransitioned back to non-secure. This library only allows memory mapped as 131*91f16700Schasinglulugranules to be transitioned, memory mapped as blocks have their GPIs fixed after 132*91f16700Schasinglulutable creation. 133*91f16700Schasinglulu 134*91f16700SchasingluluLibrary APIs 135*91f16700Schasinglulu------------ 136*91f16700Schasinglulu 137*91f16700SchasingluluThe public APIs and types can be found in ``include/lib/gpt_rme/gpt_rme.h`` and this 138*91f16700Schasinglulusection is intended to provide additional details and clarifications. 139*91f16700Schasinglulu 140*91f16700SchasingluluTo create the GPTs and enable granule protection checks the APIs need to be 141*91f16700Schasinglulucalled in the correct order and at the correct time during the system boot 142*91f16700Schasingluluprocess. 143*91f16700Schasinglulu 144*91f16700Schasinglulu#. Firmware must enable the MMU. 145*91f16700Schasinglulu#. Firmware must call ``gpt_init_l0_tables`` to initialize the level 0 tables to 146*91f16700Schasinglulu a default state, that is, initializing all of the L0 descriptors to allow all 147*91f16700Schasinglulu accesses to all memory. The PPS is provided to this function as an argument. 148*91f16700Schasinglulu#. DDR discovery and initialization by the system, the discovered DDR region(s) 149*91f16700Schasinglulu are then added to the L1 PAS regions to be initialized in the next step and 150*91f16700Schasinglulu used by the GTSI at runtime. 151*91f16700Schasinglulu#. Firmware must call ``gpt_init_pas_l1_tables`` with a pointer to an array of 152*91f16700Schasinglulu ``pas_region_t`` structures containing the desired memory access layout. The 153*91f16700Schasinglulu PGS is provided to this function as an argument. 154*91f16700Schasinglulu#. Firmware must call ``gpt_enable`` to enable granule protection checks by 155*91f16700Schasinglulu setting the correct register values. 156*91f16700Schasinglulu#. In systems that make use of the granule transition service, runtime 157*91f16700Schasinglulu firmware must call ``gpt_runtime_init`` to set up the data structures needed 158*91f16700Schasinglulu by the GTSI to find the tables and transition granules between PAS types. 159*91f16700Schasinglulu 160*91f16700SchasingluluAPI Constraints 161*91f16700Schasinglulu~~~~~~~~~~~~~~~ 162*91f16700Schasinglulu 163*91f16700SchasingluluThe values allowed by the API for PPS and PGS are enumerated types 164*91f16700Schasingluludefined in the file ``include/lib/gpt_rme/gpt_rme.h``. 165*91f16700Schasinglulu 166*91f16700SchasingluluAllowable values for PPS along with their corresponding size. 167*91f16700Schasinglulu 168*91f16700Schasinglulu* ``GPCCR_PPS_4GB`` (4GB protected space, 0x100000000 bytes) 169*91f16700Schasinglulu* ``GPCCR_PPS_64GB`` (64GB protected space, 0x1000000000 bytes) 170*91f16700Schasinglulu* ``GPCCR_PPS_1TB`` (1TB protected space, 0x10000000000 bytes) 171*91f16700Schasinglulu* ``GPCCR_PPS_4TB`` (4TB protected space, 0x40000000000 bytes) 172*91f16700Schasinglulu* ``GPCCR_PPS_16TB`` (16TB protected space, 0x100000000000 bytes) 173*91f16700Schasinglulu* ``GPCCR_PPS_256TB`` (256TB protected space, 0x1000000000000 bytes) 174*91f16700Schasinglulu* ``GPCCR_PPS_4PB`` (4PB protected space, 0x10000000000000 bytes) 175*91f16700Schasinglulu 176*91f16700SchasingluluAllowable values for PGS along with their corresponding size. 177*91f16700Schasinglulu 178*91f16700Schasinglulu* ``GPCCR_PGS_4K`` (4KB granules, 0x1000 bytes) 179*91f16700Schasinglulu* ``GPCCR_PGS_16K`` (16KB granules, 0x4000 bytes) 180*91f16700Schasinglulu* ``GPCCR_PGS_64K`` (64KB granules, 0x10000 bytes) 181*91f16700Schasinglulu 182*91f16700SchasingluluAllowable values for L0GPTSZ along with the corresponding size. 183*91f16700Schasinglulu 184*91f16700Schasinglulu* ``GPCCR_L0GPTSZ_30BITS`` (1GB regions, 0x40000000 bytes) 185*91f16700Schasinglulu* ``GPCCR_L0GPTSZ_34BITS`` (16GB regions, 0x400000000 bytes) 186*91f16700Schasinglulu* ``GPCCR_L0GPTSZ_36BITS`` (64GB regions, 0x1000000000 bytes) 187*91f16700Schasinglulu* ``GPCCR_L0GPTSZ_39BITS`` (512GB regions, 0x8000000000 bytes) 188*91f16700Schasinglulu 189*91f16700SchasingluluNote that the value of the PPS, PGS, and L0GPTSZ definitions is an encoded value 190*91f16700Schasinglulucorresponding to the size, not the size itself. The decoded hex representations 191*91f16700Schasingluluof the sizes have been provided for convenience. 192*91f16700Schasinglulu 193*91f16700SchasingluluThe L0 table memory has some constraints that must be taken into account. 194*91f16700Schasinglulu 195*91f16700Schasinglulu* The L0 table must be aligned to either the table size or 4096 bytes, whichever 196*91f16700Schasinglulu is greater. L0 table size is the total protected space (PPS) divided by the 197*91f16700Schasinglulu size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor 198*91f16700Schasinglulu (8 bytes). ((PPS / L0GPTSZ) * 8) 199*91f16700Schasinglulu* The L0 memory size must be greater than or equal to the table size. 200*91f16700Schasinglulu* The L0 memory must fall within a PAS of type GPT_GPI_ROOT. 201*91f16700Schasinglulu 202*91f16700SchasingluluThe L1 memory also has some constraints. 203*91f16700Schasinglulu 204*91f16700Schasinglulu* The L1 tables must be aligned to their size. The size of each L1 table is the 205*91f16700Schasinglulu size of each L0 region (L0GPTSZ) divided by the granule size (PGS) divided by 206*91f16700Schasinglulu the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2) 207*91f16700Schasinglulu* There must be enough L1 memory supplied to build all requested L1 tables. 208*91f16700Schasinglulu* The L1 memory must fall within a PAS of type GPT_GPI_ROOT. 209*91f16700Schasinglulu 210*91f16700SchasingluluIf an invalid combination of parameters is supplied, the APIs will print an 211*91f16700Schasingluluerror message and return a negative value. The return values of APIs should be 212*91f16700Schasingluluchecked to ensure successful configuration. 213*91f16700Schasinglulu 214*91f16700SchasingluluSample Calculation for L0 memory size and alignment 215*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216*91f16700Schasinglulu 217*91f16700SchasingluluLet PPS=GPCCR_PPS_4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS 218*91f16700Schasinglulu 219*91f16700SchasingluluWe can find the total L0 table size with ((PPS / L0GPTSZ) * 8) 220*91f16700Schasinglulu 221*91f16700SchasingluluSubstitute values to get this: ((0x100000000 / 0x40000000) * 8) 222*91f16700Schasinglulu 223*91f16700SchasingluluAnd solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0 224*91f16700Schasinglulutables must be aligned to 4096 bytes. 225*91f16700Schasinglulu 226*91f16700SchasingluluSample calculation for L1 table size and alignment 227*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228*91f16700Schasinglulu 229*91f16700SchasingluluLet PGS=GPCCR_PGS_4K and L0GPTSZ=GPCCR_L0GPTSZ_30BITS 230*91f16700Schasinglulu 231*91f16700SchasingluluWe can find the size of each L1 table with ((L0GPTSZ / PGS) / 2). 232*91f16700Schasinglulu 233*91f16700SchasingluluSubstitute values: ((0x40000000 / 0x1000) / 2) 234*91f16700Schasinglulu 235*91f16700SchasingluluAnd solve to get 0x20000 bytes per L1 table. 236