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