1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   * Copyright (c) 2015, Linaro Limited
4   */
5  #ifndef __LINUX_ARM_SMCCC_H
6  #define __LINUX_ARM_SMCCC_H
7  
8  #include <linux/args.h>
9  #include <linux/init.h>
10  #include <uapi/linux/const.h>
11  
12  /*
13   * This file provides common defines for ARM SMC Calling Convention as
14   * specified in
15   * https://developer.arm.com/docs/den0028/latest
16   *
17   * This code is up-to-date with version DEN 0028 C
18   */
19  
20  #define ARM_SMCCC_STD_CALL	        _AC(0,U)
21  #define ARM_SMCCC_FAST_CALL	        _AC(1,U)
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
52  #define ARM_SMCCC_OWNER_STANDARD_HYP	5
53  #define ARM_SMCCC_OWNER_VENDOR_HYP	6
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  
59  #define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff01
60  
61  #define ARM_SMCCC_QUIRK_NONE		0
62  #define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
63  
64  #define ARM_SMCCC_VERSION_1_0		0x10000
65  #define ARM_SMCCC_VERSION_1_1		0x10001
66  #define ARM_SMCCC_VERSION_1_2		0x10002
67  #define ARM_SMCCC_VERSION_1_3		0x10003
68  
69  #define ARM_SMCCC_1_3_SVE_HINT		0x10000
70  #define ARM_SMCCC_CALL_HINTS		ARM_SMCCC_1_3_SVE_HINT
71  
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  
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  
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  
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  
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  
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
117  #define ARM_SMCCC_KVM_FUNC_PTP			1
118  /* Start of pKVM hypercall range */
119  #define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO		2
120  #define ARM_SMCCC_KVM_FUNC_MEM_SHARE		3
121  #define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE		4
122  #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5		5
123  #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6		6
124  #define ARM_SMCCC_KVM_FUNC_MMIO_GUARD		7
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 */
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  
191  #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED	1
192  
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  
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  
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  
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  
228  /* ptp_kvm counter type ID */
229  #define KVM_PTP_VIRT_COUNTER			0
230  #define KVM_PTP_PHYS_COUNTER			1
231  
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  
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  
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  
285  #ifndef __ASSEMBLY__
286  
287  #include <linux/linkage.h>
288  #include <linux/types.h>
289  
290  enum 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   */
303  enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
304  
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   */
314  u32 arm_smccc_get_version(void);
315  
316  void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
317  
318  /**
319   * arm_smccc_get_soc_id_version()
320   *
321   * Returns the SOC ID version.
322   *
323   * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
324   */
325  s32 arm_smccc_get_soc_id_version(void);
326  
327  /**
328   * arm_smccc_get_soc_id_revision()
329   *
330   * Returns the SOC ID revision.
331   *
332   * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
333   */
334  s32 arm_smccc_get_soc_id_revision(void);
335  
336  /**
337   * struct arm_smccc_res - Result from SMC/HVC call
338   * @a0-a3 result values from registers 0 to 3
339   */
340  struct arm_smccc_res {
341  	unsigned long a0;
342  	unsigned long a1;
343  	unsigned long a2;
344  	unsigned long a3;
345  };
346  
347  #ifdef CONFIG_ARM64
348  /**
349   * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
350   * @a0-a17 argument values from registers 0 to 17
351   */
352  struct arm_smccc_1_2_regs {
353  	unsigned long a0;
354  	unsigned long a1;
355  	unsigned long a2;
356  	unsigned long a3;
357  	unsigned long a4;
358  	unsigned long a5;
359  	unsigned long a6;
360  	unsigned long a7;
361  	unsigned long a8;
362  	unsigned long a9;
363  	unsigned long a10;
364  	unsigned long a11;
365  	unsigned long a12;
366  	unsigned long a13;
367  	unsigned long a14;
368  	unsigned long a15;
369  	unsigned long a16;
370  	unsigned long a17;
371  };
372  
373  /**
374   * arm_smccc_1_2_hvc() - make HVC calls
375   * @args: arguments passed via struct arm_smccc_1_2_regs
376   * @res: result values via struct arm_smccc_1_2_regs
377   *
378   * This function is used to make HVC calls following SMC Calling Convention
379   * v1.2 or above. The content of the supplied param are copied from the
380   * structure to registers prior to the HVC instruction. The return values
381   * are updated with the content from registers on return from the HVC
382   * instruction.
383   */
384  asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
385  				  struct arm_smccc_1_2_regs *res);
386  
387  /**
388   * arm_smccc_1_2_smc() - make SMC calls
389   * @args: arguments passed via struct arm_smccc_1_2_regs
390   * @res: result values via struct arm_smccc_1_2_regs
391   *
392   * This function is used to make SMC calls following SMC Calling Convention
393   * v1.2 or above. The content of the supplied param are copied from the
394   * structure to registers prior to the SMC instruction. The return values
395   * are updated with the content from registers on return from the SMC
396   * instruction.
397   */
398  asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
399  				  struct arm_smccc_1_2_regs *res);
400  #endif
401  
402  /**
403   * struct arm_smccc_quirk - Contains quirk information
404   * @id: quirk identification
405   * @state: quirk specific information
406   * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
407   */
408  struct arm_smccc_quirk {
409  	int	id;
410  	union {
411  		unsigned long a6;
412  	} state;
413  };
414  
415  /**
416   * __arm_smccc_smc() - make SMC calls
417   * @a0-a7: arguments passed in registers 0 to 7
418   * @res: result values from registers 0 to 3
419   * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
420   *
421   * This function is used to make SMC calls following SMC Calling Convention.
422   * The content of the supplied param are copied to registers 0 to 7 prior
423   * to the SMC instruction. The return values are updated with the content
424   * from register 0 to 3 on return from the SMC instruction.  An optional
425   * quirk structure provides vendor specific behavior.
426   */
427  #ifdef CONFIG_HAVE_ARM_SMCCC
428  asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
429  			unsigned long a2, unsigned long a3, unsigned long a4,
430  			unsigned long a5, unsigned long a6, unsigned long a7,
431  			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
432  #else
__arm_smccc_smc(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res,struct arm_smccc_quirk * quirk)433  static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
434  			unsigned long a2, unsigned long a3, unsigned long a4,
435  			unsigned long a5, unsigned long a6, unsigned long a7,
436  			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
437  {
438  	*res = (struct arm_smccc_res){};
439  }
440  #endif
441  
442  /**
443   * __arm_smccc_hvc() - make HVC calls
444   * @a0-a7: arguments passed in registers 0 to 7
445   * @res: result values from registers 0 to 3
446   * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
447   *
448   * This function is used to make HVC calls following SMC Calling
449   * Convention.  The content of the supplied param are copied to registers 0
450   * to 7 prior to the HVC instruction. The return values are updated with
451   * the content from register 0 to 3 on return from the HVC instruction.  An
452   * optional quirk structure provides vendor specific behavior.
453   */
454  asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
455  			unsigned long a2, unsigned long a3, unsigned long a4,
456  			unsigned long a5, unsigned long a6, unsigned long a7,
457  			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
458  
459  #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
460  
461  #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
462  
463  #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
464  
465  #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
466  
467  /* SMCCC v1.1 implementation madness follows */
468  #ifdef CONFIG_ARM64
469  
470  #define SMCCC_SMC_INST	"smc	#0"
471  #define SMCCC_HVC_INST	"hvc	#0"
472  
473  #elif defined(CONFIG_ARM)
474  #include <asm/opcodes-sec.h>
475  #include <asm/opcodes-virt.h>
476  
477  #define SMCCC_SMC_INST	__SMC(0)
478  #define SMCCC_HVC_INST	__HVC(0)
479  
480  #endif
481  
482  #define __constraint_read_2	"r" (arg0)
483  #define __constraint_read_3	__constraint_read_2, "r" (arg1)
484  #define __constraint_read_4	__constraint_read_3, "r" (arg2)
485  #define __constraint_read_5	__constraint_read_4, "r" (arg3)
486  #define __constraint_read_6	__constraint_read_5, "r" (arg4)
487  #define __constraint_read_7	__constraint_read_6, "r" (arg5)
488  #define __constraint_read_8	__constraint_read_7, "r" (arg6)
489  #define __constraint_read_9	__constraint_read_8, "r" (arg7)
490  
491  #define __declare_arg_2(a0, res)					\
492  	struct arm_smccc_res   *___res = res;				\
493  	register unsigned long arg0 asm("r0") = (u32)a0
494  
495  #define __declare_arg_3(a0, a1, res)					\
496  	typeof(a1) __a1 = a1;						\
497  	struct arm_smccc_res   *___res = res;				\
498  	register unsigned long arg0 asm("r0") = (u32)a0;			\
499  	register typeof(a1) arg1 asm("r1") = __a1
500  
501  #define __declare_arg_4(a0, a1, a2, res)				\
502  	typeof(a1) __a1 = a1;						\
503  	typeof(a2) __a2 = a2;						\
504  	struct arm_smccc_res   *___res = res;				\
505  	register unsigned long arg0 asm("r0") = (u32)a0;			\
506  	register typeof(a1) arg1 asm("r1") = __a1;			\
507  	register typeof(a2) arg2 asm("r2") = __a2
508  
509  #define __declare_arg_5(a0, a1, a2, a3, res)				\
510  	typeof(a1) __a1 = a1;						\
511  	typeof(a2) __a2 = a2;						\
512  	typeof(a3) __a3 = a3;						\
513  	struct arm_smccc_res   *___res = res;				\
514  	register unsigned long arg0 asm("r0") = (u32)a0;			\
515  	register typeof(a1) arg1 asm("r1") = __a1;			\
516  	register typeof(a2) arg2 asm("r2") = __a2;			\
517  	register typeof(a3) arg3 asm("r3") = __a3
518  
519  #define __declare_arg_6(a0, a1, a2, a3, a4, res)			\
520  	typeof(a4) __a4 = a4;						\
521  	__declare_arg_5(a0, a1, a2, a3, res);				\
522  	register typeof(a4) arg4 asm("r4") = __a4
523  
524  #define __declare_arg_7(a0, a1, a2, a3, a4, a5, res)			\
525  	typeof(a5) __a5 = a5;						\
526  	__declare_arg_6(a0, a1, a2, a3, a4, res);			\
527  	register typeof(a5) arg5 asm("r5") = __a5
528  
529  #define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res)		\
530  	typeof(a6) __a6 = a6;						\
531  	__declare_arg_7(a0, a1, a2, a3, a4, a5, res);			\
532  	register typeof(a6) arg6 asm("r6") = __a6
533  
534  #define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res)		\
535  	typeof(a7) __a7 = a7;						\
536  	__declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res);		\
537  	register typeof(a7) arg7 asm("r7") = __a7
538  
539  /*
540   * We have an output list that is not necessarily used, and GCC feels
541   * entitled to optimise the whole sequence away. "volatile" is what
542   * makes it stick.
543   */
544  #define __arm_smccc_1_1(inst, ...)					\
545  	do {								\
546  		register unsigned long r0 asm("r0");			\
547  		register unsigned long r1 asm("r1");			\
548  		register unsigned long r2 asm("r2");			\
549  		register unsigned long r3 asm("r3"); 			\
550  		CONCATENATE(__declare_arg_,				\
551  			    COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__);	\
552  		asm volatile(inst "\n" :				\
553  			     "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)	\
554  			     : CONCATENATE(__constraint_read_,		\
555  					   COUNT_ARGS(__VA_ARGS__))	\
556  			     : "memory");				\
557  		if (___res)						\
558  			*___res = (typeof(*___res)){r0, r1, r2, r3};	\
559  	} while (0)
560  
561  /*
562   * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
563   *
564   * This is a variadic macro taking one to eight source arguments, and
565   * an optional return structure.
566   *
567   * @a0-a7: arguments passed in registers 0 to 7
568   * @res: result values from registers 0 to 3
569   *
570   * This macro is used to make SMC calls following SMC Calling Convention v1.1.
571   * The content of the supplied param are copied to registers 0 to 7 prior
572   * to the SMC instruction. The return values are updated with the content
573   * from register 0 to 3 on return from the SMC instruction if not NULL.
574   */
575  #define arm_smccc_1_1_smc(...)	__arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
576  
577  /*
578   * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
579   *
580   * This is a variadic macro taking one to eight source arguments, and
581   * an optional return structure.
582   *
583   * @a0-a7: arguments passed in registers 0 to 7
584   * @res: result values from registers 0 to 3
585   *
586   * This macro is used to make HVC calls following SMC Calling Convention v1.1.
587   * The content of the supplied param are copied to registers 0 to 7 prior
588   * to the HVC instruction. The return values are updated with the content
589   * from register 0 to 3 on return from the HVC instruction if not NULL.
590   */
591  #define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
592  
593  /*
594   * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
595   * Used when the SMCCC conduit is not defined. The empty asm statement
596   * avoids compiler warnings about unused variables.
597   */
598  #define __fail_smccc_1_1(...)						\
599  	do {								\
600  		CONCATENATE(__declare_arg_,				\
601  			    COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__);	\
602  		asm ("" :						\
603  		     : CONCATENATE(__constraint_read_,			\
604  				   COUNT_ARGS(__VA_ARGS__))		\
605  		     : "memory");					\
606  		if (___res)						\
607  			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
608  	} while (0)
609  
610  /*
611   * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
612   *
613   * This is a variadic macro taking one to eight source arguments, and
614   * an optional return structure.
615   *
616   * @a0-a7: arguments passed in registers 0 to 7
617   * @res: result values from registers 0 to 3
618   *
619   * This macro will make either an HVC call or an SMC call depending on the
620   * current SMCCC conduit. If no valid conduit is available then -1
621   * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
622   *
623   * The return value also provides the conduit that was used.
624   */
625  #define arm_smccc_1_1_invoke(...) ({					\
626  		int method = arm_smccc_1_1_get_conduit();		\
627  		switch (method) {					\
628  		case SMCCC_CONDUIT_HVC:					\
629  			arm_smccc_1_1_hvc(__VA_ARGS__);			\
630  			break;						\
631  		case SMCCC_CONDUIT_SMC:					\
632  			arm_smccc_1_1_smc(__VA_ARGS__);			\
633  			break;						\
634  		default:						\
635  			__fail_smccc_1_1(__VA_ARGS__);			\
636  			method = SMCCC_CONDUIT_NONE;			\
637  			break;						\
638  		}							\
639  		method;							\
640  	})
641  
642  #endif /*__ASSEMBLY__*/
643  #endif /*__LINUX_ARM_SMCCC_H*/
644