xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xen.org
Cc: julien.grall@linaro.org, tim@xen.org,
	Ian Campbell <ian.campbell@citrix.com>,
	stefano.stabellini@eu.citrix.com
Subject: [PATCH v2 5/9] xen: arm: implement arch/platform SMP and CPU initialisation framework
Date: Thu, 26 Sep 2013 11:49:12 +0100	[thread overview]
Message-ID: <1380192556-30700-5-git-send-email-ian.campbell@citrix.com> (raw)
In-Reply-To: <1380192538.29483.63.camel@kazak.uk.xensource.com>

Includes an implementation for vexpress using the sysflags interface and
support for the ARMv8 "spin-table" method.

Unused until the next patch, split out to simplify review.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/arm32/Makefile       |    1 +
 xen/arch/arm/arm32/head.S         |    2 +-
 xen/arch/arm/arm32/smpboot.c      |   29 ++++++++++++
 xen/arch/arm/arm64/Makefile       |    1 +
 xen/arch/arm/arm64/head.S         |    1 +
 xen/arch/arm/arm64/smpboot.c      |   89 +++++++++++++++++++++++++++++++++++++
 xen/arch/arm/platform.c           |   18 ++++++++
 xen/arch/arm/platforms/vexpress.c |   39 ++++++++++++++++
 xen/include/asm-arm/platform.h    |    9 ++++
 xen/include/asm-arm/smp.h         |    9 ++++
 10 files changed, 197 insertions(+), 1 deletion(-)
 create mode 100644 xen/arch/arm/arm32/smpboot.c
 create mode 100644 xen/arch/arm/arm64/smpboot.c

diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
index 18522dc..463b1f5 100644
--- a/xen/arch/arm/arm32/Makefile
+++ b/xen/arch/arm/arm32/Makefile
@@ -7,5 +7,6 @@ obj-y += proc-v7.o
 obj-y += traps.o
 obj-y += domain.o
 obj-y += vfp.o
+obj-y += smpboot.o
 
 obj-$(EARLY_PRINTK) += debug.o
diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 79e95b6..62fe475 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -59,7 +59,7 @@
          * or the initial pagetable code below will need adjustment. */
         .global start
 start:
-
+GLOBAL(init_secondary) /* currently unused */
         /* zImage magic header, see:
          * http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e309
          */
