[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC] arm: Handle SiP Service Calls



Support ARM SiP (Silicon Provider) services.
 - Import arm-smccc.h from Linux Kernel
   ca122fe376fc ("Merge tag 'arc-4.15-rc1' of
   git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc")
 - Introudce a new callback function in platform_desc
 - Add do_trap_hvccc to handle non xen specific hypercalls

 Platforms that want to use SiP service could use platform
 specific sip implementation.

Signed-off-by: Peng Fan <peng.fan@xxxxxxx>
---

In my Dom0 kernel, there is SiP smccc call. Without xen, the call
will trap to ATF. With xen, I use hvccc to replace smccc, but
xen still report error, because xen does not handle SiP calls.
Not sure this is the best way. Since SiP is silicon provider
service, so I put it into platform code.

 xen/arch/arm/platform.c         |   8 +++
 xen/arch/arm/traps.c            |  18 +++++-
 xen/include/asm-arm/arm-smccc.h | 137 ++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/platform.h  |   3 +
 4 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100644 xen/include/asm-arm/arm-smccc.h

diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 0af6d57bfe..0540edf67b 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -115,6 +115,14 @@ int __init platform_smp_init(void)
 }
 #endif
 
+void platform_sip(struct cpu_user_regs *regs)
+{
+    if ( platform && platform->sip )
+        platform->sip(regs);
+    else
+        domain_crash_synchronous();
+}
+
 void platform_reset(void)
 {
     if ( platform && platform->reset )
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 6cf9ee7244..97ff07885e 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -35,6 +35,7 @@
 #include <xen/iocap.h>
 #include <public/sched.h>
 #include <public/xen.h>
+#include <asm/arm-smccc.h>
 #include <asm/debugger.h>
 #include <asm/event.h>
 #include <asm/regs.h>
@@ -44,6 +45,7 @@
 #include <asm/cpufeature.h>
 #include <asm/flushtlb.h>
 #include <asm/monitor.h>
+#include <asm/platform.h>
 
 #include "decode.h"
 #include "vtimer.h"
@@ -1453,10 +1455,12 @@ static void do_debug_trap(struct cpu_user_regs *regs, 
unsigned int code)
 #define PSCI_RESULT_REG(reg) (reg)->x0
 #define PSCI_ARG(reg,n) (reg)->x##n
 #define PSCI_ARG32(reg,n) (uint32_t)( (reg)->x##n & 0x00000000FFFFFFFF )
+#define HVCCC_ARG(reg,n) (reg)->x##n
 #else
 #define PSCI_RESULT_REG(reg) (reg)->r0
 #define PSCI_ARG(reg,n) (reg)->r##n
 #define PSCI_ARG32(reg,n) PSCI_ARG(reg,n)
+#define HVCCC_ARG(reg,n) (reg)->r##n
 #endif
 
 /* helper function for checking arm mode 32/64 bit */
@@ -1566,6 +1570,16 @@ static void do_trap_psci(struct cpu_user_regs *regs)
     }
 }
 
+static void do_trap_hvccc(struct cpu_user_regs *regs)
+{
+    register_t fid = HVCCC_ARG(regs,0);
+
+    if (ARM_SMCCC_OWNER_NUM(fid) == ARM_SMCCC_OWNER_SIP)
+        return platform_sip(regs);
+
+    return do_trap_psci(regs);
+}
+
 #ifdef CONFIG_ARM_64
 #define HYPERCALL_RESULT_REG(r) (r)->x0
 #define HYPERCALL_ARG1(r) (r)->x0
@@ -2884,7 +2898,7 @@ asmlinkage void do_trap_guest_sync(struct cpu_user_regs 
*regs)
             return do_debug_trap(regs, hsr.iss & 0x00ff);
 #endif
         if ( hsr.iss == 0 )
-            return do_trap_psci(regs);
+            return do_trap_hvccc(regs);
         do_trap_hypercall(regs, (register_t *)&regs->r12, hsr.iss);
         break;
 #ifdef CONFIG_ARM_64
@@ -2896,7 +2910,7 @@ asmlinkage void do_trap_guest_sync(struct cpu_user_regs 
*regs)
             return do_debug_trap(regs, hsr.iss & 0x00ff);
 #endif
         if ( hsr.iss == 0 )
