]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - include/linux/arm-smccc.h
Merge tag 'printk-for-5.13-fixup' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-jammy-kernel.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
09e6be12
MZ
66
67#define ARM_SMCCC_VERSION_FUNC_ID \
68 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
69 ARM_SMCCC_SMC_32, \
70 0, 0)
71
72#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
73 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
74 ARM_SMCCC_SMC_32, \
75 0, 1)
76
821b67fa
SH
77#define ARM_SMCCC_ARCH_SOC_ID \
78 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
79 ARM_SMCCC_SMC_32, \
80 0, 2)
81
6167ec5c
MZ
82#define ARM_SMCCC_ARCH_WORKAROUND_1 \
83 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
84 ARM_SMCCC_SMC_32, \
85 0, 0x8000)
86
8e290624
MZ
87#define ARM_SMCCC_ARCH_WORKAROUND_2 \
88 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
89 ARM_SMCCC_SMC_32, \
90 0, 0x7fff)
91
6e085e0a
WD
92#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
93 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
94 ARM_SMCCC_SMC_32, \
95 ARM_SMCCC_OWNER_VENDOR_HYP, \
96 ARM_SMCCC_FUNC_QUERY_CALL_UID)
97
98/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
99#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U
100#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
101#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
102#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
103
104/* KVM "vendor specific" services */
105#define ARM_SMCCC_KVM_FUNC_FEATURES 0
3bf72569 106#define ARM_SMCCC_KVM_FUNC_PTP 1
6e085e0a
WD
107#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
108#define ARM_SMCCC_KVM_NUM_FUNCS 128
109
110#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
111 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
112 ARM_SMCCC_SMC_32, \
113 ARM_SMCCC_OWNER_VENDOR_HYP, \
114 ARM_SMCCC_KVM_FUNC_FEATURES)
115
1de111b5
SB
116#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
117
3bf72569
JW
118/*
119 * ptp_kvm is a feature used for time sync between vm and host.
120 * ptp_kvm module in guest kernel will get service from host using
121 * this hypercall ID.
122 */
123#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
124 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
125 ARM_SMCCC_SMC_32, \
126 ARM_SMCCC_OWNER_VENDOR_HYP, \
127 ARM_SMCCC_KVM_FUNC_PTP)
128
129/* ptp_kvm counter type ID */
130#define KVM_PTP_VIRT_COUNTER 0
131#define KVM_PTP_PHYS_COUNTER 1
132
7af92885
AS
133/* Paravirtualised time calls (defined by ARM DEN0057A) */
134#define ARM_SMCCC_HV_PV_TIME_FEATURES \
135 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
136 ARM_SMCCC_SMC_64, \
137 ARM_SMCCC_OWNER_STANDARD_HYP, \
138 0x20)
139
140#define ARM_SMCCC_HV_PV_TIME_ST \
141 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
142 ARM_SMCCC_SMC_64, \
143 ARM_SMCCC_OWNER_STANDARD_HYP, \
144 0x21)
145
67c6bb56
AB
146/* TRNG entropy source calls (defined by ARM DEN0098) */
147#define ARM_SMCCC_TRNG_VERSION \
148 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
149 ARM_SMCCC_SMC_32, \
150 ARM_SMCCC_OWNER_STANDARD, \
151 0x50)
152
153#define ARM_SMCCC_TRNG_FEATURES \
154 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
155 ARM_SMCCC_SMC_32, \
156 ARM_SMCCC_OWNER_STANDARD, \
157 0x51)
158
159#define ARM_SMCCC_TRNG_GET_UUID \
160 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
161 ARM_SMCCC_SMC_32, \
162 ARM_SMCCC_OWNER_STANDARD, \
163 0x52)
164
165#define ARM_SMCCC_TRNG_RND32 \
166 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
167 ARM_SMCCC_SMC_32, \
168 ARM_SMCCC_OWNER_STANDARD, \
169 0x53)
170
171#define ARM_SMCCC_TRNG_RND64 \
172 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
173 ARM_SMCCC_SMC_64, \
174 ARM_SMCCC_OWNER_STANDARD, \
175 0x53)
176
7af92885
AS
177/*
178 * Return codes defined in ARM DEN 0070A
179 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
180 */
181#define SMCCC_RET_SUCCESS 0
182#define SMCCC_RET_NOT_SUPPORTED -1
183#define SMCCC_RET_NOT_REQUIRED -2
184#define SMCCC_RET_INVALID_PARAMETER -3
185
82bcd087
AG
186#ifndef __ASSEMBLY__
187
188#include <linux/linkage.h>
189#include <linux/types.h>
6b7fe77c
MR
190
191enum arm_smccc_conduit {
192 SMCCC_CONDUIT_NONE,
193 SMCCC_CONDUIT_SMC,
194 SMCCC_CONDUIT_HVC,
195};
196
197/**
198 * arm_smccc_1_1_get_conduit()
199 *
200 * Returns the conduit to be used for SMCCCv1.1 or later.
201 *
202 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
203 */
204enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
205
a4fb1746
SH
206/**
207 * arm_smccc_get_version()
208 *
209 * Returns the version to be used for SMCCCv1.1 or later.
210 *
211 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
212 * does not imply the presence of firmware or a valid conduit. Caller
213 * handling SMCCCv1.0 must determine the conduit by other means.
214 */
215u32 arm_smccc_get_version(void);
216
269fd61e
SH
217void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
218
98dd64f3
JW
219/**
220 * struct arm_smccc_res - Result from SMC/HVC call
221 * @a0-a3 result values from registers 0 to 3
222 */
223struct arm_smccc_res {
224 unsigned long a0;
225 unsigned long a1;
226 unsigned long a2;
227 unsigned long a3;
228};
229
230/**
680a0873
AG
231 * struct arm_smccc_quirk - Contains quirk information
232 * @id: quirk identification
233 * @state: quirk specific information
234 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
235 */
236struct arm_smccc_quirk {
237 int id;
238 union {
239 unsigned long a6;
240 } state;
241};
242
243/**
244 * __arm_smccc_smc() - make SMC calls
98dd64f3
JW
245 * @a0-a7: arguments passed in registers 0 to 7
246 * @res: result values from registers 0 to 3
680a0873 247 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
248 *
249 * This function is used to make SMC calls following SMC Calling Convention.
250 * The content of the supplied param are copied to registers 0 to 7 prior
251 * to the SMC instruction. The return values are updated with the content
680a0873
AG
252 * from register 0 to 3 on return from the SMC instruction. An optional
253 * quirk structure provides vendor specific behavior.
98dd64f3 254 */
680a0873 255asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
98dd64f3
JW
256 unsigned long a2, unsigned long a3, unsigned long a4,
257 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873 258 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
98dd64f3
JW
259
260/**
680a0873 261 * __arm_smccc_hvc() - make HVC calls
98dd64f3
JW
262 * @a0-a7: arguments passed in registers 0 to 7
263 * @res: result values from registers 0 to 3
3046ec67 264 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
265 *
266 * This function is used to make HVC calls following SMC Calling
267 * Convention. The content of the supplied param are copied to registers 0
268 * to 7 prior to the HVC instruction. The return values are updated with
680a0873
AG
269 * the content from register 0 to 3 on return from the HVC instruction. An
270 * optional quirk structure provides vendor specific behavior.
98dd64f3 271 */
680a0873 272asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
98dd64f3
JW
273 unsigned long a2, unsigned long a3, unsigned long a4,
274 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873
AG
275 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
276
277#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
278
279#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
280
281#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
282
283#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
98dd64f3 284
f2d3b2e8
MZ
285/* SMCCC v1.1 implementation madness follows */
286#ifdef CONFIG_ARM64
287
288#define SMCCC_SMC_INST "smc #0"
289#define SMCCC_HVC_INST "hvc #0"
290
291#elif defined(CONFIG_ARM)
292#include <asm/opcodes-sec.h>
293#include <asm/opcodes-virt.h>
294
295#define SMCCC_SMC_INST __SMC(0)
296#define SMCCC_HVC_INST __HVC(0)
297
298#endif
299
300#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
301
302#define __count_args(...) \
303 ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
304
0794a974
AS
305#define __constraint_read_0 "r" (arg0)
306#define __constraint_read_1 __constraint_read_0, "r" (arg1)
307#define __constraint_read_2 __constraint_read_1, "r" (arg2)
308#define __constraint_read_3 __constraint_read_2, "r" (arg3)
309#define __constraint_read_4 __constraint_read_3, "r" (arg4)
310#define __constraint_read_5 __constraint_read_4, "r" (arg5)
311#define __constraint_read_6 __constraint_read_5, "r" (arg6)
312#define __constraint_read_7 __constraint_read_6, "r" (arg7)
f2d3b2e8
MZ
313
314#define __declare_arg_0(a0, res) \
315 struct arm_smccc_res *___res = res; \
0794a974 316 register unsigned long arg0 asm("r0") = (u32)a0
f2d3b2e8
MZ
317
318#define __declare_arg_1(a0, a1, res) \
755a8bf5 319 typeof(a1) __a1 = a1; \
f2d3b2e8 320 struct arm_smccc_res *___res = res; \
0794a974
AS
321 register unsigned long arg0 asm("r0") = (u32)a0; \
322 register typeof(a1) arg1 asm("r1") = __a1
f2d3b2e8
MZ
323
324#define __declare_arg_2(a0, a1, a2, res) \
755a8bf5
MZ
325 typeof(a1) __a1 = a1; \
326 typeof(a2) __a2 = a2; \
f2d3b2e8 327 struct arm_smccc_res *___res = res; \
0794a974
AS
328 register unsigned long arg0 asm("r0") = (u32)a0; \
329 register typeof(a1) arg1 asm("r1") = __a1; \
330 register typeof(a2) arg2 asm("r2") = __a2
f2d3b2e8
MZ
331
332#define __declare_arg_3(a0, a1, a2, a3, res) \
755a8bf5
MZ
333 typeof(a1) __a1 = a1; \
334 typeof(a2) __a2 = a2; \
335 typeof(a3) __a3 = a3; \
f2d3b2e8 336 struct arm_smccc_res *___res = res; \
0794a974
AS
337 register unsigned long arg0 asm("r0") = (u32)a0; \
338 register typeof(a1) arg1 asm("r1") = __a1; \
339 register typeof(a2) arg2 asm("r2") = __a2; \
340 register typeof(a3) arg3 asm("r3") = __a3
f2d3b2e8
MZ
341
342#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
755a8bf5 343 typeof(a4) __a4 = a4; \
f2d3b2e8 344 __declare_arg_3(a0, a1, a2, a3, res); \
0794a974 345 register typeof(a4) arg4 asm("r4") = __a4
f2d3b2e8
MZ
346
347#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
755a8bf5 348 typeof(a5) __a5 = a5; \
f2d3b2e8 349 __declare_arg_4(a0, a1, a2, a3, a4, res); \
0794a974 350 register typeof(a5) arg5 asm("r5") = __a5
f2d3b2e8
MZ
351
352#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
755a8bf5 353 typeof(a6) __a6 = a6; \
f2d3b2e8 354 __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
0794a974 355 register typeof(a6) arg6 asm("r6") = __a6
f2d3b2e8
MZ
356
357#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
755a8bf5 358 typeof(a7) __a7 = a7; \
f2d3b2e8 359 __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
0794a974 360 register typeof(a7) arg7 asm("r7") = __a7
f2d3b2e8
MZ
361
362#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
363#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
364
365#define ___constraints(count) \
f2d3b2e8
MZ
366 : __constraint_read_ ## count \
367 : "memory"
368#define __constraints(count) ___constraints(count)
369
370/*
371 * We have an output list that is not necessarily used, and GCC feels
372 * entitled to optimise the whole sequence away. "volatile" is what
373 * makes it stick.
374 */
375#define __arm_smccc_1_1(inst, ...) \
376 do { \
0794a974
AS
377 register unsigned long r0 asm("r0"); \
378 register unsigned long r1 asm("r1"); \
379 register unsigned long r2 asm("r2"); \
380 register unsigned long r3 asm("r3"); \
f2d3b2e8 381 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
0794a974
AS
382 asm volatile(inst "\n" : \
383 "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
f2d3b2e8
MZ
384 __constraints(__count_args(__VA_ARGS__))); \
385 if (___res) \
386 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
387 } while (0)
388
389/*
390 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
391 *
392 * This is a variadic macro taking one to eight source arguments, and
393 * an optional return structure.
394 *
395 * @a0-a7: arguments passed in registers 0 to 7
396 * @res: result values from registers 0 to 3
397 *
398 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
399 * The content of the supplied param are copied to registers 0 to 7 prior
400 * to the SMC instruction. The return values are updated with the content
401 * from register 0 to 3 on return from the SMC instruction if not NULL.
402 */
403#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
404
405/*
406 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
407 *
408 * This is a variadic macro taking one to eight source arguments, and
409 * an optional return structure.
410 *
411 * @a0-a7: arguments passed in registers 0 to 7
412 * @res: result values from registers 0 to 3
413 *
414 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
415 * The content of the supplied param are copied to registers 0 to 7 prior
416 * to the HVC instruction. The return values are updated with the content
417 * from register 0 to 3 on return from the HVC instruction if not NULL.
418 */
419#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
420
541625ac
SP
421/*
422 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
423 * Used when the SMCCC conduit is not defined. The empty asm statement
424 * avoids compiler warnings about unused variables.
425 */
426#define __fail_smccc_1_1(...) \
427 do { \
428 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
0794a974 429 asm ("" : __constraints(__count_args(__VA_ARGS__))); \
541625ac
SP
430 if (___res) \
431 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
432 } while (0)
433
434/*
435 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
436 *
437 * This is a variadic macro taking one to eight source arguments, and
438 * an optional return structure.
439 *
440 * @a0-a7: arguments passed in registers 0 to 7
441 * @res: result values from registers 0 to 3
442 *
443 * This macro will make either an HVC call or an SMC call depending on the
444 * current SMCCC conduit. If no valid conduit is available then -1
445 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
446 *
447 * The return value also provides the conduit that was used.
448 */
449#define arm_smccc_1_1_invoke(...) ({ \
450 int method = arm_smccc_1_1_get_conduit(); \
451 switch (method) { \
452 case SMCCC_CONDUIT_HVC: \
453 arm_smccc_1_1_hvc(__VA_ARGS__); \
454 break; \
455 case SMCCC_CONDUIT_SMC: \
456 arm_smccc_1_1_smc(__VA_ARGS__); \
457 break; \
458 default: \
459 __fail_smccc_1_1(__VA_ARGS__); \
460 method = SMCCC_CONDUIT_NONE; \
461 break; \
462 } \
463 method; \
464 })
465
82bcd087 466#endif /*__ASSEMBLY__*/
98dd64f3 467#endif /*__LINUX_ARM_SMCCC_H*/