aboutsummaryrefslogtreecommitdiff
path: root/include/linux/arm-smccc.h
blob: 50b47eba7d01520e8d27552cd8249e7796d227fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015, Linaro Limited
 */
#ifndef __LINUX_ARM_SMCCC_H
#define __LINUX_ARM_SMCCC_H

#include <linux/args.h>
#include <linux/init.h>

#ifndef __ASSEMBLY__
#include <linux/uuid.h>
#endif

#include <uapi/linux/const.h>

/*
 * This file provides common defines for ARM SMC Calling Convention as
 * specified in
 * https://developer.arm.com/docs/den0028/latest
 *
 * This code is up-to-date with version DEN 0028 C
 */

#define ARM_SMCCC_STD_CALL	        _AC(0,U)
#define ARM_SMCCC_FAST_CALL	        _AC(1,U)
#define ARM_SMCCC_TYPE_SHIFT		31

#define ARM_SMCCC_SMC_32		0
#define ARM_SMCCC_SMC_64		1
#define ARM_SMCCC_CALL_CONV_SHIFT	30

#define ARM_SMCCC_OWNER_MASK		0x3F
#define ARM_SMCCC_OWNER_SHIFT		24

#define ARM_SMCCC_FUNC_MASK		0xFFFF

#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
#define ARM_SMCCC_IS_64(smc_val) \
	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
#define ARM_SMCCC_OWNER_NUM(smc_val) \
	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)

#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
	((func_num) & ARM_SMCCC_FUNC_MASK))

#define ARM_SMCCC_OWNER_ARCH		0
#define ARM_SMCCC_OWNER_CPU		1
#define ARM_SMCCC_OWNER_SIP		2
#define ARM_SMCCC_OWNER_OEM		3
#define ARM_SMCCC_OWNER_STANDARD	4
#define ARM_SMCCC_OWNER_STANDARD_HYP	5
#define ARM_SMCCC_OWNER_VENDOR_HYP	6
#define ARM_SMCCC_OWNER_TRUSTED_APP	48
#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
#define ARM_SMCCC_OWNER_TRUSTED_OS	50
#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63

#define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff01

#define ARM_SMCCC_QUIRK_NONE		0
#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */

#define ARM_SMCCC_VERSION_1_0		0x10000
#define ARM_SMCCC_VERSION_1_1		0x10001
#define ARM_SMCCC_VERSION_1_2		0x10002
#define ARM_SMCCC_VERSION_1_3		0x10003

#define ARM_SMCCC_1_3_SVE_HINT		0x10000
#define ARM_SMCCC_CALL_HINTS		ARM_SMCCC_1_3_SVE_HINT


#define ARM_SMCCC_VERSION_FUNC_ID					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 0)

#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 1)

#define ARM_SMCCC_ARCH_SOC_ID						\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 2)

#define ARM_SMCCC_ARCH_WORKAROUND_1					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 0x8000)

#define ARM_SMCCC_ARCH_WORKAROUND_2					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 0x7fff)

#define ARM_SMCCC_ARCH_WORKAROUND_3					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   0, 0x3fff)

#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID				\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_FUNC_QUERY_CALL_UID)

/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
#define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\
	0x28b46fb6, 0x2ec5, 0x11e9, \
	0xa9, 0xca, 0x4b, 0x56, \
	0x4d, 0x00, 0x3a, 0x74)

/* KVM "vendor specific" services */
#define ARM_SMCCC_KVM_FUNC_FEATURES		0
#define ARM_SMCCC_KVM_FUNC_PTP			1
/* Start of pKVM hypercall range */
#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO		2
#define ARM_SMCCC_KVM_FUNC_MEM_SHARE		3
#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE		4
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5		5
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6		6
#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD		7
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8		8
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9		9
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10		10
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11		11
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12		12
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13		13
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14		14
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15		15
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16		16
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17		17
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18		18
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19		19
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20		20
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21		21
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22		22
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23		23
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24		24
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25		25
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26		26
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27		27
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28		28
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29		29
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30		30
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31		31
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32		32
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33		33
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34		34
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35		35
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36		36
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37		37
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38		38
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39		39
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40		40
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41		41
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42		42
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43		43
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44		44
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45		45
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46		46
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47		47
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48		48
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49		49
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50		50
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51		51
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52		52
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53		53
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54		54
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55		55
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56		56
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57		57
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58		58
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59		59
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60		60
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61		61
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62		62
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63		63
/* End of pKVM hypercall range */
#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER	64
#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS	65

#define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
#define ARM_SMCCC_KVM_NUM_FUNCS			128

#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID			\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_FEATURES)

