1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
5  *
6  * Authors:
7  *   Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
8  */
9 #ifndef __LINUX_ARM_SMCCC_H
10 #define __LINUX_ARM_SMCCC_H
11 
12 /*
13  * This file provides common defines for ARM SMC Calling Convention as
14  * specified in
15  * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
16  */
17 
18 #define ARM_SMCCC_STD_CALL		0UL
19 #define ARM_SMCCC_FAST_CALL		1UL
20 #define ARM_SMCCC_TYPE_SHIFT		31
21 
22 #define ARM_SMCCC_SMC_32		0
23 #define ARM_SMCCC_SMC_64		1
24 #define ARM_SMCCC_CALL_CONV_SHIFT	30
25 
26 #define ARM_SMCCC_OWNER_MASK		0x3F
27 #define ARM_SMCCC_OWNER_SHIFT		24
28 
29 #define ARM_SMCCC_FUNC_MASK		0xFFFF
30 
31 #define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
32 	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
33 #define ARM_SMCCC_IS_64(smc_val) \
34 	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
35 #define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
36 #define ARM_SMCCC_OWNER_NUM(smc_val) \
37 	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
38 
39 #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
40 	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
41 	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
42 	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
43 	((func_num) & ARM_SMCCC_FUNC_MASK))
44 
45 #define ARM_SMCCC_OWNER_ARCH		0
46 #define ARM_SMCCC_OWNER_CPU		1
47 #define ARM_SMCCC_OWNER_SIP		2
48 #define ARM_SMCCC_OWNER_OEM		3
49 #define ARM_SMCCC_OWNER_STANDARD	4
50 #define ARM_SMCCC_OWNER_TRUSTED_APP	48
51 #define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
52 #define ARM_SMCCC_OWNER_TRUSTED_OS	50
53 #define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
54 
55 #define ARM_SMCCC_QUIRK_NONE		0
56 #define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
57 
58 #define ARM_SMCCC_VERSION		0x80000000
59 #define ARM_SMCCC_ARCH_FEATURES		0x80000001
60 
61 #define ARM_SMCCC_VERSION_1_0		0x10000
62 #define ARM_SMCCC_VERSION_1_1		0x10001
63 #define ARM_SMCCC_VERSION_1_2		0x10002
64 #define ARM_SMCCC_VERSION_1_3		0x10003
65 
66 #define ARM_SMCCC_RET_NOT_SUPPORTED	((unsigned long)-1)
67 
68 #ifndef __ASSEMBLY__
69 
70 #include <linux/linkage.h>
71 #include <linux/types.h>
72 /**
73  * struct arm_smccc_res - Result from SMC/HVC call
74  * @a0-a3 result values from registers 0 to 3
75  */
76 struct arm_smccc_res {
77 	unsigned long a0;
78 	unsigned long a1;
79 	unsigned long a2;
80 	unsigned long a3;
81 };
82 
83 #ifdef CONFIG_ARM64
84 /**
85  * struct arm_smccc_1_2_regs - Arguments for or Results from SMC call
86  * @a0-a17 argument values from registers 0 to 17
87  */
88 struct arm_smccc_1_2_regs {
89 	unsigned long a0;
90 	unsigned long a1;
91 	unsigned long a2;
92 	unsigned long a3;
93 	unsigned long a4;
94 	unsigned long a5;
95 	unsigned long a6;
96 	unsigned long a7;
97 	unsigned long a8;
98 	unsigned long a9;
99 	unsigned long a10;
100 	unsigned long a11;
101 	unsigned long a12;
102 	unsigned long a13;
103 	unsigned long a14;
104 	unsigned long a15;
105 	unsigned long a16;
106 	unsigned long a17;
107 };
108 
109 /**
110  * arm_smccc_1_2_smc() - make SMC calls
111  * @args: arguments passed via struct arm_smccc_1_2_regs
112  * @res: result values via struct arm_smccc_1_2_regs
113  *
114  * This function is used to make SMC calls following SMC Calling Convention
115  * v1.2 or above. The content of the supplied param are copied from the
116  * structure to registers prior to the SMC instruction. The return values
117  * are updated with the content from registers on return from the SMC
118  * instruction.
119  */
120 asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
121 				  struct arm_smccc_1_2_regs *res);
122 #endif
123 
124 /**
125  * struct arm_smccc_quirk - Contains quirk information
126  * @id: quirk identification
127  * @state: quirk specific information
128  * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
129  */
130 struct arm_smccc_quirk {
131 	int	id;
132 	union {
133 		unsigned long a6;
134 	} state;
135 };
136 
137 /**
138  * struct arm_smccc_feature - Driver registration data for discoverable feature
139  * @driver_name: name of the driver relate to the SMCCC feature
140  * @is_supported: callback to test if SMCCC feature is supported
141  */
142 struct arm_smccc_feature {
143 	const char *driver_name;
144 	bool (*is_supported)(void (*invoke_fn)(unsigned long a0, unsigned long a1, unsigned long a2,
145 					       unsigned long a3, unsigned long a4, unsigned long a5,
146 					       unsigned long a6, unsigned long a7,
147 					       struct arm_smccc_res *res));
148 };
149 
150 #define ARM_SMCCC_FEATURE_DRIVER(__name) \
151 	ll_entry_declare(struct arm_smccc_feature, __name, arm_smccc_feature)
152 
153 /**
154  * __arm_smccc_smc() - make SMC calls
155  * @a0-a7: arguments passed in registers 0 to 7
156  * @res: result values from registers 0 to 3
157  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
158  *
159  * This function is used to make SMC calls following SMC Calling Convention.
160  * The content of the supplied param are copied to registers 0 to 7 prior
161  * to the SMC instruction. The return values are updated with the content
162  * from register 0 to 3 on return from the SMC instruction.  An optional
163  * quirk structure provides vendor specific behavior.
164  */
165 asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
166 			unsigned long a2, unsigned long a3, unsigned long a4,
167 			unsigned long a5, unsigned long a6, unsigned long a7,
168 			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
169 
170 /**
171  * __arm_smccc_hvc() - make HVC calls
172  * @a0-a7: arguments passed in registers 0 to 7
173  * @res: result values from registers 0 to 3
174  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
175  *
176  * This function is used to make HVC calls following SMC Calling
177  * Convention.  The content of the supplied param are copied to registers 0
178  * to 7 prior to the HVC instruction. The return values are updated with
179  * the content from register 0 to 3 on return from the HVC instruction.  An
180  * optional quirk structure provides vendor specific behavior.
181  */
182 asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
183 			unsigned long a2, unsigned long a3, unsigned long a4,
184 			unsigned long a5, unsigned long a6, unsigned long a7,
185 			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
186 
187 #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
188 
189 #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
190 
191 #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
192 
193 #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
194 
195 #endif /*__ASSEMBLY__*/
196 #endif /*__LINUX_ARM_SMCCC_H*/
197