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