Merge branch 'address-masking'
[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
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
21be9f71 118/* Start of pKVM hypercall range */
a06c3fad 119#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2
ebc59b12
WD
120#define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3
121#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4
21be9f71
WD
122#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5
123#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6
0f126949 124#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7
21be9f71
WD
125#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8
126#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9
127#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10
128#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11
129#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12
130#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13
131#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14
132#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15
133#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16
134#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17
135#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18
136#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19
137#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20
138#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21
139#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22
140#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23
141#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24
142#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25
143#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26
144#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27
145#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28
146#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29
147#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30
148#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31
149#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32
150#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33
151#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34
152#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35
153#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36
154#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37
155#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38
156#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39
157#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40
158#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41
159#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42
160#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43
161#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44
162#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45
163#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46
164#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47
165#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48
166#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49
167#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50
168#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51
169#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52
170#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53
171#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54
172#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55
173#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56
174#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57
175#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58
176#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59
177#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60
178#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61
179#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62
180#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63
181/* End of pKVM hypercall range */
6e085e0a
WD
182#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
183#define ARM_SMCCC_KVM_NUM_FUNCS 128
184
185#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
186 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
187 ARM_SMCCC_SMC_32, \
188 ARM_SMCCC_OWNER_VENDOR_HYP, \
189 ARM_SMCCC_KVM_FUNC_FEATURES)
190
1de111b5
SB
191#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
192
3bf72569
JW
193/*
194 * ptp_kvm is a feature used for time sync between vm and host.
195 * ptp_kvm module in guest kernel will get service from host using
196 * this hypercall ID.
197 */
198#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
199 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
200 ARM_SMCCC_SMC_32, \
201 ARM_SMCCC_OWNER_VENDOR_HYP, \
202 ARM_SMCCC_KVM_FUNC_PTP)
203
a06c3fad
WD
204#define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \
205 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
206 ARM_SMCCC_SMC_64, \
207 ARM_SMCCC_OWNER_VENDOR_HYP, \
208 ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)
209
ebc59b12
WD
210#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \
211 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
212 ARM_SMCCC_SMC_64, \
213 ARM_SMCCC_OWNER_VENDOR_HYP, \
214 ARM_SMCCC_KVM_FUNC_MEM_SHARE)
215
216#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \
217 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
218 ARM_SMCCC_SMC_64, \
219 ARM_SMCCC_OWNER_VENDOR_HYP, \
220 ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)
221
0f126949
WD
222#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \
223 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
224 ARM_SMCCC_SMC_64, \
225 ARM_SMCCC_OWNER_VENDOR_HYP, \
226 ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
227
3bf72569
JW
228/* ptp_kvm counter type ID */
229#define KVM_PTP_VIRT_COUNTER 0
230#define KVM_PTP_PHYS_COUNTER 1
231
7af92885
AS
232/* Paravirtualised time calls (defined by ARM DEN0057A) */
233#define ARM_SMCCC_HV_PV_TIME_FEATURES \
234 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
235 ARM_SMCCC_SMC_64, \
236 ARM_SMCCC_OWNER_STANDARD_HYP, \
237 0x20)
238
239#define ARM_SMCCC_HV_PV_TIME_ST \
240 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
241 ARM_SMCCC_SMC_64, \
242 ARM_SMCCC_OWNER_STANDARD_HYP, \
243 0x21)
244
67c6bb56
AB
245/* TRNG entropy source calls (defined by ARM DEN0098) */
246#define ARM_SMCCC_TRNG_VERSION \
247 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
248 ARM_SMCCC_SMC_32, \
249 ARM_SMCCC_OWNER_STANDARD, \
250 0x50)
251
252#define ARM_SMCCC_TRNG_FEATURES \
253 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
254 ARM_SMCCC_SMC_32, \
255 ARM_SMCCC_OWNER_STANDARD, \
256 0x51)
257
258#define ARM_SMCCC_TRNG_GET_UUID \
259 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
260 ARM_SMCCC_SMC_32, \
261 ARM_SMCCC_OWNER_STANDARD, \
262 0x52)
263
264#define ARM_SMCCC_TRNG_RND32 \
265 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
266 ARM_SMCCC_SMC_32, \
267 ARM_SMCCC_OWNER_STANDARD, \
268 0x53)
269
270#define ARM_SMCCC_TRNG_RND64 \
271 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
272 ARM_SMCCC_SMC_64, \
273 ARM_SMCCC_OWNER_STANDARD, \
274 0x53)
275
7af92885
AS
276/*
277 * Return codes defined in ARM DEN 0070A
278 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
279 */
280#define SMCCC_RET_SUCCESS 0
281#define SMCCC_RET_NOT_SUPPORTED -1
282#define SMCCC_RET_NOT_REQUIRED -2
283#define SMCCC_RET_INVALID_PARAMETER -3
284
82bcd087
AG
285#ifndef __ASSEMBLY__
286
287#include <linux/linkage.h>
288#include <linux/types.h>
6b7fe77c
MR
289
290enum arm_smccc_conduit {
291 SMCCC_CONDUIT_NONE,
292 SMCCC_CONDUIT_SMC,
293 SMCCC_CONDUIT_HVC,
294};
295
296/**
297 * arm_smccc_1_1_get_conduit()
298 *
299 * Returns the conduit to be used for SMCCCv1.1 or later.
300 *
301 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
302 */
303enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
304
a4fb1746
SH
305/**
306 * arm_smccc_get_version()
307 *
308 * Returns the version to be used for SMCCCv1.1 or later.
309 *
310 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
311 * does not imply the presence of firmware or a valid conduit. Caller
312 * handling SMCCCv1.0 must determine the conduit by other means.
313 */
314u32 arm_smccc_get_version(void);
315
269fd61e
SH
316void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
317
cfa7ff95
MB
318extern u64 smccc_has_sve_hint;
319
35727af2
SD
320/**
321 * arm_smccc_get_soc_id_version()
322 *
323 * Returns the SOC ID version.
324 *
325 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
326 */
327s32 arm_smccc_get_soc_id_version(void);
328
329/**
330 * arm_smccc_get_soc_id_revision()
331 *
332 * Returns the SOC ID revision.
333 *
334 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
335 */
336s32 arm_smccc_get_soc_id_revision(void);
337
98dd64f3
JW
338/**
339 * struct arm_smccc_res - Result from SMC/HVC call
340 * @a0-a3 result values from registers 0 to 3
341 */
342struct arm_smccc_res {
343 unsigned long a0;
344 unsigned long a1;
345 unsigned long a2;
346 unsigned long a3;
347};
348
3fdc0cb5
SH
349#ifdef CONFIG_ARM64
350/**
351 * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
352 * @a0-a17 argument values from registers 0 to 17
353 */
354struct arm_smccc_1_2_regs {
355 unsigned long a0;
356 unsigned long a1;
357 unsigned long a2;
358 unsigned long a3;
359 unsigned long a4;
360 unsigned long a5;
361 unsigned long a6;
362 unsigned long a7;
363 unsigned long a8;
364 unsigned long a9;
365 unsigned long a10;
366 unsigned long a11;
367 unsigned long a12;
368 unsigned long a13;
369 unsigned long a14;
370 unsigned long a15;
371 unsigned long a16;
372 unsigned long a17;
373};
374
375/**
376 * arm_smccc_1_2_hvc() - make HVC calls
377 * @args: arguments passed via struct arm_smccc_1_2_regs
378 * @res: result values via struct arm_smccc_1_2_regs
379 *
380 * This function is used to make HVC calls following SMC Calling Convention
381 * v1.2 or above. The content of the supplied param are copied from the
382 * structure to registers prior to the HVC instruction. The return values
383 * are updated with the content from registers on return from the HVC
384 * instruction.
385 */
386asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
387 struct arm_smccc_1_2_regs *res);
388
389/**
390 * arm_smccc_1_2_smc() - make SMC calls
391 * @args: arguments passed via struct arm_smccc_1_2_regs
392 * @res: result values via struct arm_smccc_1_2_regs
393 *
394 * This function is used to make SMC calls following SMC Calling Convention
395 * v1.2 or above. The content of the supplied param are copied from the
396 * structure to registers prior to the SMC instruction. The return values
397 * are updated with the content from registers on return from the SMC
398 * instruction.
399 */
400asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
401 struct arm_smccc_1_2_regs *res);
402#endif
403
98dd64f3 404/**
680a0873
AG
405 * struct arm_smccc_quirk - Contains quirk information
406 * @id: quirk identification
407 * @state: quirk specific information
408 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
409 */
410struct arm_smccc_quirk {
411 int id;
412 union {
413 unsigned long a6;
414 } state;
415};
416
cfa7ff95
MB
417/**
418 * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls
419 *
420 * Sets the SMCCC hint bit to indicate if there is live state in the SVE
421 * registers, this modifies x0 in place and should never be called from C
422 * code.
423 */
424asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
425
680a0873
AG
426/**
427 * __arm_smccc_smc() - make SMC calls
98dd64f3
JW
428 * @a0-a7: arguments passed in registers 0 to 7
429 * @res: result values from registers 0 to 3
680a0873 430 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
431 *
432 * This function is used to make SMC calls following SMC Calling Convention.
433 * The content of the supplied param are copied to registers 0 to 7 prior
434 * to the SMC instruction. The return values are updated with the content
680a0873
AG
435 * from register 0 to 3 on return from the SMC instruction. An optional
436 * quirk structure provides vendor specific behavior.
98dd64f3 437 */
424953cf 438#ifdef CONFIG_HAVE_ARM_SMCCC
680a0873 439asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
98dd64f3
JW
440 unsigned long a2, unsigned long a3, unsigned long a4,
441 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873 442 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
424953cf
AB
443#else
444static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
445 unsigned long a2, unsigned long a3, unsigned long a4,
446 unsigned long a5, unsigned long a6, unsigned long a7,
447 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
448{
449 *res = (struct arm_smccc_res){};
450}
451#endif
98dd64f3
JW
452
453/**
680a0873 454 * __arm_smccc_hvc() - make HVC calls
98dd64f3
JW
455 * @a0-a7: arguments passed in registers 0 to 7
456 * @res: result values from registers 0 to 3
3046ec67 457 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
458 *
459 * This function is used to make HVC calls following SMC Calling
460 * Convention. The content of the supplied param are copied to registers 0
461 * to 7 prior to the HVC instruction. The return values are updated with
680a0873
AG
462 * the content from register 0 to 3 on return from the HVC instruction. An
463 * optional quirk structure provides vendor specific behavior.
98dd64f3 464 */
680a0873 465asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
98dd64f3
JW
466 unsigned long a2, unsigned long a3, unsigned long a4,
467 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873
AG
468 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
469
470#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
471
472#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
473
474#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
475
476#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
98dd64f3 477
f2d3b2e8
MZ
478/* SMCCC v1.1 implementation madness follows */
479#ifdef CONFIG_ARM64
480
481#define SMCCC_SMC_INST "smc #0"
482#define SMCCC_HVC_INST "hvc #0"
483
484#elif defined(CONFIG_ARM)
485#include <asm/opcodes-sec.h>
486#include <asm/opcodes-virt.h>
487
488#define SMCCC_SMC_INST __SMC(0)
489#define SMCCC_HVC_INST __HVC(0)
490
491#endif
492
cfa7ff95
MB
493/* nVHE hypervisor doesn't have a current thread so needs separate checks */
494#if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__)
495
496#define SMCCC_SVE_CHECK ALTERNATIVE("nop \n", "bl __arm_smccc_sve_check \n", \
497 ARM64_SVE)
498#define smccc_sve_clobbers "x16", "x30", "cc",
499
500#else
501
502#define SMCCC_SVE_CHECK
503#define smccc_sve_clobbers
504
505#endif
506
90e3e185
AS
507#define __constraint_read_2 "r" (arg0)
508#define __constraint_read_3 __constraint_read_2, "r" (arg1)
509#define __constraint_read_4 __constraint_read_3, "r" (arg2)
510#define __constraint_read_5 __constraint_read_4, "r" (arg3)
511#define __constraint_read_6 __constraint_read_5, "r" (arg4)
512#define __constraint_read_7 __constraint_read_6, "r" (arg5)
513#define __constraint_read_8 __constraint_read_7, "r" (arg6)
514#define __constraint_read_9 __constraint_read_8, "r" (arg7)
f2d3b2e8 515
90e3e185 516#define __declare_arg_2(a0, res) \
f2d3b2e8 517 struct arm_smccc_res *___res = res; \
0794a974 518 register unsigned long arg0 asm("r0") = (u32)a0
f2d3b2e8 519
90e3e185 520#define __declare_arg_3(a0, a1, res) \
755a8bf5 521 typeof(a1) __a1 = a1; \
f2d3b2e8 522 struct arm_smccc_res *___res = res; \
0794a974
AS
523 register unsigned long arg0 asm("r0") = (u32)a0; \
524 register typeof(a1) arg1 asm("r1") = __a1
f2d3b2e8 525
90e3e185 526#define __declare_arg_4(a0, a1, a2, res) \
755a8bf5
MZ
527 typeof(a1) __a1 = a1; \
528 typeof(a2) __a2 = a2; \
f2d3b2e8 529 struct arm_smccc_res *___res = res; \
0794a974
AS
530 register unsigned long arg0 asm("r0") = (u32)a0; \
531 register typeof(a1) arg1 asm("r1") = __a1; \
532 register typeof(a2) arg2 asm("r2") = __a2
f2d3b2e8 533
90e3e185 534#define __declare_arg_5(a0, a1, a2, a3, res) \
755a8bf5
MZ
535 typeof(a1) __a1 = a1; \
536 typeof(a2) __a2 = a2; \
537 typeof(a3) __a3 = a3; \
f2d3b2e8 538 struct arm_smccc_res *___res = res; \
0794a974
AS
539 register unsigned long arg0 asm("r0") = (u32)a0; \
540 register typeof(a1) arg1 asm("r1") = __a1; \
541 register typeof(a2) arg2 asm("r2") = __a2; \
542 register typeof(a3) arg3 asm("r3") = __a3
f2d3b2e8 543
90e3e185 544#define __declare_arg_6(a0, a1, a2, a3, a4, res) \
755a8bf5 545 typeof(a4) __a4 = a4; \
90e3e185 546 __declare_arg_5(a0, a1, a2, a3, res); \
0794a974 547 register typeof(a4) arg4 asm("r4") = __a4
f2d3b2e8 548
90e3e185 549#define __declare_arg_7(a0, a1, a2, a3, a4, a5, res) \
755a8bf5 550 typeof(a5) __a5 = a5; \
90e3e185 551 __declare_arg_6(a0, a1, a2, a3, a4, res); \
0794a974 552 register typeof(a5) arg5 asm("r5") = __a5
f2d3b2e8 553
90e3e185 554#define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res) \
755a8bf5 555 typeof(a6) __a6 = a6; \
90e3e185 556 __declare_arg_7(a0, a1, a2, a3, a4, a5, res); \
0794a974 557 register typeof(a6) arg6 asm("r6") = __a6
f2d3b2e8 558
90e3e185 559#define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res) \
755a8bf5 560 typeof(a7) __a7 = a7; \
90e3e185 561 __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res); \
0794a974 562 register typeof(a7) arg7 asm("r7") = __a7
f2d3b2e8 563
f2d3b2e8
MZ
564/*
565 * We have an output list that is not necessarily used, and GCC feels
566 * entitled to optimise the whole sequence away. "volatile" is what
567 * makes it stick.
568 */
569#define __arm_smccc_1_1(inst, ...) \
570 do { \
0794a974
AS
571 register unsigned long r0 asm("r0"); \
572 register unsigned long r1 asm("r1"); \
573 register unsigned long r2 asm("r2"); \
574 register unsigned long r3 asm("r3"); \
90e3e185
AS
575 CONCATENATE(__declare_arg_, \
576 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
cfa7ff95
MB
577 asm volatile(SMCCC_SVE_CHECK \
578 inst "\n" : \
0794a974 579 "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
90e3e185
AS
580 : CONCATENATE(__constraint_read_, \
581 COUNT_ARGS(__VA_ARGS__)) \
582 : smccc_sve_clobbers "memory"); \
f2d3b2e8
MZ
583 if (___res) \
584 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
585 } while (0)
586
587/*
588 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
589 *
590 * This is a variadic macro taking one to eight source arguments, and
591 * an optional return structure.
592 *
593 * @a0-a7: arguments passed in registers 0 to 7
594 * @res: result values from registers 0 to 3
595 *
596 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
597 * The content of the supplied param are copied to registers 0 to 7 prior
598 * to the SMC instruction. The return values are updated with the content
599 * from register 0 to 3 on return from the SMC instruction if not NULL.
600 */
601#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
602
603/*
604 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
605 *
606 * This is a variadic macro taking one to eight source arguments, and
607 * an optional return structure.
608 *
609 * @a0-a7: arguments passed in registers 0 to 7
610 * @res: result values from registers 0 to 3
611 *
612 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
613 * The content of the supplied param are copied to registers 0 to 7 prior
614 * to the HVC instruction. The return values are updated with the content
615 * from register 0 to 3 on return from the HVC instruction if not NULL.
616 */
617#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
618
541625ac
SP
619/*
620 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
621 * Used when the SMCCC conduit is not defined. The empty asm statement
622 * avoids compiler warnings about unused variables.
623 */
624#define __fail_smccc_1_1(...) \
625 do { \
90e3e185
AS
626 CONCATENATE(__declare_arg_, \
627 COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
628 asm ("" : \
629 : CONCATENATE(__constraint_read_, \
630 COUNT_ARGS(__VA_ARGS__)) \
631 : smccc_sve_clobbers "memory"); \
541625ac
SP
632 if (___res) \
633 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
634 } while (0)
635
636/*
637 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
638 *
639 * This is a variadic macro taking one to eight source arguments, and
640 * an optional return structure.
641 *
642 * @a0-a7: arguments passed in registers 0 to 7
643 * @res: result values from registers 0 to 3
644 *
645 * This macro will make either an HVC call or an SMC call depending on the
646 * current SMCCC conduit. If no valid conduit is available then -1
647 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
648 *
649 * The return value also provides the conduit that was used.
650 */
651#define arm_smccc_1_1_invoke(...) ({ \
652 int method = arm_smccc_1_1_get_conduit(); \
653 switch (method) { \
654 case SMCCC_CONDUIT_HVC: \
655 arm_smccc_1_1_hvc(__VA_ARGS__); \
656 break; \
657 case SMCCC_CONDUIT_SMC: \
658 arm_smccc_1_1_smc(__VA_ARGS__); \
659 break; \
660 default: \
661 __fail_smccc_1_1(__VA_ARGS__); \
662 method = SMCCC_CONDUIT_NONE; \
663 break; \
664 } \
665 method; \
666 })
667
82bcd087 668#endif /*__ASSEMBLY__*/
98dd64f3 669#endif /*__LINUX_ARM_SMCCC_H*/