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