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