blob: 49c516dc9acf7f6b2b0beaeb6dc4eabe2323af72 [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 */
Arunachalam Ganapathy4f601e72023-05-22 11:49:29 +010078
79 unsigned long cptr_el2; /* restored only */
Soby Mathewb4c6df42022-11-09 11:13:29 +000080};
81
82/*
83 * System registers whose contents are
84 * common across all RECs in a Realm.
85 */
86struct common_sysreg_state {
87 unsigned long vttbr_el2;
88 unsigned long vtcr_el2;
89 unsigned long hcr_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +000090 unsigned long mdcr_el2;
Soby Mathewb4c6df42022-11-09 11:13:29 +000091};
92
93/*
94 * This structure is aligned on cache line size to avoid cache line trashing
95 * when allocated as an array for N CPUs.
96 */
97struct ns_state {
98 struct sysreg_state sysregs;
99 unsigned long sp_el0;
100 unsigned long icc_sre_el2;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000101 struct pmu_state *pmu;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102} __attribute__((aligned(CACHE_WRITEBACK_GRANULE)));
103
104/*
AlexeiFedorovec35c542023-04-27 17:52:02 +0100105 * Data used when handling attestation requests
106 */
107struct rec_attest_data {
108 unsigned char rmm_realm_token_buf[SZ_1K];
109 size_t rmm_realm_token_len;
110
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100111 struct token_sign_cntxt token_sign_ctx;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100112
113 /* Buffer allocation info used for heap init and management */
Arunachalam Ganapathy40b3bf02023-06-12 12:19:55 +0100114 struct buffer_alloc_ctx alloc_ctx;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100115};
116COMPILER_ASSERT(sizeof(struct rec_attest_data) <= GRANULE_SIZE);
117
118/*
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000119 * This structure contains pointers to data that are allocated
120 * in auxilary granules for a REC.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000121 */
122struct rec_aux_data {
AlexeiFedorovec35c542023-04-27 17:52:02 +0100123 /* Pointer to the heap buffer */
124 uint8_t *attest_heap_buf;
125
126 /* Pointer to PMU state */
127 struct pmu_state *pmu;
128
129 /* SIMD context region */
Arunachalam Ganapathy4f601e72023-05-22 11:49:29 +0100130 struct simd_context *simd_ctx;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100131
132 /* Pointer to attestation-related data */
133 struct rec_attest_data *attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100134
135 /* Address of the attestation token buffer */
136 uintptr_t cca_token_buf;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000137};
138
139struct rec {
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000140 struct granule *g_rec; /* the granule in which this REC lives */
141 unsigned long rec_idx; /* which REC is this */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000142 bool runnable;
143
144 unsigned long regs[31];
Arvind Ram Prakashbd36a1b2022-12-15 12:16:36 -0600145
146 /*
147 * PAuth state of Realm.
148 * Note that we do not need to save NS state as EL3 will save this as part of world switch.
149 */
150 struct pauth_state pauth;
151
Soby Mathewb4c6df42022-11-09 11:13:29 +0000152 unsigned long pc;
153 unsigned long pstate;
154
155 struct sysreg_state sysregs;
156 struct common_sysreg_state common_sysregs;
157
AlexeiFedorov5cf35ba2023-04-25 10:02:20 +0100158 /* Populated when the REC issues a RIPAS change request */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000159 struct {
AlexeiFedorov5cf35ba2023-04-25 10:02:20 +0100160 unsigned long base;
161 unsigned long top;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000162 unsigned long addr;
AlexeiFedorov0fb44552023-04-14 15:37:58 +0100163 enum ripas ripas_val;
AlexeiFedorov63614ea2023-07-14 17:07:20 +0100164 enum ripas_change_destroyed change_destroyed;
AlexeiFedorov9b29c6b2023-09-12 17:09:50 +0100165 enum ripas_response response;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166 } set_ripas;
167
168 /*
169 * Common values across all RECs in a Realm.
170 */
171 struct {
172 unsigned long ipa_bits;
173 int s2_starting_level;
174 struct granule *g_rtt;
175 struct granule *g_rd;
AlexeiFedoroveaec0c42023-02-01 18:13:32 +0000176 bool pmu_enabled;
AlexeiFedorov18002922023-04-06 10:19:51 +0100177 unsigned int pmu_num_ctrs;
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100178 enum hash_algo algorithm;
Arunachalam Ganapathy4f601e72023-05-22 11:49:29 +0100179 struct simd_config simd_cfg;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000180 } realm_info;
181
182 struct {
183 /*
184 * The contents of the *_EL2 system registers at the last time
185 * the REC exited to the host due to a synchronous exception.
186 * These are the unsanitized register values which may differ
187 * from the value returned to the host in rec_exit structure.
188 */
189 unsigned long esr;
190 unsigned long hpfar;
191 unsigned long far;
192 } last_run_info;
193
Soby Mathewb4c6df42022-11-09 11:13:29 +0000194 /* Pointer to per-cpu non-secure state */
195 struct ns_state *ns;
196
197 struct {
198 /*
199 * Set to 'true' when there is a pending PSCI
200 * command that must be resolved by the host.
201 * The command is encoded in rec->regs[0].
202 *
203 * A REC with pending PSCI is not schedulable.
204 */
205 bool pending;
206 } psci_info;
207
208 /* Number of auxiliary granules */
209 unsigned int num_rec_aux;
210
211 /* Addresses of auxiliary granules */
212 struct granule *g_aux[MAX_REC_AUX_GRANULES];
213 struct rec_aux_data aux_data;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000214 struct {
215 unsigned long vsesr_el2;
216 bool inject;
217 } serror_info;
218
219 /* True if host call is pending */
220 bool host_call;
Arunachalam Ganapathy4f601e72023-05-22 11:49:29 +0100221
222 /* The active SIMD context that is live in CPU registers */
223 struct simd_context *active_simd_ctx;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000224};
225COMPILER_ASSERT(sizeof(struct rec) <= GRANULE_SIZE);
226
227/*
228 * Check that mpidr has a valid value with all fields except
229 * Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0] set to 0.
230 */
231static inline bool mpidr_is_valid(unsigned long mpidr)
232{
233 return (mpidr & ~(MASK(MPIDR_EL2_AFF0) |
234 MASK(MPIDR_EL2_AFF1) |
235 MASK(MPIDR_EL2_AFF2) |
236 MASK(MPIDR_EL2_AFF3))) == 0ULL;
237}
238
239/*
240 * Calculate REC index from mpidr value.
241 * index = Aff3[39:32]:Aff2[23:16]:Aff1[15:8]:Aff0[3:0]
242 */
243static inline unsigned long mpidr_to_rec_idx(unsigned long mpidr)
244{
245 return (MPIDR_EL2_AFF(0, mpidr) +
246 MPIDR_EL2_AFF(1, mpidr) +
247 MPIDR_EL2_AFF(2, mpidr) +
248 MPIDR_EL2_AFF(3, mpidr));
249}
250
Soby Mathewb4c6df42022-11-09 11:13:29 +0000251void rec_run_loop(struct rec *rec, struct rmi_rec_exit *rec_exit);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000252void inject_serror(struct rec *rec, unsigned long vsesr);
AlexeiFedorov950bd7b2023-08-24 15:25:22 +0100253void emulate_stage2_data_abort(struct rec *rec, struct rmi_rec_exit *rec_exit,
Soby Mathewb4c6df42022-11-09 11:13:29 +0000254 unsigned long rtt_level);
255
256#endif /* __ASSEMBLER__ */
Soby Mathewb4c6df42022-11-09 11:13:29 +0000257#endif /* REC_H */