blob: 05354360de29b30335f57887dc198ee3a1014d58 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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 */
256struct 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
275COMPILER_ASSERT(sizeof(struct rmi_realm_params) == 0x1000);
276
277COMPILER_ASSERT(offsetof(struct rmi_realm_params, features_0) == 0);
278COMPILER_ASSERT(offsetof(struct rmi_realm_params, hash_algo) == 0x100);
279COMPILER_ASSERT(offsetof(struct rmi_realm_params, rpv) == 0x400);
280COMPILER_ASSERT(offsetof(struct rmi_realm_params, vmid) == 0x800);
281COMPILER_ASSERT(offsetof(struct rmi_realm_params, rtt_base) == 0x808);
282COMPILER_ASSERT(offsetof(struct rmi_realm_params, rtt_level_start) == 0x810);
283COMPILER_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 */
290struct 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
307COMPILER_ASSERT(sizeof(struct rmi_rec_params) == 0x1000);
308
309COMPILER_ASSERT(offsetof(struct rmi_rec_params, flags) == 0);
310COMPILER_ASSERT(offsetof(struct rmi_rec_params, mpidr) == 0x100);
311COMPILER_ASSERT(offsetof(struct rmi_rec_params, pc) == 0x200);
312COMPILER_ASSERT(offsetof(struct rmi_rec_params, gprs) == 0x300);
313COMPILER_ASSERT(offsetof(struct rmi_rec_params, num_aux) == 0x800);
314COMPILER_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 */
319struct 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
332COMPILER_ASSERT(sizeof(struct rmi_rec_entry) == 0x800);
333
334COMPILER_ASSERT(offsetof(struct rmi_rec_entry, flags) == 0);
335COMPILER_ASSERT(offsetof(struct rmi_rec_entry, gprs) == 0x200);
336COMPILER_ASSERT(offsetof(struct rmi_rec_entry, gicv3_hcr) == 0x300);
337COMPILER_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 */
342struct 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
387COMPILER_ASSERT(sizeof(struct rmi_rec_exit) == 0x800);
388
389COMPILER_ASSERT(offsetof(struct rmi_rec_exit, exit_reason) == 0);
390COMPILER_ASSERT(offsetof(struct rmi_rec_exit, esr) == 0x100);
391COMPILER_ASSERT(offsetof(struct rmi_rec_exit, far) == 0x108);
392COMPILER_ASSERT(offsetof(struct rmi_rec_exit, hpfar) == 0x110);
393COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gprs) == 0x200);
394COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_hcr) == 0x300);
395COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_lrs) == 0x308);
396COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_misr) == 0x388);
397COMPILER_ASSERT(offsetof(struct rmi_rec_exit, gicv3_vmcr) == 0x390);
398COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntp_ctl) == 0x400);
399COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntp_cval) == 0x408);
400COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntv_ctl) == 0x410);
401COMPILER_ASSERT(offsetof(struct rmi_rec_exit, cntv_cval) == 0x418);
402COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_base) == 0x500);
403COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_size) == 0x508);
404COMPILER_ASSERT(offsetof(struct rmi_rec_exit, ripas_value) == 0x510);
405COMPILER_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 */
411struct 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
418COMPILER_ASSERT(sizeof(struct rmi_rec_run) <= GRANULE_SIZE);
419
420COMPILER_ASSERT(offsetof(struct rmi_rec_run, entry) == 0);
421COMPILER_ASSERT(offsetof(struct rmi_rec_run, exit) == 0x800);
422
423#endif /* SMC_RMI_H */