blob: 135a94844a9947a3e2ae8aad16158b9594b43fe0 [file] [log] [blame]
johpow019d134022021-06-16 17:57:28 -05001/*
AlexeiFedorov46881f72025-01-24 15:53:50 +00002 * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
johpow019d134022021-06-16 17:57:28 -05003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef GPT_RME_H
8#define GPT_RME_H
9
10#include <stdint.h>
AlexeiFedorov46881f72025-01-24 15:53:50 +000011#include <lib/spinlock.h>
johpow019d134022021-06-16 17:57:28 -050012
13/******************************************************************************/
14/* GPT helper macros and definitions */
15/******************************************************************************/
16
AlexeiFedorov46881f72025-01-24 15:53:50 +000017#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
22CASSERT((UL(1) == LOCK_SIZE), assert_bitlock_type_not_uint8_t);
23#endif /* RME_GPT_BITLOCK_BLOCK */
24
johpow019d134022021-06-16 17:57:28 -050025/*
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 */
30typedef 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
Robert Wakim48e6b572021-10-21 15:39:56 +010045#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
johpow019d134022021-06-16 17:57:28 -050052/* 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
115typedef 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
135typedef 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
146typedef 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
157typedef 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
169typedef 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
181typedef 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 */
214int 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 */
234int 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 *
AlexeiFedorov46881f72025-01-24 15:53:50 +0000248 * 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 *
johpow019d134022021-06-16 17:57:28 -0500252 * Return
253 * Negative Linux error code in the event of a failure, 0 for success.
254 */
AlexeiFedorov46881f72025-01-24 15:53:50 +0000255int gpt_runtime_init(uintptr_t l1_bitlocks_base, size_t l1_bitlocks_size);
johpow019d134022021-06-16 17:57:28 -0500256
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 */
265int gpt_enable(void);
266
267/*
268 * Public API to disable granule protection checks.
269 */
270void 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.
Robert Wakim48e6b572021-10-21 15:39:56 +0100283 * src_sec_state: Security state of the originating SMC invoking the API.
johpow019d134022021-06-16 17:57:28 -0500284 *
285 * Return
286 * Negative Linux error code in the event of a failure, 0 for success.
287 */
Robert Wakim48e6b572021-10-21 15:39:56 +0100288int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state);
289int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state);
johpow019d134022021-06-16 17:57:28 -0500290
291#endif /* GPT_RME_H */