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