16ee92598Sjohpow01Granule Protection Tables Library 26ee92598Sjohpow01================================= 36ee92598Sjohpow01 46ee92598Sjohpow01This document describes the design of the granule protection tables (GPT) 56ee92598Sjohpow01library used by Trusted Firmware-A (TF-A). This library provides the APIs needed 66ee92598Sjohpow01to initialize the GPTs based on a data structure containing information about 76ee92598Sjohpow01the systems memory layout, configure the system registers to enable granule 86ee92598Sjohpow01protection checks based on these tables, and transition granules between 96ee92598Sjohpow01different PAS (physical address spaces) at runtime. 106ee92598Sjohpow01 116ee92598Sjohpow01Arm CCA adds two new security states for a total of four: root, realm, secure, and 126ee92598Sjohpow01non-secure. In addition to new security states, corresponding physical address 136ee92598Sjohpow01spaces have been added to control memory access for each state. The PAS access 146ee92598Sjohpow01allowed to each security state can be seen in the table below. 156ee92598Sjohpow01 166ee92598Sjohpow01.. list-table:: Security states and PAS access rights 176ee92598Sjohpow01 :widths: 25 25 25 25 25 186ee92598Sjohpow01 :header-rows: 1 196ee92598Sjohpow01 206ee92598Sjohpow01 * - 216ee92598Sjohpow01 - Root state 226ee92598Sjohpow01 - Realm state 236ee92598Sjohpow01 - Secure state 246ee92598Sjohpow01 - Non-secure state 256ee92598Sjohpow01 * - Root PAS 266ee92598Sjohpow01 - yes 276ee92598Sjohpow01 - no 286ee92598Sjohpow01 - no 296ee92598Sjohpow01 - no 306ee92598Sjohpow01 * - Realm PAS 316ee92598Sjohpow01 - yes 326ee92598Sjohpow01 - yes 336ee92598Sjohpow01 - no 346ee92598Sjohpow01 - no 356ee92598Sjohpow01 * - Secure PAS 366ee92598Sjohpow01 - yes 376ee92598Sjohpow01 - no 386ee92598Sjohpow01 - yes 396ee92598Sjohpow01 - no 406ee92598Sjohpow01 * - Non-secure PAS 416ee92598Sjohpow01 - yes 426ee92598Sjohpow01 - yes 436ee92598Sjohpow01 - yes 446ee92598Sjohpow01 - yes 456ee92598Sjohpow01 466ee92598Sjohpow01The GPT can function as either a 1 level or 2 level lookup depending on how a 476ee92598Sjohpow01PAS region is configured. The first step is the level 0 table, each entry in the 486ee92598Sjohpow01level 0 table controls access to a relatively large region in memory (block 496ee92598Sjohpow01descriptor), and the entire region can belong to a single PAS when a one step 506ee92598Sjohpow01mapping is used, or a level 0 entry can link to a level 1 table where relatively 516ee92598Sjohpow01small regions (granules) of memory can be assigned to different PAS with a 2 526ee92598Sjohpow01step mapping. The type of mapping used for each PAS is determined by the user 536ee92598Sjohpow01when setting up the configuration structure. 546ee92598Sjohpow01 556ee92598Sjohpow01Design Concepts and Interfaces 566ee92598Sjohpow01------------------------------ 576ee92598Sjohpow01 586ee92598Sjohpow01This section covers some important concepts and data structures used in the GPT 596ee92598Sjohpow01library. 606ee92598Sjohpow01 616ee92598Sjohpow01There are three main parameters that determine how the tables are organized and 626ee92598Sjohpow01function: the PPS (protected physical space) which is the total amount of 636ee92598Sjohpow01protected physical address space in the system, PGS (physical granule size) 646ee92598Sjohpow01which is how large each level 1 granule is, and L0GPTSZ (level 0 GPT size) which 656ee92598Sjohpow01determines how much physical memory is governed by each level 0 entry. A granule 666ee92598Sjohpow01is the smallest unit of memory that can be independently assigned to a PAS. 676ee92598Sjohpow01 686ee92598Sjohpow01L0GPTSZ is determined by the hardware and is read from the GPCCR_EL3 register. 696ee92598Sjohpow01PPS and PGS are passed into the APIs at runtime and can be determined in 706ee92598Sjohpow01whatever way is best for a given platform, either through some algorithm or hard 716ee92598Sjohpow01coded in the firmware. 726ee92598Sjohpow01 736ee92598Sjohpow01GPT setup is split into two parts: table creation and runtime initialization. In 746ee92598Sjohpow01the table creation step, a data structure containing information about the 756ee92598Sjohpow01desired PAS regions is passed into the library which validates the mappings, 766ee92598Sjohpow01creates the tables in memory, and enables granule protection checks. In the 776ee92598Sjohpow01runtime initialization step, the runtime firmware locates the existing tables in 786ee92598Sjohpow01memory using the GPT register configuration and saves important data to a 796ee92598Sjohpow01structure used by the granule transition service which will be covered more 806ee92598Sjohpow01below. 816ee92598Sjohpow01 826ee92598Sjohpow01In the reference implementation for FVP models, you can find an example of PAS 8386e4859aSRohit Mathewregion definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``. 84*341df6afSRohit MathewTable creation API calls can be found in ``plat/arm/common/arm_common.c`` and 856ee92598Sjohpow01runtime initialization API calls can be seen in 866ee92598Sjohpow01``plat/arm/common/arm_bl31_setup.c``. 876ee92598Sjohpow01 886ee92598Sjohpow01Defining PAS regions 896ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~ 906ee92598Sjohpow01 916ee92598Sjohpow01A ``pas_region_t`` structure is a way to represent a physical address space and 926ee92598Sjohpow01its attributes that can be used by the GPT library to initialize the tables. 936ee92598Sjohpow01 946ee92598Sjohpow01This structure is composed of the following: 956ee92598Sjohpow01 966ee92598Sjohpow01#. The base physical address 976ee92598Sjohpow01#. The region size 986ee92598Sjohpow01#. The desired attributes of this memory region (mapping type, PAS type) 996ee92598Sjohpow01 1006ee92598Sjohpow01See the ``pas_region_t`` type in ``include/lib/gpt_rme/gpt_rme.h``. 1016ee92598Sjohpow01 1026ee92598Sjohpow01The programmer should provide the API with an array containing ``pas_region_t`` 1036ee92598Sjohpow01structures, then the library will check the desired memory access layout for 1046ee92598Sjohpow01validity and create tables to implement it. 1056ee92598Sjohpow01 1066ee92598Sjohpow01``pas_region_t`` is a public type, however it is recommended that the macros 1076ee92598Sjohpow01``GPT_MAP_REGION_BLOCK`` and ``GPT_MAP_REGION_GRANULE`` be used to populate 1086ee92598Sjohpow01these structures instead of doing it manually to reduce the risk of future 1096ee92598Sjohpow01compatibility issues. These macros take the base physical address, region size, 1106ee92598Sjohpow01and PAS type as arguments to generate the pas_region_t structure. As the names 1116ee92598Sjohpow01imply, ``GPT_MAP_REGION_BLOCK`` creates a region using only L0 mapping while 1126ee92598Sjohpow01``GPT_MAP_REGION_GRANULE`` creates a region using L0 and L1 mappings. 1136ee92598Sjohpow01 1146ee92598Sjohpow01Level 0 and Level 1 Tables 1156ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~ 1166ee92598Sjohpow01 1176ee92598Sjohpow01The GPT initialization APIs require memory to be passed in for the tables to be 1186ee92598Sjohpow01constructed, ``gpt_init_l0_tables`` takes a memory address and size for building 1196ee92598Sjohpow01the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for 1206ee92598Sjohpow01building the level 1 tables which are linked from level 0 descriptors. The 1216ee92598Sjohpow01tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place 1226ee92598Sjohpow01its level 0 table in SRAM and its level 1 table(s) in DRAM. 1236ee92598Sjohpow01 1246ee92598Sjohpow01Granule Transition Service 1256ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~ 1266ee92598Sjohpow01 1276ee92598Sjohpow01The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE 1286ee92598Sjohpow01ownership to be changed using SMC calls. Non-secure granules can be transitioned 1296ee92598Sjohpow01to either realm or secure space, and realm and secure granules can be 1306ee92598Sjohpow01transitioned back to non-secure. This library only allows memory mapped as 1316ee92598Sjohpow01granules to be transitioned, memory mapped as blocks have their GPIs fixed after 1326ee92598Sjohpow01table creation. 1336ee92598Sjohpow01 1346ee92598Sjohpow01Library APIs 1356ee92598Sjohpow01------------ 1366ee92598Sjohpow01 1376ee92598Sjohpow01The public APIs and types can be found in ``include/lib/gpt_rme/gpt_rme.h`` and this 1386ee92598Sjohpow01section is intended to provide additional details and clarifications. 1396ee92598Sjohpow01 1406ee92598Sjohpow01To create the GPTs and enable granule protection checks the APIs need to be 1416ee92598Sjohpow01called in the correct order and at the correct time during the system boot 1426ee92598Sjohpow01process. 1436ee92598Sjohpow01 1446ee92598Sjohpow01#. Firmware must enable the MMU. 1456ee92598Sjohpow01#. Firmware must call ``gpt_init_l0_tables`` to initialize the level 0 tables to 1466ee92598Sjohpow01 a default state, that is, initializing all of the L0 descriptors to allow all 1476ee92598Sjohpow01 accesses to all memory. The PPS is provided to this function as an argument. 1486ee92598Sjohpow01#. DDR discovery and initialization by the system, the discovered DDR region(s) 1496ee92598Sjohpow01 are then added to the L1 PAS regions to be initialized in the next step and 1506ee92598Sjohpow01 used by the GTSI at runtime. 1516ee92598Sjohpow01#. Firmware must call ``gpt_init_pas_l1_tables`` with a pointer to an array of 1526ee92598Sjohpow01 ``pas_region_t`` structures containing the desired memory access layout. The 1536ee92598Sjohpow01 PGS is provided to this function as an argument. 1546ee92598Sjohpow01#. Firmware must call ``gpt_enable`` to enable granule protection checks by 1556ee92598Sjohpow01 setting the correct register values. 1566ee92598Sjohpow01#. In systems that make use of the granule transition service, runtime 1576ee92598Sjohpow01 firmware must call ``gpt_runtime_init`` to set up the data structures needed 1586ee92598Sjohpow01 by the GTSI to find the tables and transition granules between PAS types. 1596ee92598Sjohpow01 1606ee92598Sjohpow01API Constraints 1616ee92598Sjohpow01~~~~~~~~~~~~~~~ 1626ee92598Sjohpow01 1636ee92598Sjohpow01The values allowed by the API for PPS and PGS are enumerated types 1646ee92598Sjohpow01defined in the file ``include/lib/gpt_rme/gpt_rme.h``. 1656ee92598Sjohpow01 1666ee92598Sjohpow01Allowable values for PPS along with their corresponding size. 1676ee92598Sjohpow01 1686ee92598Sjohpow01* ``GPCCR_PPS_4GB`` (4GB protected space, 0x100000000 bytes) 1696ee92598Sjohpow01* ``GPCCR_PPS_64GB`` (64GB protected space, 0x1000000000 bytes) 1706ee92598Sjohpow01* ``GPCCR_PPS_1TB`` (1TB protected space, 0x10000000000 bytes) 1716ee92598Sjohpow01* ``GPCCR_PPS_4TB`` (4TB protected space, 0x40000000000 bytes) 1726ee92598Sjohpow01* ``GPCCR_PPS_16TB`` (16TB protected space, 0x100000000000 bytes) 1736ee92598Sjohpow01* ``GPCCR_PPS_256TB`` (256TB protected space, 0x1000000000000 bytes) 1746ee92598Sjohpow01* ``GPCCR_PPS_4PB`` (4PB protected space, 0x10000000000000 bytes) 1756ee92598Sjohpow01 1766ee92598Sjohpow01Allowable values for PGS along with their corresponding size. 1776ee92598Sjohpow01 1786ee92598Sjohpow01* ``GPCCR_PGS_4K`` (4KB granules, 0x1000 bytes) 1796ee92598Sjohpow01* ``GPCCR_PGS_16K`` (16KB granules, 0x4000 bytes) 1806ee92598Sjohpow01* ``GPCCR_PGS_64K`` (64KB granules, 0x10000 bytes) 1816ee92598Sjohpow01 1826ee92598Sjohpow01Allowable values for L0GPTSZ along with the corresponding size. 1836ee92598Sjohpow01 1846ee92598Sjohpow01* ``GPCCR_L0GPTSZ_30BITS`` (1GB regions, 0x40000000 bytes) 1856ee92598Sjohpow01* ``GPCCR_L0GPTSZ_34BITS`` (16GB regions, 0x400000000 bytes) 1866ee92598Sjohpow01* ``GPCCR_L0GPTSZ_36BITS`` (64GB regions, 0x1000000000 bytes) 1876ee92598Sjohpow01* ``GPCCR_L0GPTSZ_39BITS`` (512GB regions, 0x8000000000 bytes) 1886ee92598Sjohpow01 1896ee92598Sjohpow01Note that the value of the PPS, PGS, and L0GPTSZ definitions is an encoded value 1906ee92598Sjohpow01corresponding to the size, not the size itself. The decoded hex representations 1916ee92598Sjohpow01of the sizes have been provided for convenience. 1926ee92598Sjohpow01 1936ee92598Sjohpow01The L0 table memory has some constraints that must be taken into account. 1946ee92598Sjohpow01 1956ee92598Sjohpow01* The L0 table must be aligned to either the table size or 4096 bytes, whichever 1966ee92598Sjohpow01 is greater. L0 table size is the total protected space (PPS) divided by the 1976ee92598Sjohpow01 size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor 1986ee92598Sjohpow01 (8 bytes). ((PPS / L0GPTSZ) * 8) 1996ee92598Sjohpow01* The L0 memory size must be greater than or equal to the table size. 2006ee92598Sjohpow01* The L0 memory must fall within a PAS of type GPT_GPI_ROOT. 2016ee92598Sjohpow01 2026ee92598Sjohpow01The L1 memory also has some constraints. 2036ee92598Sjohpow01 2046ee92598Sjohpow01* The L1 tables must be aligned to their size. The size of each L1 table is the 2056ee92598Sjohpow01 size of each L0 region (L0GPTSZ) divided by the granule size (PGS) divided by 2066ee92598Sjohpow01 the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2) 2076ee92598Sjohpow01* There must be enough L1 memory supplied to build all requested L1 tables. 2086ee92598Sjohpow01* The L1 memory must fall within a PAS of type GPT_GPI_ROOT. 2096ee92598Sjohpow01 2106ee92598Sjohpow01If an invalid combination of parameters is supplied, the APIs will print an 2116ee92598Sjohpow01error message and return a negative value. The return values of APIs should be 2126ee92598Sjohpow01checked to ensure successful configuration. 2136ee92598Sjohpow01 2146ee92598Sjohpow01Sample Calculation for L0 memory size and alignment 2156ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2166ee92598Sjohpow01 2176ee92598Sjohpow01Let PPS=GPCCR_PPS_4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS 2186ee92598Sjohpow01 2196ee92598Sjohpow01We can find the total L0 table size with ((PPS / L0GPTSZ) * 8) 2206ee92598Sjohpow01 2216ee92598Sjohpow01Substitute values to get this: ((0x100000000 / 0x40000000) * 8) 2226ee92598Sjohpow01 2236ee92598Sjohpow01And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0 2246ee92598Sjohpow01tables must be aligned to 4096 bytes. 2256ee92598Sjohpow01 2266ee92598Sjohpow01Sample calculation for L1 table size and alignment 2276ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2286ee92598Sjohpow01 2296ee92598Sjohpow01Let PGS=GPCCR_PGS_4K and L0GPTSZ=GPCCR_L0GPTSZ_30BITS 2306ee92598Sjohpow01 2316ee92598Sjohpow01We can find the size of each L1 table with ((L0GPTSZ / PGS) / 2). 2326ee92598Sjohpow01 2336ee92598Sjohpow01Substitute values: ((0x40000000 / 0x1000) / 2) 2346ee92598Sjohpow01 2356ee92598Sjohpow01And solve to get 0x20000 bytes per L1 table. 236