changeset: 22040:fd2a4320924f
tag: tip
user: jimix@xxxxxxxxxxxxxxxxxxxxx
date: Fri Mar 24 17:57:30 2006 -0500
summary: [ppc] mpic and evtchn merge.
diff -r aaab77f6d562 -r fd2a4320924f arch/powerpc/platforms/xen/evtchn.c
--- a/arch/powerpc/platforms/xen/evtchn.c Thu Mar 23 16:42:35 2006 -0500
+++ b/arch/powerpc/platforms/xen/evtchn.c Fri Mar 24 17:57:30 2006 -0500
@@ -1,152 +1,102 @@
-#include <linux/types.h>
-#include <linux/spinlock_types.h>
#include <linux/module.h>
-#include <xen/interface/xen.h>
-#include <xen/interface/event_channel.h>
#include <xen/evtchn.h>
-#include <asm/irq.h>
-#include <asm/hypercall.h>
+#include <asm/mpic.h>
+#include <asm/machdep.h>
-/* this is specific to MPIC */
-#define NR_MPIC_IPIS 4
-#define NR_IPIS NR_MPIC_IPIS
+/*
+ * We are currently letting Dom0 control the mpic. However, Xen will
+ * Ack all interrupts. Here is how it works:
+ *
+ * 1. Dom0 sees a device and uses the and requests that Xen binds
+ * the IRQ to it.
+ * 2. Dom0 then enables that IRQ on the PIC and in the evtchn.
+ * 3. Xen recieved external interrupt, ACKs the PIC, and uses the
+ * evtchn to deliver the IRQ to the domain that is bound to is (Dom0).
+ * 4. Dom0 gets the IRQ val from evtchn, satisfies interrupt and
+ * EOIs the PIC and the evtchn.
+ */
-/* JX Remove this when you build with normal optimization */
-void __xchg_called_with_bad_pointer(void) { return; }
-#if 0
-
-#define HAS_HW_RESENT_IRQ
-
-#define init_IRQ xen_init_evtchn
-#include "../../xen/kernel/evtchn.c"
-
-#else
-
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- ~(sh)->evtchn_mask[idx])
-
-void force_evtchn_callback(void)
-{
- (void)HYPERVISOR_xen_version(0, NULL);
-}
+struct hw_interrupt_type *xen_pirq;
+static struct hw_interrupt_type hc_irq;
+extern struct machdep_calls maple_md;
+extern void evtchn_init_IRQ(void);
int xen_get_irq(struct pt_regs *regs)
{
- u32 l1, l2;
- unsigned int l1i, l2i, port;
- int irq, cpu = smp_processor_id();
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
-
- vcpu_info->evtchn_upcall_pending = 0;
-
- /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
- l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
- while (l1 != 0) {
- l1i = __ffs(l1);
- l1 &= ~(1 << l1i);
- while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 ) {
- l2i = __ffs(l2);
- l2 &= ~(1 << l2i);
-
- port = (l1i << 5) + l2i;
-#ifdef MORE_THAN_PIC
- if ( (irq = evtchn_to_irq[port]) != -1 ) {
- do_IRQ(irq, regs);
- } else
- evtchn_device_upcall(port);
-#else
- irq = port;
- clear_evtchn(irq);
- return irq;
-#endif
- }
- }
- return 0;
-}
-
-int bind_evtchn_to_irqhandler(
- unsigned int evtchn,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
- const char *devname,
- void *dev_id)
-{
- (void)handler;
- (void)irqflags;
- (void)devname;
- (void)dev_id;
-
- printk("%s, not yet\n", __func__);
- BUG_ON(evtchn == evtchn);
- return -1;
-
-}
-
-void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
-{
-
- printk("%s(0x%x,%p), not yet\n", __func__, evtchn, dev_id);
- BUG_ON(evtchn == evtchn);
-}
-
-int bind_virq_to_irq(int virq)
-{
- printk("%s(0x%x), not yet\n", __func__, virq);
- BUG_ON(virq == virq);
+ evtchn_do_upcall(regs);
return -1;
}
-void unbind_from_irqhandler(unsigned int irq, void *dev_id)
+static unsigned int xen_startup_irq(unsigned int irq)
{
- printk("%s(0x%x,%p), not yet\n", __func__, irq, dev_id);
- BUG_ON(irq == irq);
+ xen_pirq->startup(irq);
+ return hc_irq.startup(irq);
}
-#include <linux/kthread.h>
-#include <linux/err.h>
-#include <linux/delay.h>
+static void xen_enable_irq(unsigned int irq)
+{
+ xen_pirq->enable(irq);
+ return hc_irq.enable(irq);
+}
-#define TIMEOUT 10
+static void xen_disable_irq(unsigned int irq)
+{
+ xen_pirq->disable(irq);
+ return hc_irq.disable(irq);
+}
-static struct task_struct *xencons_task;
-static irqreturn_t (*xencons_handler)(int, void *, struct pt_regs *);
-int xenconsd(void *unused)
+static void xen_shutdown_irq(unsigned int irq)
{
- do {
- set_current_state(TASK_RUNNING);
- xencons_handler(0, NULL, NULL);
+ xen_pirq->shutdown(irq);
+ hc_irq.shutdown(irq);
+}
- set_current_state(TASK_INTERRUPTIBLE);
- msleep_interruptible(TIMEOUT);
+static void xen_ack_irq(unsigned int irq)
+{
+ xen_pirq->ack(irq);
+ if (hc_irq.ack) hc_irq.ack(irq);
+}
+static void xen_end_irq(unsigned int irq)
+{
+ xen_pirq->end(irq);
+ hc_irq.end(irq);
+}
- } while (!kthread_should_stop());
+/* Get the mpic structure from the irq number */
+static inline struct mpic * mpic_from_irq(unsigned int irq)
+{
+ return container_of(irq_desc[irq].handler, struct mpic, hc_irq);
+}
- return 0;
+void xen_init_IRQ(void)
+{
+ struct mpic *mpic;
+
+ evtchn_init_IRQ();
+ xen_pirq = irq_desc[0].handler;
+ maple_md.init_IRQ();
+
+ /* FIXME: 0 may not be valid */
+ mpic = mpic_from_irq(0);
+
+ hc_irq.startup = mpic->hc_irq.startup;
+ mpic->hc_irq.startup = xen_startup_irq;
+
+ hc_irq.enable = mpic->hc_irq.enable;
+ mpic->hc_irq.enable = xen_enable_irq;
+
+ hc_irq.disable = mpic->hc_irq.disable;
+ mpic->hc_irq.disable = xen_disable_irq;
+
+ hc_irq.shutdown = mpic->hc_irq.shutdown;
+ mpic->hc_irq.shutdown = xen_shutdown_irq;
+
+ hc_irq.ack = mpic->hc_irq.ack;
+ mpic->hc_irq.ack = xen_ack_irq;
+
+ hc_irq.end = mpic->hc_irq.end;
+ mpic->hc_irq.end = xen_end_irq;
+
}
-
-int bind_virq_to_irqhandler(
- unsigned int virq,
- unsigned int cpu,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
- const char *devname,
- void *dev_id)
-{
- (void)cpu;
- (void)irqflags;
- (void)devname;
- (void)dev_id;
-
- printk("%s, not yet\n", __func__);
- xencons_task = kthread_run(xenconsd, NULL, "xenconsd");
- BUG_ON(IS_ERR(xencons_task));
-
- xencons_handler = handler;
-
- return 0;
-}
-#endif
diff -r aaab77f6d562 -r fd2a4320924f arch/powerpc/platforms/xen/setup.c
--- a/arch/powerpc/platforms/xen/setup.c Thu Mar 23 16:42:35 2006 -0500
+++ b/arch/powerpc/platforms/xen/setup.c Fri Mar 24 17:57:30 2006 -0500
@@ -6,7 +6,6 @@
#include <linux/delay.h>
#include <linux/console.h>
#include <xen/interface/xen.h>
-#include <asm/mpic.h>
#include <asm/udbg.h>
#include <asm/pgtable.h>
#include <asm/prom.h>
@@ -169,11 +168,6 @@ static int pseries_set_xdabr(unsigned lo
H_DABRX_KERNEL | H_DABRX_USER);
}
-static __init void domU_init_IRQ(void)
-{
- /* nothing to do here */
-}
-
/*
* Early initialization.
*/
@@ -207,7 +201,6 @@ static void __init xen_init_early(void)
is_dom0 = !!(xen_start_info->flags & SIF_INITDOMAIN);
xen_init_udbg(is_dom0);
if (is_dom0) {
- ppc_md.init_IRQ = maple_md.init_IRQ;
ppc_md.pcibios_fixup = maple_md.pcibios_fixup;
ppc_md.pci_get_legacy_ide_irq =
maple_md.pci_get_legacy_ide_irq;
ppc_md.restart = maple_md.restart;
@@ -374,12 +367,13 @@ static void __init xen_progress(char *s,
printk("*** %04x : %s\n", hex, s ? s : "");
}
+extern void xen_init_IRQ(void);
extern int xen_get_irq(struct pt_regs *regs);
struct machdep_calls __initdata xen_md = {
.probe = xen_probe,
.setup_arch = xen_setup_arch,
.init_early = xen_init_early,
- .init_IRQ = domU_init_IRQ,
+ .init_IRQ = xen_init_IRQ,
.get_irq = xen_get_irq,
.restart = xen_restart,
.power_off = xen_power_off,
@@ -391,4 +385,3 @@ struct machdep_calls __initdata xen_md =
.progress = xen_progress,
.idle_loop = xen_idle,
};
-
diff -r aaab77f6d562 -r fd2a4320924f drivers/xen/Makefile
--- a/drivers/xen/Makefile Thu Mar 23 16:42:35 2006 -0500
+++ b/drivers/xen/Makefile Fri Mar 24 17:57:30 2006 -0500
@@ -7,8 +7,8 @@ obj-y += core/
obj-y += core/
obj-y += char/
obj-y += console/
+obj-y += evtchn/
ifndef CONFIG_PPC_XEN
-obj-y += evtchn/
obj-y += balloon/
endif
obj-y += privcmd/
diff -r aaab77f6d562 -r fd2a4320924f drivers/xen/core/Makefile
--- a/drivers/xen/core/Makefile Thu Mar 23 16:42:35 2006 -0500
+++ b/drivers/xen/core/Makefile Fri Mar 24 17:57:30 2006 -0500
@@ -2,8 +2,10 @@
# Makefile for the linux kernel.
#
+obj-y := evtchn.o
+
ifndef CONFIG_PPC_XEN
-obj-y := evtchn.o reboot.o gnttab.o features.o
+obj-y := reboot.o gnttab.o features.o
endif
obj-$(CONFIG_PROC_FS) += xen_proc.o
diff -r aaab77f6d562 -r fd2a4320924f drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Thu Mar 23 16:42:35 2006 -0500
+++ b/drivers/xen/core/evtchn.c Fri Mar 24 17:57:30 2006 -0500
@@ -133,6 +133,17 @@ static inline void exit_idle(void) {}
(regs)->IRQ_REG = (irq); \
do_IRQ((regs)); \
} while (0)
+#elif defined (__powerpc__)
+static inline void exit_idle(void) {}
+#define do_IRQ(irq, regs) __do_IRQ(irq, regs)
+#define init_IRQ evtchn_init_IRQ
+/* this is funky */
+#ifdef irq_ctx_init
+#undef irq_ctx_init
+#define irq_ctx_init(x)
+#else
+#define irq_ctx_init(x) irq_ctx_init()
+#endif
#endif
/* Xen will never allocate port zero for any purpose. */
@@ -622,6 +633,7 @@ static struct hw_interrupt_type pirq_typ
set_affinity_irq
};
+#if !defined (__powerpc__)
void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
int evtchn = evtchn_from_irq(i);
@@ -631,6 +643,7 @@ void hw_resend_irq(struct hw_interrupt_t
BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
synch_set_bit(evtchn, &s->evtchn_pending[0]);
}
+#endif
void notify_remote_via_irq(int irq)
{
@@ -803,7 +816,6 @@ void __init init_IRQ(void)
!(xen_start_info->flags & SIF_INITDOMAIN))
continue;
#endif
-
irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
irq_desc[pirq_to_irq(i)].action = NULL;
irq_desc[pirq_to_irq(i)].depth = 1;
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|