1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
5  */
6 
7 #ifndef SMC_RMI_H
8 #define SMC_RMI_H
9 
10 #include <measurement.h>
11 #include <smc.h>
12 
13 /*
14  * This file describes the Realm Management Interface (RMI) Application Binary
15  * Interface (ABI) for SMC calls made from Non-secure state to the RMM and
16  * serviced by the RMM.
17  *
18  * See doc/rmm_interface.md for more details.
19  */
20 
21 /*
22  * The major version number of the RMI implementation.  Increase this whenever
23  * the binary format or semantics of the SMC calls change.
24  */
25 #define RMI_ABI_VERSION_MAJOR		(56U)
26 
27 /*
28  * The minor version number of the RMI implementation.  Increase this when
29  * a bug is fixed, or a feature is added without breaking binary compatibility.
30  */
31 #define RMI_ABI_VERSION_MINOR		(0U)
32 
33 #define RMI_ABI_VERSION			((RMI_ABI_VERSION_MAJOR << 16U) | \
34 					RMI_ABI_VERSION_MINOR)
35 
36 #define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16U)
37 #define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFFU)
38 
39 #define SMC64_RMI_FID(_offset)		SMC64_STD_FID(RMI, _offset)
40 
41 #define IS_SMC64_RMI_FID(_fid)		IS_SMC64_STD_FAST_IN_RANGE(RMI, _fid)
42 
43 /*
44  * The number of GPRs (starting from X0) that are
45  * configured by the host when a REC is created.
46  */
47 #define REC_CREATE_NR_GPRS		(8U)
48 
49 #define REC_PARAMS_FLAG_RUNNABLE	(1UL << 0U)
50 
51 /*
52  * The number of GPRs (starting from X0) per voluntary exit context.
53  * Per SMCCC.
54  */
55 #define REC_EXIT_NR_GPRS		(31U)
56 
57 /* RmiHashAlgorithm type */
58 #define RMI_HASH_ALGO_SHA256	HASH_ALGO_SHA256
59 #define RMI_HASH_ALGO_SHA512	HASH_ALGO_SHA512
60 
61 /* Maximum number of Interrupt Controller List Registers */
62 #define REC_GIC_NUM_LRS			(16U)
63 
64 /* Maximum number of auxiliary granules required for a REC */
65 #define MAX_REC_AUX_GRANULES		(16U)
66 
67 #define REC_ENTRY_FLAG_EMUL_MMIO	(1UL << 0U)
68 #define REC_ENTRY_FLAG_INJECT_SEA	(1UL << 1U)
69 
70 /* Flags to specify if WFI/WFE should be trapped to host */
71 #define REC_ENTRY_FLAG_TRAP_WFI		(1UL << 2U)
72 #define REC_ENTRY_FLAG_TRAP_WFE		(1UL << 3U)
73 
74 /*
75  * RmiRecExitReason represents the reason for a REC exit.
76  * This is returned to NS hosts via RMI_REC_ENTER::run_ptr.
77  */
78 #define RMI_EXIT_SYNC			(0U)
79 #define RMI_EXIT_IRQ			(1U)
80 #define RMI_EXIT_FIQ			(2U)
81 #define RMI_EXIT_PSCI			(3U)
82 #define RMI_EXIT_RIPAS_CHANGE		(4U)
83 #define RMI_EXIT_HOST_CALL		(5U)
84 #define RMI_EXIT_SERROR			(6U)
85 
86 /* RmiRttEntryState represents the state of an RTTE */
87 #define RMI_RTT_STATE_UNASSIGNED	(0U)
88 #define RMI_RTT_STATE_DESTROYED		(1U)
89 #define RMI_RTT_STATE_ASSIGNED		(2U)
90 #define RMI_RTT_STATE_TABLE		(3U)
91 #define RMI_RTT_STATE_VALID_NS		(4U)
92 
93 /* no parameters */
94 #define SMC_RMM_VERSION				SMC64_RMI_FID(U(0x0))
95 
96 /*
97  * arg0 == target granule address
98  */
99 #define SMC_RMM_GRANULE_DELEGATE		SMC64_RMI_FID(U(0x1))
100 
101 /*
102  * arg0 == target granule address
103  */
104 #define SMC_RMM_GRANULE_UNDELEGATE		SMC64_RMI_FID(U(0x2))
105 
106 /* RmiDataMeasureContent type */
107 #define RMI_NO_MEASURE_CONTENT 0
108 #define RMI_MEASURE_CONTENT  1
109 
110 /*
111  * arg0 == data address
112  * arg1 == RD address
113  * arg2 == map address
114  * arg3 == SRC address
115  * arg4 == flags
116  */
117 #define SMC_RMM_DATA_CREATE			SMC64_RMI_FID(U(0x3))
118 
119 /*
120  * arg0 == data address
121  * arg1 == RD address
122  * arg2 == map address
123  */
124 #define SMC_RMM_DATA_CREATE_UNKNOWN		SMC64_RMI_FID(U(0x4))
125 
126 /*
127  * arg0 == RD address
128  * arg1 == map address
129  */
130 #define SMC_RMM_DATA_DESTROY			SMC64_RMI_FID(U(0x5))
131 
132 /*
133  * arg0 == RD address
134  */
135 #define SMC_RMM_REALM_ACTIVATE			SMC64_RMI_FID(U(0x7))
136 
137 /*
138  * arg0 == RD address
139  * arg1 == struct rmi_realm_params addr
140  */
141 #define SMC_RMM_REALM_CREATE			SMC64_RMI_FID(U(0x8))
142 
143 /*
144  * arg0 == RD address
145  */
146 #define SMC_RMM_REALM_DESTROY			SMC64_RMI_FID(U(0x9))
147 
148 /*
149  * arg0 == REC address
150  * arg1 == RD address
151  * arg2 == struct rmm_rec address
152  */
153 #define SMC_RMM_REC_CREATE			SMC64_RMI_FID(U(0xA))
154 
155 /*
156  * arg0 == REC address
157  */
158 #define SMC_RMM_REC_DESTROY			SMC64_RMI_FID(U(0xB))
159 
160 /*
161  * arg0 == rec address
162  * arg1 == rec_run address
163  */
164 #define SMC_RMM_REC_ENTER			SMC64_RMI_FID(U(0xC))
165 
166 /*
167  * arg0 == RTT address
168  * arg1 == RD address
169  * arg2 == map address
170  * arg3 == level
171  */
172 #define SMC_RMM_RTT_CREATE			SMC64_RMI_FID(U(0xD))
173 
174 /*
175  * arg0 == RTT address
176  * arg1 == RD address
177  * arg2 == map address
178  * arg3 == level
179  */
180 #define SMC_RMM_RTT_DESTROY			SMC64_RMI_FID(U(0xE))
181 
182 /*
183  * arg0 == RD address
184  * arg1 == map address
185  * arg2 == level
186  * arg3 == s2tte
187  */
188 #define SMC_RMM_RTT_MAP_UNPROTECTED		SMC64_RMI_FID(U(0xF))
189 
190 /*
191  * arg0 == RD address
192  * arg1 == map address
193  * arg2 == level
194  * ret1 == level
195  * ret2 == s2tte type
196  * ret3 == s2tte
197  * ret4 == ripas
198  */
199 #define SMC_RMM_RTT_READ_ENTRY			SMC64_RMI_FID(U(0x11))
200 
201 /*
202  * arg0 == RD address
203  * arg1 == map address
204  * arg2 == level
205  */
206 #define SMC_RMM_RTT_UNMAP_UNPROTECTED		SMC64_RMI_FID(U(0x12))
207 
208 /*
209  * arg0 == calling rec address
210  * arg1 == target rec address
211  */
212 #define SMC_RMM_PSCI_COMPLETE			SMC64_RMI_FID(U(0x14))
213 
214 /*
215  * arg0 == Feature register index
216  */
217 #define SMC_RMM_FEATURES			SMC64_RMI_FID(U(0x15))
218 
219 /*
220  * arg0 == RTT address
221  * arg1 == RD address
222  * arg2 == map address
223  * arg3 == level
224  */
225 #define SMC_RMM_RTT_FOLD			SMC64_RMI_FID(U(0x16))
226 
227 /*
228  * arg0 == RD address
229  */
230 #define SMC_RMM_REC_AUX_COUNT			SMC64_RMI_FID(U(0x17))
231 
232 /*
233  * arg1 == RD address
234  * arg2 == map address
235  * arg3 == level
236  */
237 #define SMC_RMM_RTT_INIT_RIPAS			SMC64_RMI_FID(U(0x18))
238 
239 /*
240  * arg0 == RD address
241  * arg1 == REC address
242  * arg2 == map address
243  * arg3 == level
244  * arg4 == ripas
245  */
246 #define SMC_RMM_RTT_SET_RIPAS			SMC64_RMI_FID(U(0x19))
247 
248 /* Size of Realm Personalization Value */
249 #define RPV_SIZE		64
250 
251 /*
252  * The Realm attribute parameters are shared by the Host via
253  * RMI_REALM_CREATE::params_ptr. The values can be observed or modified
254  * either by the Host or by the Realm.
255  */
256 struct rmi_realm_params {
257 	/* Realm feature register 0 */
258 	SET_MEMBER(unsigned long features_0, 0, 0x100);		/* Offset 0 */
259 	/* Measurement algorithm */
260 	SET_MEMBER(unsigned char hash_algo, 0x100, 0x400);	/* 0x100 */
261 	/* Realm Personalization Value */
262 	SET_MEMBER(unsigned char rpv[RPV_SIZE], 0x400, 0x800);	/* 0x400 */
263 	SET_MEMBER(struct {
264 			/* Virtual Machine Identifier */
265 			unsigned short vmid;			/* 0x800 */
266 			/* Realm Translation Table base */
267 			unsigned long rtt_base;			/* 0x808 */
268 			/* RTT starting level */
269 			long rtt_level_start;			/* 0x810 */
270 			/* Number of starting level RTTs */
271 			unsigned int rtt_num_start;		/* 0x818 */
272 		   }, 0x800, 0x1000);
273 };
274 
275 COMPILER_ASSERT(sizeof(struct rmi_realm_params) == 0x1000);
276 
277 COMPILER_ASSERT(offsetof(struct rmi_realm_params, features_0) == 0);
278 COMPILER_ASSERT(offsetof(struct rmi_realm_params, hash_algo) == 0x100);
279 COMPILER_ASSERT(offsetof(struct rmi_realm_params, rpv) == 0x400);
280 COMPILER_ASSERT(offsetof(struct rmi_realm_params, vmid) == 0x800);
281 COMPILER_ASSERT(offsetof(struct rmi_realm_params, rtt_base) == 0x808);
282 COMPILER_ASSERT(offsetof(struct rmi_realm_params, rtt_level_start) == 0x810);
283 COMPILER_ASSERT(offsetof(struct rmi_realm_params, rtt_num_start) == 0x818);
284 
285 /*
286  * The REC attribute parameters are shared by the Host via
287  * MI_REC_CREATE::params_ptr. The values can be observed or modified
288  * either by the Host or by the Realm which owns the REC.
289  */
290 struct rmi_rec_params {
291 	/* Flags */
292 	SET_MEMBER(unsigned long flags, 0, 0x100);	/* Offset 0 */
293 	/* MPIDR of the REC */
294 	SET_MEMBER(unsigned long mpidr, 0x100, 0x200);	/* 0x100 */
295 	/* Program counter */
296 	SET_MEMBER(unsigned long pc, 0x200, 0x300);	/* 0x200 */
297 	/* General-purpose registers */
298 	SET_MEMBER(unsigned long gprs[REC_CREATE_NR_GPRS], 0x300, 0x800); /* 0x300 */
299 	SET_MEMBER(struct {
300 			/* Number of auxiliary Granules */
301 			unsigned long num_aux;			/* 0x800 */
302 			/* Addresses of auxiliary Granules */
303 			unsigned long aux[MAX_REC_AUX_GRANULES];/* 0x808 */
304 		   }, 0x800, 0x1000);
305 };
306 
307 COMPILER_ASSERT(sizeof(struct rmi_rec_params) == 0x1000);
308 
309 COMPILER_ASSERT(offsetof(struct rmi_rec_params, flags) == 0);
310 COMPILER_ASSERT(offsetof(struct rmi_rec_params, mpidr) == 0x100);
311 COMPILER_ASSERT(offsetof(struct rmi_rec_params, pc) == 0x200);
312 COMPILER_ASSERT(offsetof(struct rmi_rec_params, gprs) == 0x300);
313 COMPILER_ASSERT(offsetof(struct rmi_rec_params, num_aux) == 0x800);
314 COMPILER_ASSERT(offsetof(struct rmi_rec_params, aux) == 0x808);
315 
316 /*
317  * Structure contains data passed from the Host to the RMM on REC entry
318  */
319 struct rmi_rec_entry {
320 	/* Flags */
321 	SET_MEMBER(unsigned long flags, 0, 0x200);	/* Offset 0 */
322 	/* General-purpose registers */
323 	SET_MEMBER(unsigned long gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
324 	SET_MEMBER(struct {
325 			/* GICv3 Hypervisor Control Register */
326 			unsigned long gicv3_hcr;			/* 0x300 */
327 			/* GICv3 List Registers */
328 			unsigned long gicv3_lrs[REC_GIC_NUM_LRS];	/* 0x308 */
329 		   }, 0x300, 0x800);
330 };
331 
332 COMPILER_ASSERT(sizeof(struct rmi_rec_entry) == 0x800);
333 
334 COMPILER_ASSERT(offsetof(struct rmi_rec_entry, flags) == 0);
335 COMPILER_ASSERT(offsetof(struct rmi_rec_entry, gprs) == 0x200);
336 COMPILER_ASSERT(offsetof(struct rmi_rec_entry, gicv3_hcr) == 0x300);
337 COMPILER_ASSERT(offsetof(struct rmi_rec_entry, gicv3_lrs) == 0x308);
338 
339 /*
340  * Structure contains data passed from the RMM to the Host on REC exit
341  */
342 struct rmi_rec_exit {
343 	/* Exit reason */
344 	SET_MEMBER(unsigned long exit_reason, 0, 0x100);/* Offset 0 */
345 	SET_MEMBER(struct {
346 			/* Exception Syndrome Register */
347 			unsigned long esr;		/* 0x100 */
348 			/* Fault Address Register */
349 			unsigned long far;		/* 0x108 */
350 			/* Hypervisor IPA Fault Address register */
351 			unsigned long hpfar;		/* 0x110 */
352 		   }, 0x100, 0x200);
353 	/* General-purpose registers */
354 	SET_MEMBER(unsigned long gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
355 	SET_MEMBER(struct {
356 			/* GICv3 Hypervisor Control Register */
357 			unsigned long gicv3_hcr;	/* 0x300 */
358 			/* GICv3 List Registers */
359 			unsigned long gicv3_lrs[REC_GIC_NUM_LRS]; /* 0x308 */
360 			/* GICv3 Maintenance Interrupt State Register */
361 			unsigned long gicv3_misr;	/* 0x388 */
362 			/* GICv3 Virtual Machine Control Register */
363 			unsigned long gicv3_vmcr;	/* 0x390 */
364 		   }, 0x300, 0x400);
365 	SET_MEMBER(struct {
366 			/* Counter-timer Physical Timer Control Register */
367 			unsigned long cntp_ctl;		/* 0x400 */
368 			/* Counter-timer Physical Timer CompareValue Register */
369 			unsigned long cntp_cval;	/* 0x408 */
370 			/* Counter-timer Virtual Timer Control Register */
371 			unsigned long cntv_ctl;		/* 0x410 */
372 			/* Counter-timer Virtual Timer CompareValue Register */
373 			unsigned long cntv_cval;	/* 0x418 */
374 		   }, 0x400, 0x500);
375 	SET_MEMBER(struct {
376 			/* Base address of pending RIPAS change */
377 			unsigned long ripas_base;	/* 0x500 */
378 			/* Size of pending RIPAS change */
379 			unsigned long ripas_size;	/* 0x508 */
380 			/* RIPAS value of pending RIPAS change */
381 			unsigned char ripas_value;	/* 0x510 */
382 		   }, 0x500, 0x600);
383 	/* Host call immediate value */
384 	SET_MEMBER(unsigned int imm, 0x600, 0x800);	/* 0x600 */
385 };
386 
387 COMPILER_ASSERT(sizeof(struct rmi_rec_exit) == 0x800);
388 
389 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, exit_reason) == 0);
390 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, esr) == 0x100);
391 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, far) == 0x108);
392 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, hpfar) == 0x110);
393 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gprs) == 0x200);
394 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_hcr) == 0x300);
395 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_lrs) == 0x308);
396 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_misr) == 0x388);
397 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_vmcr) == 0x390);
398 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntp_ctl) == 0x400);
399 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntp_cval) == 0x408);
400 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntv_ctl) == 0x410);
401 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntv_cval) == 0x418);
402 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_base) == 0x500);
403 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_size) == 0x508);
404 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_value) == 0x510);
405 COMPILER_ASSERT(offsetof(struct rmi_rec_exit, imm) == 0x600);
406 
407 /*
408  * Structure contains shared information between RMM and Host
409  * during REC entry and REC exit.
410  */
411 struct rmi_rec_run {
412 	/* Entry information */
413 	SET_MEMBER(struct rmi_rec_entry entry, 0, 0x800);	/* Offset 0 */
414 	/* Exit information */
415 	SET_MEMBER(struct rmi_rec_exit exit, 0x800, 0x1000);	/* 0x800 */
416 };
417 
418 COMPILER_ASSERT(sizeof(struct rmi_rec_run) <= GRANULE_SIZE);
419 
420 COMPILER_ASSERT(offsetof(struct rmi_rec_run, entry) == 0);
421 COMPILER_ASSERT(offsetof(struct rmi_rec_run, exit) == 0x800);
422 
423 #endif /* SMC_RMI_H */
424