1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright (c) 2015, Linaro Limited
4 */
5 #ifndef __LINUX_ARM_SMCCC_H
6 #define __LINUX_ARM_SMCCC_H
7
8 #include <linux/args.h>
9 #include <linux/init.h>
10
11 #ifndef __ASSEMBLY__
12 #include <linux/uuid.h>
13 #endif
14
15 #include <uapi/linux/const.h>
16
17 /*
18 * This file provides common defines for ARM SMC Calling Convention as
19 * specified in
20 * https://developer.arm.com/docs/den0028/latest
21 *
22 * This code is up-to-date with version DEN 0028 C
23 */
24
25 #define ARM_SMCCC_STD_CALL _AC(0,U)
26 #define ARM_SMCCC_FAST_CALL _AC(1,U)
27 #define ARM_SMCCC_TYPE_SHIFT 31
28
29 #define ARM_SMCCC_SMC_32 0
30 #define ARM_SMCCC_SMC_64 1
31 #define ARM_SMCCC_CALL_CONV_SHIFT 30
32
33 #define ARM_SMCCC_OWNER_MASK 0x3F
34 #define ARM_SMCCC_OWNER_SHIFT 24
35
36 #define ARM_SMCCC_FUNC_MASK 0xFFFF
37
38 #define ARM_SMCCC_IS_FAST_CALL(smc_val) \
39 ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
40 #define ARM_SMCCC_IS_64(smc_val) \
41 ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
42 #define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
43 #define ARM_SMCCC_OWNER_NUM(smc_val) \
44 (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
45
46 #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
47 (((type) << ARM_SMCCC_TYPE_SHIFT) | \
48 ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
49 (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
50 ((func_num) & ARM_SMCCC_FUNC_MASK))
51
52 #define ARM_SMCCC_OWNER_ARCH 0
53 #define ARM_SMCCC_OWNER_CPU 1
54 #define ARM_SMCCC_OWNER_SIP 2
55 #define ARM_SMCCC_OWNER_OEM 3
56 #define ARM_SMCCC_OWNER_STANDARD 4
57 #define ARM_SMCCC_OWNER_STANDARD_HYP 5
58 #define ARM_SMCCC_OWNER_VENDOR_HYP 6
59 #define ARM_SMCCC_OWNER_TRUSTED_APP 48
60 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
61 #define ARM_SMCCC_OWNER_TRUSTED_OS 50
62 #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
63
64 #define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01
65
66 #define ARM_SMCCC_QUIRK_NONE 0
67 #define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
68
69 #define ARM_SMCCC_VERSION_1_0 0x10000
70 #define ARM_SMCCC_VERSION_1_1 0x10001
71 #define ARM_SMCCC_VERSION_1_2 0x10002
72 #define ARM_SMCCC_VERSION_1_3 0x10003
73
74 #define ARM_SMCCC_1_3_SVE_HINT 0x10000
75 #define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT
76
77
78 #define ARM_SMCCC_VERSION_FUNC_ID \
79 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
80 ARM_SMCCC_SMC_32, \
81 0, 0)
82
83 #define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
84 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
85 ARM_SMCCC_SMC_32, \
86 0, 1)
87
88 #define ARM_SMCCC_ARCH_SOC_ID \
89 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
90 ARM_SMCCC_SMC_32, \
91 0, 2)
92
93 #define ARM_SMCCC_ARCH_WORKAROUND_1 \
94 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
95 ARM_SMCCC_SMC_32, \
96 0, 0x8000)
97
98 #define ARM_SMCCC_ARCH_WORKAROUND_2 \
99 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
100 ARM_SMCCC_SMC_32, \
101 0, 0x7fff)
102
103 #define ARM_SMCCC_ARCH_WORKAROUND_3 \
104 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
105 ARM_SMCCC_SMC_32, \
106 0, 0x3fff)
107
108 #define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
109 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
110 ARM_SMCCC_SMC_32, \
111 ARM_SMCCC_OWNER_VENDOR_HYP, \
112 ARM_SMCCC_FUNC_QUERY_CALL_UID)
113
114 /* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
115 #define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\
116 0x28b46fb6, 0x2ec5, 0x11e9, \
117 0xa9, 0xca, 0x4b, 0x56, \
118 0x4d, 0x00, 0x3a, 0x74)
119
120 /* KVM "vendor specific" services */
121 #define ARM_SMCCC_KVM_FUNC_FEATURES 0
122 #define ARM_SMCCC_KVM_FUNC_PTP 1
123 /* Start of pKVM hypercall range */
124 #define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2
125 #define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3
126 #define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4
127 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5
128 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6
129 #define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7
130 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8
131 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9
132 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10
133 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11
134 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12
135 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13
136 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14
137 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15
138 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16
139 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17
140 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18
141 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19
142 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20
143 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21
144 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22
145 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23
146 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24
147 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25
148 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26
149 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27
150 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28
151 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29
152 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30
153 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31
154 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32
155 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33
156 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34
157 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35
158 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36
159 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37
160 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38
161 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39
162 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40
163 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41
164 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42
165 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43
166 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44
167 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45
168 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46
169 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47
170 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48
171 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49
172 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50
173 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51
174 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52
175 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53
176 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54
177 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55
178 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56
179 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57
180 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58
181 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59
182 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60
183 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61
184 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62
185 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63
186 /* End of pKVM hypercall range */
187 #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64
188 #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65
189
190 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
191 #define ARM_SMCCC_KVM_NUM_FUNCS 128
192
193 #define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
194 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
195 ARM_SMCCC_SMC_32, \
196 ARM_SMCCC_OWNER_VENDOR_HYP, \
197 ARM_SMCCC_KVM_FUNC_FEATURES)
198
199 #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
200
201 /*
202 * ptp_kvm is a feature used for time sync between vm and host.
203 * ptp_kvm module in guest kernel will get service from host using
204 * this hypercall ID.
205 */
206 #define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
207 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
208 ARM_SMCCC_SMC_32, \
209 ARM_SMCCC_OWNER_VENDOR_HYP, \
210 ARM_SMCCC_KVM_FUNC_PTP)
211
212 #define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \
213 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
214 ARM_SMCCC_SMC_64, \
215 ARM_SMCCC_OWNER_VENDOR_HYP, \
216 ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)
217
218 #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \
219 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
220 ARM_SMCCC_SMC_64, \
221 ARM_SMCCC_OWNER_VENDOR_HYP, \
222 ARM_SMCCC_KVM_FUNC_MEM_SHARE)
223
224 #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \
225 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
226 ARM_SMCCC_SMC_64, \
227 ARM_SMCCC_OWNER_VENDOR_HYP, \
228 ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)
229
230 #define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \
231 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
232 ARM_SMCCC_SMC_64, \
233 ARM_SMCCC_OWNER_VENDOR_HYP, \
234 ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
235
236 #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \
237 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
238 ARM_SMCCC_SMC_64, \
239 ARM_SMCCC_OWNER_VENDOR_HYP, \
240 ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER)
241
242 #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \
243 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
244 ARM_SMCCC_SMC_64, \
245 ARM_SMCCC_OWNER_VENDOR_HYP, \
246 ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
247
248 /* ptp_kvm counter type ID */
249 #define KVM_PTP_VIRT_COUNTER 0
250 #define KVM_PTP_PHYS_COUNTER 1
251
252 /* Paravirtualised time calls (defined by ARM DEN0057A) */
253 #define ARM_SMCCC_HV_PV_TIME_FEATURES \
254 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
255 ARM_SMCCC_SMC_64, \
256 ARM_SMCCC_OWNER_STANDARD_HYP, \
257 0x20)
258
259 #define ARM_SMCCC_HV_PV_TIME_ST \
260 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
261 ARM_SMCCC_SMC_64, \
262 ARM_SMCCC_OWNER_STANDARD_HYP, \
263 0x21)
264
265 /* TRNG entropy source calls (defined by ARM DEN0098) */
266 #define ARM_SMCCC_TRNG_VERSION \
267 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
268 ARM_SMCCC_SMC_32, \
269 ARM_SMCCC_OWNER_STANDARD, \
270 0x50)
271
272 #define ARM_SMCCC_TRNG_FEATURES \
273 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
274 ARM_SMCCC_SMC_32, \
275 ARM_SMCCC_OWNER_STANDARD, \
276 0x51)
277
278 #define ARM_SMCCC_TRNG_GET_UUID \
279 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
280 ARM_SMCCC_SMC_32, \
281 ARM_SMCCC_OWNER_STANDARD, \
282 0x52)
283
284 #define ARM_SMCCC_TRNG_RND32 \
285 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
286 ARM_SMCCC_SMC_32, \
287 ARM_SMCCC_OWNER_STANDARD, \
288 0x53)
289
290 #define ARM_SMCCC_TRNG_RND64 \
291 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
292 ARM_SMCCC_SMC_64, \
293 ARM_SMCCC_OWNER_STANDARD, \
294 0x53)
295
296 /*
297 * Return codes defined in ARM DEN 0070A
298 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
299 */
300 #define SMCCC_RET_SUCCESS 0
301 #define SMCCC_RET_NOT_SUPPORTED -1
302 #define SMCCC_RET_NOT_REQUIRED -2
303 #define SMCCC_RET_INVALID_PARAMETER -3
304
305 #ifndef __ASSEMBLY__
306
307 #include <linux/linkage.h>
308 #include <linux/types.h>
309
310 enum arm_smccc_conduit {
311 SMCCC_CONDUIT_NONE,
312 SMCCC_CONDUIT_SMC,
313 SMCCC_CONDUIT_HVC,
314 };
315
316 /**
317 * arm_smccc_1_1_get_conduit()
318 *
319 * Returns the conduit to be used for SMCCCv1.1 or later.
320 *
321 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
322 */
323 enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
324
325 /**
326 * arm_smccc_get_version()
327 *
328 * Returns the version to be used for SMCCCv1.1 or later.
329 *
330 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
331 * does not imply the presence of firmware or a valid conduit. Caller
332 * handling SMCCCv1.0 must determine the conduit by other means.
333 */
334 u32 arm_smccc_get_version(void);
335
336 void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
337
338 /**
339 * arm_smccc_get_soc_id_version()
340 *
341 * Returns the SOC ID version.
342 *
343 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
344 */
345 s32 arm_smccc_get_soc_id_version(void);
346
347 /**
348 * arm_smccc_get_soc_id_revision()
349 *
350 * Returns the SOC ID revision.
351 *
352 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
353 */
354 s32 arm_smccc_get_soc_id_revision(void);
355
356 #ifndef __ASSEMBLY__
357
358 /*
359 * Returns whether a specific hypervisor UUID is advertised for the
360 * Vendor Specific Hypervisor Service range.
361 */
362 bool arm_smccc_hypervisor_has_uuid(const uuid_t *uuid);
363
smccc_res_to_uuid(u32 r0,u32 r1,u32 r2,u32 r3)364 static inline uuid_t smccc_res_to_uuid(u32 r0, u32 r1, u32 r2, u32 r3)
365 {
366 uuid_t uuid = {
367 .b = {
368 [0] = (r0 >> 0) & 0xff,
369 [1] = (r0 >> 8) & 0xff,
370 [2] = (r0 >> 16) & 0xff,
371 [3] = (r0 >> 24) & 0xff,
372
373 [4] = (r1 >> 0) & 0xff,
374 [5] = (r1 >> 8) & 0xff,
375 [6] = (r1 >> 16) & 0xff,
376 [7] = (r1 >> 24) & 0xff,
377
378 [8] = (r2 >> 0) & 0xff,
379 [9] = (r2 >> 8) & 0xff,
380 [10] = (r2 >> 16) & 0xff,
381 [11] = (r2 >> 24) & 0xff,
382
383 [12] = (r3 >> 0) & 0xff,
384 [13] = (r3 >> 8) & 0xff,
385 [14] = (r3 >> 16) & 0xff,
386 [15] = (r3 >> 24) & 0xff,
387 },
388 };
389
390 return uuid;
391 }
392
smccc_uuid_to_reg(const uuid_t * uuid,int reg)393 static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg)
394 {
395 u32 val = 0;
396
397 val |= (u32)(uuid->b[4 * reg + 0] << 0);
398 val |= (u32)(uuid->b[4 * reg + 1] << 8);
399 val |= (u32)(uuid->b[4 * reg + 2] << 16);
400 val |= (u32)(uuid->b[4 * reg + 3] << 24);
401
402 return val;
403 }
404
405 #endif /* !__ASSEMBLY__ */
406
407 /**
408 * struct arm_smccc_res - Result from SMC/HVC call
409 * @a0-a3 result values from registers 0 to 3
410 */
411 struct arm_smccc_res {
412 unsigned long a0;
413 unsigned long a1;
414 unsigned long a2;
415 unsigned long a3;
416 };
417
418 #ifdef CONFIG_ARM64
419 /**
420 * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
421 * @a0-a17 argument values from registers 0 to 17
422 */
423 struct arm_smccc_1_2_regs {
424 unsigned long a0;
425 unsigned long a1;
426 unsigned long a2;
427 unsigned long a3;
428 unsigned long a4;
429 unsigned long a5;
430 unsigned long a6;
431 unsigned long a7;
432 unsigned long a8;
433 unsigned long a9;
434 unsigned long a10;
435 unsigned long a11;
436 unsigned long a12;
437 unsigned long a13;
438 unsigned long a14;
439 unsigned long a15;
440 unsigned long a16;
441 unsigned long a17;
442 };
443
444 /**
445 * arm_smccc_1_2_hvc() - make HVC calls
446 * @args: arguments passed via struct arm_smccc_1_2_regs
447 * @res: result values via struct arm_smccc_1_2_regs
448 *
449 * This function is used to make HVC calls following SMC Calling Convention
450 * v1.2 or above. The content of the supplied param are copied from the
451 * structure to registers prior to the HVC instruction. The return values
452 * are updated with the content from registers on return from the HVC
453 * instruction.
454 */
455 asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
456 struct arm_smccc_1_2_regs *res);
457
458 /**
459 * arm_smccc_1_2_smc() - make SMC calls
460 * @args: arguments passed via struct arm_smccc_1_2_regs
461 * @res: result values via struct arm_smccc_1_2_regs
462 *
463 * This function is used to make SMC calls following SMC Calling Convention
464 * v1.2 or above. The content of the supplied param are copied from the
465 * structure to registers prior to the SMC instruction. The return values
466 * are updated with the content from registers on return from the SMC
467 * instruction.
468 */
469 asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
470 struct arm_smccc_1_2_regs *res);
471 #endif
472
473 /**
474 * struct arm_smccc_quirk - Contains quirk information
475 * @id: quirk identification
476 * @state: quirk specific information
477 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
478 */
479 struct arm_smccc_quirk {
480 int id;
481 union {
482 unsigned long a6;
483 } state;
484 };
485
486 /**
487 * __arm_smccc_smc() - make SMC calls
488 * @a0-a7: arguments passed in registers 0 to 7
489 * @res: result values from registers 0 to 3
490 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
491 *
492 * This function is used to make SMC calls following SMC Calling Convention.
493 * The content of the supplied param are copied to registers 0 to 7 prior
494 * to the SMC instruction. The return values are updated with the content
495 * from register 0 to 3 on return from the SMC instruction. An optional
496 * quirk structure provides vendor specific behavior.
497 */
498 #ifdef CONFIG_HAVE_ARM_SMCCC
499 asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
500 unsigned long a2, unsigned long a3, unsigned long a4,
501 unsigned long a5, unsigned long a6, unsigned long a7,
502 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
503 #else
__arm_smccc_smc(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res,struct arm_smccc_quirk * quirk)504 static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
505 unsigned long a2, unsigned long a3, unsigned long a4,
506 unsigned long a5, unsigned long a6, unsigned long a7,
507 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
508 {
509 *res = (struct arm_smccc_res){};
510 }
511 #endif
512
513 /**
514 * __arm_smccc_hvc() - make HVC calls
515 * @a0-a7: arguments passed in registers 0 to 7
516 * @res: result values from registers 0 to 3
517 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
518 *
519 * This function is used to make HVC calls following SMC Calling
520 * Convention. The content of the supplied param are copied to registers 0
521 * to 7 prior to the HVC instruction. The return values are updated with
522 * the content from register 0 to 3 on return from the HVC instruction. An
523 * optional quirk structure provides vendor specific behavior.
524 */
525 asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
526 unsigned long a2, unsigned long a3, unsigned long a4,
527 unsigned long a5, unsigned long a6, unsigned long a7,
528 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
529
530 #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
531
532 #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
533
534 #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
535
536 #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
537
538 /* SMCCC v1.1 implementation madness follows */
539 #ifdef CONFIG_ARM64
540
541 #define SMCCC_SMC_INST "smc #0"
542 #define SMCCC_HVC_INST "hvc #0"
543
544 #elif defined(CONFIG_ARM)
545 #include <asm/opcodes-sec.h>
546 #include <asm/opcodes-virt.h>
547
548 #define SMCCC_SMC_INST __SMC(0)
549 #define SMCCC_HVC_INST __HVC(0)
550
551 #endif
552
553 #define __constraint_read_2 "r" (arg0)
554 #define __constraint_read_3 __constraint_read_2, "r" (arg1)
555 #define __constraint_read_4 __constraint_read_3, "r" (arg2)
556 #define __constraint_read_5 __constraint_read_4, "r" (arg3)
557 #define __constraint_read_6 __constraint_read_5, "r" (arg4)
558 #define __constraint_read_7 __constraint_read_6, "r" (arg5)
559 #define __constraint_read_8 __constraint_read_7, "r" (arg6)
560 #define __constraint_read_9 __constraint_read_8, "r" (arg7)
561
562 #define __declare_arg_2(a0, res) \
563 struct arm_smccc_res *___res = res; \
564 register unsigned long arg0 asm("r0") = (u32)a0
565
566 #define __declare_arg_3(a0, a1, res) \
567 typeof(a1) __a1 = a1; \
568 struct arm_smccc_res *___res = res; \
569 register unsigned long arg0 asm("r0") = (u32)a0; \
570 register typeof(a1) arg1 asm("r1") = __a1
571
572 #define __declare_arg_4(a0, a1, a2, res) \
573 typeof(a1) __a1 = a1; \
574 typeof(a2) __a2 = a2; \
575 struct arm_smccc_res *___res = res; \
576 register unsigned long arg0 asm("r0") = (u32)a0; \
577 register typeof(a1) arg1 asm("r1") = __a1; \
578 register typeof(a2) arg2 asm("r2") = __a2
579
580 #define __declare_arg_5(a0, a1, a2, a3, res) \
581 typeof(a1) __a1 = a1; \
582 typeof(a2) __a2 = a2; \
583 typeof(a3) __a3 = a3; \
584 struct arm_smccc_res *___res = res; \
585 register unsigned long arg0 asm("r0") = (u32)a0; \
586 register typeof(a1) arg1 asm("r1") = __a1; \
587 register typeof(a2) arg2 asm("r2") = __a2; \
588 register typeof(a3) arg3 asm("r3") = __a3
589
590 #define __declare_arg_6(a0, a1, a2, a3, a4, res) \
591 typeof(a4) __a4 = a4; \
592 __declare_arg_5(a0, a1, a2, a3, res); \
593 register typeof(a4) arg4 asm("r4") = __a4
594
595 #define __declare_arg_7(a0, a1, a2, a3, a4, a5, res) \
596 typeof(a5) __a5 = a5; \
597 __declare_arg_6(a0, a1, a2, a3, a4, res); \
598 register typeof(a5) arg5 asm("r5") = __a5
599
600 #define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res) \
601 typeof(a6) __a6 = a6; \
602 __declare_arg_7(a0, a1, a2, a3, a4, a5, res); \
603 register typeof(a6) arg6 asm("r6") = __a6
604
605 #define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res) \
606 typeof(a7) __a7 = a7; \
607 __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res); \
608 register typeof(a7) arg7 asm("r7") = __a7
609
610 /*
611 * We have an output list that is not necessarily used, and GCC feels
612 * entitled to optimise the whole sequence away. "volatile" is what
613 * makes it stick.
614 */
615 #define __arm_smccc_1_1(inst, ...) \
616 do { \
617 register unsigned long r0 asm("r0"); \
618 register unsigned long r1 asm("r1"); \
619 register unsigned long r2 asm("r2"); \
620 register unsigned long r3 asm("r3"); \
621 CONCATENATE(__declare_arg_, \
622 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
623 asm volatile(inst "\n" : \
624 "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
625 : CONCATENATE(__constraint_read_, \
626 COUNT_ARGS(__VA_ARGS__)) \
627 : "memory"); \
628 if (___res) \
629 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
630 } while (0)
631
632 /*
633 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
634 *
635 * This is a variadic macro taking one to eight source arguments, and
636 * an optional return structure.
637 *
638 * @a0-a7: arguments passed in registers 0 to 7
639 * @res: result values from registers 0 to 3
640 *
641 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
642 * The content of the supplied param are copied to registers 0 to 7 prior
643 * to the SMC instruction. The return values are updated with the content
644 * from register 0 to 3 on return from the SMC instruction if not NULL.
645 */
646 #define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
647
648 /*
649 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
650 *
651 * This is a variadic macro taking one to eight source arguments, and
652 * an optional return structure.
653 *
654 * @a0-a7: arguments passed in registers 0 to 7
655 * @res: result values from registers 0 to 3
656 *
657 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
658 * The content of the supplied param are copied to registers 0 to 7 prior
659 * to the HVC instruction. The return values are updated with the content
660 * from register 0 to 3 on return from the HVC instruction if not NULL.
661 */
662 #define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
663
664 /*
665 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
666 * Used when the SMCCC conduit is not defined. The empty asm statement
667 * avoids compiler warnings about unused variables.
668 */
669 #define __fail_smccc_1_1(...) \
670 do { \
671 CONCATENATE(__declare_arg_, \
672 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
673 asm ("" : \
674 : CONCATENATE(__constraint_read_, \
675 COUNT_ARGS(__VA_ARGS__)) \
676 : "memory"); \
677 if (___res) \
678 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
679 } while (0)
680
681 /*
682 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
683 *
684 * This is a variadic macro taking one to eight source arguments, and
685 * an optional return structure.
686 *
687 * @a0-a7: arguments passed in registers 0 to 7
688 * @res: result values from registers 0 to 3
689 *
690 * This macro will make either an HVC call or an SMC call depending on the
691 * current SMCCC conduit. If no valid conduit is available then -1
692 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
693 *
694 * The return value also provides the conduit that was used.
695 */
696 #define arm_smccc_1_1_invoke(...) ({ \
697 int method = arm_smccc_1_1_get_conduit(); \
698 switch (method) { \
699 case SMCCC_CONDUIT_HVC: \
700 arm_smccc_1_1_hvc(__VA_ARGS__); \
701 break; \
702 case SMCCC_CONDUIT_SMC: \
703 arm_smccc_1_1_smc(__VA_ARGS__); \
704 break; \
705 default: \
706 __fail_smccc_1_1(__VA_ARGS__); \
707 method = SMCCC_CONDUIT_NONE; \
708 break; \
709 } \
710 method; \
711 })
712
713 #ifdef CONFIG_ARM64
714
715 #define __fail_smccc_1_2(___res) \
716 do { \
717 if (___res) \
718 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
719 } while (0)
720
721 /*
722 * arm_smccc_1_2_invoke() - make an SMCCC v1.2 compliant call
723 *
724 * @args: SMC args are in the a0..a17 fields of the arm_smcc_1_2_regs structure
725 * @res: result values from registers 0 to 17
726 *
727 * This macro will make either an HVC call or an SMC call depending on the
728 * current SMCCC conduit. If no valid conduit is available then -1
729 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
730 *
731 * The return value also provides the conduit that was used.
732 */
733 #define arm_smccc_1_2_invoke(args, res) ({ \
734 struct arm_smccc_1_2_regs *__args = args; \
735 struct arm_smccc_1_2_regs *__res = res; \
736 int method = arm_smccc_1_1_get_conduit(); \
737 switch (method) { \
738 case SMCCC_CONDUIT_HVC: \
739 arm_smccc_1_2_hvc(__args, __res); \
740 break; \
741 case SMCCC_CONDUIT_SMC: \
742 arm_smccc_1_2_smc(__args, __res); \
743 break; \
744 default: \
745 __fail_smccc_1_2(__res); \
746 method = SMCCC_CONDUIT_NONE; \
747 break; \
748 } \
749 method; \
750 })
751 #endif /*CONFIG_ARM64*/
752
753 #endif /*__ASSEMBLY__*/
754 #endif /*__LINUX_ARM_SMCCC_H*/
755