xref: /rk3399_rockchip-uboot/include/linux/arm-smccc.h (revision 4f66e09bb9fbc47b73f67c3cc08ee2663e8fcdb1)
1c2da86f3SMasahiro Yamada /*
2c2da86f3SMasahiro Yamada  * Copyright (c) 2015, Linaro Limited
3c2da86f3SMasahiro Yamada  *
4*c54bcf68SMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0
5c2da86f3SMasahiro Yamada  */
6c2da86f3SMasahiro Yamada #ifndef __LINUX_ARM_SMCCC_H
7c2da86f3SMasahiro Yamada #define __LINUX_ARM_SMCCC_H
8c2da86f3SMasahiro Yamada 
9c2da86f3SMasahiro Yamada /*
10c2da86f3SMasahiro Yamada  * This file provides common defines for ARM SMC Calling Convention as
11c2da86f3SMasahiro Yamada  * specified in
12c2da86f3SMasahiro Yamada  * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
13c2da86f3SMasahiro Yamada  */
14c2da86f3SMasahiro Yamada 
15c2da86f3SMasahiro Yamada #define ARM_SMCCC_STD_CALL		0
16c2da86f3SMasahiro Yamada #define ARM_SMCCC_FAST_CALL		1
17c2da86f3SMasahiro Yamada #define ARM_SMCCC_TYPE_SHIFT		31
18c2da86f3SMasahiro Yamada 
19c2da86f3SMasahiro Yamada #define ARM_SMCCC_SMC_32		0
20c2da86f3SMasahiro Yamada #define ARM_SMCCC_SMC_64		1
21c2da86f3SMasahiro Yamada #define ARM_SMCCC_CALL_CONV_SHIFT	30
22c2da86f3SMasahiro Yamada 
23c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_MASK		0x3F
24c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_SHIFT		24
25c2da86f3SMasahiro Yamada 
26c2da86f3SMasahiro Yamada #define ARM_SMCCC_FUNC_MASK		0xFFFF
27c2da86f3SMasahiro Yamada 
28c2da86f3SMasahiro Yamada #define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
29c2da86f3SMasahiro Yamada 	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
30c2da86f3SMasahiro Yamada #define ARM_SMCCC_IS_64(smc_val) \
31c2da86f3SMasahiro Yamada 	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
32c2da86f3SMasahiro Yamada #define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
33c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_NUM(smc_val) \
34c2da86f3SMasahiro Yamada 	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
35c2da86f3SMasahiro Yamada 
36c2da86f3SMasahiro Yamada #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
37c2da86f3SMasahiro Yamada 	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
38c2da86f3SMasahiro Yamada 	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
39c2da86f3SMasahiro Yamada 	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
40c2da86f3SMasahiro Yamada 	((func_num) & ARM_SMCCC_FUNC_MASK))
41c2da86f3SMasahiro Yamada 
42c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_ARCH		0
43c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_CPU		1
44c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_SIP		2
45c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_OEM		3
46c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_STANDARD	4
47c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_TRUSTED_APP	48
48c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
49c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_TRUSTED_OS	50
50c2da86f3SMasahiro Yamada #define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
51c2da86f3SMasahiro Yamada 
52c2da86f3SMasahiro Yamada #define ARM_SMCCC_QUIRK_NONE		0
53c2da86f3SMasahiro Yamada #define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
54c2da86f3SMasahiro Yamada 
55c2da86f3SMasahiro Yamada #ifndef __ASSEMBLY__
56c2da86f3SMasahiro Yamada 
57c2da86f3SMasahiro Yamada #include <linux/linkage.h>
58c2da86f3SMasahiro Yamada #include <linux/types.h>
59c2da86f3SMasahiro Yamada /**
60c2da86f3SMasahiro Yamada  * struct arm_smccc_res - Result from SMC/HVC call
61c2da86f3SMasahiro Yamada  * @a0-a3 result values from registers 0 to 3
62c2da86f3SMasahiro Yamada  */
63c2da86f3SMasahiro Yamada struct arm_smccc_res {
64c2da86f3SMasahiro Yamada 	unsigned long a0;
65c2da86f3SMasahiro Yamada 	unsigned long a1;
66c2da86f3SMasahiro Yamada 	unsigned long a2;
67c2da86f3SMasahiro Yamada 	unsigned long a3;
68c2da86f3SMasahiro Yamada };
69c2da86f3SMasahiro Yamada 
70c2da86f3SMasahiro Yamada /**
71c2da86f3SMasahiro Yamada  * struct arm_smccc_quirk - Contains quirk information
72c2da86f3SMasahiro Yamada  * @id: quirk identification
73c2da86f3SMasahiro Yamada  * @state: quirk specific information
74c2da86f3SMasahiro Yamada  * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
75c2da86f3SMasahiro Yamada  */
76c2da86f3SMasahiro Yamada struct arm_smccc_quirk {
77c2da86f3SMasahiro Yamada 	int	id;
78c2da86f3SMasahiro Yamada 	union {
79c2da86f3SMasahiro Yamada 		unsigned long a6;
80c2da86f3SMasahiro Yamada 	} state;
81c2da86f3SMasahiro Yamada };
82c2da86f3SMasahiro Yamada 
83c2da86f3SMasahiro Yamada /**
84c2da86f3SMasahiro Yamada  * __arm_smccc_smc() - make SMC calls
85c2da86f3SMasahiro Yamada  * @a0-a7: arguments passed in registers 0 to 7
86c2da86f3SMasahiro Yamada  * @res: result values from registers 0 to 3
87c2da86f3SMasahiro Yamada  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
88c2da86f3SMasahiro Yamada  *
89c2da86f3SMasahiro Yamada  * This function is used to make SMC calls following SMC Calling Convention.
90c2da86f3SMasahiro Yamada  * The content of the supplied param are copied to registers 0 to 7 prior
91c2da86f3SMasahiro Yamada  * to the SMC instruction. The return values are updated with the content
92c2da86f3SMasahiro Yamada  * from register 0 to 3 on return from the SMC instruction.  An optional
93c2da86f3SMasahiro Yamada  * quirk structure provides vendor specific behavior.
94c2da86f3SMasahiro Yamada  */
95c2da86f3SMasahiro Yamada asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
96c2da86f3SMasahiro Yamada 			unsigned long a2, unsigned long a3, unsigned long a4,
97c2da86f3SMasahiro Yamada 			unsigned long a5, unsigned long a6, unsigned long a7,
98c2da86f3SMasahiro Yamada 			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
99c2da86f3SMasahiro Yamada 
100c2da86f3SMasahiro Yamada /**
101c2da86f3SMasahiro Yamada  * __arm_smccc_hvc() - make HVC calls
102c2da86f3SMasahiro Yamada  * @a0-a7: arguments passed in registers 0 to 7
103c2da86f3SMasahiro Yamada  * @res: result values from registers 0 to 3
104c2da86f3SMasahiro Yamada  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
105c2da86f3SMasahiro Yamada  *
106c2da86f3SMasahiro Yamada  * This function is used to make HVC calls following SMC Calling
107c2da86f3SMasahiro Yamada  * Convention.  The content of the supplied param are copied to registers 0
108c2da86f3SMasahiro Yamada  * to 7 prior to the HVC instruction. The return values are updated with
109c2da86f3SMasahiro Yamada  * the content from register 0 to 3 on return from the HVC instruction.  An
110c2da86f3SMasahiro Yamada  * optional quirk structure provides vendor specific behavior.
111c2da86f3SMasahiro Yamada  */
112c2da86f3SMasahiro Yamada asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
113c2da86f3SMasahiro Yamada 			unsigned long a2, unsigned long a3, unsigned long a4,
114c2da86f3SMasahiro Yamada 			unsigned long a5, unsigned long a6, unsigned long a7,
115c2da86f3SMasahiro Yamada 			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
116c2da86f3SMasahiro Yamada 
117c2da86f3SMasahiro Yamada #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
118c2da86f3SMasahiro Yamada 
119c2da86f3SMasahiro Yamada #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
120c2da86f3SMasahiro Yamada 
121c2da86f3SMasahiro Yamada #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
122c2da86f3SMasahiro Yamada 
123c2da86f3SMasahiro Yamada #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
124c2da86f3SMasahiro Yamada 
125c2da86f3SMasahiro Yamada #endif /*__ASSEMBLY__*/
126c2da86f3SMasahiro Yamada #endif /*__LINUX_ARM_SMCCC_H*/
127