root/include/linux/arm-smccc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   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 <uapi/linux/const.h>
   9 
  10 /*
  11  * This file provides common defines for ARM SMC Calling Convention as
  12  * specified in
  13  * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
  14  */
  15 
  16 #define ARM_SMCCC_STD_CALL              _AC(0,U)
  17 #define ARM_SMCCC_FAST_CALL             _AC(1,U)
  18 #define ARM_SMCCC_TYPE_SHIFT            31
  19 
  20 #define ARM_SMCCC_SMC_32                0
  21 #define ARM_SMCCC_SMC_64                1
  22 #define ARM_SMCCC_CALL_CONV_SHIFT       30
  23 
  24 #define ARM_SMCCC_OWNER_MASK            0x3F
  25 #define ARM_SMCCC_OWNER_SHIFT           24
  26 
  27 #define ARM_SMCCC_FUNC_MASK             0xFFFF
  28 
  29 #define ARM_SMCCC_IS_FAST_CALL(smc_val) \
  30         ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
  31 #define ARM_SMCCC_IS_64(smc_val) \
  32         ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
  33 #define ARM_SMCCC_FUNC_NUM(smc_val)     ((smc_val) & ARM_SMCCC_FUNC_MASK)
  34 #define ARM_SMCCC_OWNER_NUM(smc_val) \
  35         (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
  36 
  37 #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
  38         (((type) << ARM_SMCCC_TYPE_SHIFT) | \
  39         ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
  40         (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
  41         ((func_num) & ARM_SMCCC_FUNC_MASK))
  42 
  43 #define ARM_SMCCC_OWNER_ARCH            0
  44 #define ARM_SMCCC_OWNER_CPU             1
  45 #define ARM_SMCCC_OWNER_SIP             2
  46 #define ARM_SMCCC_OWNER_OEM             3
  47 #define ARM_SMCCC_OWNER_STANDARD        4
  48 #define ARM_SMCCC_OWNER_TRUSTED_APP     48
  49 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
  50 #define ARM_SMCCC_OWNER_TRUSTED_OS      50
  51 #define ARM_SMCCC_OWNER_TRUSTED_OS_END  63
  52 
  53 #define ARM_SMCCC_QUIRK_NONE            0
  54 #define ARM_SMCCC_QUIRK_QCOM_A6         1 /* Save/restore register a6 */
  55 
  56 #define ARM_SMCCC_VERSION_1_0           0x10000
  57 #define ARM_SMCCC_VERSION_1_1           0x10001
  58 
  59 #define ARM_SMCCC_VERSION_FUNC_ID                                       \
  60         ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
  61                            ARM_SMCCC_SMC_32,                            \
  62                            0, 0)
  63 
  64 #define ARM_SMCCC_ARCH_FEATURES_FUNC_ID                                 \
  65         ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
  66                            ARM_SMCCC_SMC_32,                            \
  67                            0, 1)
  68 
  69 #define ARM_SMCCC_ARCH_WORKAROUND_1                                     \
  70         ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
  71                            ARM_SMCCC_SMC_32,                            \
  72                            0, 0x8000)
  73 
  74 #define ARM_SMCCC_ARCH_WORKAROUND_2                                     \
  75         ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                         \
  76                            ARM_SMCCC_SMC_32,                            \
  77                            0, 0x7fff)
  78 
  79 #ifndef __ASSEMBLY__
  80 
  81 #include <linux/linkage.h>
  82 #include <linux/types.h>
  83 /**
  84  * struct arm_smccc_res - Result from SMC/HVC call
  85  * @a0-a3 result values from registers 0 to 3
  86  */
  87 struct arm_smccc_res {
  88         unsigned long a0;
  89         unsigned long a1;
  90         unsigned long a2;
  91         unsigned long a3;
  92 };
  93 
  94 /**
  95  * struct arm_smccc_quirk - Contains quirk information
  96  * @id: quirk identification
  97  * @state: quirk specific information
  98  * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
  99  */
 100 struct arm_smccc_quirk {
 101         int     id;
 102         union {
 103                 unsigned long a6;
 104         } state;
 105 };
 106 
 107 /**
 108  * __arm_smccc_smc() - make SMC calls
 109  * @a0-a7: arguments passed in registers 0 to 7
 110  * @res: result values from registers 0 to 3
 111  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
 112  *
 113  * This function is used to make SMC calls following SMC Calling Convention.
 114  * The content of the supplied param are copied to registers 0 to 7 prior
 115  * to the SMC instruction. The return values are updated with the content
 116  * from register 0 to 3 on return from the SMC instruction.  An optional
 117  * quirk structure provides vendor specific behavior.
 118  */
 119 asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
 120                         unsigned long a2, unsigned long a3, unsigned long a4,
 121                         unsigned long a5, unsigned long a6, unsigned long a7,
 122                         struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
 123 
 124 /**
 125  * __arm_smccc_hvc() - make HVC calls
 126  * @a0-a7: arguments passed in registers 0 to 7
 127  * @res: result values from registers 0 to 3
 128  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
 129  *
 130  * This function is used to make HVC calls following SMC Calling
 131  * Convention.  The content of the supplied param are copied to registers 0
 132  * to 7 prior to the HVC instruction. The return values are updated with
 133  * the content from register 0 to 3 on return from the HVC instruction.  An
 134  * optional quirk structure provides vendor specific behavior.
 135  */
 136 asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 137                         unsigned long a2, unsigned long a3, unsigned long a4,
 138                         unsigned long a5, unsigned long a6, unsigned long a7,
 139                         struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
 140 
 141 #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
 142 
 143 #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
 144 
 145 #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
 146 
 147 #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
 148 
 149 /* SMCCC v1.1 implementation madness follows */
 150 #ifdef CONFIG_ARM64
 151 
 152 #define SMCCC_SMC_INST  "smc    #0"
 153 #define SMCCC_HVC_INST  "hvc    #0"
 154 
 155 #elif defined(CONFIG_ARM)
 156 #include <asm/opcodes-sec.h>
 157 #include <asm/opcodes-virt.h>
 158 
 159 #define SMCCC_SMC_INST  __SMC(0)
 160 #define SMCCC_HVC_INST  __HVC(0)
 161 
 162 #endif
 163 
 164 #define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
 165 
 166 #define __count_args(...)                                               \
 167         ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
 168 
 169 #define __constraint_write_0                                            \
 170         "+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3)
 171 #define __constraint_write_1                                            \
 172         "+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3)
 173 #define __constraint_write_2                                            \
 174         "+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3)
 175 #define __constraint_write_3                                            \
 176         "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3)
 177 #define __constraint_write_4    __constraint_write_3
 178 #define __constraint_write_5    __constraint_write_4
 179 #define __constraint_write_6    __constraint_write_5
 180 #define __constraint_write_7    __constraint_write_6
 181 
 182 #define __constraint_read_0
 183 #define __constraint_read_1
 184 #define __constraint_read_2
 185 #define __constraint_read_3
 186 #define __constraint_read_4     "r" (r4)
 187 #define __constraint_read_5     __constraint_read_4, "r" (r5)
 188 #define __constraint_read_6     __constraint_read_5, "r" (r6)
 189 #define __constraint_read_7     __constraint_read_6, "r" (r7)
 190 
 191 #define __declare_arg_0(a0, res)                                        \
 192         struct arm_smccc_res   *___res = res;                           \
 193         register unsigned long r0 asm("r0") = (u32)a0;                  \
 194         register unsigned long r1 asm("r1");                            \
 195         register unsigned long r2 asm("r2");                            \
 196         register unsigned long r3 asm("r3")
 197 
 198 #define __declare_arg_1(a0, a1, res)                                    \
 199         typeof(a1) __a1 = a1;                                           \
 200         struct arm_smccc_res   *___res = res;                           \
 201         register unsigned long r0 asm("r0") = (u32)a0;                  \
 202         register unsigned long r1 asm("r1") = __a1;                     \
 203         register unsigned long r2 asm("r2");                            \
 204         register unsigned long r3 asm("r3")
 205 
 206 #define __declare_arg_2(a0, a1, a2, res)                                \
 207         typeof(a1) __a1 = a1;                                           \
 208         typeof(a2) __a2 = a2;                                           \
 209         struct arm_smccc_res   *___res = res;                           \
 210         register unsigned long r0 asm("r0") = (u32)a0;                  \
 211         register unsigned long r1 asm("r1") = __a1;                     \
 212         register unsigned long r2 asm("r2") = __a2;                     \
 213         register unsigned long r3 asm("r3")
 214 
 215 #define __declare_arg_3(a0, a1, a2, a3, res)                            \
 216         typeof(a1) __a1 = a1;                                           \
 217         typeof(a2) __a2 = a2;                                           \
 218         typeof(a3) __a3 = a3;                                           \
 219         struct arm_smccc_res   *___res = res;                           \
 220         register unsigned long r0 asm("r0") = (u32)a0;                  \
 221         register unsigned long r1 asm("r1") = __a1;                     \
 222         register unsigned long r2 asm("r2") = __a2;                     \
 223         register unsigned long r3 asm("r3") = __a3
 224 
 225 #define __declare_arg_4(a0, a1, a2, a3, a4, res)                        \
 226         typeof(a4) __a4 = a4;                                           \
 227         __declare_arg_3(a0, a1, a2, a3, res);                           \
 228         register unsigned long r4 asm("r4") = __a4
 229 
 230 #define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)                    \
 231         typeof(a5) __a5 = a5;                                           \
 232         __declare_arg_4(a0, a1, a2, a3, a4, res);                       \
 233         register unsigned long r5 asm("r5") = __a5
 234 
 235 #define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)                \
 236         typeof(a6) __a6 = a6;                                           \
 237         __declare_arg_5(a0, a1, a2, a3, a4, a5, res);                   \
 238         register unsigned long r6 asm("r6") = __a6
 239 
 240 #define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)            \
 241         typeof(a7) __a7 = a7;                                           \
 242         __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);               \
 243         register unsigned long r7 asm("r7") = __a7
 244 
 245 #define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
 246 #define __declare_args(count, ...)  ___declare_args(count, __VA_ARGS__)
 247 
 248 #define ___constraints(count)                                           \
 249         : __constraint_write_ ## count                                  \
 250         : __constraint_read_ ## count                                   \
 251         : "memory"
 252 #define __constraints(count)    ___constraints(count)
 253 
 254 /*
 255  * We have an output list that is not necessarily used, and GCC feels
 256  * entitled to optimise the whole sequence away. "volatile" is what
 257  * makes it stick.
 258  */
 259 #define __arm_smccc_1_1(inst, ...)                                      \
 260         do {                                                            \
 261                 __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
 262                 asm volatile(inst "\n"                                  \
 263                              __constraints(__count_args(__VA_ARGS__))); \
 264                 if (___res)                                             \
 265                         *___res = (typeof(*___res)){r0, r1, r2, r3};    \
 266         } while (0)
 267 
 268 /*
 269  * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
 270  *
 271  * This is a variadic macro taking one to eight source arguments, and
 272  * an optional return structure.
 273  *
 274  * @a0-a7: arguments passed in registers 0 to 7
 275  * @res: result values from registers 0 to 3
 276  *
 277  * This macro is used to make SMC calls following SMC Calling Convention v1.1.
 278  * The content of the supplied param are copied to registers 0 to 7 prior
 279  * to the SMC instruction. The return values are updated with the content
 280  * from register 0 to 3 on return from the SMC instruction if not NULL.
 281  */
 282 #define arm_smccc_1_1_smc(...)  __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
 283 
 284 /*
 285  * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
 286  *
 287  * This is a variadic macro taking one to eight source arguments, and
 288  * an optional return structure.
 289  *
 290  * @a0-a7: arguments passed in registers 0 to 7
 291  * @res: result values from registers 0 to 3
 292  *
 293  * This macro is used to make HVC calls following SMC Calling Convention v1.1.
 294  * The content of the supplied param are copied to registers 0 to 7 prior
 295  * to the HVC instruction. The return values are updated with the content
 296  * from register 0 to 3 on return from the HVC instruction if not NULL.
 297  */
 298 #define arm_smccc_1_1_hvc(...)  __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
 299 
 300 /* Return codes defined in ARM DEN 0070A */
 301 #define SMCCC_RET_SUCCESS                       0
 302 #define SMCCC_RET_NOT_SUPPORTED                 -1
 303 #define SMCCC_RET_NOT_REQUIRED                  -2
 304 
 305 #endif /*__ASSEMBLY__*/
 306 #endif /*__LINUX_ARM_SMCCC_H*/

/* [<][>][^][v][top][bottom][index][help] */