Merge tag 'powerpc-6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-block.git] / include / linux / arm-smccc.h
CommitLineData
9c92ab61 1/* SPDX-License-Identifier: GPL-2.0-only */
98dd64f3
JW
2/*
3 * Copyright (c) 2015, Linaro Limited
98dd64f3
JW
4 */
5#ifndef __LINUX_ARM_SMCCC_H
6#define __LINUX_ARM_SMCCC_H
7
90e3e185 8#include <linux/args.h>
269fd61e 9#include <linux/init.h>
ded4c39e
MZ
10#include <uapi/linux/const.h>
11
98dd64f3
JW
12/*
13 * This file provides common defines for ARM SMC Calling Convention as
14 * specified in
15c704ab
SH
15 * https://developer.arm.com/docs/den0028/latest
16 *
0441bfe7 17 * This code is up-to-date with version DEN 0028 C
98dd64f3
JW
18 */
19
ded4c39e
MZ
20#define ARM_SMCCC_STD_CALL _AC(0,U)
21#define ARM_SMCCC_FAST_CALL _AC(1,U)
98dd64f3
JW
22#define ARM_SMCCC_TYPE_SHIFT 31
23
24#define ARM_SMCCC_SMC_32 0
25#define ARM_SMCCC_SMC_64 1
26#define ARM_SMCCC_CALL_CONV_SHIFT 30
27
28#define ARM_SMCCC_OWNER_MASK 0x3F
29#define ARM_SMCCC_OWNER_SHIFT 24
30
31#define ARM_SMCCC_FUNC_MASK 0xFFFF
32
33#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
34 ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
35#define ARM_SMCCC_IS_64(smc_val) \
36 ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
37#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
38#define ARM_SMCCC_OWNER_NUM(smc_val) \
39 (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
40
41#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
42 (((type) << ARM_SMCCC_TYPE_SHIFT) | \
43 ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
44 (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
45 ((func_num) & ARM_SMCCC_FUNC_MASK))
46
47#define ARM_SMCCC_OWNER_ARCH 0
48#define ARM_SMCCC_OWNER_CPU 1
49#define ARM_SMCCC_OWNER_SIP 2
50#define ARM_SMCCC_OWNER_OEM 3
51#define ARM_SMCCC_OWNER_STANDARD 4
b48c1a45 52#define ARM_SMCCC_OWNER_STANDARD_HYP 5
cf650168 53#define ARM_SMCCC_OWNER_VENDOR_HYP 6
98dd64f3
JW
54#define ARM_SMCCC_OWNER_TRUSTED_APP 48
55#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
56#define ARM_SMCCC_OWNER_TRUSTED_OS 50
57#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
58
6e085e0a
WD
59#define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01
60
82bcd087
AG
61#define ARM_SMCCC_QUIRK_NONE 0
62#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
63
09e6be12
MZ
64#define ARM_SMCCC_VERSION_1_0 0x10000
65#define ARM_SMCCC_VERSION_1_1 0x10001
0441bfe7 66#define ARM_SMCCC_VERSION_1_2 0x10002
cfa7ff95
MB
67#define ARM_SMCCC_VERSION_1_3 0x10003
68
69#define ARM_SMCCC_1_3_SVE_HINT 0x10000
373beef0
JPB
70#define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT
71
09e6be12
MZ
72
73#define ARM_SMCCC_VERSION_FUNC_ID \
74 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
75 ARM_SMCCC_SMC_32, \
76 0, 0)
77
78#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
79 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
80 ARM_SMCCC_SMC_32, \
81 0, 1)
82
821b67fa
SH
83#define ARM_SMCCC_ARCH_SOC_ID \
84 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
85 ARM_SMCCC_SMC_32, \
86 0, 2)
87
6167ec5c
MZ
88#define ARM_SMCCC_ARCH_WORKAROUND_1 \
89 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
90 ARM_SMCCC_SMC_32, \
91 0, 0x8000)
92
8e290624
MZ
93#define ARM_SMCCC_ARCH_WORKAROUND_2 \
94 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
95 ARM_SMCCC_SMC_32, \
96 0, 0x7fff)
97
ba268923
JM
98#define ARM_SMCCC_ARCH_WORKAROUND_3 \
99 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
100 ARM_SMCCC_SMC_32, \
101 0, 0x3fff)
102
6e085e0a
WD
103#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
104 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
105 ARM_SMCCC_SMC_32, \
106 ARM_SMCCC_OWNER_VENDOR_HYP, \
107 ARM_SMCCC_FUNC_QUERY_CALL_UID)
108
109/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
110#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U
111#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
112#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
113#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
114
115/* KVM "vendor specific" services */
116#define ARM_SMCCC_KVM_FUNC_FEATURES 0
3bf72569 117#define ARM_SMCCC_KVM_FUNC_PTP 1
6e085e0a
WD
118#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
119#define ARM_SMCCC_KVM_NUM_FUNCS 128
120
121#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
122 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
123 ARM_SMCCC_SMC_32, \
124 ARM_SMCCC_OWNER_VENDOR_HYP, \
125 ARM_SMCCC_KVM_FUNC_FEATURES)
126
1de111b5
SB
127#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
128
3bf72569
JW
129/*
130 * ptp_kvm is a feature used for time sync between vm and host.
131 * ptp_kvm module in guest kernel will get service from host using
132 * this hypercall ID.
133 */
134#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
135 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
136 ARM_SMCCC_SMC_32, \
137 ARM_SMCCC_OWNER_VENDOR_HYP, \
138 ARM_SMCCC_KVM_FUNC_PTP)
139
140/* ptp_kvm counter type ID */
141#define KVM_PTP_VIRT_COUNTER 0
142#define KVM_PTP_PHYS_COUNTER 1
143
7af92885
AS
144/* Paravirtualised time calls (defined by ARM DEN0057A) */
145#define ARM_SMCCC_HV_PV_TIME_FEATURES \
146 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
147 ARM_SMCCC_SMC_64, \
148 ARM_SMCCC_OWNER_STANDARD_HYP, \
149 0x20)
150
151#define ARM_SMCCC_HV_PV_TIME_ST \
152 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
153 ARM_SMCCC_SMC_64, \
154 ARM_SMCCC_OWNER_STANDARD_HYP, \
155 0x21)
156
67c6bb56
AB
157/* TRNG entropy source calls (defined by ARM DEN0098) */
158#define ARM_SMCCC_TRNG_VERSION \
159 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
160 ARM_SMCCC_SMC_32, \
161 ARM_SMCCC_OWNER_STANDARD, \
162 0x50)
163
164#define ARM_SMCCC_TRNG_FEATURES \
165 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
166 ARM_SMCCC_SMC_32, \
167 ARM_SMCCC_OWNER_STANDARD, \
168 0x51)
169
170#define ARM_SMCCC_TRNG_GET_UUID \
171 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
172 ARM_SMCCC_SMC_32, \
173 ARM_SMCCC_OWNER_STANDARD, \
174 0x52)
175
176#define ARM_SMCCC_TRNG_RND32 \
177 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
178 ARM_SMCCC_SMC_32, \
179 ARM_SMCCC_OWNER_STANDARD, \
180 0x53)
181
182#define ARM_SMCCC_TRNG_RND64 \
183 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
184 ARM_SMCCC_SMC_64, \
185 ARM_SMCCC_OWNER_STANDARD, \
186 0x53)
187
7af92885
AS
188/*
189 * Return codes defined in ARM DEN 0070A
190 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
191 */
192#define SMCCC_RET_SUCCESS 0
193#define SMCCC_RET_NOT_SUPPORTED -1
194#define SMCCC_RET_NOT_REQUIRED -2
195#define SMCCC_RET_INVALID_PARAMETER -3
196
82bcd087
AG
197#ifndef __ASSEMBLY__
198
199#include <linux/linkage.h>
200#include <linux/types.h>
6b7fe77c
MR
201
202enum arm_smccc_conduit {
203 SMCCC_CONDUIT_NONE,
204 SMCCC_CONDUIT_SMC,
205 SMCCC_CONDUIT_HVC,
206};
207
208/**
209 * arm_smccc_1_1_get_conduit()
210 *
211 * Returns the conduit to be used for SMCCCv1.1 or later.
212 *
213 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
214 */
215enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
216
a4fb1746
SH
217/**
218 * arm_smccc_get_version()
219 *
220 * Returns the version to be used for SMCCCv1.1 or later.
221 *
222 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
223 * does not imply the presence of firmware or a valid conduit. Caller
224 * handling SMCCCv1.0 must determine the conduit by other means.
225 */
226u32 arm_smccc_get_version(void);
227
269fd61e
SH
228void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
229
cfa7ff95
MB
230extern u64 smccc_has_sve_hint;
231
35727af2
SD
232/**
233 * arm_smccc_get_soc_id_version()
234 *
235 * Returns the SOC ID version.
236 *
237 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
238 */
239s32 arm_smccc_get_soc_id_version(void);
240
241/**
242 * arm_smccc_get_soc_id_revision()
243 *
244 * Returns the SOC ID revision.
245 *
246 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
247 */
248s32 arm_smccc_get_soc_id_revision(void);
249
98dd64f3
JW
250/**
251 * struct arm_smccc_res - Result from SMC/HVC call
252 * @a0-a3 result values from registers 0 to 3
253 */
254struct arm_smccc_res {
255 unsigned long a0;
256 unsigned long a1;
257 unsigned long a2;
258 unsigned long a3;
259};
260
3fdc0cb5
SH
261#ifdef CONFIG_ARM64
262/**
263 * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
264 * @a0-a17 argument values from registers 0 to 17
265 */
266struct arm_smccc_1_2_regs {
267 unsigned long a0;
268 unsigned long a1;
269 unsigned long a2;
270 unsigned long a3;
271 unsigned long a4;
272 unsigned long a5;
273 unsigned long a6;
274 unsigned long a7;
275 unsigned long a8;
276 unsigned long a9;
277 unsigned long a10;
278 unsigned long a11;
279 unsigned long a12;
280 unsigned long a13;
281 unsigned long a14;
282 unsigned long a15;
283 unsigned long a16;
284 unsigned long a17;
285};
286
287/**
288 * arm_smccc_1_2_hvc() - make HVC calls
289 * @args: arguments passed via struct arm_smccc_1_2_regs
290 * @res: result values via struct arm_smccc_1_2_regs
291 *
292 * This function is used to make HVC calls following SMC Calling Convention
293 * v1.2 or above. The content of the supplied param are copied from the
294 * structure to registers prior to the HVC instruction. The return values
295 * are updated with the content from registers on return from the HVC
296 * instruction.
297 */
298asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
299 struct arm_smccc_1_2_regs *res);
300
301/**
302 * arm_smccc_1_2_smc() - make SMC calls
303 * @args: arguments passed via struct arm_smccc_1_2_regs
304 * @res: result values via struct arm_smccc_1_2_regs
305 *
306 * This function is used to make SMC calls following SMC Calling Convention
307 * v1.2 or above. The content of the supplied param are copied from the
308 * structure to registers prior to the SMC instruction. The return values
309 * are updated with the content from registers on return from the SMC
310 * instruction.
311 */
312asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
313 struct arm_smccc_1_2_regs *res);
314#endif
315
98dd64f3 316/**
680a0873
AG
317 * struct arm_smccc_quirk - Contains quirk information
318 * @id: quirk identification
319 * @state: quirk specific information
320 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
321 */
322struct arm_smccc_quirk {
323 int id;
324 union {
325 unsigned long a6;
326 } state;
327};
328
cfa7ff95
MB
329/**
330 * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls
331 *
332 * Sets the SMCCC hint bit to indicate if there is live state in the SVE
333 * registers, this modifies x0 in place and should never be called from C
334 * code.
335 */
336asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
337
680a0873
AG
338/**
339 * __arm_smccc_smc() - make SMC calls
98dd64f3
JW
340 * @a0-a7: arguments passed in registers 0 to 7
341 * @res: result values from registers 0 to 3
680a0873 342 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
343 *
344 * This function is used to make SMC calls following SMC Calling Convention.
345 * The content of the supplied param are copied to registers 0 to 7 prior
346 * to the SMC instruction. The return values are updated with the content
680a0873
AG
347 * from register 0 to 3 on return from the SMC instruction. An optional
348 * quirk structure provides vendor specific behavior.
98dd64f3 349 */
424953cf 350#ifdef CONFIG_HAVE_ARM_SMCCC
680a0873 351asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
98dd64f3
JW
352 unsigned long a2, unsigned long a3, unsigned long a4,
353 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873 354 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
424953cf
AB
355#else
356static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
357 unsigned long a2, unsigned long a3, unsigned long a4,
358 unsigned long a5, unsigned long a6, unsigned long a7,
359 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
360{
361 *res = (struct arm_smccc_res){};
362}
363#endif
98dd64f3
JW
364
365/**
680a0873 366 * __arm_smccc_hvc() - make HVC calls
98dd64f3
JW
367 * @a0-a7: arguments passed in registers 0 to 7
368 * @res: result values from registers 0 to 3
3046ec67 369 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
370 *
371 * This function is used to make HVC calls following SMC Calling
372 * Convention. The content of the supplied param are copied to registers 0
373 * to 7 prior to the HVC instruction. The return values are updated with
680a0873
AG
374 * the content from register 0 to 3 on return from the HVC instruction. An
375 * optional quirk structure provides vendor specific behavior.
98dd64f3 376 */
680a0873 377asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
98dd64f3
JW
378 unsigned long a2, unsigned long a3, unsigned long a4,
379 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873
AG
380 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
381
382#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
383
384#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
385
386#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
387
388#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
98dd64f3 389
f2d3b2e8
MZ
390/* SMCCC v1.1 implementation madness follows */
391#ifdef CONFIG_ARM64
392
393#define SMCCC_SMC_INST "smc #0"
394#define SMCCC_HVC_INST "hvc #0"
395
396#elif defined(CONFIG_ARM)
397#include <asm/opcodes-sec.h>
398#include <asm/opcodes-virt.h>
399
400#define SMCCC_SMC_INST __SMC(0)
401#define SMCCC_HVC_INST __HVC(0)
402
403#endif
404
cfa7ff95
MB
405/* nVHE hypervisor doesn't have a current thread so needs separate checks */
406#if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__)
407
408#define SMCCC_SVE_CHECK ALTERNATIVE("nop \n", "bl __arm_smccc_sve_check \n", \
409 ARM64_SVE)
410#define smccc_sve_clobbers "x16", "x30", "cc",
411
412#else
413
414#define SMCCC_SVE_CHECK
415#define smccc_sve_clobbers
416
417#endif
418
90e3e185
AS
419#define __constraint_read_2 "r" (arg0)
420#define __constraint_read_3 __constraint_read_2, "r" (arg1)
421#define __constraint_read_4 __constraint_read_3, "r" (arg2)
422#define __constraint_read_5 __constraint_read_4, "r" (arg3)
423#define __constraint_read_6 __constraint_read_5, "r" (arg4)
424#define __constraint_read_7 __constraint_read_6, "r" (arg5)
425#define __constraint_read_8 __constraint_read_7, "r" (arg6)
426#define __constraint_read_9 __constraint_read_8, "r" (arg7)
f2d3b2e8 427
90e3e185 428#define __declare_arg_2(a0, res) \
f2d3b2e8 429 struct arm_smccc_res *___res = res; \
0794a974 430 register unsigned long arg0 asm("r0") = (u32)a0
f2d3b2e8 431
90e3e185 432#define __declare_arg_3(a0, a1, res) \
755a8bf5 433 typeof(a1) __a1 = a1; \
f2d3b2e8 434 struct arm_smccc_res *___res = res; \
0794a974
AS
435 register unsigned long arg0 asm("r0") = (u32)a0; \
436 register typeof(a1) arg1 asm("r1") = __a1
f2d3b2e8 437
90e3e185 438#define __declare_arg_4(a0, a1, a2, res) \
755a8bf5
MZ
439 typeof(a1) __a1 = a1; \
440 typeof(a2) __a2 = a2; \
f2d3b2e8 441 struct arm_smccc_res *___res = res; \
0794a974
AS
442 register unsigned long arg0 asm("r0") = (u32)a0; \
443 register typeof(a1) arg1 asm("r1") = __a1; \
444 register typeof(a2) arg2 asm("r2") = __a2
f2d3b2e8 445
90e3e185 446#define __declare_arg_5(a0, a1, a2, a3, res) \
755a8bf5
MZ
447 typeof(a1) __a1 = a1; \
448 typeof(a2) __a2 = a2; \
449 typeof(a3) __a3 = a3; \
f2d3b2e8 450 struct arm_smccc_res *___res = res; \
0794a974
AS
451 register unsigned long arg0 asm("r0") = (u32)a0; \
452 register typeof(a1) arg1 asm("r1") = __a1; \
453 register typeof(a2) arg2 asm("r2") = __a2; \
454 register typeof(a3) arg3 asm("r3") = __a3
f2d3b2e8 455
90e3e185 456#define __declare_arg_6(a0, a1, a2, a3, a4, res) \
755a8bf5 457 typeof(a4) __a4 = a4; \
90e3e185 458 __declare_arg_5(a0, a1, a2, a3, res); \
0794a974 459 register typeof(a4) arg4 asm("r4") = __a4
f2d3b2e8 460
90e3e185 461#define __declare_arg_7(a0, a1, a2, a3, a4, a5, res) \
755a8bf5 462 typeof(a5) __a5 = a5; \
90e3e185 463 __declare_arg_6(a0, a1, a2, a3, a4, res); \
0794a974 464 register typeof(a5) arg5 asm("r5") = __a5
f2d3b2e8 465
90e3e185 466#define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res) \
755a8bf5 467 typeof(a6) __a6 = a6; \
90e3e185 468 __declare_arg_7(a0, a1, a2, a3, a4, a5, res); \
0794a974 469 register typeof(a6) arg6 asm("r6") = __a6
f2d3b2e8 470
90e3e185 471#define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res) \
755a8bf5 472 typeof(a7) __a7 = a7; \
90e3e185 473 __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res); \
0794a974 474 register typeof(a7) arg7 asm("r7") = __a7
f2d3b2e8 475
f2d3b2e8
MZ
476/*
477 * We have an output list that is not necessarily used, and GCC feels
478 * entitled to optimise the whole sequence away. "volatile" is what
479 * makes it stick.
480 */
481#define __arm_smccc_1_1(inst, ...) \
482 do { \
0794a974
AS
483 register unsigned long r0 asm("r0"); \
484 register unsigned long r1 asm("r1"); \
485 register unsigned long r2 asm("r2"); \
486 register unsigned long r3 asm("r3"); \
90e3e185
AS
487 CONCATENATE(__declare_arg_, \
488 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
cfa7ff95
MB
489 asm volatile(SMCCC_SVE_CHECK \
490 inst "\n" : \
0794a974 491 "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
90e3e185
AS
492 : CONCATENATE(__constraint_read_, \
493 COUNT_ARGS(__VA_ARGS__)) \
494 : smccc_sve_clobbers "memory"); \
f2d3b2e8
MZ
495 if (___res) \
496 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
497 } while (0)
498
499/*
500 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
501 *
502 * This is a variadic macro taking one to eight source arguments, and
503 * an optional return structure.
504 *
505 * @a0-a7: arguments passed in registers 0 to 7
506 * @res: result values from registers 0 to 3
507 *
508 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
509 * The content of the supplied param are copied to registers 0 to 7 prior
510 * to the SMC instruction. The return values are updated with the content
511 * from register 0 to 3 on return from the SMC instruction if not NULL.
512 */
513#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
514
515/*
516 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
517 *
518 * This is a variadic macro taking one to eight source arguments, and
519 * an optional return structure.
520 *
521 * @a0-a7: arguments passed in registers 0 to 7
522 * @res: result values from registers 0 to 3
523 *
524 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
525 * The content of the supplied param are copied to registers 0 to 7 prior
526 * to the HVC instruction. The return values are updated with the content
527 * from register 0 to 3 on return from the HVC instruction if not NULL.
528 */
529#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
530
541625ac
SP
531/*
532 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
533 * Used when the SMCCC conduit is not defined. The empty asm statement
534 * avoids compiler warnings about unused variables.
535 */
536#define __fail_smccc_1_1(...) \
537 do { \
90e3e185
AS
538 CONCATENATE(__declare_arg_, \
539 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
540 asm ("" : \
541 : CONCATENATE(__constraint_read_, \
542 COUNT_ARGS(__VA_ARGS__)) \
543 : smccc_sve_clobbers "memory"); \
541625ac
SP
544 if (___res) \
545 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
546 } while (0)
547
548/*
549 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
550 *
551 * This is a variadic macro taking one to eight source arguments, and
552 * an optional return structure.
553 *
554 * @a0-a7: arguments passed in registers 0 to 7
555 * @res: result values from registers 0 to 3
556 *
557 * This macro will make either an HVC call or an SMC call depending on the
558 * current SMCCC conduit. If no valid conduit is available then -1
559 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
560 *
561 * The return value also provides the conduit that was used.
562 */
563#define arm_smccc_1_1_invoke(...) ({ \
564 int method = arm_smccc_1_1_get_conduit(); \
565 switch (method) { \
566 case SMCCC_CONDUIT_HVC: \
567 arm_smccc_1_1_hvc(__VA_ARGS__); \
568 break; \
569 case SMCCC_CONDUIT_SMC: \
570 arm_smccc_1_1_smc(__VA_ARGS__); \
571 break; \
572 default: \
573 __fail_smccc_1_1(__VA_ARGS__); \
574 method = SMCCC_CONDUIT_NONE; \
575 break; \
576 } \
577 method; \
578 })
579
82bcd087 580#endif /*__ASSEMBLY__*/
98dd64f3 581#endif /*__LINUX_ARM_SMCCC_H*/