blob: 05ac7f49d876c6e4b906bf24f534fce0dac8ebbe [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>
AlexeiFedoroveaec0c42023-02-01 18:13:32 +000015#include <pmu.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000016#include <ripas.h>
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +000017#include <simd.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000018#include <sizes.h>
19#include <smc-rmi.h>
20#include <utils_def.h>
21
22struct granule;
23
24/*
25 * System registers whose contents are specific to a REC.
26 */
27struct sysreg_state {
28 unsigned long sp_el0;
29 unsigned long sp_el1;
30 unsigned long elr_el1;
31 unsigned long spsr_el1;
32 unsigned long pmcr_el0;
Soby Mathewb4c6df42022-11-09 11:13:29 +000033 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 */
83struct common_sysreg_state {
84 unsigned long vttbr_el2;
85 unsigned long vtcr_el2;
86 unsigned long hcr_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +000087 unsigned long mdcr_el2;
Soby Mathewb4c6df42022-11-09 11:13:29 +000088};
89
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +000090/* This structure is used for storing FPU or SVE context for realm. */
91struct rec_simd_state {
92 struct simd_state *simd; /* Pointer to SIMD context in AUX page */
93 bool simd_allowed; /* Set when REC is allowed to use SIMD */
94 bool init_done; /* flag used to check if SIMD state initialized */
95};
96
Soby Mathewb4c6df42022-11-09 11:13:29 +000097/*
98 * This structure is aligned on cache line size to avoid cache line trashing
99 * when allocated as an array for N CPUs.
100 */
101struct ns_state {
102 struct sysreg_state sysregs;
103 unsigned long sp_el0;
104 unsigned long icc_sre_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000105 struct pmu_state *pmu;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000106} __attribute__((aligned(CACHE_WRITEBACK_GRANULE)));
107
108/*
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000109 * This structure contains pointers to data that are allocated
110 * in auxilary granules for a REC.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000111 */
112struct rec_aux_data {
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000113 uint8_t *attest_heap_buf; /* pointer to the heap buffer */
114 struct pmu_state *pmu; /* pointer to PMU state */
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000115 struct rec_simd_state rec_simd; /* REC SIMD context region */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000116};
117
118struct rec {
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000119 struct granule *g_rec; /* the granule in which this REC lives */
120 unsigned long rec_idx; /* which REC is this */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000121 bool runnable;
122
123 unsigned long regs[31];
124 unsigned long pc;
125 unsigned long pstate;
126
127 struct sysreg_state sysregs;
128 struct common_sysreg_state common_sysregs;
129
130 struct {
131 unsigned long start;
132 unsigned long end;
133 unsigned long addr;
134 enum ripas ripas;
135 } set_ripas;
136
137 /*
138 * Common values across all RECs in a Realm.
139 */
140 struct {
141 unsigned long ipa_bits;
142 int s2_starting_level;
143 struct granule *g_rtt;
144 struct granule *g_rd;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000145 bool pmu_enabled;
146 unsigned int pmu_num_cnts;
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000147 bool sve_enabled;
148 uint8_t sve_vq;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000149 } realm_info;
150
151 struct {
152 /*
153 * The contents of the *_EL2 system registers at the last time
154 * the REC exited to the host due to a synchronous exception.
155 * These are the unsanitized register values which may differ
156 * from the value returned to the host in rec_exit structure.
157 */
158 unsigned long esr;
159 unsigned long hpfar;
160 unsigned long far;
161 } last_run_info;
162
Soby Mathewb4c6df42022-11-09 11:13:29 +0000163 /* Pointer to per-cpu non-secure state */
164 struct ns_state *ns;
165
166 struct {
167 /*
168 * Set to 'true' when there is a pending PSCI
169 * command that must be resolved by the host.
170 * The command is encoded in rec->regs[0].
171 *
172 * A REC with pending PSCI is not schedulable.
173 */
174 bool pending;
175 } psci_info;
176
177 /* Number of auxiliary granules */
178 unsigned int num_rec_aux;
179
180 /* Addresses of auxiliary granules */
181 struct granule *g_aux[MAX_REC_AUX_GRANULES];
182 struct rec_aux_data aux_data;
183
184 unsigned char rmm_realm_token_buf[SZ_1K];
185 struct q_useful_buf_c rmm_realm_token;
186
187 struct token_sign_ctx token_sign_ctx;
188
189 /* Buffer allocation info used for heap init and management */
190 struct {
191 struct buffer_alloc_ctx ctx;
192 bool ctx_initialised;
193 } alloc_info;
194
195 struct {
196 unsigned long vsesr_el2;
197 bool inject;
198 } serror_info;
199
200 /* True if host call is pending */
201 bool host_call;
202};
203COMPILER_ASSERT(sizeof(struct rec) <= GRANULE_SIZE);
204
205/*
206 * Check that mpidr has a valid value with all fields except
207 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0] set to 0.
208 */
209static inline bool mpidr_is_valid(unsigned long mpidr)
210{
211 return (mpidr & ~(MASK(MPIDR_EL2_AFF0) |
212 MASK(MPIDR_EL2_AFF1) |
213 MASK(MPIDR_EL2_AFF2) |
214 MASK(MPIDR_EL2_AFF3))) == 0ULL;
215}
216
217/*
218 * Calculate REC index from mpidr value.
219 * index = Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
220 */
221static inline unsigned long mpidr_to_rec_idx(unsigned long mpidr)
222{
223 return (MPIDR_EL2_AFF(0, mpidr) +
224 MPIDR_EL2_AFF(1, mpidr) +
225 MPIDR_EL2_AFF(2, mpidr) +
226 MPIDR_EL2_AFF(3, mpidr));
227}
228
Arunachalam Ganapathyf6491212023-02-23 16:04:34 +0000229static inline simd_t rec_simd_type(struct rec *rec)
230{
231 if (rec->realm_info.sve_enabled) {
232 return SIMD_SVE;
233 } else {
234 return SIMD_FPU;
235 }
236}
237
238static inline bool rec_is_simd_allowed(struct rec *rec)
239{
240 assert(rec != NULL);
241 return rec->aux_data.rec_simd.simd_allowed;
242}
243
Soby Mathewb4c6df42022-11-09 11:13:29 +0000244void rec_run_loop(struct rec *rec, struct rmi_rec_exit *rec_exit);
245
246unsigned long smc_rec_create(unsigned long rec_addr,
247 unsigned long rd_addr,
248 unsigned long rec_params_addr);
249
250unsigned long smc_rec_destroy(unsigned long rec_addr);
251
252unsigned long smc_rec_enter(unsigned long rec_addr,
253 unsigned long rec_run_addr);
254
255void inject_serror(struct rec *rec, unsigned long vsesr);
256
257void emulate_stage2_data_abort(struct rec *rec, struct rmi_rec_exit *exit,
258 unsigned long rtt_level);
259
260#endif /* __ASSEMBLER__ */
261
262#endif /* REC_H */