cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

arm-smccc.h (18126B)


      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 <linux/init.h>
      9#include <uapi/linux/const.h>
     10
     11/*
     12 * This file provides common defines for ARM SMC Calling Convention as
     13 * specified in
     14 * https://developer.arm.com/docs/den0028/latest
     15 *
     16 * This code is up-to-date with version DEN 0028 C
     17 */
     18
     19#define ARM_SMCCC_STD_CALL	        _AC(0,U)
     20#define ARM_SMCCC_FAST_CALL	        _AC(1,U)
     21#define ARM_SMCCC_TYPE_SHIFT		31
     22
     23#define ARM_SMCCC_SMC_32		0
     24#define ARM_SMCCC_SMC_64		1
     25#define ARM_SMCCC_CALL_CONV_SHIFT	30
     26
     27#define ARM_SMCCC_OWNER_MASK		0x3F
     28#define ARM_SMCCC_OWNER_SHIFT		24
     29
     30#define ARM_SMCCC_FUNC_MASK		0xFFFF
     31
     32#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
     33	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
     34#define ARM_SMCCC_IS_64(smc_val) \
     35	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
     36#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
     37#define ARM_SMCCC_OWNER_NUM(smc_val) \
     38	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
     39
     40#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
     41	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
     42	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
     43	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
     44	((func_num) & ARM_SMCCC_FUNC_MASK))
     45
     46#define ARM_SMCCC_OWNER_ARCH		0
     47#define ARM_SMCCC_OWNER_CPU		1
     48#define ARM_SMCCC_OWNER_SIP		2
     49#define ARM_SMCCC_OWNER_OEM		3
     50#define ARM_SMCCC_OWNER_STANDARD	4
     51#define ARM_SMCCC_OWNER_STANDARD_HYP	5
     52#define ARM_SMCCC_OWNER_VENDOR_HYP	6
     53#define ARM_SMCCC_OWNER_TRUSTED_APP	48
     54#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
     55#define ARM_SMCCC_OWNER_TRUSTED_OS	50
     56#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
     57
     58#define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff01
     59
     60#define ARM_SMCCC_QUIRK_NONE		0
     61#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
     62
     63#define ARM_SMCCC_VERSION_1_0		0x10000
     64#define ARM_SMCCC_VERSION_1_1		0x10001
     65#define ARM_SMCCC_VERSION_1_2		0x10002
     66#define ARM_SMCCC_VERSION_1_3		0x10003
     67
     68#define ARM_SMCCC_1_3_SVE_HINT		0x10000
     69
     70#define ARM_SMCCC_VERSION_FUNC_ID					\
     71	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     72			   ARM_SMCCC_SMC_32,				\
     73			   0, 0)
     74
     75#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\
     76	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     77			   ARM_SMCCC_SMC_32,				\
     78			   0, 1)
     79
     80#define ARM_SMCCC_ARCH_SOC_ID						\
     81	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     82			   ARM_SMCCC_SMC_32,				\
     83			   0, 2)
     84
     85#define ARM_SMCCC_ARCH_WORKAROUND_1					\
     86	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     87			   ARM_SMCCC_SMC_32,				\
     88			   0, 0x8000)
     89
     90#define ARM_SMCCC_ARCH_WORKAROUND_2					\
     91	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     92			   ARM_SMCCC_SMC_32,				\
     93			   0, 0x7fff)
     94
     95#define ARM_SMCCC_ARCH_WORKAROUND_3					\
     96	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
     97			   ARM_SMCCC_SMC_32,				\
     98			   0, 0x3fff)
     99
    100#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID				\
    101	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
    102			   ARM_SMCCC_SMC_32,				\
    103			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
    104			   ARM_SMCCC_FUNC_QUERY_CALL_UID)
    105
    106/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
    107#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0	0xb66fb428U
    108#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1	0xe911c52eU
    109#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2	0x564bcaa9U
    110#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3	0x743a004dU
    111
    112/* KVM "vendor specific" services */
    113#define ARM_SMCCC_KVM_FUNC_FEATURES		0
    114#define ARM_SMCCC_KVM_FUNC_PTP			1
    115#define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
    116#define ARM_SMCCC_KVM_NUM_FUNCS			128
    117
    118#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID			\
    119	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
    120			   ARM_SMCCC_SMC_32,				\
    121			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
    122			   ARM_SMCCC_KVM_FUNC_FEATURES)
    123
    124#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED	1
    125
    126/*
    127 * ptp_kvm is a feature used for time sync between vm and host.
    128 * ptp_kvm module in guest kernel will get service from host using
    129 * this hypercall ID.
    130 */
    131#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID				\
    132	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
    133			   ARM_SMCCC_SMC_32,				\
    134			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
    135			   ARM_SMCCC_KVM_FUNC_PTP)
    136
    137/* ptp_kvm counter type ID */
    138#define KVM_PTP_VIRT_COUNTER			0
    139#define KVM_PTP_PHYS_COUNTER			1
    140
    141/* Paravirtualised time calls (defined by ARM DEN0057A) */
    142#define ARM_SMCCC_HV_PV_TIME_FEATURES				\
    143	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    144			   ARM_SMCCC_SMC_64,			\
    145			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
    146			   0x20)
    147
    148#define ARM_SMCCC_HV_PV_TIME_ST					\
    149	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    150			   ARM_SMCCC_SMC_64,			\
    151			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
    152			   0x21)
    153
    154/* TRNG entropy source calls (defined by ARM DEN0098) */
    155#define ARM_SMCCC_TRNG_VERSION					\
    156	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    157			   ARM_SMCCC_SMC_32,			\
    158			   ARM_SMCCC_OWNER_STANDARD,		\
    159			   0x50)
    160
    161#define ARM_SMCCC_TRNG_FEATURES					\
    162	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    163			   ARM_SMCCC_SMC_32,			\
    164			   ARM_SMCCC_OWNER_STANDARD,		\
    165			   0x51)
    166
    167#define ARM_SMCCC_TRNG_GET_UUID					\
    168	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    169			   ARM_SMCCC_SMC_32,			\
    170			   ARM_SMCCC_OWNER_STANDARD,		\
    171			   0x52)
    172
    173#define ARM_SMCCC_TRNG_RND32					\
    174	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    175			   ARM_SMCCC_SMC_32,			\
    176			   ARM_SMCCC_OWNER_STANDARD,		\
    177			   0x53)
    178
    179#define ARM_SMCCC_TRNG_RND64					\
    180	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
    181			   ARM_SMCCC_SMC_64,			\
    182			   ARM_SMCCC_OWNER_STANDARD,		\
    183			   0x53)
    184
    185/*
    186 * Return codes defined in ARM DEN 0070A
    187 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
    188 */
    189#define SMCCC_RET_SUCCESS			0
    190#define SMCCC_RET_NOT_SUPPORTED			-1
    191#define SMCCC_RET_NOT_REQUIRED			-2
    192#define SMCCC_RET_INVALID_PARAMETER		-3
    193
    194#ifndef __ASSEMBLY__
    195
    196#include <linux/linkage.h>
    197#include <linux/types.h>
    198
    199enum arm_smccc_conduit {
    200	SMCCC_CONDUIT_NONE,
    201	SMCCC_CONDUIT_SMC,
    202	SMCCC_CONDUIT_HVC,
    203};
    204
    205/**
    206 * arm_smccc_1_1_get_conduit()
    207 *
    208 * Returns the conduit to be used for SMCCCv1.1 or later.
    209 *
    210 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
    211 */
    212enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
    213
    214/**
    215 * arm_smccc_get_version()
    216 *
    217 * Returns the version to be used for SMCCCv1.1 or later.
    218 *
    219 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
    220 * does not imply the presence of firmware or a valid conduit. Caller
    221 * handling SMCCCv1.0 must determine the conduit by other means.
    222 */
    223u32 arm_smccc_get_version(void);
    224
    225void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
    226
    227extern u64 smccc_has_sve_hint;
    228
    229/**
    230 * struct arm_smccc_res - Result from SMC/HVC call
    231 * @a0-a3 result values from registers 0 to 3
    232 */
    233struct arm_smccc_res {
    234	unsigned long a0;
    235	unsigned long a1;
    236	unsigned long a2;
    237	unsigned long a3;
    238};
    239
    240#ifdef CONFIG_ARM64
    241/**
    242 * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
    243 * @a0-a17 argument values from registers 0 to 17
    244 */
    245struct arm_smccc_1_2_regs {
    246	unsigned long a0;
    247	unsigned long a1;
    248	unsigned long a2;
    249	unsigned long a3;
    250	unsigned long a4;
    251	unsigned long a5;
    252	unsigned long a6;
    253	unsigned long a7;
    254	unsigned long a8;
    255	unsigned long a9;
    256	unsigned long a10;
    257	unsigned long a11;
    258	unsigned long a12;
    259	unsigned long a13;
    260	unsigned long a14;
    261	unsigned long a15;
    262	unsigned long a16;
    263	unsigned long a17;
    264};
    265
    266/**
    267 * arm_smccc_1_2_hvc() - make HVC calls
    268 * @args: arguments passed via struct arm_smccc_1_2_regs
    269 * @res: result values via struct arm_smccc_1_2_regs
    270 *
    271 * This function is used to make HVC calls following SMC Calling Convention
    272 * v1.2 or above. The content of the supplied param are copied from the
    273 * structure to registers prior to the HVC instruction. The return values
    274 * are updated with the content from registers on return from the HVC
    275 * instruction.
    276 */
    277asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
    278				  struct arm_smccc_1_2_regs *res);
    279
    280/**
    281 * arm_smccc_1_2_smc() - make SMC calls
    282 * @args: arguments passed via struct arm_smccc_1_2_regs
    283 * @res: result values via struct arm_smccc_1_2_regs
    284 *
    285 * This function is used to make SMC calls following SMC Calling Convention
    286 * v1.2 or above. The content of the supplied param are copied from the
    287 * structure to registers prior to the SMC instruction. The return values
    288 * are updated with the content from registers on return from the SMC
    289 * instruction.
    290 */
    291asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
    292				  struct arm_smccc_1_2_regs *res);
    293#endif
    294
    295/**
    296 * struct arm_smccc_quirk - Contains quirk information
    297 * @id: quirk identification
    298 * @state: quirk specific information
    299 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
    300 */
    301struct arm_smccc_quirk {
    302	int	id;
    303	union {
    304		unsigned long a6;
    305	} state;
    306};
    307
    308/**
    309 * __arm_smccc_sve_check() - Set the SVE hint bit when doing SMC calls
    310 *
    311 * Sets the SMCCC hint bit to indicate if there is live state in the SVE
    312 * registers, this modifies x0 in place and should never be called from C
    313 * code.
    314 */
    315asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
    316
    317/**
    318 * __arm_smccc_smc() - make SMC calls
    319 * @a0-a7: arguments passed in registers 0 to 7
    320 * @res: result values from registers 0 to 3
    321 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
    322 *
    323 * This function is used to make SMC calls following SMC Calling Convention.
    324 * The content of the supplied param are copied to registers 0 to 7 prior
    325 * to the SMC instruction. The return values are updated with the content
    326 * from register 0 to 3 on return from the SMC instruction.  An optional
    327 * quirk structure provides vendor specific behavior.
    328 */
    329#ifdef CONFIG_HAVE_ARM_SMCCC
    330asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
    331			unsigned long a2, unsigned long a3, unsigned long a4,
    332			unsigned long a5, unsigned long a6, unsigned long a7,
    333			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
    334#else
    335static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
    336			unsigned long a2, unsigned long a3, unsigned long a4,
    337			unsigned long a5, unsigned long a6, unsigned long a7,
    338			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
    339{
    340	*res = (struct arm_smccc_res){};
    341}
    342#endif
    343
    344/**
    345 * __arm_smccc_hvc() - make HVC calls
    346 * @a0-a7: arguments passed in registers 0 to 7
    347 * @res: result values from registers 0 to 3
    348 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
    349 *
    350 * This function is used to make HVC calls following SMC Calling
    351 * Convention.  The content of the supplied param are copied to registers 0
    352 * to 7 prior to the HVC instruction. The return values are updated with
    353 * the content from register 0 to 3 on return from the HVC instruction.  An
    354 * optional quirk structure provides vendor specific behavior.
    355 */
    356asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
    357			unsigned long a2, unsigned long a3, unsigned long a4,
    358			unsigned long a5, unsigned long a6, unsigned long a7,
    359			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
    360
    361#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
    362
    363#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
    364
    365#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
    366
    367#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
    368
    369/* SMCCC v1.1 implementation madness follows */
    370#ifdef CONFIG_ARM64
    371
    372#define SMCCC_SMC_INST	"smc	#0"
    373#define SMCCC_HVC_INST	"hvc	#0"
    374
    375#elif defined(CONFIG_ARM)
    376#include <asm/opcodes-sec.h>
    377#include <asm/opcodes-virt.h>
    378
    379#define SMCCC_SMC_INST	__SMC(0)
    380#define SMCCC_HVC_INST	__HVC(0)
    381
    382#endif
    383
    384/* nVHE hypervisor doesn't have a current thread so needs separate checks */
    385#if defined(CONFIG_ARM64_SVE) && !defined(__KVM_NVHE_HYPERVISOR__)
    386
    387#define SMCCC_SVE_CHECK ALTERNATIVE("nop \n",  "bl __arm_smccc_sve_check \n", \
    388				    ARM64_SVE)
    389#define smccc_sve_clobbers "x16", "x30", "cc",
    390
    391#else
    392
    393#define SMCCC_SVE_CHECK
    394#define smccc_sve_clobbers
    395
    396#endif
    397
    398#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
    399
    400#define __count_args(...)						\
    401	___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
    402
    403#define __constraint_read_0	"r" (arg0)
    404#define __constraint_read_1	__constraint_read_0, "r" (arg1)
    405#define __constraint_read_2	__constraint_read_1, "r" (arg2)
    406#define __constraint_read_3	__constraint_read_2, "r" (arg3)
    407#define __constraint_read_4	__constraint_read_3, "r" (arg4)
    408#define __constraint_read_5	__constraint_read_4, "r" (arg5)
    409#define __constraint_read_6	__constraint_read_5, "r" (arg6)
    410#define __constraint_read_7	__constraint_read_6, "r" (arg7)
    411
    412#define __declare_arg_0(a0, res)					\
    413	struct arm_smccc_res   *___res = res;				\
    414	register unsigned long arg0 asm("r0") = (u32)a0
    415
    416#define __declare_arg_1(a0, a1, res)					\
    417	typeof(a1) __a1 = a1;						\
    418	struct arm_smccc_res   *___res = res;				\
    419	register unsigned long arg0 asm("r0") = (u32)a0;			\
    420	register typeof(a1) arg1 asm("r1") = __a1
    421
    422#define __declare_arg_2(a0, a1, a2, res)				\
    423	typeof(a1) __a1 = a1;						\
    424	typeof(a2) __a2 = a2;						\
    425	struct arm_smccc_res   *___res = res;				\
    426	register unsigned long arg0 asm("r0") = (u32)a0;			\
    427	register typeof(a1) arg1 asm("r1") = __a1;			\
    428	register typeof(a2) arg2 asm("r2") = __a2
    429
    430#define __declare_arg_3(a0, a1, a2, a3, res)				\
    431	typeof(a1) __a1 = a1;						\
    432	typeof(a2) __a2 = a2;						\
    433	typeof(a3) __a3 = a3;						\
    434	struct arm_smccc_res   *___res = res;				\
    435	register unsigned long arg0 asm("r0") = (u32)a0;			\
    436	register typeof(a1) arg1 asm("r1") = __a1;			\
    437	register typeof(a2) arg2 asm("r2") = __a2;			\
    438	register typeof(a3) arg3 asm("r3") = __a3
    439
    440#define __declare_arg_4(a0, a1, a2, a3, a4, res)			\
    441	typeof(a4) __a4 = a4;						\
    442	__declare_arg_3(a0, a1, a2, a3, res);				\
    443	register typeof(a4) arg4 asm("r4") = __a4
    444
    445#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)			\
    446	typeof(a5) __a5 = a5;						\
    447	__declare_arg_4(a0, a1, a2, a3, a4, res);			\
    448	register typeof(a5) arg5 asm("r5") = __a5
    449
    450#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)		\
    451	typeof(a6) __a6 = a6;						\
    452	__declare_arg_5(a0, a1, a2, a3, a4, a5, res);			\
    453	register typeof(a6) arg6 asm("r6") = __a6
    454
    455#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)		\
    456	typeof(a7) __a7 = a7;						\
    457	__declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);		\
    458	register typeof(a7) arg7 asm("r7") = __a7
    459
    460#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
    461#define __declare_args(count, ...)  ___declare_args(count, __VA_ARGS__)
    462
    463#define ___constraints(count)						\
    464	: __constraint_read_ ## count					\
    465	: smccc_sve_clobbers "memory"
    466#define __constraints(count)	___constraints(count)
    467
    468/*
    469 * We have an output list that is not necessarily used, and GCC feels
    470 * entitled to optimise the whole sequence away. "volatile" is what
    471 * makes it stick.
    472 */
    473#define __arm_smccc_1_1(inst, ...)					\
    474	do {								\
    475		register unsigned long r0 asm("r0");			\
    476		register unsigned long r1 asm("r1");			\
    477		register unsigned long r2 asm("r2");			\
    478		register unsigned long r3 asm("r3"); 			\
    479		__declare_args(__count_args(__VA_ARGS__), __VA_ARGS__);	\
    480		asm volatile(SMCCC_SVE_CHECK				\
    481			     inst "\n" :				\
    482			     "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)	\
    483			     __constraints(__count_args(__VA_ARGS__)));	\
    484		if (___res)						\
    485			*___res = (typeof(*___res)){r0, r1, r2, r3};	\
    486	} while (0)
    487
    488/*
    489 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
    490 *
    491 * This is a variadic macro taking one to eight source arguments, and
    492 * an optional return structure.
    493 *
    494 * @a0-a7: arguments passed in registers 0 to 7
    495 * @res: result values from registers 0 to 3
    496 *
    497 * This macro is used to make SMC calls following SMC Calling Convention v1.1.
    498 * The content of the supplied param are copied to registers 0 to 7 prior
    499 * to the SMC instruction. The return values are updated with the content
    500 * from register 0 to 3 on return from the SMC instruction if not NULL.
    501 */
    502#define arm_smccc_1_1_smc(...)	__arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
    503
    504/*
    505 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
    506 *
    507 * This is a variadic macro taking one to eight source arguments, and
    508 * an optional return structure.
    509 *
    510 * @a0-a7: arguments passed in registers 0 to 7
    511 * @res: result values from registers 0 to 3
    512 *
    513 * This macro is used to make HVC calls following SMC Calling Convention v1.1.
    514 * The content of the supplied param are copied to registers 0 to 7 prior
    515 * to the HVC instruction. The return values are updated with the content
    516 * from register 0 to 3 on return from the HVC instruction if not NULL.
    517 */
    518#define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
    519
    520/*
    521 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
    522 * Used when the SMCCC conduit is not defined. The empty asm statement
    523 * avoids compiler warnings about unused variables.
    524 */
    525#define __fail_smccc_1_1(...)						\
    526	do {								\
    527		__declare_args(__count_args(__VA_ARGS__), __VA_ARGS__);	\
    528		asm ("" : __constraints(__count_args(__VA_ARGS__)));	\
    529		if (___res)						\
    530			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\
    531	} while (0)
    532
    533/*
    534 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
    535 *
    536 * This is a variadic macro taking one to eight source arguments, and
    537 * an optional return structure.
    538 *
    539 * @a0-a7: arguments passed in registers 0 to 7
    540 * @res: result values from registers 0 to 3
    541 *
    542 * This macro will make either an HVC call or an SMC call depending on the
    543 * current SMCCC conduit. If no valid conduit is available then -1
    544 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
    545 *
    546 * The return value also provides the conduit that was used.
    547 */
    548#define arm_smccc_1_1_invoke(...) ({					\
    549		int method = arm_smccc_1_1_get_conduit();		\
    550		switch (method) {					\
    551		case SMCCC_CONDUIT_HVC:					\
    552			arm_smccc_1_1_hvc(__VA_ARGS__);			\
    553			break;						\
    554		case SMCCC_CONDUIT_SMC:					\
    555			arm_smccc_1_1_smc(__VA_ARGS__);			\
    556			break;						\
    557		default:						\
    558			__fail_smccc_1_1(__VA_ARGS__);			\
    559			method = SMCCC_CONDUIT_NONE;			\
    560			break;						\
    561		}							\
    562		method;							\
    563	})
    564
    565#endif /*__ASSEMBLY__*/
    566#endif /*__LINUX_ARM_SMCCC_H*/