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 <attestation_token.h>
13 #include <fpu_helpers.h>
14 #include <gic.h>
15 #include <memory_alloc.h>
16 #include <ripas.h>
17 #include <sizes.h>
18 #include <smc-rmi.h>
19 #include <utils_def.h>
20
21 struct granule;
22
23 /*
24 * System registers whose contents are specific to a REC.
25 */
26 struct sysreg_state {
27 unsigned long sp_el0;
28 unsigned long sp_el1;
29 unsigned long elr_el1;
30 unsigned long spsr_el1;
31 unsigned long pmcr_el0;
32 unsigned long pmuserenr_el0;
33 unsigned long tpidrro_el0;
34 unsigned long tpidr_el0;
35 unsigned long csselr_el1;
36 unsigned long sctlr_el1;
37 unsigned long actlr_el1;
38 unsigned long cpacr_el1;
39 unsigned long zcr_el1;
40 unsigned long ttbr0_el1;
41 unsigned long ttbr1_el1;
42 unsigned long tcr_el1;
43 unsigned long esr_el1;
44 unsigned long afsr0_el1;
45 unsigned long afsr1_el1;
46 unsigned long far_el1;
47 unsigned long mair_el1;
48 unsigned long vbar_el1;
49 unsigned long contextidr_el1;
50 unsigned long tpidr_el1;
51 unsigned long amair_el1;
52 unsigned long cntkctl_el1;
53 unsigned long par_el1;
54 unsigned long mdscr_el1;
55 unsigned long mdccint_el1;
56 unsigned long disr_el1;
57 unsigned long mpam0_el1;
58
59 /* Timer Registers */
60 unsigned long cnthctl_el2;
61 unsigned long cntvoff_el2;
62 unsigned long cntpoff_el2;
63 unsigned long cntp_ctl_el0;
64 unsigned long cntp_cval_el0;
65 unsigned long cntv_ctl_el0;
66 unsigned long cntv_cval_el0;
67
68 /* GIC Registers */
69 struct gic_cpu_state gicstate;
70
71 /* TODO MPAM */
72 /* TODO Performance Monitor Registers */
73 /* TODO Pointer Authentication Registers */
74
75 unsigned long vmpidr_el2; /* restored only */
76 unsigned long hcr_el2; /* restored only */
77 };
78
79 /*
80 * System registers whose contents are
81 * common across all RECs in a Realm.
82 */
83 struct common_sysreg_state {
84 unsigned long vttbr_el2;
85 unsigned long vtcr_el2;
86 unsigned long hcr_el2;
87 };
88
89 /*
90 * This structure is aligned on cache line size to avoid cache line trashing
91 * when allocated as an array for N CPUs.
92 */
93 struct ns_state {
94 struct sysreg_state sysregs;
95 unsigned long sp_el0;
96 unsigned long icc_sre_el2;
97 struct fpu_state *fpu; /* FPU/SVE saved lazily. */
98 struct sve_state *sve;
99 } __attribute__((aligned(CACHE_WRITEBACK_GRANULE)));
100
101 /*
102 * This structure contains pointers to data that is allocated
103 * in auxilary granules.
104 */
105 struct rec_aux_data {
106 uint8_t *attest_heap_buf; /* Pointer to the heap buffer of this REC. */
107 };
108
109 /* This structure is used for storing FPU/SIMD context for realm. */
110 struct rec_fpu_context {
111 struct fpu_state fpu;
112 bool used;
113 };
114
115 struct rec {
116 struct granule *g_rec; /* the granule in which this rec lives */
117 unsigned long rec_idx; /* Which rec is this */
118 bool runnable;
119
120 unsigned long regs[31];
121 unsigned long pc;
122 unsigned long pstate;
123
124 struct sysreg_state sysregs;
125 struct common_sysreg_state common_sysregs;
126
127 struct {
128 unsigned long start;
129 unsigned long end;
130 unsigned long addr;
131 enum ripas ripas;
132 } set_ripas;
133
134 /*
135 * Common values across all RECs in a Realm.
136 */
137 struct {
138 unsigned long ipa_bits;
139 int s2_starting_level;
140 struct granule *g_rtt;
141 struct granule *g_rd;
142 } realm_info;
143
144 struct {
145 /*
146 * The contents of the *_EL2 system registers at the last time
147 * the REC exited to the host due to a synchronous exception.
148 * These are the unsanitized register values which may differ
149 * from the value returned to the host in rec_exit structure.
150 */
151 unsigned long esr;
152 unsigned long hpfar;
153 unsigned long far;
154 } last_run_info;
155
156 /* Structure for storing FPU/SIMD context for realm. */
157 struct rec_fpu_context fpu_ctx;
158
159 /* Pointer to per-cpu non-secure state */
160 struct ns_state *ns;
161
162 struct {
163 /*
164 * Set to 'true' when there is a pending PSCI
165 * command that must be resolved by the host.
166 * The command is encoded in rec->regs[0].
167 *
168 * A REC with pending PSCI is not schedulable.
169 */
170 bool pending;
171 } psci_info;
172
173 /* Number of auxiliary granules */
174 unsigned int num_rec_aux;
175
176 /* Addresses of auxiliary granules */
177 struct granule *g_aux[MAX_REC_AUX_GRANULES];
178 struct rec_aux_data aux_data;
179
180 unsigned char rmm_realm_token_buf[SZ_1K];
181 struct q_useful_buf_c rmm_realm_token;
182
183 struct token_sign_ctx token_sign_ctx;
184
185 /* Buffer allocation info used for heap init and management */
186 struct {
187 struct buffer_alloc_ctx ctx;
188 bool ctx_initialised;
189 } alloc_info;
190
191 struct {
192 unsigned long vsesr_el2;
193 bool inject;
194 } serror_info;
195
196 /* True if host call is pending */
197 bool host_call;
198 };
199 COMPILER_ASSERT(sizeof(struct rec) <= GRANULE_SIZE);
200
201 /*
202 * Check that mpidr has a valid value with all fields except
203 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0] set to 0.
204 */
mpidr_is_valid(unsigned long mpidr)205 static inline bool mpidr_is_valid(unsigned long mpidr)
206 {
207 return (mpidr & ~(MASK(MPIDR_EL2_AFF0) |
208 MASK(MPIDR_EL2_AFF1) |
209 MASK(MPIDR_EL2_AFF2) |
210 MASK(MPIDR_EL2_AFF3))) == 0ULL;
211 }
212
213 /*
214 * Calculate REC index from mpidr value.
215 * index = Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
216 */
mpidr_to_rec_idx(unsigned long mpidr)217 static inline unsigned long mpidr_to_rec_idx(unsigned long mpidr)
218 {
219 return (MPIDR_EL2_AFF(0, mpidr) +
220 MPIDR_EL2_AFF(1, mpidr) +
221 MPIDR_EL2_AFF(2, mpidr) +
222 MPIDR_EL2_AFF(3, mpidr));
223 }
224
225 void rec_run_loop(struct rec *rec, struct rmi_rec_exit *rec_exit);
226
227 unsigned long smc_rec_create(unsigned long rec_addr,
228 unsigned long rd_addr,
229 unsigned long rec_params_addr);
230
231 unsigned long smc_rec_destroy(unsigned long rec_addr);
232
233 unsigned long smc_rec_enter(unsigned long rec_addr,
234 unsigned long rec_run_addr);
235
236 void inject_serror(struct rec *rec, unsigned long vsesr);
237
238 void emulate_stage2_data_abort(struct rec *rec, struct rmi_rec_exit *exit,
239 unsigned long rtt_level);
240
241 #endif /* __ASSEMBLER__ */
242
243 #endif /* REC_H */
244