blob: 379b91562a0b83f56b945d0fb21fa0028cdca81c [file] [log] [blame]
johpow019d134022021-06-16 17:57:28 -05001/*
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 */
23typedef 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
101typedef 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
121typedef 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
132typedef 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
143typedef 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
155typedef 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
167typedef 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 */
200int 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 */
220int 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 */
237int 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 */
247int gpt_enable(void);
248
249/*
250 * Public API to disable granule protection checks.
251 */
252void 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 */
271int 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 */