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