aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-01-04 18:37:24 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-01-04 18:37:24 +0100
commit65abb26969948bb60897c814d3862594d11e76dd (patch)
tree30015dcd81a8f9ae7d15580284159644090d9d5b
parentff6e4be615cb8a299908c6c65d2d257a2104edb1 (diff)
downloadxen-65abb26969948bb60897c814d3862594d11e76dd.tar.gz
xen-65abb26969948bb60897c814d3862594d11e76dd.tar.bz2
xen-65abb26969948bb60897c814d3862594d11e76dd.zip
Add IO-APIC interrupt debugging to 'i' debug key.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/io_apic.c44
-rw-r--r--xen/arch/x86/irq.c8
2 files changed, 51 insertions, 1 deletions
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 7dd6bd590a..841bd10a03 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -1807,3 +1807,47 @@ int ioapic_guest_write(int apicid, int address, u32 val)
return 0;
}
+
+void dump_ioapic_irq_info(void)
+{
+ struct irq_pin_list *entry;
+ struct IO_APIC_route_entry rte;
+ unsigned int irq, pin, printed = 0;
+ unsigned long flags;
+
+ for ( irq = 0; irq < NR_IRQS; irq++ )
+ {
+ entry = &irq_2_pin[irq];
+ if ( entry->pin == -1 )
+ continue;
+
+ if ( !printed++ )
+ printk("IO-APIC interrupt information:\n");
+
+ printk(" IRQ%3d Vec%3d:\n", irq, irq_to_vector(irq));
+
+ for ( ; ; )
+ {
+ pin = entry->pin;
+
+ printk(" Apic 0x%02x, Pin %2d: ", entry->apic, pin);
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ *(((int *)&rte) + 0) = io_apic_read(entry->apic, 0x10 + 2 * pin);
+ *(((int *)&rte) + 1) = io_apic_read(entry->apic, 0x11 + 2 * pin);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ printk("vector=%u, delivery_mode=%u, dest_mode=%s, "
+ "delivery_status=%d, polarity=%d, irr=%d, "
+ "trigger=%s, mask=%d\n",
+ rte.vector, rte.delivery_mode,
+ rte.dest_mode ? "logical" : "physical",
+ rte.delivery_status, rte.polarity, rte.irr,
+ rte.trigger ? "level" : "edge", rte.mask);
+
+ if ( entry->next == 0 )
+ break;
+ entry = &irq_2_pin[entry->next];
+ }
+ }
+}
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 4ac1d62dff..d81d8749a6 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -313,6 +313,8 @@ int pirq_guest_unbind(struct domain *d, int irq)
return 0;
}
+extern void dump_ioapic_irq_info(void);
+
static void dump_irqs(unsigned char key)
{
int i, irq, vector;
@@ -321,6 +323,8 @@ static void dump_irqs(unsigned char key)
struct domain *d;
unsigned long flags;
+ printk("Guest interrupt information:\n");
+
for ( irq = 0; irq < NR_IRQS; irq++ )
{
vector = irq_to_vector(irq);
@@ -335,7 +339,7 @@ static void dump_irqs(unsigned char key)
{
action = (irq_guest_action_t *)desc->action;
- printk("IRQ%3d Vec%3d: type=%-15s status=%08x "
+ printk(" IRQ%3d Vec%3d: type=%-15s status=%08x "
"in-flight=%d domain-list=",
irq, vector, desc->handler->typename,
desc->status, action->in_flight);
@@ -366,6 +370,8 @@ static void dump_irqs(unsigned char key)
spin_unlock_irqrestore(&desc->lock, flags);
}
+
+ dump_ioapic_irq_info();
}
static int __init setup_dump_irqs(void)