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