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