Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (c) 2015, Linaro Limited
0004  */
0005 #ifndef __LINUX_ARM_SMCCC_H
0006 #define __LINUX_ARM_SMCCC_H
0007 
0008 #include <linux/init.h>
0009 #include <uapi/linux/const.h>
0010 
0011 /*
0012  * This file provides common defines for ARM SMC Calling Convention as
0013  * specified in
0014  * https://developer.arm.com/docs/den0028/latest
0015  *
0016  * This code is up-to-date with version DEN 0028 C
0017  */
0018 
0019 #define ARM_SMCCC_STD_CALL          _AC(0,U)
0020 #define ARM_SMCCC_FAST_CALL         _AC(1,U)
0021 #define ARM_SMCCC_TYPE_SHIFT        31
0022 
0023 #define ARM_SMCCC_SMC_32        0
0024 #define ARM_SMCCC_SMC_64        1
0025 #define ARM_SMCCC_CALL_CONV_SHIFT   30
0026 
0027 #define ARM_SMCCC_OWNER_MASK        0x3F
0028 #define ARM_SMCCC_OWNER_SHIFT       24
0029 
0030 #define ARM_SMCCC_FUNC_MASK     0xFFFF
0031 
0032 #define ARM_SMCCC_IS_FAST_CALL(smc_val) \
0033     ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
0034 #define ARM_SMCCC_IS_64(smc_val) \
0035     ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
0036 #define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
0037 #define ARM_SMCCC_OWNER_NUM(smc_val) \
0038     (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
0039 
0040 #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
0041     (((type) << ARM_SMCCC_TYPE_SHIFT) | \
0042     ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
0043     (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
0044     ((func_num) & ARM_SMCCC_FUNC_MASK))
0045 
0046 #define ARM_SMCCC_OWNER_ARCH        0
0047 #define ARM_SMCCC_OWNER_CPU     1
0048 #define ARM_SMCCC_OWNER_SIP     2
0049 #define ARM_SMCCC_OWNER_OEM     3
0050 #define ARM_SMCCC_OWNER_STANDARD    4
0051 #define ARM_SMCCC_OWNER_STANDARD_HYP    5
0052 #define ARM_SMCCC_OWNER_VENDOR_HYP  6
0053 #define ARM_SMCCC_OWNER_TRUSTED_APP 48
0054 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
0055 #define ARM_SMCCC_OWNER_TRUSTED_OS  50
0056 #define ARM_SMCCC_OWNER_TRUSTED_OS_END  63
0057 
0058 #define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff01
0059 
0060 #define ARM_SMCCC_QUIRK_NONE        0
0061 #define ARM_SMCCC_QUIRK_QCOM_A6     1 /* Save/restore register a6 */
0062 
0063 #define ARM_SMCCC_VERSION_1_0       0x10000
0064 #define ARM_SMCCC_VERSION_1_1       0x10001
0065 #define ARM_SMCCC_VERSION_1_2       0x10002
0066 #define ARM_SMCCC_VERSION_1_3       0x10003
0067 
0068 #define ARM_SMCCC_1_3_SVE_HINT      0x10000
0069 
0070 #define ARM_SMCCC_VERSION_FUNC_ID                   \
0071     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0072                ARM_SMCCC_SMC_32,                \
0073                0, 0)
0074 
0075 #define ARM_SMCCC_ARCH_FEATURES_FUNC_ID                 \
0076     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0077                ARM_SMCCC_SMC_32,                \
0078                0, 1)
0079 
0080 #define ARM_SMCCC_ARCH_SOC_ID                       \
0081     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0082                ARM_SMCCC_SMC_32,                \
0083                0, 2)
0084 
0085 #define ARM_SMCCC_ARCH_WORKAROUND_1                 \
0086     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0087                ARM_SMCCC_SMC_32,                \
0088                0, 0x8000)
0089 
0090 #define ARM_SMCCC_ARCH_WORKAROUND_2                 \
0091     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0092                ARM_SMCCC_SMC_32,                \
0093                0, 0x7fff)
0094 
0095 #define ARM_SMCCC_ARCH_WORKAROUND_3                 \
0096     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0097                ARM_SMCCC_SMC_32,                \
0098                0, 0x3fff)
0099 
0100 #define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID               \
0101     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0102                ARM_SMCCC_SMC_32,                \
0103                ARM_SMCCC_OWNER_VENDOR_HYP,          \
0104                ARM_SMCCC_FUNC_QUERY_CALL_UID)
0105 
0106 /* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
0107 #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0  0xb66fb428U
0108 #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1  0xe911c52eU
0109 #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2  0x564bcaa9U
0110 #define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3  0x743a004dU
0111 
0112 /* KVM "vendor specific" services */
0113 #define ARM_SMCCC_KVM_FUNC_FEATURES     0
0114 #define ARM_SMCCC_KVM_FUNC_PTP          1
0115 #define ARM_SMCCC_KVM_FUNC_FEATURES_2       127
0116 #define ARM_SMCCC_KVM_NUM_FUNCS         128
0117 
0118 #define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID           \
0119     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0120                ARM_SMCCC_SMC_32,                \
0121                ARM_SMCCC_OWNER_VENDOR_HYP,          \
0122                ARM_SMCCC_KVM_FUNC_FEATURES)
0123 
0124 #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED    1
0125 
0126 /*
0127  * ptp_kvm is a feature used for time sync between vm and host.
0128  * ptp_kvm module in guest kernel will get service from host using
0129  * this hypercall ID.
0130  */
0131 #define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID                \
0132     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,             \
0133                ARM_SMCCC_SMC_32,                \
0134                ARM_SMCCC_OWNER_VENDOR_HYP,          \
0135                ARM_SMCCC_KVM_FUNC_PTP)
0136 
0137 /* ptp_kvm counter type ID */
0138 #define KVM_PTP_VIRT_COUNTER            0
0139 #define KVM_PTP_PHYS_COUNTER            1
0140 
0141 /* Paravirtualised time calls (defined by ARM DEN0057A) */
0142 #define ARM_SMCCC_HV_PV_TIME_FEATURES               \
0143     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0144                ARM_SMCCC_SMC_64,            \
0145                ARM_SMCCC_OWNER_STANDARD_HYP,    \
0146                0x20)
0147 
0148 #define ARM_SMCCC_HV_PV_TIME_ST                 \
0149     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0150                ARM_SMCCC_SMC_64,            \
0151                ARM_SMCCC_OWNER_STANDARD_HYP,    \
0152                0x21)
0153 
0154 /* TRNG entropy source calls (defined by ARM DEN0098) */
0155 #define ARM_SMCCC_TRNG_VERSION                  \
0156     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0157                ARM_SMCCC_SMC_32,            \
0158                ARM_SMCCC_OWNER_STANDARD,        \
0159                0x50)
0160 
0161 #define ARM_SMCCC_TRNG_FEATURES                 \
0162     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0163                ARM_SMCCC_SMC_32,            \
0164                ARM_SMCCC_OWNER_STANDARD,        \
0165                0x51)
0166 
0167 #define ARM_SMCCC_TRNG_GET_UUID                 \
0168     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0169                ARM_SMCCC_SMC_32,            \
0170                ARM_SMCCC_OWNER_STANDARD,        \
0171                0x52)
0172 
0173 #define ARM_SMCCC_TRNG_RND32                    \
0174     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0175                ARM_SMCCC_SMC_32,            \
0176                ARM_SMCCC_OWNER_STANDARD,        \
0177                0x53)
0178 
0179 #define ARM_SMCCC_TRNG_RND64                    \
0180     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
0181                ARM_SMCCC_SMC_64,            \
0182                ARM_SMCCC_OWNER_STANDARD,        \
0183                0x53)
0184 
0185 /*
0186  * Return codes defined in ARM DEN 0070A
0187  * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
0188  */
0189 #define SMCCC_RET_SUCCESS           0
0190 #define SMCCC_RET_NOT_SUPPORTED         -1
0191 #define SMCCC_RET_NOT_REQUIRED          -2
0192 #define SMCCC_RET_INVALID_PARAMETER     -3
0193 
0194 #ifndef __ASSEMBLY__
0195 
0196 #include <linux/linkage.h>
0197 #include <linux/types.h>
0198 
0199 enum arm_smccc_conduit {
0200     SMCCC_CONDUIT_NONE,
0201     SMCCC_CONDUIT_SMC,
0202     SMCCC_CONDUIT_HVC,
0203 };
0204 
0205 /**
0206  * arm_smccc_1_1_get_conduit()
0207  *
0208  * Returns the conduit to be used for SMCCCv1.1 or later.
0209  *
0210  * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
0211  */
0212 enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
0213 
0214 /**
0215  * arm_smccc_get_version()
0216  *
0217  * Returns the version to be used for SMCCCv1.1 or later.
0218  *
0219  * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
0220  * does not imply the presence of firmware or a valid conduit. Caller
0221  * handling SMCCCv1.0 must determine the conduit by other means.
0222  */
0223 u32 arm_smccc_get_version(void);
0224 
0225 void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
0226 
0227 extern u64 smccc_has_sve_hint;
0228 
0229 /**
0230  * struct arm_smccc_res - Result from SMC/HVC call
0231  * @a0-a3 result values from registers 0 to 3
0232  */
0233 struct arm_smccc_res {
0234     unsigned long a0;
0235     unsigned long a1;
0236     unsigned long a2;
0237     unsigned long a3;
0238 };
0239 
0240 #ifdef CONFIG_ARM64
0241 /**
0242  * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
0243  * @a0-a17 argument values from registers 0 to 17
0244  */
0245 struct arm_smccc_1_2_regs {
0246     unsigned long a0;
0247     unsigned long a1;
0248     unsigned long a2;
0249     unsigned long a3;
0250     unsigned long a4;
0251     unsigned long a5;
0252     unsigned long a6;
0253     unsigned long a7;
0254     unsigned long a8;
0255     unsigned long a9;
0256     unsigned long a10;
0257     unsigned long a11;
0258     unsigned long a12;
0259     unsigned long a13;
0260     unsigned long a14;
0261     unsigned long a15;
0262     unsigned long a16;
0263     unsigned long a17;
0264 };
0265 
0266 /**
0267  * arm_smccc_1_2_hvc() - make HVC calls
0268  * @args: arguments passed via struct arm_smccc_1_2_regs
0269  * @res: result values via struct arm_smccc_1_2_regs
0270  *
0271  * This function is used to make HVC calls following SMC Calling Convention
0272  * v1.2 or above. The content of the supplied param are copied from the
0273  * structure to registers prior to the HVC instruction. The return values
0274  * are updated with the content from registers on return from the HVC
0275  * instruction.
0276  */
0277 asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
0278                   struct arm_smccc_1_2_regs *res);
0279 
0280 /**
0281  * arm_smccc_1_2_smc() - make SMC calls
0282  * @args: arguments passed via struct arm_smccc_1_2_regs
0283  * @res: result values via struct arm_smccc_1_2_regs
0284  *
0285  * This function is used to make SMC calls following SMC Calling Convention
0286  * v1.2 or above. The content of the supplied param are copied from the
0287  * structure to registers prior to the SMC instruction. The return values
0288  * are updated with the content from registers on return from the SMC
0289  * instruction.
0290  */
0291 asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
0292                   struct arm_smccc_1_2_regs *res);
0293 #endif
0294 
0295 /**
0296  * struct arm_smccc_quirk - Contains quirk information
0297  * @id: quirk identification
0298  * @state: quirk specific information
0299  * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
0300  */
0301 struct arm_smccc_quirk {
0302     int id;
0303     union {
0304         unsigned long a6;
0305     } state;
0306 };
0307 
0308 /**
0309  * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls
0310  *
0311  * Sets the SMCCC hint bit to indicate if there is live state in the SVE
0312  * registers, this modifies x0 in place and should never be called from C
0313  * code.
0314  */
0315 asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
0316 
0317 /**
0318  * __arm_smccc_smc() - make SMC calls
0319  * @a0-a7: arguments passed in registers 0 to 7
0320  * @res: result values from registers 0 to 3
0321  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
0322  *
0323  * This function is used to make SMC calls following SMC Calling Convention.
0324  * The content of the supplied param are copied to registers 0 to 7 prior
0325  * to the SMC instruction. The return values are updated with the content
0326  * from register 0 to 3 on return from the SMC instruction.  An optional
0327  * quirk structure provides vendor specific behavior.
0328  */
0329 #ifdef CONFIG_HAVE_ARM_SMCCC
0330 asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
0331             unsigned long a2, unsigned long a3, unsigned long a4,
0332             unsigned long a5, unsigned long a6, unsigned long a7,
0333             struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
0334 #else
0335 static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
0336             unsigned long a2, unsigned long a3, unsigned long a4,
0337             unsigned long a5, unsigned long a6, unsigned long a7,
0338             struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
0339 {
0340     *res = (struct arm_smccc_res){};
0341 }
0342 #endif
0343 
0344 /**
0345  * __arm_smccc_hvc() - make HVC calls
0346  * @a0-a7: arguments passed in registers 0 to 7
0347  * @res: result values from registers 0 to 3
0348  * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
0349  *
0350  * This function is used to make HVC calls following SMC Calling
0351  * Convention.  The content of the supplied param are copied to registers 0
0352  * to 7 prior to the HVC instruction. The return values are updated with
0353  * the content from register 0 to 3 on return from the HVC instruction.  An
0354  * optional quirk structure provides vendor specific behavior.
0355  */
0356 asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
0357             unsigned long a2, unsigned long a3, unsigned long a4,
0358             unsigned long a5, unsigned long a6, unsigned long a7,
0359             struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
0360 
0361 #define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
0362 
0363 #define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
0364 
0365 #define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
0366 
0367 #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
0368 
0369 /* SMCCC v1.1 implementation madness follows */
0370 #ifdef CONFIG_ARM64
0371 
0372 #define SMCCC_SMC_INST  "smc    #0"
0373 #define SMCCC_HVC_INST  "hvc    #0"
0374 
0375 #elif defined(CONFIG_ARM)
0376 #include <asm/opcodes-sec.h>
0377 #include <asm/opcodes-virt.h>
0378 
0379 #define SMCCC_SMC_INST  __SMC(0)
0380 #define SMCCC_HVC_INST  __HVC(0)
0381 
0382 #endif
0383 
0384 /* nVHE hypervisor doesn't have a current thread so needs separate checks */
0385 #if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__)
0386 
0387 #define SMCCC_SVE_CHECK ALTERNATIVE("nop \n",  "bl __arm_smccc_sve_check \n", \
0388                     ARM64_SVE)
0389 #define smccc_sve_clobbers "x16", "x30", "cc",
0390 
0391 #else
0392 
0393 #define SMCCC_SVE_CHECK
0394 #define smccc_sve_clobbers
0395 
0396 #endif
0397 
0398 #define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
0399 
0400 #define __count_args(...)                       \
0401     ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
0402 
0403 #define __constraint_read_0 "r" (arg0)
0404 #define __constraint_read_1 __constraint_read_0, "r" (arg1)
0405 #define __constraint_read_2 __constraint_read_1, "r" (arg2)
0406 #define __constraint_read_3 __constraint_read_2, "r" (arg3)
0407 #define __constraint_read_4 __constraint_read_3, "r" (arg4)
0408 #define __constraint_read_5 __constraint_read_4, "r" (arg5)
0409 #define __constraint_read_6 __constraint_read_5, "r" (arg6)
0410 #define __constraint_read_7 __constraint_read_6, "r" (arg7)
0411 
0412 #define __declare_arg_0(a0, res)                    \
0413     struct arm_smccc_res   *___res = res;               \
0414     register unsigned long arg0 asm("r0") = (u32)a0
0415 
0416 #define __declare_arg_1(a0, a1, res)                    \
0417     typeof(a1) __a1 = a1;                       \
0418     struct arm_smccc_res   *___res = res;               \
0419     register unsigned long arg0 asm("r0") = (u32)a0;            \
0420     register typeof(a1) arg1 asm("r1") = __a1
0421 
0422 #define __declare_arg_2(a0, a1, a2, res)                \
0423     typeof(a1) __a1 = a1;                       \
0424     typeof(a2) __a2 = a2;                       \
0425     struct arm_smccc_res   *___res = res;               \
0426     register unsigned long arg0 asm("r0") = (u32)a0;            \
0427     register typeof(a1) arg1 asm("r1") = __a1;          \
0428     register typeof(a2) arg2 asm("r2") = __a2
0429 
0430 #define __declare_arg_3(a0, a1, a2, a3, res)                \
0431     typeof(a1) __a1 = a1;                       \
0432     typeof(a2) __a2 = a2;                       \
0433     typeof(a3) __a3 = a3;                       \
0434     struct arm_smccc_res   *___res = res;               \
0435     register unsigned long arg0 asm("r0") = (u32)a0;            \
0436     register typeof(a1) arg1 asm("r1") = __a1;          \
0437     register typeof(a2) arg2 asm("r2") = __a2;          \
0438     register typeof(a3) arg3 asm("r3") = __a3
0439 
0440 #define __declare_arg_4(a0, a1, a2, a3, a4, res)            \
0441     typeof(a4) __a4 = a4;                       \
0442     __declare_arg_3(a0, a1, a2, a3, res);               \
0443     register typeof(a4) arg4 asm("r4") = __a4
0444 
0445 #define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)            \
0446     typeof(a5) __a5 = a5;                       \
0447     __declare_arg_4(a0, a1, a2, a3, a4, res);           \
0448     register typeof(a5) arg5 asm("r5") = __a5
0449 
0450 #define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)        \
0451     typeof(a6) __a6 = a6;                       \
0452     __declare_arg_5(a0, a1, a2, a3, a4, a5, res);           \
0453     register typeof(a6) arg6 asm("r6") = __a6
0454 
0455 #define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)        \
0456     typeof(a7) __a7 = a7;                       \
0457     __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);       \
0458     register typeof(a7) arg7 asm("r7") = __a7
0459 
0460 #define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
0461 #define __declare_args(count, ...)  ___declare_args(count, __VA_ARGS__)
0462 
0463 #define ___constraints(count)                       \
0464     : __constraint_read_ ## count                   \
0465     : smccc_sve_clobbers "memory"
0466 #define __constraints(count)    ___constraints(count)
0467 
0468 /*
0469  * We have an output list that is not necessarily used, and GCC feels
0470  * entitled to optimise the whole sequence away. "volatile" is what
0471  * makes it stick.
0472  */
0473 #define __arm_smccc_1_1(inst, ...)                  \
0474     do {                                \
0475         register unsigned long r0 asm("r0");            \
0476         register unsigned long r1 asm("r1");            \
0477         register unsigned long r2 asm("r2");            \
0478         register unsigned long r3 asm("r3");            \
0479         __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
0480         asm volatile(SMCCC_SVE_CHECK                \
0481                  inst "\n" :                \
0482                  "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
0483                  __constraints(__count_args(__VA_ARGS__))); \
0484         if (___res)                     \
0485             *___res = (typeof(*___res)){r0, r1, r2, r3};    \
0486     } while (0)
0487 
0488 /*
0489  * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
0490  *
0491  * This is a variadic macro taking one to eight source arguments, and
0492  * an optional return structure.
0493  *
0494  * @a0-a7: arguments passed in registers 0 to 7
0495  * @res: result values from registers 0 to 3
0496  *
0497  * This macro is used to make SMC calls following SMC Calling Convention v1.1.
0498  * The content of the supplied param are copied to registers 0 to 7 prior
0499  * to the SMC instruction. The return values are updated with the content
0500  * from register 0 to 3 on return from the SMC instruction if not NULL.
0501  */
0502 #define arm_smccc_1_1_smc(...)  __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
0503 
0504 /*
0505  * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
0506  *
0507  * This is a variadic macro taking one to eight source arguments, and
0508  * an optional return structure.
0509  *
0510  * @a0-a7: arguments passed in registers 0 to 7
0511  * @res: result values from registers 0 to 3
0512  *
0513  * This macro is used to make HVC calls following SMC Calling Convention v1.1.
0514  * The content of the supplied param are copied to registers 0 to 7 prior
0515  * to the HVC instruction. The return values are updated with the content
0516  * from register 0 to 3 on return from the HVC instruction if not NULL.
0517  */
0518 #define arm_smccc_1_1_hvc(...)  __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
0519 
0520 /*
0521  * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
0522  * Used when the SMCCC conduit is not defined. The empty asm statement
0523  * avoids compiler warnings about unused variables.
0524  */
0525 #define __fail_smccc_1_1(...)                       \
0526     do {                                \
0527         __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
0528         asm ("" : __constraints(__count_args(__VA_ARGS__)));    \
0529         if (___res)                     \
0530             ___res->a0 = SMCCC_RET_NOT_SUPPORTED;       \
0531     } while (0)
0532 
0533 /*
0534  * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
0535  *
0536  * This is a variadic macro taking one to eight source arguments, and
0537  * an optional return structure.
0538  *
0539  * @a0-a7: arguments passed in registers 0 to 7
0540  * @res: result values from registers 0 to 3
0541  *
0542  * This macro will make either an HVC call or an SMC call depending on the
0543  * current SMCCC conduit. If no valid conduit is available then -1
0544  * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
0545  *
0546  * The return value also provides the conduit that was used.
0547  */
0548 #define arm_smccc_1_1_invoke(...) ({                    \
0549         int method = arm_smccc_1_1_get_conduit();       \
0550         switch (method) {                   \
0551         case SMCCC_CONDUIT_HVC:                 \
0552             arm_smccc_1_1_hvc(__VA_ARGS__);         \
0553             break;                      \
0554         case SMCCC_CONDUIT_SMC:                 \
0555             arm_smccc_1_1_smc(__VA_ARGS__);         \
0556             break;                      \
0557         default:                        \
0558             __fail_smccc_1_1(__VA_ARGS__);          \
0559             method = SMCCC_CONDUIT_NONE;            \
0560             break;                      \
0561         }                           \
0562         method;                         \
0563     })
0564 
0565 #endif /*__ASSEMBLY__*/
0566 #endif /*__LINUX_ARM_SMCCC_H*/