blob: 923c00356259457250c386ed8b5c681bbd22506c [file] [log] [blame]
nabkah01002e5692022-10-10 12:36:46 +01001/*
AlexeiFedorov2f30f102023-03-13 19:37:46 +00002 * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
nabkah01002e5692022-10-10 12:36:46 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef HOST_REALM_RMI_H
9#define HOST_REALM_RMI_H
10
11#include <stdint.h>
AlexeiFedorov2f30f102023-03-13 19:37:46 +000012#include <stdbool.h>
nabkah01002e5692022-10-10 12:36:46 +010013
nabkah01002e5692022-10-10 12:36:46 +010014#include <smccc.h>
15#include <utils_def.h>
16
17#define RMI_FNUM_MIN_VALUE U(0x150)
18#define RMI_FNUM_MAX_VALUE U(0x18F)
19
20/* Get RMI fastcall std FID from offset */
21#define SMC64_RMI_FID(_offset) \
22 ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
23 (SMC_64 << FUNCID_CC_SHIFT) | \
24 (OEN_STD_START << FUNCID_OEN_SHIFT) | \
25 (((RMI_FNUM_MIN_VALUE + (_offset)) & FUNCID_NUM_MASK) \
26 << FUNCID_NUM_SHIFT))
27
28#define RMI_ABI_VERSION_GET_MAJOR(_version) (((_version) >> 16U) & 0x8FFF)
29#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
30
31#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
32#define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1U)
33#define ALIGN(x, a) __ALIGN((x), (a))
34
35/*
36 * SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from
37 * the Realm world and is handled by the RMMD. The remaining functions are
38 * always invoked by the Normal world, forwarded by RMMD and handled by the
39 * RMM
40 */
41/* RMI SMC64 FIDs handled by the RMMD */
42/* no parameters */
43#define RMI_VERSION SMC64_RMI_FID(U(0x0))
44
45/*
46 * arg0 == target granule address
47 */
48#define RMI_GRANULE_DELEGATE SMC64_RMI_FID(U(0x1))
49
50/*
51 * arg0 == target granule address
52 */
53#define RMI_GRANULE_UNDELEGATE SMC64_RMI_FID(U(0x2))
54
55/*
56 * arg0 == data address
57 * arg1 == RD address
58 * arg2 == map address
59 * arg3 == SRC address
60 */
61#define RMI_DATA_CREATE SMC64_RMI_FID(U(0x3))
62
63/*
64 * arg0 == data address
65 * arg1 == RD address
66 * arg2 == map address
67 */
68#define RMI_DATA_CREATE_UNKNOWN SMC64_RMI_FID(U(0x4))
69
70/*
71 * arg0 == RD address
72 * arg1 == map address
73 */
74#define RMI_DATA_DESTROY SMC64_RMI_FID(U(0x5))
75
76/*
77 * arg0 == RD address
78 */
79#define RMI_REALM_ACTIVATE SMC64_RMI_FID(U(0x7))
80
81/*
82 * arg0 == RD address
83 * arg1 == struct rmi_realm_params addr
84 */
85#define RMI_REALM_CREATE SMC64_RMI_FID(U(0x8))
86
87/*
88 * arg0 == RD address
89 */
90#define RMI_REALM_DESTROY SMC64_RMI_FID(U(0x9))
91
92/*
93 * arg0 == REC address
94 * arg1 == RD address
95 * arg2 == struct rmm_rec address
96 */
97#define RMI_REC_CREATE SMC64_RMI_FID(U(0xA))
98
99/*
100 * arg0 == REC address
101 */
102#define RMI_REC_DESTROY SMC64_RMI_FID(U(0xB))
103
104/*
105 * arg0 == rec address
106 * arg1 == rec_run address
107 */
108#define RMI_REC_ENTER SMC64_RMI_FID(U(0xC))
109
110/*
111 * arg0 == RTT address
112 * arg1 == RD address
113 * arg2 == map address
114 * arg3 == level
115 */
116#define RMI_RTT_CREATE SMC64_RMI_FID(U(0xD))
117
118/*
119 * arg0 == RTT address
120 * arg1 == RD address
121 * arg2 == map address
122 * arg3 == level
123 */
124#define RMI_RTT_DESTROY SMC64_RMI_FID(U(0xE))
125
126/*
127 * arg0 == RD address
128 * arg1 == map address
129 * arg2 == level
130 * arg3 == s2tte
131 */
132#define RMI_RTT_MAP_UNPROTECTED SMC64_RMI_FID(U(0xF))
133
134/*
135 * arg0 == RD address
136 * arg1 == map address
137 * arg2 == level
138 * ret1 == level
139 * ret2 == s2tte type
140 * ret3 == s2tte
141 * ret4 == ripas
142 */
143#define RMI_RTT_READ_ENTRY SMC64_RMI_FID(U(0x11))
144
145/*
146 * arg0 == RD address
147 * arg1 == map address
148 * arg2 == level
149 */
150#define RMI_RTT_UNMAP_UNPROTECTED SMC64_RMI_FID(U(0x12))
151
152/*
153 * arg0 == calling rec address
154 * arg1 == target rec address
155 */
156#define RMI_PSCI_COMPLETE SMC64_RMI_FID(U(0x14))
157
158/*
159 * arg0 == Feature register index
160 */
161#define RMI_FEATURES SMC64_RMI_FID(U(0x15))
162
163/*
164 * arg0 == RTT address
165 * arg1 == RD address
166 * arg2 == map address
167 * arg3 == level
168 */
169#define RMI_RTT_FOLD SMC64_RMI_FID(U(0x16))
170
171/*
172 * arg0 == RD address
173 */
174#define RMI_REC_AUX_COUNT SMC64_RMI_FID(U(0x17))
175
176/*
177 * arg1 == RD address
178 * arg2 == map address
179 * arg3 == level
180 */
181#define RMI_RTT_INIT_RIPAS SMC64_RMI_FID(U(0x18))
182
183/*
184 * arg0 == RD address
185 * arg1 == REC address
186 * arg2 == map address
187 * arg3 == level
188 * arg4 == ripas
189 */
190#define RMI_RTT_SET_RIPAS SMC64_RMI_FID(U(0x19))
191
192#define GRANULE_SIZE PAGE_SIZE_4KB
193
194/* Maximum number of auxiliary granules required for a REC */
195#define MAX_REC_AUX_GRANULES 16U
196#define REC_PARAMS_AUX_GRANULES 16U
197#define REC_EXIT_NR_GPRS 31U
198/* Size of Realm Personalization Value */
199#define RPV_SIZE 64U
200/* RmiDisposeResponse types */
201#define RMI_DISPOSE_ACCEPT 0U
202#define RMI_DISPOSE_REJECT 1U
203
204/* RmiFeatureLpa2 types */
205#define RMI_NO_LPA2 0U
206#define RMI_LPA2 1U
207
208/* RmiInterfaceVersion type */
209#define RMI_MAJOR_VERSION 0U
210#define RMI_MINOR_VERSION 0U
211
212/* RmiRealmMeasurementAlgorithm types */
213#define RMI_HASH_SHA_256 0U
214#define RMI_HASH_SHA_512 1U
215
216/* RmiRecEmulatedMmio types */
217#define RMI_NOT_EMULATED_MMIO 0U
218#define RMI_EMULATED_MMIO 1U
219
220/*
221 * RmiRecExitReason represents the reason for a REC exit.
222 * This is returned to NS hosts via RMI_REC_ENTER::run_ptr.
223 */
224#define RMI_EXIT_SYNC 0U
225#define RMI_EXIT_IRQ 1U
226#define RMI_EXIT_FIQ 2U
227#define RMI_EXIT_PSCI 3U
228#define RMI_EXIT_RIPAS_CHANGE 4U
229#define RMI_EXIT_HOST_CALL 5U
230#define RMI_EXIT_SERROR 6U
231#define RMI_EXIT_INVALID 0xFFFFFU
232
233/* RmiRecRunnable types */
234#define RMI_NOT_RUNNABLE 0U
235#define RMI_RUNNABLE 1U
236
237/* RttEntryState: represents the state of an RTTE */
238#define RMI_UNASSIGNED 0U
239#define RMI_DESTROYED 1U
240#define RMI_ASSIGNED 2U
241#define RMI_TABLE 3U
242#define RMI_VALID_NS 4U
243
244#define RMI_FEATURE_REGISTER_0_S2SZ GENMASK(7, 0)
245#define RMI_FEATURE_REGISTER_0_LPA2 BIT(8)
246#define RMI_FEATURE_REGISTER_0_SVE_EN BIT(9)
247#define RMI_FEATURE_REGISTER_0_SVE_VL GENMASK(13, 10)
248#define RMI_FEATURE_REGISTER_0_NUM_BPS GENMASK(17, 14)
249#define RMI_FEATURE_REGISTER_0_NUM_WPS GENMASK(21, 18)
250#define RMI_FEATURE_REGISTER_0_PMU_EN BIT(22)
251#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS GENMASK(27, 23)
252#define RMI_FEATURE_REGISTER_0_HASH_SHA_256 BIT(28)
253#define RMI_FEATURE_REGISTER_0_HASH_SHA_512 BIT(29)
254
255#define RMM_FEATURE_MIN_IPA_SIZE 32U
256#define RMM_FEATURE_REGISTER_0_INDEX 0UL
257#define RMM_FEATURE_REGISTER_0_S2SZ_SHIFT 0UL
258#define RMM_FEATURE_REGISTER_0_S2SZ_WIDTH 8UL
259#define RMM_FEATURE_REGISTER_0_LPA2_SHIFT 8UL
260#define RMM_FEATURE_REGISTER_0_LPA2_WIDTH 1UL
261
262/* RmiStatusCode types */
263/*
264 * Status codes which can be returned from RMM commands.
265 *
266 * For each code, the meaning of return_code_t::index is stated.
267 */
268typedef enum {
269 /*
270 * Command completed successfully.
271 *
272 * index is zero.
273 */
274 RMI_SUCCESS = 0,
275 /*
276 * The value of a command input value caused the command to fail.
277 *
278 * index is zero.
279 */
280 RMI_ERROR_INPUT = 1,
281 /*
282 * An attribute of a Realm does not match the expected value.
283 *
284 * index varies between usages.
285 */
286 RMI_ERROR_REALM = 2,
287 /*
288 * An attribute of a REC does not match the expected value.
289 *
290 * index is zero.
291 */
292 RMI_ERROR_REC = 3,
293 /*
294 * An RTT walk terminated before reaching the target RTT level,
295 * or reached an RTTE with an unexpected value.
296 *
297 * index: RTT level at which the walk terminated
298 */
299 RMI_ERROR_RTT = 4,
300 /*
301 * An operation cannot be completed because a resource is in use.
302 *
303 * index is zero.
304 */
305 RMI_ERROR_IN_USE = 5,
306 RMI_ERROR_COUNT
307} status_t;
308
309#define RMI_RETURN_STATUS(ret) ((ret) & 0xFF)
310#define RMI_RETURN_INDEX(ret) (((ret) >> 8U) & 0xFF)
311#define RTT_MAX_LEVEL 3U
312#define ALIGN_DOWN(x, a) ((uint64_t)(x) & ~(((uint64_t)(a)) - 1ULL))
313#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a)-1U)) == 0U)
314#define PAGE_SHIFT FOUR_KB_SHIFT
315#define RTT_LEVEL_SHIFT(l) XLAT_ADDR_SHIFT(l)
316#define RTT_L2_BLOCK_SIZE (1UL << RTT_LEVEL_SHIFT(2U))
317
318#define REC_CREATE_NR_GPRS 8U
319#define REC_HVC_NR_GPRS 7U
320#define REC_GIC_NUM_LRS 16U
321
322/*
nabkah01002e5692022-10-10 12:36:46 +0100323 * The Realm attribute parameters are shared by the Host via
324 * RMI_REALM_CREATE::params_ptr. The values can be observed or modified
325 * either by the Host or by the Realm.
326 */
327struct rmi_realm_params {
328 /* Realm feature register 0 */
329 SET_MEMBER(u_register_t features_0, 0, 0x100); /* Offset 0 */
330 /* Measurement algorithm */
331 SET_MEMBER(unsigned char hash_algo, 0x100, 0x400); /* 0x100 */
332 /* Realm Personalization Value */
333 SET_MEMBER(unsigned char rpv[RPV_SIZE], 0x400, 0x800); /* 0x400 */
334 SET_MEMBER(struct {
335 /* Virtual Machine Identifier */
336 unsigned short vmid; /* 0x800 */
337 /* Realm Translation Table base */
338 u_register_t rtt_base; /* 0x808 */
339 /* RTT starting level */
340 long rtt_level_start; /* 0x810 */
341 /* Number of starting level RTTs */
342 unsigned int rtt_num_start; /* 0x818 */
343 }, 0x800, 0x1000);
344};
345
346/*
347 * The REC attribute parameters are shared by the Host via
348 * MI_REC_CREATE::params_ptr. The values can be observed or modified
349 * either by the Host or by the Realm which owns the REC.
350 */
351struct rmi_rec_params {
352 /* Flags */
353 SET_MEMBER(u_register_t flags, 0, 0x100); /* Offset 0 */
354 /* MPIDR of the REC */
355 SET_MEMBER(u_register_t mpidr, 0x100, 0x200); /* 0x100 */
356 /* Program counter */
357 SET_MEMBER(u_register_t pc, 0x200, 0x300); /* 0x200 */
358 /* General-purpose registers */
359 SET_MEMBER(u_register_t gprs[REC_CREATE_NR_GPRS], 0x300, 0x800); /* 0x300 */
360 SET_MEMBER(struct {
361 /* Number of auxiliary Granules */
362 u_register_t num_aux; /* 0x800 */
363 /* Addresses of auxiliary Granules */
364 u_register_t aux[MAX_REC_AUX_GRANULES]; /* 0x808 */
365 }, 0x800, 0x1000);
366};
367
368/*
369 * Structure contains data passed from the Host to the RMM on REC entry
370 */
371struct rmi_rec_entry {
372 /* Flags */
373 SET_MEMBER(u_register_t flags, 0, 0x200); /* Offset 0 */
374 /* General-purpose registers */
375 SET_MEMBER(u_register_t gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
376 SET_MEMBER(struct {
377 /* GICv3 Hypervisor Control Register */
378 u_register_t gicv3_hcr; /* 0x300 */
379 /* GICv3 List Registers */
380 u_register_t gicv3_lrs[REC_GIC_NUM_LRS]; /* 0x308 */
381 }, 0x300, 0x800);
382};
383
384/*
385 * Structure contains data passed from the RMM to the Host on REC exit
386 */
387struct rmi_rec_exit {
388 /* Exit reason */
389 SET_MEMBER(u_register_t exit_reason, 0, 0x100);/* Offset 0 */
390 SET_MEMBER(struct {
391 /* Exception Syndrome Register */
392 u_register_t esr; /* 0x100 */
393 /* Fault Address Register */
394 u_register_t far; /* 0x108 */
395 /* Hypervisor IPA Fault Address register */
396 u_register_t hpfar; /* 0x110 */
397 }, 0x100, 0x200);
398 /* General-purpose registers */
399 SET_MEMBER(u_register_t gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
400 SET_MEMBER(struct {
401 /* GICv3 Hypervisor Control Register */
402 u_register_t gicv3_hcr; /* 0x300 */
403 /* GICv3 List Registers */
404 u_register_t gicv3_lrs[REC_GIC_NUM_LRS]; /* 0x308 */
405 /* GICv3 Maintenance Interrupt State Register */
406 u_register_t gicv3_misr; /* 0x388 */
407 /* GICv3 Virtual Machine Control Register */
408 u_register_t gicv3_vmcr; /* 0x390 */
409 }, 0x300, 0x400);
410 SET_MEMBER(struct {
411 /* Counter-timer Physical Timer Control Register */
412 u_register_t cntp_ctl; /* 0x400 */
413 /* Counter-timer Physical Timer CompareValue Register */
414 u_register_t cntp_cval; /* 0x408 */
415 /* Counter-timer Virtual Timer Control Register */
416 u_register_t cntv_ctl; /* 0x410 */
417 /* Counter-timer Virtual Timer CompareValue Register */
418 u_register_t cntv_cval; /* 0x418 */
419 }, 0x400, 0x500);
420 SET_MEMBER(struct {
421 /* Base address of pending RIPAS change */
422 u_register_t ripas_base; /* 0x500 */
423 /* Size of pending RIPAS change */
424 u_register_t ripas_size; /* 0x508 */
425 /* RIPAS value of pending RIPAS change */
426 unsigned char ripas_value; /* 0x510 */
427 }, 0x500, 0x600);
428 /* Host call immediate value */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000429 SET_MEMBER(unsigned int imm, 0x600, 0x700); /* 0x600 */
430 /* PMU overflow */
431 SET_MEMBER(unsigned long pmu_ovf, 0x700, 0x708); /* 0x700 */
432 /* PMU interrupt enable */
433 SET_MEMBER(unsigned long pmu_intr_en, 0x708, 0x710); /* 0x708 */
434 /* PMU counter enable */
435 SET_MEMBER(unsigned long pmu_cntr_en, 0x710, 0x800); /* 0x710 */
nabkah01002e5692022-10-10 12:36:46 +0100436};
437
438/*
439 * Structure contains shared information between RMM and Host
440 * during REC entry and REC exit.
441 */
442struct rmi_rec_run {
443 /* Entry information */
444 SET_MEMBER(struct rmi_rec_entry entry, 0, 0x800); /* Offset 0 */
445 /* Exit information */
446 SET_MEMBER(struct rmi_rec_exit exit, 0x800, 0x1000); /* 0x800 */
447};
448
449struct rtt_entry {
450 uint64_t walk_level;
451 uint64_t out_addr;
452 int state;
453};
454
455enum realm_state {
456 REALM_STATE_NULL,
457 REALM_STATE_NEW,
458 REALM_STATE_ACTIVE,
459 REALM_STATE_SYSTEM_OFF
460};
461
462struct realm {
463 u_register_t par_base;
464 u_register_t par_size;
465 u_register_t rd;
466 u_register_t rtt_addr;
467 u_register_t rec;
468 u_register_t run;
469 u_register_t num_aux;
470 u_register_t rmm_feat_reg0;
471 u_register_t ipa_ns_buffer;
472 u_register_t ns_buffer_size;
473 u_register_t aux_pages[REC_PARAMS_AUX_GRANULES];
474 enum realm_state state;
475};
476
477/* RMI/SMC */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000478u_register_t host_rmi_version(void);
479u_register_t host_rmi_granule_delegate(u_register_t addr);
480u_register_t host_rmi_granule_undelegate(u_register_t addr);
481u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr);
482u_register_t host_rmi_realm_destroy(u_register_t rd);
483u_register_t host_rmi_features(u_register_t index, u_register_t *features);
nabkah01002e5692022-10-10 12:36:46 +0100484
485/* Realm management */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000486u_register_t host_realm_create(struct realm *realm);
487u_register_t host_realm_map_payload_image(struct realm *realm,
488 u_register_t realm_payload_adr);
489u_register_t host_realm_map_ns_shared(struct realm *realm,
490 u_register_t ns_shared_mem_adr,
491 u_register_t ns_shared_mem_size);
492u_register_t host_realm_rec_create(struct realm *realm);
493u_register_t host_realm_activate(struct realm *realm);
494u_register_t host_realm_destroy(struct realm *realm);
495u_register_t host_realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
496 unsigned int *host_call_result);
497u_register_t host_realm_init_ipa_state(struct realm *realm, u_register_t level,
498 u_register_t start, uint64_t end);
499void host_rmi_init_cmp_result(void);
500bool host_rmi_get_cmp_result(void);
nabkah01002e5692022-10-10 12:36:46 +0100501
502#endif /* HOST_REALM_RMI_H */