-            return do_trap_psci(regs);
+            return do_trap_hvccc(regs);
         do_trap_hypercall(regs, &regs->x16, hsr.iss);
         break;
     case HSR_EC_SMC64:
diff --git a/xen/include/asm-arm/arm-smccc.h b/xen/include/asm-arm/arm-smccc.h
new file mode 100644
index 0000000000..92ab9417c8
--- /dev/null
+++ b/xen/include/asm-arm/arm-smccc.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+#define ARM_SMCCC_STD_CALL             0
+#define ARM_SMCCC_FAST_CALL            1
+#define ARM_SMCCC_TYPE_SHIFT           31
+
+#define ARM_SMCCC_SMC_32               0
+#define ARM_SMCCC_SMC_64               1
+#define ARM_SMCCC_CALL_CONV_SHIFT      30
+
+#define ARM_SMCCC_OWNER_MASK           0x3F
+#define ARM_SMCCC_OWNER_SHIFT          24
+
+#define ARM_SMCCC_FUNC_MASK            0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val)        \
+       ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+       ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val)    ((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+       (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+       (((type) << ARM_SMCCC_TYPE_SHIFT) | \
+       ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+       (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+       ((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH           0
+#define ARM_SMCCC_OWNER_CPU            1
+#define ARM_SMCCC_OWNER_SIP            2
+#define ARM_SMCCC_OWNER_OEM            3
+#define ARM_SMCCC_OWNER_STANDARD       4
+#define ARM_SMCCC_OWNER_TRUSTED_APP    48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END        49
+#define ARM_SMCCC_OWNER_TRUSTED_OS     50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
+
+#define ARM_SMCCC_QUIRK_NONE           0
+#define ARM_SMCCC_QUIRK_QCOM_A6                1 /* Save/restore register a6 */
+
+#ifndef __ASSEMBLY__
+
+/**
+ * #include <linux/linkage.h>
+ * #include <linux/types.h>
+ */
+
+/**
+ * struct arm_smccc_res - Result from SMC/HVC call
+ * @a0-a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+       unsigned long a0;
+       unsigned long a1;
+       unsigned long a2;
+       unsigned long a3;
+};
+
+/**
+ * struct arm_smccc_quirk - Contains quirk information
+ * @id: quirk identification
+ * @state: quirk specific information
+ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6
+ */
+struct arm_smccc_quirk {
+       int     id;
+       union {
+               unsigned long a6;
+       } state;
+};
+
+/**
+ * __arm_smccc_smc() - make SMC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make SMC calls following SMC Calling Convention.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction.  An optional
+ * quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
+                       unsigned long a2, unsigned long a3, unsigned long a4,
+                       unsigned long a5, unsigned long a6, unsigned long a7,
+                       struct arm_smccc_res *res, struct arm_smccc_quirk 
*quirk);
+
+/**
+ * __arm_smccc_hvc() - make HVC calls
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
+ *
+ * This function is used to make HVC calls following SMC Calling
+ * Convention.  The content of the supplied param are copied to registers 0
+ * to 7 prior to the HVC instruction. The return values are updated with
+ * the content from register 0 to 3 on return from the HVC instruction.  An
+ * optional quirk structure provides vendor specific behavior.
+ */
+asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
+                       unsigned long a2, unsigned long a3, unsigned long a4,
+                       unsigned long a5, unsigned long a6, unsigned long a7,
+                       struct arm_smccc_res *res, struct arm_smccc_quirk 
*quirk);
+
+#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
+
+#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
+
+#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
+
+#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
+
+#endif /*__ASSEMBLY__*/
+#endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index 08010ba09b..d49980e25d 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -26,6 +26,8 @@ struct platform_desc {
     void (*reset)(void);
     /* Platform power-off */
     void (*poweroff)(void);
+    /* Platform SIP service */
+    void (*sip)(struct cpu_user_regs *regs);
     /*
      * Platform quirks
      * Defined has a function because a platform can support multiple
@@ -53,6 +55,7 @@ int __init platform_specific_mapping(struct domain *d);
 int platform_smp_init(void);
 int platform_cpu_up(int cpu);
 #endif
+void platform_sip(struct cpu_user_regs *regs);
 void platform_reset(void);
 void platform_poweroff(void);
 bool_t platform_has_quirk(uint32_t quirk);
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.