xref: /arm-trusted-firmware/include/lib/gpt_rme/gpt_rme.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #ifndef GPT_RME_H
8*91f16700Schasinglulu #define GPT_RME_H
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <stdint.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <arch.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu /******************************************************************************/
15*91f16700Schasinglulu /* GPT helper macros and definitions                                          */
16*91f16700Schasinglulu /******************************************************************************/
17*91f16700Schasinglulu 
18*91f16700Schasinglulu /*
19*91f16700Schasinglulu  * Structure for specifying a mapping range and it's properties. This should not
20*91f16700Schasinglulu  * be manually initialized, using the MAP_GPT_REGION_x macros is recommended as
21*91f16700Schasinglulu  * to avoid potential incompatibilities in the future.
22*91f16700Schasinglulu  */
23*91f16700Schasinglulu typedef struct pas_region {
24*91f16700Schasinglulu 	uintptr_t	base_pa;	/* Base address for PAS. */
25*91f16700Schasinglulu 	size_t		size;		/* Size of the PAS. */
26*91f16700Schasinglulu 	unsigned int	attrs;		/* PAS GPI and entry type. */
27*91f16700Schasinglulu } pas_region_t;
28*91f16700Schasinglulu 
29*91f16700Schasinglulu /* GPT GPI definitions */
30*91f16700Schasinglulu #define GPT_GPI_NO_ACCESS		U(0x0)
31*91f16700Schasinglulu #define GPT_GPI_SECURE			U(0x8)
32*91f16700Schasinglulu #define GPT_GPI_NS			U(0x9)
33*91f16700Schasinglulu #define GPT_GPI_ROOT			U(0xA)
34*91f16700Schasinglulu #define GPT_GPI_REALM			U(0xB)
35*91f16700Schasinglulu #define GPT_GPI_ANY			U(0xF)
36*91f16700Schasinglulu #define GPT_GPI_VAL_MASK		UL(0xF)
37*91f16700Schasinglulu 
38*91f16700Schasinglulu #define GPT_NSE_SECURE			U(0b00)
39*91f16700Schasinglulu #define GPT_NSE_ROOT			U(0b01)
40*91f16700Schasinglulu #define GPT_NSE_NS			U(0b10)
41*91f16700Schasinglulu #define GPT_NSE_REALM			U(0b11)
42*91f16700Schasinglulu 
43*91f16700Schasinglulu #define GPT_NSE_SHIFT                   U(62)
44*91f16700Schasinglulu 
45*91f16700Schasinglulu /* PAS attribute GPI definitions. */
46*91f16700Schasinglulu #define GPT_PAS_ATTR_GPI_SHIFT		U(0)
47*91f16700Schasinglulu #define GPT_PAS_ATTR_GPI_MASK		U(0xF)
48*91f16700Schasinglulu #define GPT_PAS_ATTR_GPI(_attrs)	(((_attrs)			\
49*91f16700Schasinglulu 					>> GPT_PAS_ATTR_GPI_SHIFT)	\
50*91f16700Schasinglulu 					& GPT_PAS_ATTR_GPI_MASK)
51*91f16700Schasinglulu 
52*91f16700Schasinglulu /* PAS attribute mapping type definitions */
53*91f16700Schasinglulu #define GPT_PAS_ATTR_MAP_TYPE_BLOCK	U(0x0)
54*91f16700Schasinglulu #define GPT_PAS_ATTR_MAP_TYPE_GRANULE	U(0x1)
55*91f16700Schasinglulu #define GPT_PAS_ATTR_MAP_TYPE_SHIFT	U(4)
56*91f16700Schasinglulu #define GPT_PAS_ATTR_MAP_TYPE_MASK	U(0x1)
57*91f16700Schasinglulu #define GPT_PAS_ATTR_MAP_TYPE(_attrs)	(((_attrs)			\
58*91f16700Schasinglulu 					>> GPT_PAS_ATTR_MAP_TYPE_SHIFT)	\
59*91f16700Schasinglulu 					& GPT_PAS_ATTR_MAP_TYPE_MASK)
60*91f16700Schasinglulu 
61*91f16700Schasinglulu /*
62*91f16700Schasinglulu  * Macro to initialize the attributes field in the pas_region_t structure.
63*91f16700Schasinglulu  * [31:5] Reserved
64*91f16700Schasinglulu  * [4]    Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions)
65*91f16700Schasinglulu  * [3:0]  PAS GPI type (GPT_GPI_x definitions)
66*91f16700Schasinglulu  */
67*91f16700Schasinglulu #define GPT_PAS_ATTR(_type, _gpi)					\
68*91f16700Schasinglulu 	((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK)			\
69*91f16700Schasinglulu 	  << GPT_PAS_ATTR_MAP_TYPE_SHIFT) |				\
70*91f16700Schasinglulu 	(((_gpi) & GPT_PAS_ATTR_GPI_MASK)				\
71*91f16700Schasinglulu 	 << GPT_PAS_ATTR_GPI_SHIFT))
72*91f16700Schasinglulu 
73*91f16700Schasinglulu /*
74*91f16700Schasinglulu  * Macro to create a GPT entry for this PAS range as a block descriptor. If this
75*91f16700Schasinglulu  * region does not fit the requirements for a block descriptor then GPT
76*91f16700Schasinglulu  * initialization will fail.
77*91f16700Schasinglulu  */
78*91f16700Schasinglulu #define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi)				\
79*91f16700Schasinglulu 	{								\
80*91f16700Schasinglulu 		.base_pa = (_pa),					\
81*91f16700Schasinglulu 		.size = (_sz),						\
82*91f16700Schasinglulu 		.attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \
83*91f16700Schasinglulu 	}
84*91f16700Schasinglulu 
85*91f16700Schasinglulu /*
86*91f16700Schasinglulu  * Macro to create a GPT entry for this PAS range as a table descriptor. If this
87*91f16700Schasinglulu  * region does not fit the requirements for a table descriptor then GPT
88*91f16700Schasinglulu  * initialization will fail.
89*91f16700Schasinglulu  */
90*91f16700Schasinglulu #define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi)				\
91*91f16700Schasinglulu 	{								\
92*91f16700Schasinglulu 		.base_pa = (_pa),					\
93*91f16700Schasinglulu 		.size = (_sz),						\
94*91f16700Schasinglulu 		.attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \
95*91f16700Schasinglulu 	}
96*91f16700Schasinglulu 
97*91f16700Schasinglulu /******************************************************************************/
98*91f16700Schasinglulu /* GPT register field definitions                                             */
99*91f16700Schasinglulu /******************************************************************************/
100*91f16700Schasinglulu 
101*91f16700Schasinglulu /*
102*91f16700Schasinglulu  * Least significant address bits protected by each entry in level 0 GPT. This
103*91f16700Schasinglulu  * field is read-only.
104*91f16700Schasinglulu  */
105*91f16700Schasinglulu #define GPCCR_L0GPTSZ_SHIFT	U(20)
106*91f16700Schasinglulu #define GPCCR_L0GPTSZ_MASK	U(0xF)
107*91f16700Schasinglulu 
108*91f16700Schasinglulu typedef enum {
109*91f16700Schasinglulu 	GPCCR_L0GPTSZ_30BITS	= U(0x0),
110*91f16700Schasinglulu 	GPCCR_L0GPTSZ_34BITS	= U(0x4),
111*91f16700Schasinglulu 	GPCCR_L0GPTSZ_36BITS	= U(0x6),
112*91f16700Schasinglulu 	GPCCR_L0GPTSZ_39BITS	= U(0x9)
113*91f16700Schasinglulu } gpccr_l0gptsz_e;
114*91f16700Schasinglulu 
115*91f16700Schasinglulu /* Granule protection check priority bit definitions */
116*91f16700Schasinglulu #define GPCCR_GPCP_SHIFT	U(17)
117*91f16700Schasinglulu #define GPCCR_GPCP_BIT		(ULL(1) << GPCCR_EL3_GPCP_SHIFT)
118*91f16700Schasinglulu 
119*91f16700Schasinglulu /* Granule protection check bit definitions */
120*91f16700Schasinglulu #define GPCCR_GPC_SHIFT		U(16)
121*91f16700Schasinglulu #define GPCCR_GPC_BIT		(ULL(1) << GPCCR_GPC_SHIFT)
122*91f16700Schasinglulu 
123*91f16700Schasinglulu /* Physical granule size bit definitions */
124*91f16700Schasinglulu #define GPCCR_PGS_SHIFT		U(14)
125*91f16700Schasinglulu #define GPCCR_PGS_MASK		U(0x3)
126*91f16700Schasinglulu #define SET_GPCCR_PGS(x)	(((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT)
127*91f16700Schasinglulu 
128*91f16700Schasinglulu typedef enum {
129*91f16700Schasinglulu 	GPCCR_PGS_4K		= U(0x0),
130*91f16700Schasinglulu 	GPCCR_PGS_64K		= U(0x1),
131*91f16700Schasinglulu 	GPCCR_PGS_16K		= U(0x2)
132*91f16700Schasinglulu } gpccr_pgs_e;
133*91f16700Schasinglulu 
134*91f16700Schasinglulu /* GPT fetch shareability attribute bit definitions */
135*91f16700Schasinglulu #define GPCCR_SH_SHIFT		U(12)
136*91f16700Schasinglulu #define GPCCR_SH_MASK		U(0x3)
137*91f16700Schasinglulu #define SET_GPCCR_SH(x)		(((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT)
138*91f16700Schasinglulu 
139*91f16700Schasinglulu typedef enum {
140*91f16700Schasinglulu 	GPCCR_SH_NS		= U(0x0),
141*91f16700Schasinglulu 	GPCCR_SH_OS		= U(0x2),
142*91f16700Schasinglulu 	GPCCR_SH_IS		= U(0x3)
143*91f16700Schasinglulu } gpccr_sh_e;
144*91f16700Schasinglulu 
145*91f16700Schasinglulu /* GPT fetch outer cacheability attribute bit definitions */
146*91f16700Schasinglulu #define GPCCR_ORGN_SHIFT	U(10)
147*91f16700Schasinglulu #define GPCCR_ORGN_MASK		U(0x3)
148*91f16700Schasinglulu #define SET_GPCCR_ORGN(x)	(((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT)
149*91f16700Schasinglulu 
150*91f16700Schasinglulu typedef enum {
151*91f16700Schasinglulu 	GPCCR_ORGN_NC		= U(0x0),
152*91f16700Schasinglulu 	GPCCR_ORGN_WB_RA_WA	= U(0x1),
153*91f16700Schasinglulu 	GPCCR_ORGN_WT_RA_NWA	= U(0x2),
154*91f16700Schasinglulu 	GPCCR_ORGN_WB_RA_NWA	= U(0x3)
155*91f16700Schasinglulu } gpccr_orgn_e;
156*91f16700Schasinglulu 
157*91f16700Schasinglulu /* GPT fetch inner cacheability attribute bit definitions */
158*91f16700Schasinglulu #define GPCCR_IRGN_SHIFT	U(8)
159*91f16700Schasinglulu #define GPCCR_IRGN_MASK		U(0x3)
160*91f16700Schasinglulu #define SET_GPCCR_IRGN(x)	(((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT)
161*91f16700Schasinglulu 
162*91f16700Schasinglulu typedef enum {
163*91f16700Schasinglulu 	GPCCR_IRGN_NC		= U(0x0),
164*91f16700Schasinglulu 	GPCCR_IRGN_WB_RA_WA	= U(0x1),
165*91f16700Schasinglulu 	GPCCR_IRGN_WT_RA_NWA	= U(0x2),
166*91f16700Schasinglulu 	GPCCR_IRGN_WB_RA_NWA	= U(0x3)
167*91f16700Schasinglulu } gpccr_irgn_e;
168*91f16700Schasinglulu 
169*91f16700Schasinglulu /* Protected physical address size bit definitions */
170*91f16700Schasinglulu #define GPCCR_PPS_SHIFT		U(0)
171*91f16700Schasinglulu #define GPCCR_PPS_MASK		U(0x7)
172*91f16700Schasinglulu #define SET_GPCCR_PPS(x)	(((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT)
173*91f16700Schasinglulu 
174*91f16700Schasinglulu typedef enum {
175*91f16700Schasinglulu 	GPCCR_PPS_4GB		= U(0x0),
176*91f16700Schasinglulu 	GPCCR_PPS_64GB		= U(0x1),
177*91f16700Schasinglulu 	GPCCR_PPS_1TB		= U(0x2),
178*91f16700Schasinglulu 	GPCCR_PPS_4TB		= U(0x3),
179*91f16700Schasinglulu 	GPCCR_PPS_16TB		= U(0x4),
180*91f16700Schasinglulu 	GPCCR_PPS_256TB		= U(0x5),
181*91f16700Schasinglulu 	GPCCR_PPS_4PB		= U(0x6)
182*91f16700Schasinglulu } gpccr_pps_e;
183*91f16700Schasinglulu 
184*91f16700Schasinglulu /* Base Address for the GPT bit definitions */
185*91f16700Schasinglulu #define GPTBR_BADDR_SHIFT	U(0)
186*91f16700Schasinglulu #define GPTBR_BADDR_VAL_SHIFT	U(12)
187*91f16700Schasinglulu #define GPTBR_BADDR_MASK	ULL(0xffffffffff)
188*91f16700Schasinglulu 
189*91f16700Schasinglulu /******************************************************************************/
190*91f16700Schasinglulu /* GPT public APIs                                                            */
191*91f16700Schasinglulu /******************************************************************************/
192*91f16700Schasinglulu 
193*91f16700Schasinglulu /*
194*91f16700Schasinglulu  * Public API that initializes the entire protected space to GPT_GPI_ANY using
195*91f16700Schasinglulu  * the L0 tables (block descriptors).  Ideally, this function is invoked prior
196*91f16700Schasinglulu  * to DDR discovery and initialization.  The MMU must be initialized before
197*91f16700Schasinglulu  * calling this function.
198*91f16700Schasinglulu  *
199*91f16700Schasinglulu  * Parameters
200*91f16700Schasinglulu  *   pps		PPS value to use for table generation
201*91f16700Schasinglulu  *   l0_mem_base	Base address of L0 tables in memory.
202*91f16700Schasinglulu  *   l0_mem_size	Total size of memory available for L0 tables.
203*91f16700Schasinglulu  *
204*91f16700Schasinglulu  * Return
205*91f16700Schasinglulu  *   Negative Linux error code in the event of a failure, 0 for success.
206*91f16700Schasinglulu  */
207*91f16700Schasinglulu int gpt_init_l0_tables(gpccr_pps_e pps,
208*91f16700Schasinglulu 		       uintptr_t l0_mem_base,
209*91f16700Schasinglulu 		       size_t l0_mem_size);
210*91f16700Schasinglulu 
211*91f16700Schasinglulu /*
212*91f16700Schasinglulu  * Public API that carves out PAS regions from the L0 tables and builds any L1
213*91f16700Schasinglulu  * tables that are needed.  This function ideally is run after DDR discovery and
214*91f16700Schasinglulu  * initialization.  The L0 tables must have already been initialized to GPI_ANY
215*91f16700Schasinglulu  * when this function is called.
216*91f16700Schasinglulu  *
217*91f16700Schasinglulu  * Parameters
218*91f16700Schasinglulu  *   pgs		PGS value to use for table generation.
219*91f16700Schasinglulu  *   l1_mem_base	Base address of memory used for L1 tables.
220*91f16700Schasinglulu  *   l1_mem_size	Total size of memory available for L1 tables.
221*91f16700Schasinglulu  *   *pas_regions	Pointer to PAS regions structure array.
222*91f16700Schasinglulu  *   pas_count		Total number of PAS regions.
223*91f16700Schasinglulu  *
224*91f16700Schasinglulu  * Return
225*91f16700Schasinglulu  *   Negative Linux error code in the event of a failure, 0 for success.
226*91f16700Schasinglulu  */
227*91f16700Schasinglulu int gpt_init_pas_l1_tables(gpccr_pgs_e pgs,
228*91f16700Schasinglulu 			   uintptr_t l1_mem_base,
229*91f16700Schasinglulu 			   size_t l1_mem_size,
230*91f16700Schasinglulu 			   pas_region_t *pas_regions,
231*91f16700Schasinglulu 			   unsigned int pas_count);
232*91f16700Schasinglulu 
233*91f16700Schasinglulu /*
234*91f16700Schasinglulu  * Public API to initialize the runtime gpt_config structure based on the values
235*91f16700Schasinglulu  * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization
236*91f16700Schasinglulu  * typically happens in a bootloader stage prior to setting up the EL3 runtime
237*91f16700Schasinglulu  * environment for the granule transition service so this function detects the
238*91f16700Schasinglulu  * initialization from a previous stage. Granule protection checks must be
239*91f16700Schasinglulu  * enabled already or this function will return an error.
240*91f16700Schasinglulu  *
241*91f16700Schasinglulu  * Return
242*91f16700Schasinglulu  *   Negative Linux error code in the event of a failure, 0 for success.
243*91f16700Schasinglulu  */
244*91f16700Schasinglulu int gpt_runtime_init(void);
245*91f16700Schasinglulu 
246*91f16700Schasinglulu /*
247*91f16700Schasinglulu  * Public API to enable granule protection checks once the tables have all been
248*91f16700Schasinglulu  * initialized.  This function is called at first initialization and then again
249*91f16700Schasinglulu  * later during warm boots of CPU cores.
250*91f16700Schasinglulu  *
251*91f16700Schasinglulu  * Return
252*91f16700Schasinglulu  *   Negative Linux error code in the event of a failure, 0 for success.
253*91f16700Schasinglulu  */
254*91f16700Schasinglulu int gpt_enable(void);
255*91f16700Schasinglulu 
256*91f16700Schasinglulu /*
257*91f16700Schasinglulu  * Public API to disable granule protection checks.
258*91f16700Schasinglulu  */
259*91f16700Schasinglulu void gpt_disable(void);
260*91f16700Schasinglulu 
261*91f16700Schasinglulu /*
262*91f16700Schasinglulu  * This function is the core of the granule transition service. When a granule
263*91f16700Schasinglulu  * transition request occurs it is routed to this function where the request is
264*91f16700Schasinglulu  * validated then fulfilled if possible.
265*91f16700Schasinglulu  *
266*91f16700Schasinglulu  * TODO: implement support for transitioning multiple granules at once.
267*91f16700Schasinglulu  *
268*91f16700Schasinglulu  * Parameters
269*91f16700Schasinglulu  *   base: Base address of the region to transition, must be aligned to granule
270*91f16700Schasinglulu  *         size.
271*91f16700Schasinglulu  *   size: Size of region to transition, must be aligned to granule size.
272*91f16700Schasinglulu  *   src_sec_state: Security state of the originating SMC invoking the API.
273*91f16700Schasinglulu  *
274*91f16700Schasinglulu  * Return
275*91f16700Schasinglulu  *    Negative Linux error code in the event of a failure, 0 for success.
276*91f16700Schasinglulu  */
277*91f16700Schasinglulu int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state);
278*91f16700Schasinglulu int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state);
279*91f16700Schasinglulu 
280*91f16700Schasinglulu #endif /* GPT_RME_H */
281