]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - include/linux/arm-smccc.h
mm/hotplug: invalid PFNs from pfn_to_online_page()
[mirror_ubuntu-bionic-kernel.git] / include / linux / arm-smccc.h
CommitLineData
98dd64f3
JW
1/*
2 * Copyright (c) 2015, Linaro Limited
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14#ifndef __LINUX_ARM_SMCCC_H
15#define __LINUX_ARM_SMCCC_H
16
e391aa59
MZ
17#include <uapi/linux/const.h>
18
98dd64f3
JW
19/*
20 * This file provides common defines for ARM SMC Calling Convention as
21 * specified in
22 * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
23 */
24
e391aa59
MZ
25#define ARM_SMCCC_STD_CALL _AC(0,U)
26#define ARM_SMCCC_FAST_CALL _AC(1,U)
98dd64f3
JW
27#define ARM_SMCCC_TYPE_SHIFT 31
28
29#define ARM_SMCCC_SMC_32 0
30#define ARM_SMCCC_SMC_64 1
31#define ARM_SMCCC_CALL_CONV_SHIFT 30
32
33#define ARM_SMCCC_OWNER_MASK 0x3F
34#define ARM_SMCCC_OWNER_SHIFT 24
35
36#define ARM_SMCCC_FUNC_MASK 0xFFFF
37
38#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
39 ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
40#define ARM_SMCCC_IS_64(smc_val) \
41 ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
42#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
43#define ARM_SMCCC_OWNER_NUM(smc_val) \
44 (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
45
46#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
47 (((type) << ARM_SMCCC_TYPE_SHIFT) | \
48 ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
49 (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
50 ((func_num) & ARM_SMCCC_FUNC_MASK))
51
52#define ARM_SMCCC_OWNER_ARCH 0
53#define ARM_SMCCC_OWNER_CPU 1
54#define ARM_SMCCC_OWNER_SIP 2
55#define ARM_SMCCC_OWNER_OEM 3
56#define ARM_SMCCC_OWNER_STANDARD 4
57#define ARM_SMCCC_OWNER_TRUSTED_APP 48
58#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
59#define ARM_SMCCC_OWNER_TRUSTED_OS 50
60#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
61
82bcd087
AG
62#define ARM_SMCCC_QUIRK_NONE 0
63#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
64
7b5b30e9
MZ
65#define ARM_SMCCC_VERSION_1_0 0x10000
66#define ARM_SMCCC_VERSION_1_1 0x10001
67
68#define ARM_SMCCC_VERSION_FUNC_ID \
69 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
70 ARM_SMCCC_SMC_32, \
71 0, 0)
72
73#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
74 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
75 ARM_SMCCC_SMC_32, \
76 0, 1)
77
d5a70971
MZ
78#define ARM_SMCCC_ARCH_WORKAROUND_1 \
79 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
80 ARM_SMCCC_SMC_32, \
81 0, 0x8000)
82
4a07468f
MZ
83#define ARM_SMCCC_ARCH_WORKAROUND_2 \
84 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
85 ARM_SMCCC_SMC_32, \
86 0, 0x7fff)
87
82bcd087
AG
88#ifndef __ASSEMBLY__
89
90#include <linux/linkage.h>
91#include <linux/types.h>
98dd64f3
JW
92/**
93 * struct arm_smccc_res - Result from SMC/HVC call
94 * @a0-a3 result values from registers 0 to 3
95 */
96struct arm_smccc_res {
97 unsigned long a0;
98 unsigned long a1;
99 unsigned long a2;
100 unsigned long a3;
101};
102
103/**
680a0873
AG
104 * struct arm_smccc_quirk - Contains quirk information
105 * @id: quirk identification
106 * @state: quirk specific information
107 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
108 */
109struct arm_smccc_quirk {
110 int id;
111 union {
112 unsigned long a6;
113 } state;
114};
115
116/**
117 * __arm_smccc_smc() - make SMC calls
98dd64f3
JW
118 * @a0-a7: arguments passed in registers 0 to 7
119 * @res: result values from registers 0 to 3
680a0873 120 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
121 *
122 * This function is used to make SMC calls following SMC Calling Convention.
123 * The content of the supplied param are copied to registers 0 to 7 prior
124 * to the SMC instruction. The return values are updated with the content
680a0873
AG
125 * from register 0 to 3 on return from the SMC instruction. An optional
126 * quirk structure provides vendor specific behavior.
98dd64f3 127 */
680a0873 128asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
98dd64f3
JW
129 unsigned long a2, unsigned long a3, unsigned long a4,
130 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873 131 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
98dd64f3
JW
132
133/**
680a0873 134 * __arm_smccc_hvc() - make HVC calls
98dd64f3
JW
135 * @a0-a7: arguments passed in registers 0 to 7
136 * @res: result values from registers 0 to 3
3046ec67 137 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
98dd64f3
JW
138 *
139 * This function is used to make HVC calls following SMC Calling
140 * Convention. The content of the supplied param are copied to registers 0
141 * to 7 prior to the HVC instruction. The return values are updated with
680a0873
AG
142 * the content from register 0 to 3 on return from the HVC instruction. An
143 * optional quirk structure provides vendor specific behavior.
98dd64f3 144 */
680a0873 145asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
98dd64f3
JW
146 unsigned long a2, unsigned long a3, unsigned long a4,
147 unsigned long a5, unsigned long a6, unsigned long a7,
680a0873
AG
148 struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
149
150#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
151
152#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
153
154#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
155
156#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
98dd64f3 157
79cead80
MZ
158/* SMCCC v1.1 implementation madness follows */
159#ifdef CONFIG_ARM64
160
161#define SMCCC_SMC_INST "smc #0"
162#define SMCCC_HVC_INST "hvc #0"
163
164#elif defined(CONFIG_ARM)
165#include <asm/opcodes-sec.h>
166#include <asm/opcodes-virt.h>
167
168#define SMCCC_SMC_INST __SMC(0)
169#define SMCCC_HVC_INST __HVC(0)
170
171#endif
172
173#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
174
175#define __count_args(...) \
176 ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
177
178#define __constraint_write_0 \
179 "+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3)
180#define __constraint_write_1 \
181 "+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3)
182#define __constraint_write_2 \
183 "+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3)
184#define __constraint_write_3 \
185 "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3)
186#define __constraint_write_4 __constraint_write_3
187#define __constraint_write_5 __constraint_write_4
188#define __constraint_write_6 __constraint_write_5
189#define __constraint_write_7 __constraint_write_6
190
191#define __constraint_read_0
192#define __constraint_read_1
193#define __constraint_read_2
194#define __constraint_read_3
195#define __constraint_read_4 "r" (r4)
196#define __constraint_read_5 __constraint_read_4, "r" (r5)
197#define __constraint_read_6 __constraint_read_5, "r" (r6)
198#define __constraint_read_7 __constraint_read_6, "r" (r7)
199
200#define __declare_arg_0(a0, res) \
201 struct arm_smccc_res *___res = res; \
2d95dcda 202 register unsigned long r0 asm("r0") = (u32)a0; \
79cead80
MZ
203 register unsigned long r1 asm("r1"); \
204 register unsigned long r2 asm("r2"); \
205 register unsigned long r3 asm("r3")
206
207#define __declare_arg_1(a0, a1, res) \
d9bdf96d 208 typeof(a1) __a1 = a1; \
79cead80 209 struct arm_smccc_res *___res = res; \
2d95dcda 210 register unsigned long r0 asm("r0") = (u32)a0; \
d9bdf96d 211 register unsigned long r1 asm("r1") = __a1; \
79cead80
MZ
212 register unsigned long r2 asm("r2"); \
213 register unsigned long r3 asm("r3")
214
215#define __declare_arg_2(a0, a1, a2, res) \
d9bdf96d
MZ
216 typeof(a1) __a1 = a1; \
217 typeof(a2) __a2 = a2; \
79cead80 218 struct arm_smccc_res *___res = res; \
2d95dcda 219 register unsigned long r0 asm("r0") = (u32)a0; \
d9bdf96d
MZ
220 register unsigned long r1 asm("r1") = __a1; \
221 register unsigned long r2 asm("r2") = __a2; \
79cead80
MZ
222 register unsigned long r3 asm("r3")
223
224#define __declare_arg_3(a0, a1, a2, a3, res) \
d9bdf96d
MZ
225 typeof(a1) __a1 = a1; \
226 typeof(a2) __a2 = a2; \
227 typeof(a3) __a3 = a3; \
79cead80 228 struct arm_smccc_res *___res = res; \
2d95dcda 229 register unsigned long r0 asm("r0") = (u32)a0; \
d9bdf96d
MZ
230 register unsigned long r1 asm("r1") = __a1; \
231 register unsigned long r2 asm("r2") = __a2; \
232 register unsigned long r3 asm("r3") = __a3
79cead80
MZ
233
234#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
d9bdf96d 235 typeof(a4) __a4 = a4; \
79cead80 236 __declare_arg_3(a0, a1, a2, a3, res); \
d9bdf96d 237 register unsigned long r4 asm("r4") = __a4
79cead80
MZ
238
239#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
d9bdf96d 240 typeof(a5) __a5 = a5; \
79cead80 241 __declare_arg_4(a0, a1, a2, a3, a4, res); \
d9bdf96d 242 register unsigned long r5 asm("r5") = __a5
79cead80
MZ
243
244#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
d9bdf96d 245 typeof(a6) __a6 = a6; \
79cead80 246 __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
d9bdf96d 247 register unsigned long r6 asm("r6") = __a6
79cead80
MZ
248
249#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
d9bdf96d 250 typeof(a7) __a7 = a7; \
79cead80 251 __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
d9bdf96d 252 register unsigned long r7 asm("r7") = __a7
79cead80
MZ
253
254#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
255#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
256
257#define ___constraints(count) \
258 : __constraint_write_ ## count \
259 : __constraint_read_ ## count \
260 : "memory"
261#define __constraints(count) ___constraints(count)
262
263/*
264 * We have an output list that is not necessarily used, and GCC feels
265 * entitled to optimise the whole sequence away. "volatile" is what
266 * makes it stick.
267 */
268#define __arm_smccc_1_1(inst, ...) \
269 do { \
270 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
271 asm volatile(inst "\n" \
272 __constraints(__count_args(__VA_ARGS__))); \
273 if (___res) \
274 *___res = (typeof(*___res)){r0, r1, r2, r3}; \
275 } while (0)
276
277/*
278 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
279 *
280 * This is a variadic macro taking one to eight source arguments, and
281 * an optional return structure.
282 *
283 * @a0-a7: arguments passed in registers 0 to 7
284 * @res: result values from registers 0 to 3
285 *
286 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
287 * The content of the supplied param are copied to registers 0 to 7 prior
288 * to the SMC instruction. The return values are updated with the content
289 * from register 0 to 3 on return from the SMC instruction if not NULL.
290 */
291#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
292
293/*
294 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
295 *
296 * This is a variadic macro taking one to eight source arguments, and
297 * an optional return structure.
298 *
299 * @a0-a7: arguments passed in registers 0 to 7
300 * @res: result values from registers 0 to 3
301 *
302 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
303 * The content of the supplied param are copied to registers 0 to 7 prior
304 * to the HVC instruction. The return values are updated with the content
305 * from register 0 to 3 on return from the HVC instruction if not NULL.
306 */
307#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
308
f2ad53c9
MZ
309/* Return codes defined in ARM DEN 0070A */
310#define SMCCC_RET_SUCCESS 0
311#define SMCCC_RET_NOT_SUPPORTED -1
312#define SMCCC_RET_NOT_REQUIRED -2
313
82bcd087 314#endif /*__ASSEMBLY__*/
98dd64f3 315#endif /*__LINUX_ARM_SMCCC_H*/