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