[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH] xen/arm: arm32: Enable smpboot on Arm32 based systems
On some of the Arm32 based systems (eg Cortex-R52), smpboot is supported. In these systems PSCI may not always be supported. In case of Cortex-R52, there is no EL3 or secure mode. Thus, PSCI is not supported as it requires EL3. Thus, we use 'spin-table' mechanism to boot the secondary cpus. The primary cpu provides the startup address of the secondary cores. This address is provided using the 'cpu-release-addr' property. To support smpboot, we have copied the code from xen/arch/arm/arm64/smpboot.c with the following changes :- 1. 'enable-method' is an optional property. Refer to the comment in https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpus.yaml " # On ARM 32-bit systems this property is optional" 2. psci is not currently supported as a value for 'enable-method'. 3. update_identity_mapping() is not invoked as we are not sure if it is required. Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx> --- The dts snippet with which this has been validated is :- cpus { #address-cells = <0x02>; #size-cells = <0x00>; cpu-map { cluster0 { core0 { thread0 { cpu = <0x02>; }; }; core1 { thread0 { cpu = <0x03>; }; }; }; }; cpu@0 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x00 0x00>; phandle = <0x02>; }; cpu@1 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x00 0x01>; enable-method = "spin-table"; cpu-release-addr = <0xEB58C010>; phandle = <0x03>; }; }; Although currently I have tested this on Cortex-R52, I feel this may be helpful to enable smp on other Arm32 based systems as well. Happy to hear opinions. xen/arch/arm/arm32/smpboot.c | 84 ++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/arm32/smpboot.c b/xen/arch/arm/arm32/smpboot.c index 518e9f9c7e..feb249d3f8 100644 --- a/xen/arch/arm/arm32/smpboot.c +++ b/xen/arch/arm/arm32/smpboot.c @@ -1,24 +1,100 @@ #include <xen/device_tree.h> #include <xen/init.h> #include <xen/smp.h> +#include <xen/vmap.h> +#include <asm/io.h> #include <asm/platform.h> +struct smp_enable_ops { + int (*prepare_cpu)(int); +}; + +static uint32_t cpu_release_addr[NR_CPUS]; +static struct smp_enable_ops smp_enable_ops[NR_CPUS]; + int __init arch_smp_init(void) { return platform_smp_init(); } -int __init arch_cpu_init(int cpu, struct dt_device_node *dn) +static int __init smp_spin_table_cpu_up(int cpu) +{ + uint32_t __iomem *release; + + if (!cpu_release_addr[cpu]) + { + printk("CPU%d: No release addr\n", cpu); + return -ENODEV; + } + + release = ioremap_nocache(cpu_release_addr[cpu], 4); + if ( !release ) + { + dprintk(XENLOG_ERR, "CPU%d: Unable to map release address\n", cpu); + return -EFAULT; + } + + writel(__pa(init_secondary), release); + + iounmap(release); + + sev(); + + return 0; +} + +static void __init smp_spin_table_init(int cpu, struct dt_device_node *dn) { - /* Not needed on ARM32, as there is no relevant information in - * the CPU device tree node for ARMv7 CPUs. + if ( !dt_property_read_u32(dn, "cpu-release-addr", &cpu_release_addr[cpu]) ) + { + printk("CPU%d has no cpu-release-addr\n", cpu); + return; + } + + smp_enable_ops[cpu].prepare_cpu = smp_spin_table_cpu_up; +} + +static int __init dt_arch_cpu_init(int cpu, struct dt_device_node *dn) +{ + const char *enable_method; + + /* + * Refer Documentation/devicetree/bindings/arm/cpus.yaml, it says on + * ARM 32-bit systems this property is optional. */ + enable_method = dt_get_property(dn, "enable-method", NULL); + if (!enable_method) + { + return 0; + } + + if ( !strcmp(enable_method, "spin-table") ) + smp_spin_table_init(cpu, dn); + else + { + printk("CPU%d has unknown enable method \"%s\"\n", cpu, enable_method); + return -EINVAL; + } + return 0; } +int __init arch_cpu_init(int cpu, struct dt_device_node *dn) +{ + return dt_arch_cpu_init(cpu, dn); +} + int arch_cpu_up(int cpu) { - return platform_cpu_up(cpu); + int ret = 0; + + if ( smp_enable_ops[cpu].prepare_cpu ) + ret = smp_enable_ops[cpu].prepare_cpu(cpu); + + if ( !ret ) + return platform_cpu_up(cpu); + + return ret; } void arch_cpu_up_finish(void) -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |