xref: /rk3399_ARM-atf/docs/components/granule-protection-tables-design.rst (revision e13622312ea61c4455f0428daedb75786dd0a2f4)
16ee92598Sjohpow01Granule Protection Tables Library
26ee92598Sjohpow01=================================
36ee92598Sjohpow01
4c944952bSAlexeiFedorovThis 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
11c944952bSAlexeiFedorovArm CCA adds two new security states for a total of four: root, realm, secure,
12c944952bSAlexeiFedorovand non-secure. In addition to new security states, corresponding physical
13c944952bSAlexeiFedorovaddress spaces have been added to control memory access for each state. The PAS
14c944952bSAlexeiFedorovaccess allowed 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
48c944952bSAlexeiFedorovlevel 0 table controls access to a relatively large region in memory (GPT Block
496ee92598Sjohpow01descriptor), and the entire region can belong to a single PAS when a one step
50c944952bSAlexeiFedorovmapping is used. Level 0 entry can also link to a level 1 table (GPT Table
51c944952bSAlexeiFedorovdescriptor) with a 2 step mapping. To change PAS of a region dynamically, the
52c944952bSAlexeiFedorovregion must be mapped in Level 1 table.
53c944952bSAlexeiFedorov
54c944952bSAlexeiFedorovThe Level 1 tables entries with the same PAS can be combined to form a
55c944952bSAlexeiFedorovcontiguous block entry using GPT Contiguous descriptor. More details about this
56c944952bSAlexeiFedorovis explained in the following section.
576ee92598Sjohpow01
586ee92598Sjohpow01Design Concepts and Interfaces
596ee92598Sjohpow01------------------------------
606ee92598Sjohpow01
616ee92598Sjohpow01This section covers some important concepts and data structures used in the GPT
626ee92598Sjohpow01library.
636ee92598Sjohpow01
646ee92598Sjohpow01There are three main parameters that determine how the tables are organized and
656ee92598Sjohpow01function: the PPS (protected physical space) which is the total amount of
666ee92598Sjohpow01protected physical address space in the system, PGS (physical granule size)
676ee92598Sjohpow01which is how large each level 1 granule is, and L0GPTSZ (level 0 GPT size) which
686ee92598Sjohpow01determines how much physical memory is governed by each level 0 entry. A granule
696ee92598Sjohpow01is the smallest unit of memory that can be independently assigned to a PAS.
706ee92598Sjohpow01
716ee92598Sjohpow01L0GPTSZ is determined by the hardware and is read from the GPCCR_EL3 register.
726ee92598Sjohpow01PPS and PGS are passed into the APIs at runtime and can be determined in
736ee92598Sjohpow01whatever way is best for a given platform, either through some algorithm or hard
746ee92598Sjohpow01coded in the firmware.
756ee92598Sjohpow01
766ee92598Sjohpow01GPT setup is split into two parts: table creation and runtime initialization. In
776ee92598Sjohpow01the table creation step, a data structure containing information about the
786ee92598Sjohpow01desired PAS regions is passed into the library which validates the mappings,
79c944952bSAlexeiFedorovcreates the tables in memory, and enables granule protection checks. It also
80c944952bSAlexeiFedorovallocates memory for fine-grained locks adjacent to the L0 tables. In the
816ee92598Sjohpow01runtime initialization step, the runtime firmware locates the existing tables in
826ee92598Sjohpow01memory using the GPT register configuration and saves important data to a
836ee92598Sjohpow01structure used by the granule transition service which will be covered more
846ee92598Sjohpow01below.
856ee92598Sjohpow01
866ee92598Sjohpow01In the reference implementation for FVP models, you can find an example of PAS
8786e4859aSRohit Mathewregion definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``.
88341df6afSRohit MathewTable creation API calls can be found in ``plat/arm/common/arm_common.c`` and
896ee92598Sjohpow01runtime initialization API calls can be seen in
906ee92598Sjohpow01``plat/arm/common/arm_bl31_setup.c``.
916ee92598Sjohpow01
92c944952bSAlexeiFedorovDuring the table creation time, the GPT lib opportunistically fuses contiguous
93c944952bSAlexeiFedorovGPT L1 entries having the same PAS. The maximum size of
94c944952bSAlexeiFedorovsupported contiguous blocks is defined by ``RME_GPT_MAX_BLOCK`` build option.
95c944952bSAlexeiFedorov
966ee92598Sjohpow01Defining PAS regions
976ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~
986ee92598Sjohpow01
996ee92598Sjohpow01A ``pas_region_t`` structure is a way to represent a physical address space and
1006ee92598Sjohpow01its attributes that can be used by the GPT library to initialize the tables.
1016ee92598Sjohpow01
1026ee92598Sjohpow01This structure is composed of the following:
1036ee92598Sjohpow01
1046ee92598Sjohpow01#. The base physical address
1056ee92598Sjohpow01#. The region size
1066ee92598Sjohpow01#. The desired attributes of this memory region (mapping type, PAS type)
1076ee92598Sjohpow01
1086ee92598Sjohpow01See the ``pas_region_t`` type in ``include/lib/gpt_rme/gpt_rme.h``.
1096ee92598Sjohpow01
1106ee92598Sjohpow01The programmer should provide the API with an array containing ``pas_region_t``
1116ee92598Sjohpow01structures, then the library will check the desired memory access layout for
1126ee92598Sjohpow01validity and create tables to implement it.
1136ee92598Sjohpow01
1146ee92598Sjohpow01``pas_region_t`` is a public type, however it is recommended that the macros
1156ee92598Sjohpow01``GPT_MAP_REGION_BLOCK`` and ``GPT_MAP_REGION_GRANULE`` be used to populate
1166ee92598Sjohpow01these structures instead of doing it manually to reduce the risk of future
1176ee92598Sjohpow01compatibility issues. These macros take the base physical address, region size,
1186ee92598Sjohpow01and PAS type as arguments to generate the pas_region_t structure. As the names
1196ee92598Sjohpow01imply, ``GPT_MAP_REGION_BLOCK`` creates a region using only L0 mapping while
1206ee92598Sjohpow01``GPT_MAP_REGION_GRANULE`` creates a region using L0 and L1 mappings.
1216ee92598Sjohpow01
1226ee92598Sjohpow01Level 0 and Level 1 Tables
1236ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~
1246ee92598Sjohpow01
1256ee92598Sjohpow01The GPT initialization APIs require memory to be passed in for the tables to be
126c944952bSAlexeiFedorovconstructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
127*b0f1c840SAlexeiFedorovbuilding the level 0 tables.
128c944952bSAlexeiFedorov
129c944952bSAlexeiFedorovThe ``gpt_init_pas_l1_tables`` API takes an address and size for
1306ee92598Sjohpow01building the level 1 tables which are linked from level 0 descriptors. The
1316ee92598Sjohpow01tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
1326ee92598Sjohpow01its level 0 table in SRAM and its level 1 table(s) in DRAM.
1336ee92598Sjohpow01
1346ee92598Sjohpow01Granule Transition Service
1356ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~
1366ee92598Sjohpow01
137c944952bSAlexeiFedorovThe Granule Transition Service allows memory mapped with
138c944952bSAlexeiFedorov``GPT_MAP_REGION_GRANULE`` ownership to be changed using SMC calls. Non-secure
139c944952bSAlexeiFedorovgranules can be transitioned to either realm or secure space, and realm and
140c944952bSAlexeiFedorovsecure granules can be transitioned back to non-secure. This library only
141c944952bSAlexeiFedorovallows Level 1 entries to be transitioned. The lib may either shatter
142c944952bSAlexeiFedorovcontiguous blocks or fuse adjacent GPT entries to form a contiguous block
143c944952bSAlexeiFedorovopportunistically. Depending on the maximum block size, the fuse operation may
144c944952bSAlexeiFedorovpropogate to higher block sizes as allowed by RME Architecture. Thus a higher
145c944952bSAlexeiFedorovmaximum block size may have a higher runtime cost due to software operations
146c944952bSAlexeiFedorovthat need to be performed for fuse to bigger block sizes. This cost may
147c944952bSAlexeiFedorovbe offset by better TLB performance due to the higher block size and platforms
148c944952bSAlexeiFedorovneed to make the trade-off decision based on their particular workload.
149c944952bSAlexeiFedorov
150c944952bSAlexeiFedorovLocking Scheme
151c944952bSAlexeiFedorov~~~~~~~~~~~~~~
152c944952bSAlexeiFedorov
153c944952bSAlexeiFedorovDuring Granule Transition access to L1 tables is controlled by a lock to ensure
154c944952bSAlexeiFedorovthat no more than one CPU is allowed to make changes at any given time.
155c944952bSAlexeiFedorovThe granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
156*b0f1c840SAlexeiFedorovwhich defines the size of the memory block protected by one bit of ``bitlock_t``
157c944952bSAlexeiFedorovstructure. Setting this option to 0 chooses a single spinlock for all GPT L1
158c944952bSAlexeiFedorovtable entries.
1596ee92598Sjohpow01
1606ee92598Sjohpow01Library APIs
1616ee92598Sjohpow01------------
1626ee92598Sjohpow01
1636ee92598Sjohpow01The public APIs and types can be found in ``include/lib/gpt_rme/gpt_rme.h`` and this
1646ee92598Sjohpow01section is intended to provide additional details and clarifications.
1656ee92598Sjohpow01
1666ee92598Sjohpow01To create the GPTs and enable granule protection checks the APIs need to be
1676ee92598Sjohpow01called in the correct order and at the correct time during the system boot
1686ee92598Sjohpow01process.
1696ee92598Sjohpow01
1706ee92598Sjohpow01#. Firmware must enable the MMU.
1716ee92598Sjohpow01#. Firmware must call ``gpt_init_l0_tables`` to initialize the level 0 tables to
1726ee92598Sjohpow01   a default state, that is, initializing all of the L0 descriptors to allow all
1736ee92598Sjohpow01   accesses to all memory. The PPS is provided to this function as an argument.
1746ee92598Sjohpow01#. DDR discovery and initialization by the system, the discovered DDR region(s)
1756ee92598Sjohpow01   are then added to the L1 PAS regions to be initialized in the next step and
1766ee92598Sjohpow01   used by the GTSI at runtime.
1776ee92598Sjohpow01#. Firmware must call ``gpt_init_pas_l1_tables`` with a pointer to an array of
1786ee92598Sjohpow01   ``pas_region_t`` structures containing the desired memory access layout. The
1796ee92598Sjohpow01   PGS is provided to this function as an argument.
1806ee92598Sjohpow01#. Firmware must call ``gpt_enable`` to enable granule protection checks by
1816ee92598Sjohpow01   setting the correct register values.
1826ee92598Sjohpow01#. In systems that make use of the granule transition service, runtime
1836ee92598Sjohpow01   firmware must call ``gpt_runtime_init`` to set up the data structures needed
1846ee92598Sjohpow01   by the GTSI to find the tables and transition granules between PAS types.
185*b0f1c840SAlexeiFedorov   The base address of bitlocks array and its size are provided to this function
186*b0f1c840SAlexeiFedorov   as arguments. These parameters are not used in case of a single spinlock for
187*b0f1c840SAlexeiFedorov   all GPT L1 table entries(``RME_GPT_BITLOCK_BLOCK`` is 0) and are passed as zero
188*b0f1c840SAlexeiFedorov   values.
1896ee92598Sjohpow01
1906ee92598Sjohpow01API Constraints
1916ee92598Sjohpow01~~~~~~~~~~~~~~~
1926ee92598Sjohpow01
1936ee92598Sjohpow01The values allowed by the API for PPS and PGS are enumerated types
1946ee92598Sjohpow01defined in the file ``include/lib/gpt_rme/gpt_rme.h``.
1956ee92598Sjohpow01
1966ee92598Sjohpow01Allowable values for PPS along with their corresponding size.
1976ee92598Sjohpow01
1986ee92598Sjohpow01* ``GPCCR_PPS_4GB`` (4GB protected space, 0x100000000 bytes)
1996ee92598Sjohpow01* ``GPCCR_PPS_64GB`` (64GB protected space, 0x1000000000 bytes)
2006ee92598Sjohpow01* ``GPCCR_PPS_1TB`` (1TB protected space, 0x10000000000 bytes)
2016ee92598Sjohpow01* ``GPCCR_PPS_4TB`` (4TB protected space, 0x40000000000 bytes)
2026ee92598Sjohpow01* ``GPCCR_PPS_16TB`` (16TB protected space, 0x100000000000 bytes)
2036ee92598Sjohpow01* ``GPCCR_PPS_256TB`` (256TB protected space, 0x1000000000000 bytes)
2046ee92598Sjohpow01* ``GPCCR_PPS_4PB`` (4PB protected space, 0x10000000000000 bytes)
2056ee92598Sjohpow01
2066ee92598Sjohpow01Allowable values for PGS along with their corresponding size.
2076ee92598Sjohpow01
2086ee92598Sjohpow01* ``GPCCR_PGS_4K`` (4KB granules, 0x1000 bytes)
2096ee92598Sjohpow01* ``GPCCR_PGS_16K`` (16KB granules, 0x4000 bytes)
2106ee92598Sjohpow01* ``GPCCR_PGS_64K`` (64KB granules, 0x10000 bytes)
2116ee92598Sjohpow01
2126ee92598Sjohpow01Allowable values for L0GPTSZ along with the corresponding size.
2136ee92598Sjohpow01
2146ee92598Sjohpow01* ``GPCCR_L0GPTSZ_30BITS`` (1GB regions, 0x40000000 bytes)
2156ee92598Sjohpow01* ``GPCCR_L0GPTSZ_34BITS`` (16GB regions, 0x400000000 bytes)
2166ee92598Sjohpow01* ``GPCCR_L0GPTSZ_36BITS`` (64GB regions, 0x1000000000 bytes)
2176ee92598Sjohpow01* ``GPCCR_L0GPTSZ_39BITS`` (512GB regions, 0x8000000000 bytes)
2186ee92598Sjohpow01
2196ee92598Sjohpow01Note that the value of the PPS, PGS, and L0GPTSZ definitions is an encoded value
2206ee92598Sjohpow01corresponding to the size, not the size itself. The decoded hex representations
2216ee92598Sjohpow01of the sizes have been provided for convenience.
2226ee92598Sjohpow01
2236ee92598Sjohpow01The L0 table memory has some constraints that must be taken into account.
2246ee92598Sjohpow01
2256ee92598Sjohpow01* The L0 table must be aligned to either the table size or 4096 bytes, whichever
2266ee92598Sjohpow01  is greater. L0 table size is the total protected space (PPS) divided by the
2276ee92598Sjohpow01  size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
2286ee92598Sjohpow01  (8 bytes). ((PPS / L0GPTSZ) * 8)
2296ee92598Sjohpow01* The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
2306ee92598Sjohpow01
2316ee92598Sjohpow01The L1 memory also has some constraints.
2326ee92598Sjohpow01
2336ee92598Sjohpow01* The L1 tables must be aligned to their size. The size of each L1 table is the
2346ee92598Sjohpow01  size of each L0 region (L0GPTSZ) divided by the granule size (PGS) divided by
2356ee92598Sjohpow01  the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2)
2366ee92598Sjohpow01* There must be enough L1 memory supplied to build all requested L1 tables.
2376ee92598Sjohpow01* The L1 memory must fall within a PAS of type GPT_GPI_ROOT.
238*b0f1c840SAlexeiFedorov* The platform allocates the bitlock array which contains fine-grained
239*b0f1c840SAlexeiFedorov  ``bitlock_t`` data structures. The RME GPT library will check that the array
240*b0f1c840SAlexeiFedorov  has at least the amount of memory defined by PPS and ``RME_GPT_BITLOCK_BLOCK``
241*b0f1c840SAlexeiFedorov  value.
2426ee92598Sjohpow01
2436ee92598Sjohpow01If an invalid combination of parameters is supplied, the APIs will print an
2446ee92598Sjohpow01error message and return a negative value. The return values of APIs should be
2456ee92598Sjohpow01checked to ensure successful configuration.
2466ee92598Sjohpow01
2476ee92598Sjohpow01Sample Calculation for L0 memory size and alignment
2486ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2496ee92598Sjohpow01
250*b0f1c840SAlexeiFedorovLet PPS=4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
2516ee92598Sjohpow01
2526ee92598Sjohpow01We can find the total L0 table size with ((PPS / L0GPTSZ) * 8)
2536ee92598Sjohpow01
2546ee92598Sjohpow01Substitute values to get this: ((0x100000000 / 0x40000000) * 8)
2556ee92598Sjohpow01
2566ee92598Sjohpow01And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
2576ee92598Sjohpow01tables must be aligned to 4096 bytes.
2586ee92598Sjohpow01
259*b0f1c840SAlexeiFedorovSample calculation for bitlocks array size
260*b0f1c840SAlexeiFedorov~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261c944952bSAlexeiFedorov
262*b0f1c840SAlexeiFedorovLet PPS=256TB and RME_GPT_BITLOCK_BLOCK=1
263c944952bSAlexeiFedorov
264*b0f1c840SAlexeiFedorovThe size of bitlocks array in bits is the total protected space (PPS) divided
265c944952bSAlexeiFedorovby the size of memory block per bit. The size of memory block
266c944952bSAlexeiFedorovis ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
267*b0f1c840SAlexeiFedorov512MB (0x20000000). This is then divided by the number of bits in ``bitlock_t``
268*b0f1c840SAlexeiFedorovstructure (8) to get the size of array in bytes.
269c944952bSAlexeiFedorov
270*b0f1c840SAlexeiFedorovIn other words, we can find the total size of ``bitlock_t`` array
271c944952bSAlexeiFedorovin bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 * 8).
272c944952bSAlexeiFedorov
273c944952bSAlexeiFedorovSubstitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)
274c944952bSAlexeiFedorov
275c944952bSAlexeiFedorovAnd solve to get 0x10000 bytes.
276c944952bSAlexeiFedorov
2776ee92598Sjohpow01Sample calculation for L1 table size and alignment
2786ee92598Sjohpow01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2796ee92598Sjohpow01
2806ee92598Sjohpow01Let PGS=GPCCR_PGS_4K and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
2816ee92598Sjohpow01
2826ee92598Sjohpow01We can find the size of each L1 table with ((L0GPTSZ / PGS) / 2).
2836ee92598Sjohpow01
2846ee92598Sjohpow01Substitute values: ((0x40000000 / 0x1000) / 2)
2856ee92598Sjohpow01
2866ee92598Sjohpow01And solve to get 0x20000 bytes per L1 table.
287