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

[Xen-changelog] [xen master] xen/arm: Initial support for PSCI-0.2



commit 4d3d72c0146776e7c8efe6e531561bcbdab1cea7
Author:     Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx>
AuthorDate: Fri Oct 3 09:31:10 2014 -0500
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Tue Oct 14 10:19:39 2014 +0100

    xen/arm: Initial support for PSCI-0.2
    
    This patch adds SMC calls to suport a subset of PSCI-0.2 functions
    (PSCI_VERSION, CPU_ON, SYSTEM_OFF, SYSTEM_RESET).
    
    By default, the psci_init() will use PSCI-0.2. Otherwise, it will
    use PSCI-0.1 if PSCI-0.2 fails or un-supported.
    
    To add support for PSCI_VERSION, this patch replaces the "bool_t 
psci_available"
    variable with "int psci_ver", which contains the PSCI_VERSION as described 
in the
    PSCI-0.2 spec.
    
    Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/arm64/smpboot.c |    2 +-
 xen/arch/arm/platform.c      |    2 +-
 xen/arch/arm/psci.c          |   80 +++++++++++++++++++++++++++++++++++++-----
 xen/include/asm-arm/psci.h   |    4 ++-
 4 files changed, 76 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/arm64/smpboot.c b/xen/arch/arm/arm64/smpboot.c
index 9146476..341cc77 100644
--- a/xen/arch/arm/arm64/smpboot.c
+++ b/xen/arch/arm/arm64/smpboot.c
@@ -54,7 +54,7 @@ static void __init smp_spin_table_init(int cpu, struct 
dt_device_node *dn)
 
 static int __init smp_psci_init(int cpu)
 {
-    if ( !psci_available )
+    if ( !psci_ver )
     {
         printk("CPU%d asks for PSCI, but DTB has no PSCI node\n", cpu);
         return -ENODEV;
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 74c3328..cb4cda8 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -110,7 +110,7 @@ int __init platform_specific_mapping(struct domain *d)
 #ifdef CONFIG_ARM_32
 int __init platform_cpu_up(int cpu)
 {
-    if ( psci_available )
+    if ( psci_ver )
         return call_psci_cpu_on(cpu);
 
     if ( platform && platform->cpu_up )
diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index b6360d5..604ff4c 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -23,7 +23,7 @@
 #include <xen/smp.h>
 #include <asm/psci.h>
 
-bool_t psci_available;
+uint32_t psci_ver;
 
 #ifdef CONFIG_ARM_32
 #define REG_PREFIX "r"
@@ -58,16 +58,23 @@ int call_psci_cpu_on(int cpu)
                                 cpu_logical_map(cpu), __pa(init_secondary), 0);
 }
 
-int __init psci_init(void)
+void call_psci_system_off(void)
+{
+    if ( psci_ver > XEN_PSCI_V_0_1 )
+        __invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+}
+
+void call_psci_system_reset(void)
+{
+    if ( psci_ver > XEN_PSCI_V_0_1 )
+        __invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+
+int __init psci_is_smc_method(const struct dt_device_node *psci)
 {
-    const struct dt_device_node *psci;
     int ret;
     const char *prop_str;
 
-    psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
-    if ( !psci )
-        return -ENODEV;
-
     ret = dt_property_read_string(psci, "method", &prop_str);
     if ( ret )
     {
@@ -85,19 +92,74 @@ int __init psci_init(void)
         return -EINVAL;
     }
 
+    return 0;
+}
+
+int __init psci_init_0_1(void)
+{
+    int ret;
+    const struct dt_device_node *psci;
+
+    psci = dt_find_compatible_node(NULL, NULL, "arm,psci");
+    if ( !psci )
+        return -EOPNOTSUPP;
+
+    ret = psci_is_smc_method(psci);
+    if ( ret )
+        return -EINVAL;
+
     if ( !dt_property_read_u32(psci, "cpu_on", &psci_cpu_on_nr) )
     {
         printk("/psci node is missing the \"cpu_on\" property\n");
         return -ENOENT;
     }
 
-    psci_available = 1;
+    psci_ver = XEN_PSCI_V_0_1;
+
+    printk(XENLOG_INFO "Using PSCI-0.1 for SMP bringup\n");
+
+    return 0;
+}
+
+int __init psci_init_0_2(void)
+{
+    int ret;
+    const struct dt_device_node *psci;
+
+    psci = dt_find_compatible_node(NULL, NULL, "arm,psci-0.2");
+    if ( !psci )
+       return -EOPNOTSUPP;
+
+    ret = psci_is_smc_method(psci);
+    if ( ret )
+        return -EINVAL;
+
+    psci_ver = __invoke_psci_fn_smc(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
+
+    if ( psci_ver != XEN_PSCI_V_0_2 )
+    {
+        printk("Error: PSCI version %#x is not supported.\n", psci_ver);
+        return -EOPNOTSUPP;
+    }
+
+    psci_cpu_on_nr = PSCI_0_2_FN_CPU_ON;
 
-    printk(XENLOG_INFO "Using PSCI for SMP bringup\n");
+    printk(XENLOG_INFO "Using PSCI-0.2 for SMP bringup\n");
 
     return 0;
 }
 
+int __init psci_init(void)
+{
+    int ret;
+
+    ret = psci_init_0_2();
+    if ( ret )
+        ret = psci_init_0_1();
+
+    return ret;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
index 9777c03..5d17ee3 100644
--- a/xen/include/asm-arm/psci.h
+++ b/xen/include/asm-arm/psci.h
@@ -13,10 +13,12 @@
 #define PSCI_DISABLED               -8
 
 /* availability of PSCI on the host for SMP bringup */
-extern bool_t psci_available;
+extern uint32_t psci_ver;
 
 int psci_init(void);
 int call_psci_cpu_on(int cpu);
+void call_psci_system_off(void);
+void call_psci_system_reset(void);
 
 /* functions to handle guest PSCI requests */
 int32_t do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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