brintos

brintos / linux-shallow public Read only

0
0
Text · 20.7 KiB · 67f6fdf Raw
644 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2015, Linaro Limited4 */5#ifndef __LINUX_ARM_SMCCC_H6#define __LINUX_ARM_SMCCC_H7 8#include <linux/args.h>9#include <linux/init.h>10#include <uapi/linux/const.h>11 12/*13 * This file provides common defines for ARM SMC Calling Convention as14 * specified in15 * https://developer.arm.com/docs/den0028/latest16 *17 * This code is up-to-date with version DEN 0028 C18 */19 20#define ARM_SMCCC_STD_CALL	        _AC(0,U)21#define ARM_SMCCC_FAST_CALL	        _AC(1,U)22#define ARM_SMCCC_TYPE_SHIFT		3123 24#define ARM_SMCCC_SMC_32		025#define ARM_SMCCC_SMC_64		126#define ARM_SMCCC_CALL_CONV_SHIFT	3027 28#define ARM_SMCCC_OWNER_MASK		0x3F29#define ARM_SMCCC_OWNER_SHIFT		2430 31#define ARM_SMCCC_FUNC_MASK		0xFFFF32 33#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\34	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))35#define ARM_SMCCC_IS_64(smc_val) \36	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))37#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)38#define ARM_SMCCC_OWNER_NUM(smc_val) \39	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)40 41#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \42	(((type) << ARM_SMCCC_TYPE_SHIFT) | \43	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \44	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \45	((func_num) & ARM_SMCCC_FUNC_MASK))46 47#define ARM_SMCCC_OWNER_ARCH		048#define ARM_SMCCC_OWNER_CPU		149#define ARM_SMCCC_OWNER_SIP		250#define ARM_SMCCC_OWNER_OEM		351#define ARM_SMCCC_OWNER_STANDARD	452#define ARM_SMCCC_OWNER_STANDARD_HYP	553#define ARM_SMCCC_OWNER_VENDOR_HYP	654#define ARM_SMCCC_OWNER_TRUSTED_APP	4855#define ARM_SMCCC_OWNER_TRUSTED_APP_END	4956#define ARM_SMCCC_OWNER_TRUSTED_OS	5057#define ARM_SMCCC_OWNER_TRUSTED_OS_END	6358 59#define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff0160 61#define ARM_SMCCC_QUIRK_NONE		062#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */63 64#define ARM_SMCCC_VERSION_1_0		0x1000065#define ARM_SMCCC_VERSION_1_1		0x1000166#define ARM_SMCCC_VERSION_1_2		0x1000267#define ARM_SMCCC_VERSION_1_3		0x1000368 69#define ARM_SMCCC_1_3_SVE_HINT		0x1000070#define ARM_SMCCC_CALL_HINTS		ARM_SMCCC_1_3_SVE_HINT71 72 73#define ARM_SMCCC_VERSION_FUNC_ID					\74	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\75			   ARM_SMCCC_SMC_32,				\76			   0, 0)77 78#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\79	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\80			   ARM_SMCCC_SMC_32,				\81			   0, 1)82 83#define ARM_SMCCC_ARCH_SOC_ID						\84	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\85			   ARM_SMCCC_SMC_32,				\86			   0, 2)87 88#define ARM_SMCCC_ARCH_WORKAROUND_1					\89	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\90			   ARM_SMCCC_SMC_32,				\91			   0, 0x8000)92 93#define ARM_SMCCC_ARCH_WORKAROUND_2					\94	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\95			   ARM_SMCCC_SMC_32,				\96			   0, 0x7fff)97 98#define ARM_SMCCC_ARCH_WORKAROUND_3					\99	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\100			   ARM_SMCCC_SMC_32,				\101			   0, 0x3fff)102 103#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID				\104	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\105			   ARM_SMCCC_SMC_32,				\106			   ARM_SMCCC_OWNER_VENDOR_HYP,			\107			   ARM_SMCCC_FUNC_QUERY_CALL_UID)108 109/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */110#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0	0xb66fb428U111#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1	0xe911c52eU112#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2	0x564bcaa9U113#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3	0x743a004dU114 115/* KVM "vendor specific" services */116#define ARM_SMCCC_KVM_FUNC_FEATURES		0117#define ARM_SMCCC_KVM_FUNC_PTP			1118/* Start of pKVM hypercall range */119#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO		2120#define ARM_SMCCC_KVM_FUNC_MEM_SHARE		3121#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE		4122#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5		5123#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6		6124#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD		7125#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8		8126#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9		9127#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10		10128#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11		11129#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12		12130#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13		13131#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14		14132#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15		15133#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16		16134#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17		17135#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18		18136#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19		19137#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20		20138#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21		21139#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22		22140#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23		23141#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24		24142#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25		25143#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26		26144#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27		27145#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28		28146#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29		29147#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30		30148#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31		31149#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32		32150#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33		33151#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34		34152#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35		35153#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36		36154#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37		37155#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38		38156#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39		39157#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40		40158#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41		41159#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42		42160#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43		43161#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44		44162#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45		45163#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46		46164#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47		47165#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48		48166#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49		49167#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50		50168#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51		51169#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52		52170#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53		53171#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54		54172#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55		55173#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56		56174#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57		57175#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58		58176#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59		59177#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60		60178#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61		61179#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62		62180#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63		63181/* End of pKVM hypercall range */182#define ARM_SMCCC_KVM_FUNC_FEATURES_2		127183#define ARM_SMCCC_KVM_NUM_FUNCS			128184 185#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID			\186	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\187			   ARM_SMCCC_SMC_32,				\188			   ARM_SMCCC_OWNER_VENDOR_HYP,			\189			   ARM_SMCCC_KVM_FUNC_FEATURES)190 191#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED	1192 193/*194 * ptp_kvm is a feature used for time sync between vm and host.195 * ptp_kvm module in guest kernel will get service from host using196 * this hypercall ID.197 */198#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID				\199	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\200			   ARM_SMCCC_SMC_32,				\201			   ARM_SMCCC_OWNER_VENDOR_HYP,			\202			   ARM_SMCCC_KVM_FUNC_PTP)203 204#define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID			\205	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\206			   ARM_SMCCC_SMC_64,				\207			   ARM_SMCCC_OWNER_VENDOR_HYP,			\208			   ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)209 210#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID			\211	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\212			   ARM_SMCCC_SMC_64,				\213			   ARM_SMCCC_OWNER_VENDOR_HYP,			\214			   ARM_SMCCC_KVM_FUNC_MEM_SHARE)215 216#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID			\217	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\218			   ARM_SMCCC_SMC_64,				\219			   ARM_SMCCC_OWNER_VENDOR_HYP,			\220			   ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)221 222#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID			\223	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\224			   ARM_SMCCC_SMC_64,				\225			   ARM_SMCCC_OWNER_VENDOR_HYP,			\226			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD)227 228/* ptp_kvm counter type ID */229#define KVM_PTP_VIRT_COUNTER			0230#define KVM_PTP_PHYS_COUNTER			1231 232/* Paravirtualised time calls (defined by ARM DEN0057A) */233#define ARM_SMCCC_HV_PV_TIME_FEATURES				\234	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\235			   ARM_SMCCC_SMC_64,			\236			   ARM_SMCCC_OWNER_STANDARD_HYP,	\237			   0x20)238 239#define ARM_SMCCC_HV_PV_TIME_ST					\240	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\241			   ARM_SMCCC_SMC_64,			\242			   ARM_SMCCC_OWNER_STANDARD_HYP,	\243			   0x21)244 245/* TRNG entropy source calls (defined by ARM DEN0098) */246#define ARM_SMCCC_TRNG_VERSION					\247	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\248			   ARM_SMCCC_SMC_32,			\249			   ARM_SMCCC_OWNER_STANDARD,		\250			   0x50)251 252#define ARM_SMCCC_TRNG_FEATURES					\253	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\254			   ARM_SMCCC_SMC_32,			\255			   ARM_SMCCC_OWNER_STANDARD,		\256			   0x51)257 258#define ARM_SMCCC_TRNG_GET_UUID					\259	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\260			   ARM_SMCCC_SMC_32,			\261			   ARM_SMCCC_OWNER_STANDARD,		\262			   0x52)263 264#define ARM_SMCCC_TRNG_RND32					\265	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\266			   ARM_SMCCC_SMC_32,			\267			   ARM_SMCCC_OWNER_STANDARD,		\268			   0x53)269 270#define ARM_SMCCC_TRNG_RND64					\271	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\272			   ARM_SMCCC_SMC_64,			\273			   ARM_SMCCC_OWNER_STANDARD,		\274			   0x53)275 276/*277 * Return codes defined in ARM DEN 0070A278 * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C279 */280#define SMCCC_RET_SUCCESS			0281#define SMCCC_RET_NOT_SUPPORTED			-1282#define SMCCC_RET_NOT_REQUIRED			-2283#define SMCCC_RET_INVALID_PARAMETER		-3284 285#ifndef __ASSEMBLY__286 287#include <linux/linkage.h>288#include <linux/types.h>289 290enum arm_smccc_conduit {291	SMCCC_CONDUIT_NONE,292	SMCCC_CONDUIT_SMC,293	SMCCC_CONDUIT_HVC,294};295 296/**297 * arm_smccc_1_1_get_conduit()298 *299 * Returns the conduit to be used for SMCCCv1.1 or later.300 *301 * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.302 */303enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);304 305/**306 * arm_smccc_get_version()307 *308 * Returns the version to be used for SMCCCv1.1 or later.309 *310 * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this311 * does not imply the presence of firmware or a valid conduit. Caller312 * handling SMCCCv1.0 must determine the conduit by other means.313 */314u32 arm_smccc_get_version(void);315 316void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);317 318/**319 * arm_smccc_get_soc_id_version()320 *321 * Returns the SOC ID version.322 *323 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.324 */325s32 arm_smccc_get_soc_id_version(void);326 327/**328 * arm_smccc_get_soc_id_revision()329 *330 * Returns the SOC ID revision.331 *332 * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.333 */334s32 arm_smccc_get_soc_id_revision(void);335 336/**337 * struct arm_smccc_res - Result from SMC/HVC call338 * @a0-a3 result values from registers 0 to 3339 */340struct arm_smccc_res {341	unsigned long a0;342	unsigned long a1;343	unsigned long a2;344	unsigned long a3;345};346 347#ifdef CONFIG_ARM64348/**349 * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call350 * @a0-a17 argument values from registers 0 to 17351 */352struct arm_smccc_1_2_regs {353	unsigned long a0;354	unsigned long a1;355	unsigned long a2;356	unsigned long a3;357	unsigned long a4;358	unsigned long a5;359	unsigned long a6;360	unsigned long a7;361	unsigned long a8;362	unsigned long a9;363	unsigned long a10;364	unsigned long a11;365	unsigned long a12;366	unsigned long a13;367	unsigned long a14;368	unsigned long a15;369	unsigned long a16;370	unsigned long a17;371};372 373/**374 * arm_smccc_1_2_hvc() - make HVC calls375 * @args: arguments passed via struct arm_smccc_1_2_regs376 * @res: result values via struct arm_smccc_1_2_regs377 *378 * This function is used to make HVC calls following SMC Calling Convention379 * v1.2 or above. The content of the supplied param are copied from the380 * structure to registers prior to the HVC instruction. The return values381 * are updated with the content from registers on return from the HVC382 * instruction.383 */384asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,385				  struct arm_smccc_1_2_regs *res);386 387/**388 * arm_smccc_1_2_smc() - make SMC calls389 * @args: arguments passed via struct arm_smccc_1_2_regs390 * @res: result values via struct arm_smccc_1_2_regs391 *392 * This function is used to make SMC calls following SMC Calling Convention393 * v1.2 or above. The content of the supplied param are copied from the394 * structure to registers prior to the SMC instruction. The return values395 * are updated with the content from registers on return from the SMC396 * instruction.397 */398asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,399				  struct arm_smccc_1_2_regs *res);400#endif401 402/**403 * struct arm_smccc_quirk - Contains quirk information404 * @id: quirk identification405 * @state: quirk specific information406 * @a6: Qualcomm quirk entry for returning post-smc call contents of a6407 */408struct arm_smccc_quirk {409	int	id;410	union {411		unsigned long a6;412	} state;413};414 415/**416 * __arm_smccc_smc() - make SMC calls417 * @a0-a7: arguments passed in registers 0 to 7418 * @res: result values from registers 0 to 3419 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.420 *421 * This function is used to make SMC calls following SMC Calling Convention.422 * The content of the supplied param are copied to registers 0 to 7 prior423 * to the SMC instruction. The return values are updated with the content424 * from register 0 to 3 on return from the SMC instruction.  An optional425 * quirk structure provides vendor specific behavior.426 */427#ifdef CONFIG_HAVE_ARM_SMCCC428asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,429			unsigned long a2, unsigned long a3, unsigned long a4,430			unsigned long a5, unsigned long a6, unsigned long a7,431			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);432#else433static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,434			unsigned long a2, unsigned long a3, unsigned long a4,435			unsigned long a5, unsigned long a6, unsigned long a7,436			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)437{438	*res = (struct arm_smccc_res){};439}440#endif441 442/**443 * __arm_smccc_hvc() - make HVC calls444 * @a0-a7: arguments passed in registers 0 to 7445 * @res: result values from registers 0 to 3446 * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.447 *448 * This function is used to make HVC calls following SMC Calling449 * Convention.  The content of the supplied param are copied to registers 0450 * to 7 prior to the HVC instruction. The return values are updated with451 * the content from register 0 to 3 on return from the HVC instruction.  An452 * optional quirk structure provides vendor specific behavior.453 */454asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,455			unsigned long a2, unsigned long a3, unsigned long a4,456			unsigned long a5, unsigned long a6, unsigned long a7,457			struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);458 459#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)460 461#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)462 463#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)464 465#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)466 467/* SMCCC v1.1 implementation madness follows */468#ifdef CONFIG_ARM64469 470#define SMCCC_SMC_INST	"smc	#0"471#define SMCCC_HVC_INST	"hvc	#0"472 473#elif defined(CONFIG_ARM)474#include <asm/opcodes-sec.h>475#include <asm/opcodes-virt.h>476 477#define SMCCC_SMC_INST	__SMC(0)478#define SMCCC_HVC_INST	__HVC(0)479 480#endif481 482#define __constraint_read_2	"r" (arg0)483#define __constraint_read_3	__constraint_read_2, "r" (arg1)484#define __constraint_read_4	__constraint_read_3, "r" (arg2)485#define __constraint_read_5	__constraint_read_4, "r" (arg3)486#define __constraint_read_6	__constraint_read_5, "r" (arg4)487#define __constraint_read_7	__constraint_read_6, "r" (arg5)488#define __constraint_read_8	__constraint_read_7, "r" (arg6)489#define __constraint_read_9	__constraint_read_8, "r" (arg7)490 491#define __declare_arg_2(a0, res)					\492	struct arm_smccc_res   *___res = res;				\493	register unsigned long arg0 asm("r0") = (u32)a0494 495#define __declare_arg_3(a0, a1, res)					\496	typeof(a1) __a1 = a1;						\497	struct arm_smccc_res   *___res = res;				\498	register unsigned long arg0 asm("r0") = (u32)a0;			\499	register typeof(a1) arg1 asm("r1") = __a1500 501#define __declare_arg_4(a0, a1, a2, res)				\502	typeof(a1) __a1 = a1;						\503	typeof(a2) __a2 = a2;						\504	struct arm_smccc_res   *___res = res;				\505	register unsigned long arg0 asm("r0") = (u32)a0;			\506	register typeof(a1) arg1 asm("r1") = __a1;			\507	register typeof(a2) arg2 asm("r2") = __a2508 509#define __declare_arg_5(a0, a1, a2, a3, res)				\510	typeof(a1) __a1 = a1;						\511	typeof(a2) __a2 = a2;						\512	typeof(a3) __a3 = a3;						\513	struct arm_smccc_res   *___res = res;				\514	register unsigned long arg0 asm("r0") = (u32)a0;			\515	register typeof(a1) arg1 asm("r1") = __a1;			\516	register typeof(a2) arg2 asm("r2") = __a2;			\517	register typeof(a3) arg3 asm("r3") = __a3518 519#define __declare_arg_6(a0, a1, a2, a3, a4, res)			\520	typeof(a4) __a4 = a4;						\521	__declare_arg_5(a0, a1, a2, a3, res);				\522	register typeof(a4) arg4 asm("r4") = __a4523 524#define __declare_arg_7(a0, a1, a2, a3, a4, a5, res)			\525	typeof(a5) __a5 = a5;						\526	__declare_arg_6(a0, a1, a2, a3, a4, res);			\527	register typeof(a5) arg5 asm("r5") = __a5528 529#define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res)		\530	typeof(a6) __a6 = a6;						\531	__declare_arg_7(a0, a1, a2, a3, a4, a5, res);			\532	register typeof(a6) arg6 asm("r6") = __a6533 534#define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res)		\535	typeof(a7) __a7 = a7;						\536	__declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res);		\537	register typeof(a7) arg7 asm("r7") = __a7538 539/*540 * We have an output list that is not necessarily used, and GCC feels541 * entitled to optimise the whole sequence away. "volatile" is what542 * makes it stick.543 */544#define __arm_smccc_1_1(inst, ...)					\545	do {								\546		register unsigned long r0 asm("r0");			\547		register unsigned long r1 asm("r1");			\548		register unsigned long r2 asm("r2");			\549		register unsigned long r3 asm("r3"); 			\550		CONCATENATE(__declare_arg_,				\551			    COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__);	\552		asm volatile(inst "\n" :				\553			     "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)	\554			     : CONCATENATE(__constraint_read_,		\555					   COUNT_ARGS(__VA_ARGS__))	\556			     : "memory");				\557		if (___res)						\558			*___res = (typeof(*___res)){r0, r1, r2, r3};	\559	} while (0)560 561/*562 * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call563 *564 * This is a variadic macro taking one to eight source arguments, and565 * an optional return structure.566 *567 * @a0-a7: arguments passed in registers 0 to 7568 * @res: result values from registers 0 to 3569 *570 * This macro is used to make SMC calls following SMC Calling Convention v1.1.571 * The content of the supplied param are copied to registers 0 to 7 prior572 * to the SMC instruction. The return values are updated with the content573 * from register 0 to 3 on return from the SMC instruction if not NULL.574 */575#define arm_smccc_1_1_smc(...)	__arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)576 577/*578 * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call579 *580 * This is a variadic macro taking one to eight source arguments, and581 * an optional return structure.582 *583 * @a0-a7: arguments passed in registers 0 to 7584 * @res: result values from registers 0 to 3585 *586 * This macro is used to make HVC calls following SMC Calling Convention v1.1.587 * The content of the supplied param are copied to registers 0 to 7 prior588 * to the HVC instruction. The return values are updated with the content589 * from register 0 to 3 on return from the HVC instruction if not NULL.590 */591#define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)592 593/*594 * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.595 * Used when the SMCCC conduit is not defined. The empty asm statement596 * avoids compiler warnings about unused variables.597 */598#define __fail_smccc_1_1(...)						\599	do {								\600		CONCATENATE(__declare_arg_,				\601			    COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__);	\602		asm ("" :						\603		     : CONCATENATE(__constraint_read_,			\604				   COUNT_ARGS(__VA_ARGS__))		\605		     : "memory");					\606		if (___res)						\607			___res->a0 = SMCCC_RET_NOT_SUPPORTED;		\608	} while (0)609 610/*611 * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call612 *613 * This is a variadic macro taking one to eight source arguments, and614 * an optional return structure.615 *616 * @a0-a7: arguments passed in registers 0 to 7617 * @res: result values from registers 0 to 3618 *619 * This macro will make either an HVC call or an SMC call depending on the620 * current SMCCC conduit. If no valid conduit is available then -1621 * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).622 *623 * The return value also provides the conduit that was used.624 */625#define arm_smccc_1_1_invoke(...) ({					\626		int method = arm_smccc_1_1_get_conduit();		\627		switch (method) {					\628		case SMCCC_CONDUIT_HVC:					\629			arm_smccc_1_1_hvc(__VA_ARGS__);			\630			break;						\631		case SMCCC_CONDUIT_SMC:					\632			arm_smccc_1_1_smc(__VA_ARGS__);			\633			break;						\634		default:						\635			__fail_smccc_1_1(__VA_ARGS__);			\636			method = SMCCC_CONDUIT_NONE;			\637			break;						\638		}							\639		method;							\640	})641 642#endif /*__ASSEMBLY__*/643#endif /*__LINUX_ARM_SMCCC_H*/644