diff --git a/xen/arch/arm/arm32/smpboot.c b/xen/arch/arm/arm32/smpboot.c
new file mode 100644
index 0000000..88fe8fb
--- /dev/null
+++ b/xen/arch/arm/arm32/smpboot.c
@@ -0,0 +1,29 @@
+#include <xen/device_tree.h>
+#include <xen/init.h>
+#include <xen/smp.h>
+#include <asm/platform.h>
+
+int __init arch_smp_init(void)
+{
+    return platform_smp_init();
+}
+
+int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+{
+    /* TODO handle PSCI init */
+    return 0;
+}
+
+int __init arch_cpu_up(int cpu)
+{
+    return platform_cpu_up(cpu);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index e06a0a9..30fb480 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -6,5 +6,6 @@ obj-y += mode_switch.o
 obj-y += traps.o
 obj-y += domain.o
 obj-y += vfp.o
+obj-y += smpboot.o
 
 obj-$(EARLY_PRINTK) += debug.o
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 21b7e4d..4a45cc5 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -65,6 +65,7 @@
 
         .global start
 start:
+GLOBAL(init_secondary) /* currently unused */
         /*
          * DO NOT MODIFY. Image header expected by Linux boot-loaders.
          */
diff --git a/xen/arch/arm/arm64/smpboot.c b/xen/arch/arm/arm64/smpboot.c
new file mode 100644
index 0000000..8239590
--- /dev/null
+++ b/xen/arch/arm/arm64/smpboot.c
@@ -0,0 +1,89 @@
+#include <xen/cpu.h>
+#include <xen/lib.h>
+#include <xen/init.h>
+#include <xen/errno.h>
+#include <xen/mm.h>
+#include <xen/smp.h>
+
+struct smp_enable_ops {
+        int             (*prepare_cpu)(int);
+};
+
+static paddr_t cpu_release_addr[NR_CPUS];
+static struct smp_enable_ops smp_enable_ops[NR_CPUS];
+
+static int __init smp_spin_table_cpu_up(int cpu)
+{
+    paddr_t *release;
+
+    if (!cpu_release_addr[cpu])
+    {
+        printk("CPU%d: No release addr\n", cpu);
+        return -ENODEV;
+    }
+
+    release = __va(cpu_release_addr[cpu]);
+
+    release[0] = __pa(init_secondary);
+    flush_xen_data_tlb_range_va((vaddr_t)release, sizeof(*release));
+
+    sev();
+    return 0;
+}
+
+static void __init smp_spin_table_init(int cpu, struct dt_device_node *dn)
+{
+    if ( !dt_property_read_u64(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;
+}
+
+int __init arch_smp_init(void)
+{
+    /* Nothing */
+    return 0;
+}
+
+int __init arch_cpu_init(int cpu, struct dt_device_node *dn)
+{
+    const char *enable_method;
+
+    enable_method = dt_get_property(dn, "enable-method", NULL);
+    if (!enable_method)
+    {
+        printk("CPU%d has no enable method\n", cpu);
+        return -EINVAL;
+    }
+
+    if ( !strcmp(enable_method, "spin-table") )
+        smp_spin_table_init(cpu, dn);
+    /* TODO: method "psci" */
+    else
+    {
+        printk("CPU%d has unknown enable method \"%s\"\n", cpu, enable_method);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+int __init arch_cpu_up(int cpu)
+{
+    if ( !smp_enable_ops[cpu].prepare_cpu )
+        return -ENODEV;
+
+    return smp_enable_ops[cpu].prepare_cpu(cpu);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index db79368..db135f8 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -105,6 +105,24 @@ int __init platform_specific_mapping(struct domain *d)
     return res;
 }
 
+#ifdef CONFIG_ARM_32
+int __init platform_cpu_up(int cpu)
+{
+    if ( platform && platform->cpu_up )
+        return platform->cpu_up(cpu);
+
+    return -EAGAIN;
+}
+
+int __init platform_smp_init(void)
+{
+    if ( platform && platform->smp_init )
+        return platform->smp_init();
+
+    return 0;
+}
+#endif
+
 void platform_reset(void)
 {
     if ( platform && platform->reset )
diff --git a/xen/arch/arm/platforms/vexpress.c b/xen/arch/arm/platforms/vexpress.c
index 298c141..6255a0c 100644
--- a/xen/arch/arm/platforms/vexpress.c
+++ b/xen/arch/arm/platforms/vexpress.c
@@ -21,6 +21,7 @@
 #include <asm/platform.h>
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <asm/gic.h>
 
 #define DCC_SHIFT      26
 #define FUNCTION_SHIFT 20
@@ -119,6 +120,40 @@ static void vexpress_reset(void)
     iounmap(sp810);
 }
 
+#ifdef CONFIG_ARM_32
+
+static int vexpress_smp_init(void)
+{
+    void __iomem *sysflags;
+
+    sysflags = ioremap_nocache(V2M_SYS_MMIO_BASE, PAGE_SIZE);
+    if ( !sysflags )
+    {
+        dprintk(XENLOG_ERR, "Unable to map vexpress MMIO\n");
+        return -EFAULT;
+    }
+
+    printk("Set SYS_FLAGS to %"PRIpaddr" (%p)\n",
+           __pa(init_secondary), init_secondary);
+    iowritel(sysflags + V2M_SYS_FLAGSCLR, ~0);
+    iowritel(sysflags + V2M_SYS_FLAGSSET,
+             __pa(init_secondary));
+
+    iounmap(sysflags);
+
+    return 0;
+}
+
+static int vexpress_cpu_up(int cpu)
+{
+    /* Nothing to do here, the generic sev() will suffice to kick CPUs
+     * out of either the firmware or our own smp_up_cpu gate,
+     * depending on where they have ended up. */
+
+    return 0;
+}
+#endif
+
 static const char * const vexpress_dt_compat[] __initdata =
 {
     "arm,vexpress",
@@ -143,6 +178,10 @@ static const struct dt_device_match vexpress_blacklist_dev[] __initconst =
 
 PLATFORM_START(vexpress, "VERSATILE EXPRESS")
     .compatible = vexpress_dt_compat,
+#ifdef CONFIG_ARM_32
+    .smp_init = vexpress_smp_init,
+    .cpu_up = vexpress_cpu_up,
+#endif
     .reset = vexpress_reset,
     .blacklist_dev = vexpress_blacklist_dev,
 PLATFORM_END
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index a19dbf7..dbd2a15 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -15,6 +15,11 @@ struct platform_desc {
     /* Platform initialization */
     int (*init)(void);
     int (*init_time)(void);
+#ifdef CONFIG_ARM_32
+    /* SMP */
+    int (*smp_init)(void);
+    int (*cpu_up)(int cpu);
+#endif
     /* Specific mapping for dom0 */
     int (*specific_mapping)(struct domain *d);
     /* Platform reset */
@@ -43,6 +48,10 @@ struct platform_desc {
 int __init platform_init(void);
 int __init platform_init_time(void);
 int __init platform_specific_mapping(struct domain *d);
+#ifdef CONFIG_ARM_32
+int platform_smp_init(void);
+int platform_cpu_up(int cpu);
+#endif
 void platform_reset(void);
 void platform_poweroff(void);
 bool_t platform_has_quirk(uint32_t quirk);
diff --git a/xen/include/asm-arm/smp.h b/xen/include/asm-arm/smp.h
index 1c2746b..1added5 100644
--- a/xen/include/asm-arm/smp.h
+++ b/xen/include/asm-arm/smp.h
@@ -4,6 +4,7 @@
 #ifndef __ASSEMBLY__
 #include <xen/config.h>
 #include <xen/cpumask.h>
+#include <xen/device_tree.h>
 #include <asm/current.h>
 #endif
 
@@ -22,9 +23,17 @@ extern void stop_cpu(void);
 extern void
 make_cpus_ready(unsigned int max_cpus, unsigned long boot_phys_offset);
 
+extern int arch_smp_init(void);
+extern int arch_cpu_init(int cpu, struct dt_device_node *dn);
+extern int arch_cpu_up(int cpu);
+
+/* Secondary CPU entry point */
+extern void init_secondary(void);
+
 extern void smp_clear_cpu_maps (void);
 extern int smp_get_max_cpus (void);
 #endif
+
 /*
  * Local variables:
  * mode: C
-- 
1.7.10.4

  parent reply	other threads:[~2013-09-26 10:49 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-26 10:48 [PATCH v2 0/9] xen: arm: rework early bring up Ian Campbell
2013-09-26 10:49 ` [PATCH v2 1/9] xen: arm: Load xen under 4GB on 32-bit Ian Campbell
2013-09-26 10:49 ` [PATCH v2 2/9] xen: arm: Log the raw MIDR on boot Ian Campbell
2013-09-26 10:49 ` [PATCH v2 3/9] xen: arm: make sure we stay within the memory bank during mm setup Ian Campbell
2013-09-26 11:14   ` Julien Grall
2013-09-26 13:17   ` Tim Deegan
2013-09-26 10:49 ` [PATCH v2 4/9] xen: arm: add two new device tree helpers Ian Campbell
2013-09-26 10:49 ` Ian Campbell [this message]
2013-09-26 13:47   ` [PATCH v2 5/9] xen: arm: implement arch/platform SMP and CPU initialisation framework Tim Deegan
2013-09-26 14:06   ` Julien Grall
2013-09-26 14:12     ` Ian Campbell
2013-09-26 10:49 ` [PATCH v2 6/9] xen: arm: rewrite start of day page table and cpu bring up Ian Campbell
2013-09-26 12:59   ` Ian Campbell
2013-09-26 14:31     ` Tim Deegan
2013-09-26 10:49 ` [PATCH v2 7/9] xen: arm: use symbolic names for MPIDR bits Ian Campbell
2013-09-26 13:22   ` Tim Deegan
2013-09-26 13:35     ` Ian Campbell
2013-09-26 13:45       ` Tim Deegan
2013-09-26 10:49 ` [PATCH v2 8/9] xen: arm: configure TCR_EL2 for 40 bit physical address space Ian Campbell
2013-09-26 10:49 ` [PATCH v2 9/9] xen: arm: split cpu0's domheap mapping PTs out from xen_second Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1380192556-30700-5-git-send-email-ian.campbell@citrix.com \
    --to=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).