ARM: OMAP2: Use custom soc attribute group instead of device_create_file
[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
98dd64f3
JW
52#define ARM_SMCCC_OWNER_TRUSTED_APP 48
53#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
54#define ARM_SMCCC_OWNER_TRUSTED_OS 50
55#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
56
82bcd087
AG
57#define ARM_SMCCC_QUIRK_NONE 0
58#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
59
09e6be12
MZ
60#define ARM_SMCCC_VERSION_1_0 0x10000
61#define ARM_SMCCC_VERSION_1_1 0x10001
0441bfe7 62#define ARM_SMCCC_VERSION_1_2 0x10002
09e6be12
MZ
63
64#define ARM_SMCCC_VERSION_FUNC_ID \
65 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
66 ARM_SMCCC_SMC_32, \
67 0, 0)
68
69#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
70 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
71 ARM_SMCCC_SMC_32, \
72 0, 1)
73
6167ec5c
MZ
74#define ARM_SMCCC_ARCH_WORKAROUND_1 \
75 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
76 ARM_SMCCC_SMC_32, \
77 0, 0x8000)
78
8e290624
MZ
79#define ARM_SMCCC_ARCH_WORKAROUND_2 \
80 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
81 ARM_SMCCC_SMC_32, \
82 0, 0x7fff)
83
82bcd087
AG
84#ifndef __ASSEMBLY__
85
86#include <linux/linkage.h>
87#include <linux/types.h>
6b7fe77c
MR
88
89enum arm_smccc_conduit {
90 SMCCC_CONDUIT_NONE,
91 SMCCC_CONDUIT_SMC,
92 SMCCC_CONDUIT_HVC,
93};
94
95/**
96 * arm_smccc_1_1_get_conduit()
97 *
98 * Returns the conduit to be used for SMCCCv1.1 or later.
99 *
100 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
101 */
102enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
103
a4fb1746
SH
104/**
105 * arm_smccc_get_version()
106 *
107 * Returns the version to be used for SMCCCv1.1 or later.
108 *
109 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
110 * does not imply the presence of firmware or a valid conduit. Caller
111 * handling SMCCCv1.0 must determine the conduit by other means.
112 */
113u32 arm_smccc_get_version(void);
114
269fd61e
SH
115void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
116
98dd64f3
JW
117/**
118 * struct arm_smccc_res - Result from SMC/HVC call
119 * @a0-a3 result values from registers 0 to 3
120 */
121struct arm_smccc_res {
122 unsigned long a0;
123 unsigned long a1;
124 unsigned long a2;
125 unsigned long a3;
126};
127
128/**
680a0873
AG
129 * struct arm_smccc_quirk - Contains quirk information
130 * @id: quirk identification
131 * @state: quirk specific information
132 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
133 */
134struct arm_smccc_quirk {
135 int id;
136 union {
137 unsigned long a6;
138 } state;
139};
140
141/**
142 * __arm_smccc_smc() - make SMC calls
98dd64f3
JW
143 * @a0-a7: arguments passed in registers 0 to 7
144 * @res: result values from registers 0 to 3
680a0873 145 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
146 *
147 * This function is used to make SMC calls following SMC Calling Convention.
148 * The content of the supplied param are copied to registers 0 to 7 prior
149 * to the SMC instruction. The return values are updated with the content
680a0873
AG
150 * from register 0 to 3 on return from the SMC instruction. An optional
151 * quirk structure provides vendor specific behavior.
98dd64f3 152 */
680a0873 153asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
98dd64f3
JW
154 unsigned long a2, unsigned long a3, unsigned long a4,
155 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873 156 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
98dd64f3
JW
157
158/**
680a0873 159 * __arm_smccc_hvc() - make HVC calls
98dd64f3
JW
160 * @a0-a7: arguments passed in registers 0 to 7
161 * @res: result values from registers 0 to 3
3046ec67 162 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
163 *
164 * This function is used to make HVC calls following SMC Calling
165 * Convention. The content of the supplied param are copied to registers 0
166 * to 7 prior to the HVC instruction. The return values are updated with
680a0873
AG
167 * the content from register 0 to 3 on return from the HVC instruction. An
168 * optional quirk structure provides vendor specific behavior.
98dd64f3 169 */
680a0873 170asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
98dd64f3
JW
171 unsigned long a2, unsigned long a3, unsigned long a4,
172 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873
AG
173 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
174
175#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
176
177#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
178
179#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
180
181#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
98dd64f3 182
f2d3b2e8
MZ
183/* SMCCC v1.1 implementation madness follows */
184#ifdef CONFIG_ARM64
185
186#define SMCCC_SMC_INST "smc #0"
187#define SMCCC_HVC_INST "hvc #0"
188
189#elif defined(CONFIG_ARM)
190#include <asm/opcodes-sec.h>
191#include <asm/opcodes-virt.h>
192
193#define SMCCC_SMC_INST __SMC(0)
194#define SMCCC_HVC_INST __HVC(0)
195
196#endif
197
198#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
199
200#define __count_args(...) \
201 ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
202
203#define __constraint_write_0 \
204 "+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3)
205#define __constraint_write_1 \
206 "+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3)
207#define __constraint_write_2 \
208 "+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3)
209#define __constraint_write_3 \
210 "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3)
211#define __constraint_write_4 __constraint_write_3
212#define __constraint_write_5 __constraint_write_4
213#define __constraint_write_6 __constraint_write_5
214#define __constraint_write_7 __constraint_write_6
215
216#define __constraint_read_0
217#define __constraint_read_1
218#define __constraint_read_2
219#define __constraint_read_3
220#define __constraint_read_4 "r" (r4)
221#define __constraint_read_5 __constraint_read_4, "r" (r5)
222#define __constraint_read_6 __constraint_read_5, "r" (r6)
223#define __constraint_read_7 __constraint_read_6, "r" (r7)
224
225#define __declare_arg_0(a0, res) \
226 struct arm_smccc_res *___res = res; \
1d8f5747 227 register unsigned long r0 asm("r0") = (u32)a0; \
f2d3b2e8
MZ
228 register unsigned long r1 asm("r1"); \
229 register unsigned long r2 asm("r2"); \
230 register unsigned long r3 asm("r3")
231
232#define __declare_arg_1(a0, a1, res) \
755a8bf5 233 typeof(a1) __a1 = a1; \
f2d3b2e8 234 struct arm_smccc_res *___res = res; \
1d8f5747 235 register unsigned long r0 asm("r0") = (u32)a0; \
755a8bf5 236 register unsigned long r1 asm("r1") = __a1; \
f2d3b2e8
MZ
237 register unsigned long r2 asm("r2"); \
238 register unsigned long r3 asm("r3")
239
240#define __declare_arg_2(a0, a1, a2, res) \
755a8bf5
MZ
241 typeof(a1) __a1 = a1; \
242 typeof(a2) __a2 = a2; \
f2d3b2e8 243 struct arm_smccc_res *___res = res; \
1d8f5747 244 register unsigned long r0 asm("r0") = (u32)a0; \
755a8bf5
MZ
245 register unsigned long r1 asm("r1") = __a1; \
246 register unsigned long r2 asm("r2") = __a2; \
f2d3b2e8
MZ
247 register unsigned long r3 asm("r3")
248
249#define __declare_arg_3(a0, a1, a2, a3, res) \
755a8bf5
MZ
250 typeof(a1) __a1 = a1; \
251 typeof(a2) __a2 = a2; \
252 typeof(a3) __a3 = a3; \
f2d3b2e8 253 struct arm_smccc_res *___res = res; \
1d8f5747 254 register unsigned long r0 asm("r0") = (u32)a0; \
755a8bf5
MZ
255 register unsigned long r1 asm("r1") = __a1; \
256 register unsigned long r2 asm("r2") = __a2; \
257 register unsigned long r3 asm("r3") = __a3
f2d3b2e8
MZ
258
259#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
755a8bf5 260 typeof(a4) __a4 = a4; \
f2d3b2e8 261 __declare_arg_3(a0, a1, a2, a3, res); \
755a8bf5 262 register unsigned long r4 asm("r4") = __a4
f2d3b2e8
MZ
263
264#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
755a8bf5 265 typeof(a5) __a5 = a5; \
f2d3b2e8 266 __declare_arg_4(a0, a1, a2, a3, a4, res); \
755a8bf5 267 register unsigned long r5 asm("r5") = __a5
f2d3b2e8
MZ
268
269#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
755a8bf5 270 typeof(a6) __a6 = a6; \
f2d3b2e8 271 __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
755a8bf5 272 register unsigned long r6 asm("r6") = __a6
f2d3b2e8
MZ
273
274#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
755a8bf5 275 typeof(a7) __a7 = a7; \
f2d3b2e8 276 __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
755a8bf5 277 register unsigned long r7 asm("r7") = __a7
f2d3b2e8
MZ
278
279#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
280#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
281
282#define ___constraints(count) \
283 : __constraint_write_ ## count \
284 : __constraint_read_ ## count \
285 : "memory"
286#define __constraints(count) ___constraints(count)
287
288/*
289 * We have an output list that is not necessarily used, and GCC feels
290 * entitled to optimise the whole sequence away. "volatile" is what
291 * makes it stick.
292 */
293#define __arm_smccc_1_1(inst, ...) \
294 do { \
295 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
296 asm volatile(inst "\n" \
297 __constraints(__count_args(__VA_ARGS__))); \
298 if (___res) \
299 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
300 } while (0)
301
302/*
303 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
304 *
305 * This is a variadic macro taking one to eight source arguments, and
306 * an optional return structure.
307 *
308 * @a0-a7: arguments passed in registers 0 to 7
309 * @res: result values from registers 0 to 3
310 *
311 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
312 * The content of the supplied param are copied to registers 0 to 7 prior
313 * to the SMC instruction. The return values are updated with the content
314 * from register 0 to 3 on return from the SMC instruction if not NULL.
315 */
316#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
317
318/*
319 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
320 *
321 * This is a variadic macro taking one to eight source arguments, and
322 * an optional return structure.
323 *
324 * @a0-a7: arguments passed in registers 0 to 7
325 * @res: result values from registers 0 to 3
326 *
327 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
328 * The content of the supplied param are copied to registers 0 to 7 prior
329 * to the HVC instruction. The return values are updated with the content
330 * from register 0 to 3 on return from the HVC instruction if not NULL.
331 */
332#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
333
0441bfe7
SH
334/*
335 * Return codes defined in ARM DEN 0070A
336 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
337 */
eff0e9e1
MZ
338#define SMCCC_RET_SUCCESS 0
339#define SMCCC_RET_NOT_SUPPORTED -1
340#define SMCCC_RET_NOT_REQUIRED -2
0441bfe7 341#define SMCCC_RET_INVALID_PARAMETER -3
eff0e9e1 342
541625ac
SP
343/*
344 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
345 * Used when the SMCCC conduit is not defined. The empty asm statement
346 * avoids compiler warnings about unused variables.
347 */
348#define __fail_smccc_1_1(...) \
349 do { \
350 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
351 asm ("" __constraints(__count_args(__VA_ARGS__))); \
352 if (___res) \
353 ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
354 } while (0)
355
356/*
357 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
358 *
359 * This is a variadic macro taking one to eight source arguments, and
360 * an optional return structure.
361 *
362 * @a0-a7: arguments passed in registers 0 to 7
363 * @res: result values from registers 0 to 3
364 *
365 * This macro will make either an HVC call or an SMC call depending on the
366 * current SMCCC conduit. If no valid conduit is available then -1
367 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
368 *
369 * The return value also provides the conduit that was used.
370 */
371#define arm_smccc_1_1_invoke(...) ({ \
372 int method = arm_smccc_1_1_get_conduit(); \
373 switch (method) { \
374 case SMCCC_CONDUIT_HVC: \
375 arm_smccc_1_1_hvc(__VA_ARGS__); \
376 break; \
377 case SMCCC_CONDUIT_SMC: \
378 arm_smccc_1_1_smc(__VA_ARGS__); \
379 break; \
380 default: \
381 __fail_smccc_1_1(__VA_ARGS__); \
382 method = SMCCC_CONDUIT_NONE; \
383 break; \
384 } \
385 method; \
386 })
387
b48c1a45
SP
388/* Paravirtualised time calls (defined by ARM DEN0057A) */
389#define ARM_SMCCC_HV_PV_TIME_FEATURES \
390 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
391 ARM_SMCCC_SMC_64, \
392 ARM_SMCCC_OWNER_STANDARD_HYP, \
393 0x20)
394
395#define ARM_SMCCC_HV_PV_TIME_ST \
396 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
397 ARM_SMCCC_SMC_64, \
398 ARM_SMCCC_OWNER_STANDARD_HYP, \
399 0x21)
400
82bcd087 401#endif /*__ASSEMBLY__*/
98dd64f3 402#endif /*__LINUX_ARM_SMCCC_H*/