This is the minimal set of changes/hacks necessary to get interprocessor
interrupts delivered reliably.

This is certainly not for submission, I am just posting it because I
would appreciate any feedback on the direction this is headed.

Basically, we are "sharing" the mpic less, but I have not ripped it
entirely out of dom0 and made a proper virtual PIC.

---

 mpic.c |    4 ++++
 1 file changed, 4 insertions(+)

diff -r b9e38b262f64 arch/powerpc/sysdev/mpic.c
--- a/arch/powerpc/sysdev/mpic.c        Sun Oct 08 14:22:12 2006 -0400
+++ b/arch/powerpc/sysdev/mpic.c        Tue Oct 10 18:10:53 2006 -0400
@@ -619,6 +619,7 @@ struct mpic * __init mpic_alloc(unsigned
        mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
        BUG_ON(mpic->gregs == NULL);
 
+#if 0
        /* Reset */
        if (flags & MPIC_WANTS_RESET) {
                mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
@@ -628,6 +629,7 @@ struct mpic * __init mpic_alloc(unsigned
                       & MPIC_GREG_GCONF_RESET)
                        mb();
        }
+#endif
 
        /* Read feature register, calculate num CPUs and, for non-ISU
         * MPICs, num sources as well. On ISU MPICs, sources are counted
@@ -741,6 +743,7 @@ void __init mpic_init(struct mpic *mpic)
                           (MPIC_VEC_TIMER_0 + i));
        }
 
+#if 0
        /* Initialize IPIs to our reserved vectors and mark them disabled for 
now */
        mpic_test_broken_ipi(mpic);
        for (i = 0; i < 4; i++) {
@@ -755,6 +758,7 @@ void __init mpic_init(struct mpic *mpic)
                irq_desc[mpic->ipi_offset+i].chip = &mpic->hc_ipi;
 #endif /* CONFIG_SMP */
        }
+#endif
 
        /* Initialize interrupt sources */
        if (mpic->irq_count == 0)

---

 exceptions.c |    3 +++
 external.c   |    8 +++++++-
 mpic.c       |   24 +++++++++++++++++++++---
 mpic_init.c  |    5 ++++-
 setup.c      |   50 ++++++++++++++++++++++++++++++--------------------
 smp.c        |    7 +++++--
 6 files changed, 70 insertions(+), 27 deletions(-)

diff -r 3583d2701405 xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c     Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/exceptions.c     Tue Oct 10 18:11:10 2006 -0400
@@ -26,6 +26,7 @@
 #include <xen/gdbstub.h>
 #include <xen/console.h>
 #include <xen/shutdown.h>
+#include <asm/mpic.h>
 #include <asm/time.h>
 #include <asm/processor.h>
 #include <asm/debugger.h>
@@ -44,6 +45,8 @@ void do_timer(struct cpu_user_regs *regs
     /* Set HDEC high so it stops firing and can be reprogrammed by
      * set_preempt() */
     mthdec(INT_MAX);
+    if (mftb() % 2048 == 0)
+        mpic_send_ipi(3,2);
     raise_softirq(TIMER_SOFTIRQ);
 }
 
diff -r 3583d2701405 xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c       Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/external.c       Tue Oct 10 11:27:30 2006 -0400
@@ -85,7 +85,13 @@ void do_external(struct cpu_user_regs *r
     if (vec != -1) {
         DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
         regs->entry_vector = vec;
-        do_IRQ(regs);
+        if (vec != 131)
+           do_IRQ(regs);
+        else {
+           printk("%s: got IPI: cpu #%d!\n", __func__, smp_processor_id());
+           void mpic_end_ipi(unsigned int irq);
+           mpic_end_ipi(vec);
+        }
 
         BUG_ON(mfmsr() & MSR_EE);
         spur_count = 0;
diff -r 3583d2701405 xen/arch/powerpc/mpic.c
--- a/xen/arch/powerpc/mpic.c   Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/mpic.c   Tue Oct 10 11:30:04 2006 -0400
@@ -27,8 +27,6 @@
 
 
 #define alloc_bootmem(x) xmalloc_bytes(x)
-#define request_irq(irq, handler, f, devname, dev_id) \
-    panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
 
 typedef int irqreturn_t;
 
@@ -598,7 +596,8 @@ static void mpic_disable_ipi(unsigned in
        /* NEVER disable an IPI... that's just plain wrong! */
 }
 
-static void mpic_end_ipi(unsigned int irq)
+void mpic_end_ipi(unsigned int irq);
+void mpic_end_ipi(unsigned int irq)
 {
        struct mpic *mpic = mpic_from_ipi(irq);
 
@@ -1065,6 +1064,25 @@ int mpic_get_irq(struct pt_regs *regs)
 
 
 #ifdef CONFIG_SMP
+
+#define SA_INTERRUPT   0x20000000u
+
+/*      request_irq - allocate an interrupt line
+ *      @irq: Interrupt line to allocate
+ *      @handler: Function to be called when the IRQ occurs
+ *      @irqflags: Interrupt type flags
+ *      @devname: An ascii name for the claiming device
+ *      @dev_id: A cookie passed back to the handler function
+ */
+static int request_irq(unsigned int irq,
+                irqreturn_t (*handler)(int, void *, struct pt_regs *),
+                unsigned long irqflags, const char * devname, void *dev_id)
+{
+    printk("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id);
+    mpic_enable_ipi(irq);
+    return 0;
+}
+
 void mpic_request_ipis(void)
 {
        struct mpic *mpic = mpic_primary;
diff -r 3583d2701405 xen/arch/powerpc/mpic_init.c
--- a/xen/arch/powerpc/mpic_init.c      Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/mpic_init.c      Mon Oct 09 19:57:03 2006 -0400
@@ -26,7 +26,7 @@
 #include "oftree.h"
 #include "of-devtree.h"
 
-#undef DEBUG
+#define DEBUG
 #define CONFIG_SHARE_MPIC
 
 #ifdef DEBUG
@@ -397,6 +397,9 @@ struct hw_interrupt_type *xen_mpic_init(
     hit = share_mpic(&mpic->hc_irq, xen_irq);
 
     printk("%s: success\n", __func__);
+
+    mpic_request_ipis();
+
     return hit;
 }
 
diff -r 3583d2701405 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/setup.c  Tue Oct 10 15:17:45 2006 -0400
@@ -37,6 +37,7 @@
 #include <xen/keyhandler.h>
 #include <acm/acm_hooks.h>
 #include <public/version.h>
+#include <asm/mpic.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
 #include <asm/cache.h>
@@ -91,6 +92,8 @@ extern char __per_cpu_start[], __per_cpu
 /* move us to a header file */
 extern void initialize_keytable(void);
 
+static struct domain *idle_domain;
+
 volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
 
 int is_kernel_text(unsigned long addr)
@@ -154,8 +157,6 @@ static void percpu_free_unused_areas(voi
 
 static void __init start_of_day(void)
 {
-    struct domain *idle_domain;
-
     init_IRQ();
 
     scheduler_init();
@@ -169,23 +170,6 @@ static void __init start_of_day(void)
 
     /* for some reason we need to set our own bit in the thread map */
     cpu_set(0, cpu_sibling_map[0]);
-
-    percpu_free_unused_areas();
-
-    {
-        /* FIXME: Xen assumes that an online CPU is a schedualable
-         * CPU, but we just are not there yet. Remove this fragment when
-         * scheduling processors actually works. */
-        int cpuid;
-
-        printk("WARNING!: Taking all secondary CPUs offline\n");
-
-        for_each_online_cpu(cpuid) {
-            if (cpuid == 0)
-                continue;
-            cpu_clear(cpuid, cpu_online_map);
-        }
-    }
 
     initialize_keytable();
     /* Register another key that will allow for the the Harware Probe
@@ -258,9 +242,20 @@ static int kick_secondary_cpus(int maxcp
 /* This is the first C code that secondary processors invoke.  */
 int secondary_cpu_init(int cpuid, unsigned long r4)
 {
+    struct vcpu *vcpu;
+
     cpu_initialize(cpuid);
     smp_generic_take_timebase();
     cpu_set(cpuid, cpu_online_map);
+
+    vcpu = alloc_vcpu(idle_domain, cpuid, cpuid);
+    BUG_ON(vcpu == NULL);
+
+    set_current(idle_domain->vcpu[cpuid]);
+    idle_vcpu[cpuid] = current;
+    mpic_setup_this_cpu();
+    startup_cpu_idle_loop();
+
     while(1);
 }
 
@@ -335,6 +330,10 @@ static void __init __start_xen(multiboot
         debugger_trap_immediate();
 #endif
 
+    start_of_day();
+
+    mpic_setup_this_cpu();
+
     /* Deal with secondary processors.  */
     if (opt_nosmp || ofd_boot_cpu == -1) {
         printk("nosmp: leaving secondary processors spinning forever\n");
@@ -343,7 +342,8 @@ static void __init __start_xen(multiboot
         kick_secondary_cpus(max_cpus);
     }
 
-    start_of_day();
+    /* This cannot be called before secondary cpus are marked online.  */
+    percpu_free_unused_areas();
 
     /* Create initial domain 0. */
     dom0 = domain_create(0);
@@ -401,6 +401,16 @@ static void __init __start_xen(multiboot
     console_end_sync();
 
     domain_unpause_by_systemcontroller(dom0);
+#if 0
+    int i;
+    for (i = 0; i < 10; i++) {
+        mpic_send_ipi(3,2);
+        mpic_send_ipi(3,1);
+        printk("Sent IPI!\n");
+        sleep();
+    }
+#endif
+
     startup_cpu_idle_loop();
 }
 
diff -r 3583d2701405 xen/arch/powerpc/smp.c
--- a/xen/arch/powerpc/smp.c    Sun Oct 08 11:52:28 2006 -0400
+++ b/xen/arch/powerpc/smp.c    Tue Oct 10 12:00:45 2006 -0400
@@ -22,6 +22,7 @@
 #include <xen/smp.h>
 #include <asm/flushtlb.h>
 #include <asm/debugger.h>
+#include <asm/mpic.h>
 
 int smp_num_siblings = 1;
 int smp_num_cpus = 1;
@@ -49,8 +50,10 @@ void smp_send_event_check_mask(cpumask_t
 void smp_send_event_check_mask(cpumask_t mask)
 {
     cpu_clear(smp_processor_id(), mask);
-    if (!cpus_empty(mask))
-        unimplemented();
+    if (!cpus_empty(mask)) {
+       printk("%s: sending ipi ...\n", __func__);
+       mpic_send_ipi(3,2);
+    }
 }
 

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to