* [PATCH V3 1/2] xen/arm: Initial support for PSCI-0.2
2014-10-03 14:31 [PATCH V3 0/2] Introduce PSCI-0.2 supports suravee.suthikulpanit
@ 2014-10-03 14:31 ` suravee.suthikulpanit
2014-10-03 14:31 ` [PATCH V3 2/2] xen/arm: Use PSCI-0.2 for machine_halt/restart by default suravee.suthikulpanit
2014-10-08 11:59 ` [PATCH V3 0/2] Introduce PSCI-0.2 supports Ian Campbell
2 siblings, 0 replies; 6+ messages in thread
From: suravee.suthikulpanit @ 2014-10-03 14:31 UTC (permalink / raw)
To: stefano.stabellini, julien.grall, konrad.wilk, ian.campbell
Cc: Suravee Suthikulpanit, xen-devel
From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
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@amd.com>
---
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);
--
1.9.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH V3 2/2] xen/arm: Use PSCI-0.2 for machine_halt/restart by default
2014-10-03 14:31 [PATCH V3 0/2] Introduce PSCI-0.2 supports suravee.suthikulpanit
2014-10-03 14:31 ` [PATCH V3 1/2] xen/arm: Initial support for PSCI-0.2 suravee.suthikulpanit
@ 2014-10-03 14:31 ` suravee.suthikulpanit
2014-10-08 11:59 ` [PATCH V3 0/2] Introduce PSCI-0.2 supports Ian Campbell
2 siblings, 0 replies; 6+ messages in thread
From: suravee.suthikulpanit @ 2014-10-03 14:31 UTC (permalink / raw)
To: stefano.stabellini, julien.grall, konrad.wilk, ian.campbell
Cc: Suravee Suthikulpanit, xen-devel
From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
"machine_halt()" and "machine_restart()" are modified to use PSCI interface
by default if PSCI-0.2 is supported. The "raw_machine_reset()" is also removed
since this is unnecessary.
Also, machine_halt() is modified to add 10ms delay to make sure all auxiliary CPUs
are offlined before calling the shutdown.
For non-PSCI, platform_poweroff() and platform_reset() are used instead.
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
xen/arch/arm/shutdown.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/xen/arch/arm/shutdown.c b/xen/arch/arm/shutdown.c
index adc0529..4988b03 100644
--- a/xen/arch/arm/shutdown.c
+++ b/xen/arch/arm/shutdown.c
@@ -5,11 +5,7 @@
#include <xen/lib.h>
#include <xen/smp.h>
#include <asm/platform.h>
-
-static void raw_machine_reset(void)
-{
- platform_reset();
-}
+#include <asm/psci.h>
static void noreturn halt_this_cpu(void *arg)
{
@@ -18,10 +14,23 @@ static void noreturn halt_this_cpu(void *arg)
void machine_halt(void)
{
+ int timeout = 10;
+
watchdog_disable();
console_start_sync();
local_irq_enable();
smp_call_function(halt_this_cpu, NULL, 0);
+ local_irq_disable();
+
+ /* Wait at most another 10ms for all other CPUs to go offline. */
+ while ( (num_online_cpus() > 1) && (timeout-- > 0) )
+ mdelay(1);
+
+ /* This is mainly for PSCI-0.2, which does not return if success. */
+ call_psci_system_off();
+
+ /* Alternative halt procedure */
+ platform_poweroff();
halt_this_cpu(NULL);
}
@@ -39,9 +48,13 @@ void machine_restart(unsigned int delay_millisecs)
while ( (num_online_cpus() > 1) && (timeout-- > 0) )
mdelay(1);
+ /* This is mainly for PSCI-0.2, which does not return if success. */
+ call_psci_system_reset();
+
+ /* Alternative reset procedure */
while ( 1 )
{
- raw_machine_reset();
+ platform_reset();
mdelay(100);
}
}
--
1.9.3
^ permalink raw reply related [flat|nested] 6+ messages in thread