#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED	1

/*
 * ptp_kvm is a feature used for time sync between vm and host.
 * ptp_kvm module in guest kernel will get service from host using
 * this hypercall ID.
 */
#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID				\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_32,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_PTP)

#define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID			\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)

#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID			\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_MEM_SHARE)

#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID			\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)

#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID			\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD)

#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID		\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER)

#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID		\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
			   ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)

/* ptp_kvm counter type ID */
#define KVM_PTP_VIRT_COUNTER			0
#define KVM_PTP_PHYS_COUNTER			1

/* Paravirtualised time calls (defined by ARM DEN0057A) */
#define ARM_SMCCC_HV_PV_TIME_FEATURES				\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_64,			\
			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
			   0x20)

#define ARM_SMCCC_HV_PV_TIME_ST					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_64,			\
			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
			   0x21)

/* TRNG entropy source calls (defined by ARM DEN0098) */
#define ARM_SMCCC_TRNG_VERSION					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_32,			\
			   ARM_SMCCC_OWNER_STANDARD,		\
			   0x50)

#define ARM_SMCCC_TRNG_FEATURES					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_32,			\
			   ARM_SMCCC_OWNER_STANDARD,		\
			   0x51)

#define ARM_SMCCC_TRNG_GET_UUID					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_32,			\
			   ARM_SMCCC_OWNER_STANDARD,		\
			   0x52)

#define ARM_SMCCC_TRNG_RND32					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_32,			\
			   ARM_SMCCC_OWNER_STANDARD,		\
			   0x53)

#define ARM_SMCCC_TRNG_RND64					\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
			   ARM_SMCCC_SMC_64,			\
			   ARM_SMCCC_OWNER_STANDARD,		\
			   0x53)

/*
 * Return codes defined in ARM DEN 0070A
 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
 */
#define SMCCC_RET_SUCCESS			0
#define SMCCC_RET_NOT_SUPPORTED			-1
#define SMCCC_RET_NOT_REQUIRED			-2
#define SMCCC_RET_INVALID_PARAMETER		-3

#ifndef __ASSEMBLY__

#include <linux/linkage.h>
#include <linux/types.h>

enum arm_smccc_conduit {
	SMCCC_CONDUIT_NONE,
	SMCCC_CONDUIT_SMC,
	SMCCC_CONDUIT_HVC,
};

/**
 * arm_smccc_1_1_get_conduit()
 *
 * Returns the conduit to be used for SMCCCv1.1 or later.
 *
 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
 */
enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);

/**
 * arm_smccc_get_version()
 *
 * Returns the version to be used for SMCCCv1.1 or later.
 *
 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
 * does not imply the presence of firmware or a valid conduit. Caller
 * handling SMCCCv1.0 must determine the conduit by other means.
 */
u32 arm_smccc_get_version(void);

void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);

/**
 * arm_smccc_get_soc_id_version()
 *
 * Returns the SOC ID version.
 *
 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
 */
s32 arm_smccc_get_soc_id_version(void);

/**
 * arm_smccc_get_soc_id_revision()
 *
 * Returns the SOC ID revision.
 *
 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
 */
s32 arm_smccc_get_soc_id_revision(void);

#ifndef __ASSEMBLY__

/*
 * Returns whether a specific hypervisor UUID is advertised for the
 * Vendor Specific Hypervisor Service range.
 */
bool arm_smccc_hypervisor_has_uuid(const uuid_t *uuid);

static inline uuid_t smccc_res_to_uuid(u32 r0, u32 r1, u32 r2, u32 r3)
{
	uuid_t uuid = {
		.b = {
			[0]  = (r0 >> 0)  & 0xff,
			[1]  = (r0 >> 8)  & 0xff,
			[2]  = (r0 >> 16) & 0xff,
			[3]  = (r0 >> 24) & 0xff,

			[4]  = (r1 >> 0)  & 0xff,
			[5]  = (r1 >> 8)  & 0xff,
			[6]  = (r1 >> 16) & 0xff,
			[7]  = (r1 >> 24) & 0xff,

			[8]  = (r2 >> 0)  & 0xff,
			[9]  = (r2 >> 8)  & 0xff,
			[10] = (r2 >> 16) & 0xff,
			[11] = (r2 >> 24) & 0xff,

			[12] = (r3 >> 0)  & 0xff,
			[13] = (r3 >> 8)  & 0xff,
			[14] = (r3 >> 16) & 0xff,
			[15] = (r3 >> 24) & 0xff,
		},
	};

	return uuid;
}

static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg)
{
	u32 val = 0;

	val |= (u32)(uuid->b[4 * reg + <