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