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