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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|