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