1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6 #ifndef REC_H
7 #define REC_H
8
9 #ifndef __ASSEMBLER__
10
11 #include <arch.h>
12 #include <attest_app.h>
13 #include <gic.h>
14 #include <pauth.h>
15 #include <pmu.h>
16 #include <ripas.h>
17 #include <s2tt.h>
18 #include <simd.h>
19 #include <sizes.h>
20 #include <smc-rmi.h>
21 #include <utils_def.h>
22
23 #ifndef CBMC
24 #define RMM_REC_SAVED_GEN_REG_COUNT U(31)
25 #define STRUCT_TYPE struct
26 #define REG_TYPE unsigned long
27
28 /* Number of pages per REC for PMU state */
29 #define REC_PMU_PAGES 1U
30 #define REC_PMU_SIZE (REC_PMU_PAGES * SZ_4K)
31
32 /*
33 * SIMD context that holds FPU/SVE registers. Space to save max arch supported
34 * SVE vector length of 2048 bits.
35 * Size of 32 Z registers (256 bytes each): 8192 bytes
36 * Size of 16 P registers (32 bytes each) : 512 bytes
37 * Size of 1 FFR register (32 bytes each) : 32 bytes
38 * Size of other status registers : 32 bytes
39 * Total size is ~3 Pages (rounded up to page size).
40 */
41 #define REC_SIMD_PAGES 3U
42 #define REC_SIMD_SIZE (REC_SIMD_PAGES * SZ_4K)
43
44 /* Number of pages per REC for 'rec_attest_data' structure */
45 #define REC_ATTEST_PAGES 1U
46 #define REC_ATTEST_SIZE (REC_ATTEST_PAGES * SZ_4K)
47
48 /* Number of pages per REC to be allocated */
49 #define REC_NUM_PAGES (REC_PMU_PAGES + \
50 REC_SIMD_PAGES + \
51 REC_ATTEST_PAGES + \
52 RMM_CCA_TOKEN_BUFFER)
53
54 #else /* CBMC */
55 /*
56 * struct rec must fit in a single granule. CBMC has a smaller GRANULE_SIZE
57 * defined than on a real target, and the full structure doesn't fit there. The
58 * following definitions help making the structure smaller.
59 */
60 /*
61 * For CBMC it is not necessary to have a regs array that fits all the 31
62 * general registers
63 */
64 #define RMM_REC_SAVED_GEN_REG_COUNT SMC_RESULT_REGS
65 /*
66 * Some of the structures inside 'struct rec' don't influence the outcome of
67 * the CBMC tests, so for CBMC build make these a union making their size being
68 * of the largest field, instead of the sum of the fields' sizes.
69 */
70 #define STRUCT_TYPE union
71 /* Reserve a single byte per saved register instead of 8. */
72 #define REG_TYPE unsigned char
73
74 #define REC_PMU_PAGES 0U
75 #define REC_PMU_SIZE (REC_PMU_PAGES * SZ_4K)
76
77 #define REC_SIMD_PAGES 0U
78 #define REC_SIMD_SIZE (REC_SIMD_PAGES * SZ_4K)
79
80 #define REC_ATTEST_PAGES 0U
81 #define REC_ATTEST_SIZE (REC_ATTEST_PAGES * SZ_4K)
82
83 /* Number of aux granules pages per REC to be used */
84 #define REC_NUM_PAGES (1U)
85 #endif /* CBMC */
86
87 struct granule;
88
89 /*
90 * System registers whose contents are specific to a REC.
91 */
92 STRUCT_TYPE sysreg_state {
93 unsigned long sp_el1;
94 unsigned long elr_el1;
95 unsigned long spsr_el1;
96 unsigned long tpidrro_el0;
97 unsigned long tpidr_el0;
98 unsigned long csselr_el1;
99 unsigned long sctlr_el1;
100 unsigned long sctlr2_el1;
101 unsigned long actlr_el1;
102 unsigned long cpacr_el1;
103 unsigned long zcr_el1;
104 unsigned long ttbr0_el1;
105 unsigned long ttbr1_el1;
106 unsigned long tcr_el1;
107 unsigned long esr_el1;
108 unsigned long afsr0_el1;
109 unsigned long afsr1_el1;
110 unsigned long far_el1;
111 unsigned long mair_el1;
112 unsigned long vbar_el1;
113 unsigned long contextidr_el1;
114 unsigned long tpidr_el1;
115 unsigned long amair_el1;
116 unsigned long cntkctl_el1;
117 unsigned long par_el1;
118 unsigned long mdscr_el1;
119 unsigned long mdccint_el1;
120 unsigned long disr_el1;
121 unsigned long brbcr_el1;
122 unsigned long tcr2_el1;
123 unsigned long pir_el1;
124 unsigned long pire0_el1;
125 unsigned long por_el1;
126
127 /* Timer Registers */
128 unsigned long cnthctl_el2;
129 unsigned long cntvoff_el2;
130 unsigned long cntpoff_el2;
131 unsigned long cntp_ctl_el0;
132 unsigned long cntp_cval_el0;
133 unsigned long cntv_ctl_el0;
134 unsigned long cntv_cval_el0;
135
136 /* GIC Registers */
137 struct gic_cpu_state gicstate;
138
139 /* TODO MPAM */
140 /* TODO Performance Monitor Registers */
141 /* TODO Pointer Authentication Registers */
142
143 unsigned long vmpidr_el2; /* restored only */
144 unsigned long hcr_el2; /* restored only */
145
146 unsigned long cptr_el2; /* restored only */
147 };
148
149 /*
150 * System registers whose contents are
151 * common across all RECs in a Realm.
152 */
153 STRUCT_TYPE common_sysreg_state {
154 unsigned long vttbr_el2;
155 unsigned long vtcr_el2;
156 unsigned long hcr_el2;
157 unsigned long mdcr_el2;
158 };
159
160 /*
161 * This structure is aligned on cache line size to avoid cache line trashing
162 * when allocated as an array for N CPUs.
163 */
164 struct ns_state {
165 STRUCT_TYPE sysreg_state sysregs;
166 unsigned long sp_el0;
167 unsigned long icc_sre_el2;
168 struct pmu_state pmu;
169 } __aligned(CACHE_WRITEBACK_GRANULE);
170
171 /*
172 * Data used when handling attestation requests
173 */
174 struct rec_attest_data {
175 size_t rmm_realm_token_len;
176
177 /* Number of CCA token bytes copied to the Realm */
178 size_t rmm_cca_token_copied_len;
179
180 /* Number of CCA token bytes left to copy to the Realm */
181 size_t rmm_cca_token_len;
182 };
183 COMPILER_ASSERT(sizeof(struct rec_attest_data) <= GRANULE_SIZE);
184
185 /*
186 * This structure contains pointers to data that are allocated
187 * in auxilary granules for a REC.
188 */
189 struct rec_aux_data {
190 /* Pointer to PMU state */
191 struct pmu_state *pmu;
192
193 /* SIMD context region */
194 struct simd_context *simd_ctx;
195
196 /* Pointer to attestation-related data */
197 struct rec_attest_data *attest_data;
198 };
199
200 struct rec { /* NOLINT: Suppressing optin.performance.Padding as fields are in logical order */
201 struct granule *g_rec; /* the granule in which this REC lives */
202 unsigned long rec_idx; /* which REC is this */
203 bool runnable;
204
205 REG_TYPE regs[RMM_REC_SAVED_GEN_REG_COUNT];
206 REG_TYPE sp_el0;
207
208 #ifndef CBMC
209 /*
210 * PAuth state of Realm.
211 * Note that we do not need to save NS state as EL3 will save this as part of world switch.
212 */
213 struct pauth_state pauth;
214 #endif /* CBMC*/
215
216 unsigned long pc;
217 unsigned long pstate;
218
219 STRUCT_TYPE sysreg_state sysregs;
220 STRUCT_TYPE common_sysreg_state common_sysregs;
221
222 /* Populated when the REC issues a RIPAS change request */
223 struct {
224 unsigned long base;
225 unsigned long top;
226 unsigned long addr;
227 enum ripas ripas_val;
228 enum ripas_change_destroyed change_destroyed;
229 enum ripas_response response;
230 } set_ripas;
231
232 /*
233 * Common values across all RECs in a Realm.
234 */
235 struct {
236 struct granule *g_rd;
237 bool pmu_enabled;
238 unsigned int pmu_num_ctrs;
239 enum hash_algo algorithm;
240 struct simd_config simd_cfg;
241 struct s2tt_context s2_ctx;
242 } realm_info;
243
244 STRUCT_TYPE {
245 /*
246 * The contents of the *_EL2 system registers at the last time
247 * the REC exited to the host due to a synchronous exception.
248 * These are the unsanitized register values which may differ
249 * from the value returned to the host in rec_exit structure.
250 */
251 unsigned long esr;
252 unsigned long hpfar;
253 unsigned long far;
254 } last_run_info;
255
256 /* Pointer to per-cpu non-secure state */
257 struct ns_state *ns;
258
259 struct {
260 /*
261 * Set to 'true' when there is a pending PSCI
262 * command that must be resolved by the host.
263 * The command is encoded in rec->regs[0].
264 *
265 * A REC with pending PSCI is not schedulable.
266 */
267 bool pending;
268 } psci_info;
269
270 /* Number of auxiliary granules */
271 unsigned int num_rec_aux;
272
273 /* Addresses of auxiliary granules */
274 struct granule *g_aux[MAX_REC_AUX_GRANULES];
275 struct rec_aux_data aux_data;
276 struct {
277 unsigned long vsesr_el2;
278 bool inject;
279 } serror_info;
280
281 /* True if host call is pending */
282 bool host_call;
283
284 struct app_data_cfg attest_app_data;
285
286 /* The active SIMD context that is live in CPU registers */
287 struct simd_context *active_simd_ctx;
288 };
289 COMPILER_ASSERT(sizeof(struct rec) <= GRANULE_SIZE);
290 /*
291 * The `sp_el0` field must immediately follow `regs` field in `struct rec`.
292 * This assumption is used by the assembly code saving and restoring realm
293 * registers.
294 */
295 COMPILER_ASSERT(U(offsetof(struct rec, sp_el0)) ==
296 (U(offsetof(struct rec, regs)) + U(sizeof(REG_TYPE) * RMM_REC_SAVED_GEN_REG_COUNT)));
297
298 /*
299 * Check that mpidr of RmiRecMpidr type has a valid value with all fields except
300 * Aff3[31:24]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0] set to 0.
301 */
rec_mpidr_is_valid(unsigned long rec_mpidr)302 static inline bool rec_mpidr_is_valid(unsigned long rec_mpidr)
303 {
304 return (rec_mpidr & ~(MASK(RMI_MPIDR_AFF0) |
305 MASK(RMI_MPIDR_AFF1) |
306 MASK(RMI_MPIDR_AFF2) |
307 MASK(RMI_MPIDR_AFF3))) == 0ULL;
308 }
309
310 /*
311 * Calculate REC index from mpidr of RmiRecMpidr type value.
312 * index = Aff3[31:24]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
313 */
rec_mpidr_to_idx(unsigned long rec_mpidr)314 static inline unsigned long rec_mpidr_to_idx(unsigned long rec_mpidr)
315 {
316 return (RMI_MPIDR_AFF(0, rec_mpidr) |
317 RMI_MPIDR_AFF(1, rec_mpidr) |
318 RMI_MPIDR_AFF(2, rec_mpidr) |
319 RMI_MPIDR_AFF(3, rec_mpidr));
320 }
321
322 /*
323 * Calculate REC index from mpidr of MPIDR_EL1 register type
324 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
325 */
mpidr_to_rec_idx(unsigned long mpidr)326 static inline unsigned long mpidr_to_rec_idx(unsigned long mpidr)
327 {
328 return (MPIDR_EL1_AFF(0, mpidr) |
329 MPIDR_EL1_AFF(1, mpidr) |
330 MPIDR_EL1_AFF(2, mpidr) |
331 MPIDR_EL1_AFF(3, mpidr));
332 }
333
334 /*
335 * Convert mpidr of RmiRecMpidr type
336 * Aff3[31:24]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
337 * to MPIDR_EL1 register type value
338 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0].
339 */
rec_mpidr_to_mpidr(unsigned long rec_mpidr)340 static inline unsigned long rec_mpidr_to_mpidr(unsigned long rec_mpidr)
341 {
342 return (rec_mpidr & (MASK(RMI_MPIDR_AFF0) |
343 MASK(RMI_MPIDR_AFF1) |
344 MASK(RMI_MPIDR_AFF2))) |
345 ((rec_mpidr & MASK(RMI_MPIDR_AFF3)) <<
346 (MPIDR_EL1_AFF3_SHIFT - RMI_MPIDR_AFF3_SHIFT));
347 }
348
349 void rec_run_loop(struct rec *rec, struct rmi_rec_exit *rec_exit);
350 void inject_serror(struct rec *rec, unsigned long vsesr);
351 void emulate_stage2_data_abort(struct rec *rec, struct rmi_rec_exit *rec_exit,
352 unsigned long rtt_level);
353
354 #endif /* __ASSEMBLER__ */
355 #endif /* REC_H */
356