blob: 044641a22cf81ad61e32c3ea8ce4c7b58d77796e [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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 <attestation_token.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000013#include <gic.h>
14#include <memory_alloc.h>
Arvind Ram Prakashbd36a1b2022-12-15 12:16:36 -060015#include <pauth.h>
AlexeiFedoroveaec0c42023-02-01 18:13:32 +000016#include <pmu.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000017#include <ripas.h>
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +000018#include <simd.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000019#include <sizes.h>
20#include <smc-rmi.h>
21#include <utils_def.h>
22
23struct granule;
24
25/*
26 * System registers whose contents are specific to a REC.
27 */
28struct sysreg_state {
29 unsigned long sp_el0;
30 unsigned long sp_el1;
31 unsigned long elr_el1;
32 unsigned long spsr_el1;
33 unsigned long pmcr_el0;
Soby Mathewb4c6df42022-11-09 11:13:29 +000034 unsigned long tpidrro_el0;
35 unsigned long tpidr_el0;
36 unsigned long csselr_el1;
37 unsigned long sctlr_el1;
38 unsigned long actlr_el1;
39 unsigned long cpacr_el1;
40 unsigned long zcr_el1;
41 unsigned long ttbr0_el1;
42 unsigned long ttbr1_el1;
43 unsigned long tcr_el1;
44 unsigned long esr_el1;
45 unsigned long afsr0_el1;
46 unsigned long afsr1_el1;
47 unsigned long far_el1;
48 unsigned long mair_el1;
49 unsigned long vbar_el1;
50 unsigned long contextidr_el1;
51 unsigned long tpidr_el1;
52 unsigned long amair_el1;
53 unsigned long cntkctl_el1;
54 unsigned long par_el1;
55 unsigned long mdscr_el1;
56 unsigned long mdccint_el1;
57 unsigned long disr_el1;
58 unsigned long mpam0_el1;
59
60 /* Timer Registers */
61 unsigned long cnthctl_el2;
62 unsigned long cntvoff_el2;
63 unsigned long cntpoff_el2;
64 unsigned long cntp_ctl_el0;
65 unsigned long cntp_cval_el0;
66 unsigned long cntv_ctl_el0;
67 unsigned long cntv_cval_el0;
68
69 /* GIC Registers */
70 struct gic_cpu_state gicstate;
71
72 /* TODO MPAM */
73 /* TODO Performance Monitor Registers */
74 /* TODO Pointer Authentication Registers */
75
76 unsigned long vmpidr_el2; /* restored only */
77 unsigned long hcr_el2; /* restored only */
78};
79
80/*
81 * System registers whose contents are
82 * common across all RECs in a Realm.
83 */
84struct common_sysreg_state {
85 unsigned long vttbr_el2;
86 unsigned long vtcr_el2;
87 unsigned long hcr_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +000088 unsigned long mdcr_el2;
Soby Mathewb4c6df42022-11-09 11:13:29 +000089};
90
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +000091/* This structure is used for storing FPU or SVE context for realm. */
92struct rec_simd_state {
93 struct simd_state *simd; /* Pointer to SIMD context in AUX page */
94 bool simd_allowed; /* Set when REC is allowed to use SIMD */
95 bool init_done; /* flag used to check if SIMD state initialized */
96};
97
Soby Mathewb4c6df42022-11-09 11:13:29 +000098/*
99 * This structure is aligned on cache line size to avoid cache line trashing
100 * when allocated as an array for N CPUs.
101 */
102struct ns_state {
103 struct sysreg_state sysregs;
104 unsigned long sp_el0;
105 unsigned long icc_sre_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000106 struct pmu_state *pmu;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000107} __attribute__((aligned(CACHE_WRITEBACK_GRANULE)));
108
109/*
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000110 * This structure contains pointers to data that are allocated
111 * in auxilary granules for a REC.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000112 */
113struct rec_aux_data {
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000114 uint8_t *attest_heap_buf; /* pointer to the heap buffer */
115 struct pmu_state *pmu; /* pointer to PMU state */
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000116 struct rec_simd_state rec_simd; /* REC SIMD context region */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000117};
118
119struct rec {
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000120 struct granule *g_rec; /* the granule in which this REC lives */
121 unsigned long rec_idx; /* which REC is this */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000122 bool runnable;
123
124 unsigned long regs[31];
Arvind Ram Prakashbd36a1b2022-12-15 12:16:36 -0600125
126 /*
127 * PAuth state of Realm.
128 * Note that we do not need to save NS state as EL3 will save this as part of world switch.
129 */
130 struct pauth_state pauth;
131
Soby Mathewb4c6df42022-11-09 11:13:29 +0000132 unsigned long pc;
133 unsigned long pstate;
134
135 struct sysreg_state sysregs;
136 struct common_sysreg_state common_sysregs;
137
138 struct {
139 unsigned long start;
140 unsigned long end;
141 unsigned long addr;
142 enum ripas ripas;
143 } set_ripas;
144
145 /*
146 * Common values across all RECs in a Realm.
147 */
148 struct {
149 unsigned long ipa_bits;
150 int s2_starting_level;
151 struct granule *g_rtt;
152 struct granule *g_rd;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000153 bool pmu_enabled;
154 unsigned int pmu_num_cnts;
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000155 bool sve_enabled;
156 uint8_t sve_vq;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000157 } realm_info;
158
159 struct {
160 /*
161 * The contents of the *_EL2 system registers at the last time
162 * the REC exited to the host due to a synchronous exception.
163 * These are the unsanitized register values which may differ
164 * from the value returned to the host in rec_exit structure.
165 */
166 unsigned long esr;
167 unsigned long hpfar;
168 unsigned long far;
169 } last_run_info;
170
Soby Mathewb4c6df42022-11-09 11:13:29 +0000171 /* Pointer to per-cpu non-secure state */
172 struct ns_state *ns;
173
174 struct {
175 /*
176 * Set to 'true' when there is a pending PSCI
177 * command that must be resolved by the host.
178 * The command is encoded in rec->regs[0].
179 *
180 * A REC with pending PSCI is not schedulable.
181 */
182 bool pending;
183 } psci_info;
184
185 /* Number of auxiliary granules */
186 unsigned int num_rec_aux;
187
188 /* Addresses of auxiliary granules */
189 struct granule *g_aux[MAX_REC_AUX_GRANULES];
190 struct rec_aux_data aux_data;
191
192 unsigned char rmm_realm_token_buf[SZ_1K];
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200193 size_t rmm_realm_token_len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000194
195 struct token_sign_ctx token_sign_ctx;
196
197 /* Buffer allocation info used for heap init and management */
198 struct {
199 struct buffer_alloc_ctx ctx;
200 bool ctx_initialised;
201 } alloc_info;
202
203 struct {
204 unsigned long vsesr_el2;
205 bool inject;
206 } serror_info;
207
208 /* True if host call is pending */
209 bool host_call;
210};
211COMPILER_ASSERT(sizeof(struct rec) <= GRANULE_SIZE);
212
213/*
214 * Check that mpidr has a valid value with all fields except
215 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0] set to 0.
216 */
217static inline bool mpidr_is_valid(unsigned long mpidr)
218{
219 return (mpidr & ~(MASK(MPIDR_EL2_AFF0) |
220 MASK(MPIDR_EL2_AFF1) |
221 MASK(MPIDR_EL2_AFF2) |
222 MASK(MPIDR_EL2_AFF3))) == 0ULL;
223}
224
225/*
226 * Calculate REC index from mpidr value.
227 * index = Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
228 */
229static inline unsigned long mpidr_to_rec_idx(unsigned long mpidr)
230{
231 return (MPIDR_EL2_AFF(0, mpidr) +
232 MPIDR_EL2_AFF(1, mpidr) +
233 MPIDR_EL2_AFF(2, mpidr) +
234 MPIDR_EL2_AFF(3, mpidr));
235}
236
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000237static inline simd_t rec_simd_type(struct rec *rec)
238{
239 if (rec->realm_info.sve_enabled) {
240 return SIMD_SVE;
241 } else {
242 return SIMD_FPU;
243 }
244}
245
246static inline bool rec_is_simd_allowed(struct rec *rec)
247{
248 assert(rec != NULL);
249 return rec->aux_data.rec_simd.simd_allowed;
250}
251
Soby Mathewb4c6df42022-11-09 11:13:29 +0000252void rec_run_loop(struct rec *rec, struct rmi_rec_exit *rec_exit);
253
254unsigned long smc_rec_create(unsigned long rec_addr,
255 unsigned long rd_addr,
256 unsigned long rec_params_addr);
257
258unsigned long smc_rec_destroy(unsigned long rec_addr);
259
260unsigned long smc_rec_enter(unsigned long rec_addr,
261 unsigned long rec_run_addr);
262
263void inject_serror(struct rec *rec, unsigned long vsesr);
264
265void emulate_stage2_data_abort(struct rec *rec, struct rmi_rec_exit *exit,
266 unsigned long rtt_level);
267
268#endif /* __ASSEMBLER__ */
269
270#endif /* REC_H */