]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - include/linux/arm-smccc.h
Merge tag '5.5-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
[linux.git] / include / linux / arm-smccc.h
index df01a857903491f22199a2b6cff891e09234fb0d..59494df0f55b66e22ceebdb10255cccd61f97a8e 100644 (file)
@@ -45,6 +45,7 @@
 #define ARM_SMCCC_OWNER_SIP            2
 #define ARM_SMCCC_OWNER_OEM            3
 #define ARM_SMCCC_OWNER_STANDARD       4
+#define ARM_SMCCC_OWNER_STANDARD_HYP   5
 #define ARM_SMCCC_OWNER_TRUSTED_APP    48
 #define ARM_SMCCC_OWNER_TRUSTED_APP_END        49
 #define ARM_SMCCC_OWNER_TRUSTED_OS     50
@@ -318,5 +319,63 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 #define SMCCC_RET_NOT_SUPPORTED                        -1
 #define SMCCC_RET_NOT_REQUIRED                 -2
 
+/*
+ * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
+ * Used when the SMCCC conduit is not defined. The empty asm statement
+ * avoids compiler warnings about unused variables.
+ */
+#define __fail_smccc_1_1(...)                                          \
+       do {                                                            \
+               __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
+               asm ("" __constraints(__count_args(__VA_ARGS__)));      \
+               if (___res)                                             \
+                       ___res->a0 = SMCCC_RET_NOT_SUPPORTED;           \
+       } while (0)
+
+/*
+ * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro will make either an HVC call or an SMC call depending on the
+ * current SMCCC conduit. If no valid conduit is available then -1
+ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
+ *
+ * The return value also provides the conduit that was used.
+ */
+#define arm_smccc_1_1_invoke(...) ({                                   \
+               int method = arm_smccc_1_1_get_conduit();               \
+               switch (method) {                                       \
+               case SMCCC_CONDUIT_HVC:                                 \
+                       arm_smccc_1_1_hvc(__VA_ARGS__);                 \
+                       break;                                          \
+               case SMCCC_CONDUIT_SMC:                                 \
+                       arm_smccc_1_1_smc(__VA_ARGS__);                 \
+                       break;                                          \
+               default:                                                \
+                       __fail_smccc_1_1(__VA_ARGS__);                  \
+                       method = SMCCC_CONDUIT_NONE;                    \
+                       break;                                          \
+               }                                                       \
+               method;                                                 \
+       })
+
+/* Paravirtualised time calls (defined by ARM DEN0057A) */
+#define ARM_SMCCC_HV_PV_TIME_FEATURES                          \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                 \
+                          ARM_SMCCC_SMC_64,                    \
+                          ARM_SMCCC_OWNER_STANDARD_HYP,        \
+                          0x20)
+
+#define ARM_SMCCC_HV_PV_TIME_ST                                        \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,                 \
+                          ARM_SMCCC_SMC_64,                    \
+                          ARM_SMCCC_OWNER_STANDARD_HYP,        \
+                          0x21)
+
 #endif /*__ASSEMBLY__*/
 #endif /*__LINUX_ARM_SMCCC_H*/