[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [V2 1/2] xen/arm: Initial support for PSCI-0.2 (cpu_on, system_off, system_reset)
From: Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx> This patch adds SMC calls to suport PSCI-0.2: * PSCI_VERSION * CPU_ON * SYSTEM_OFF * SYSTEM_RESET First, the psci_init() is refactored to handle both PSCI-0.1 and PSCI-0.2. 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. For v0.1, this psci_ver is 1. Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@xxxxxxx> --- 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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |