aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorHollis Blanchard <hollis_blanchard@mentor.com>2016-04-21 08:24:41 -0700
committerStefan Hajnoczi <stefanha@redhat.com>2016-05-16 17:20:41 -0700
commit2531088f6c1ce1f620f8d5a545f0af95598e69fc (patch)
tree8b6b6e8e4d9db79000aed3a0e33ad6690bfb4505 /hw/intc
parent70f87e0f0aa04f764dabaeb3ed71ff195748076a (diff)
downloadqemu-2531088f6c1ce1f620f8d5a545f0af95598e69fc.zip
qemu-2531088f6c1ce1f620f8d5a545f0af95598e69fc.tar.gz
qemu-2531088f6c1ce1f620f8d5a545f0af95598e69fc.tar.bz2
hw/intc/arm_gic: add tracepoints
These are obviously critical to understanding interrupt delivery: gic_enable_irq gic_disable_irq gic_set_irq (inbound irq from device models) gic_update_set_irq (outbound irq to CPU) gic_acknowledge_irq The only one that I think might raise eyebrows is gic_update_bestirq, but I've (sadly) debugged problems that ended up being caused by unexpected priorities. Knowing that the GIC has an irq ready, but doesn't deliver to the CPU due to priority, has also proven important. Signed-off-by: Hollis Blanchard <hollis_blanchard@mentor.com> Message-id: 1461252281-22399-1-git-send-email-hollis_blanchard@mentor.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/arm_gic.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index f551241..5ee79b8 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -23,6 +23,7 @@
#include "gic_internal.h"
#include "qapi/error.h"
#include "qom/cpu.h"
+#include "trace.h"
//#define DEBUG_GIC
@@ -93,6 +94,11 @@ void gic_update(GICState *s)
}
}
+ if (best_irq != 1023) {
+ trace_gic_update_bestirq(cpu, best_irq, best_prio,
+ s->priority_mask[cpu], s->running_priority[cpu]);
+ }
+
irq_level = fiq_level = 0;
if (best_prio < s->priority_mask[cpu]) {
@@ -106,10 +112,12 @@ void gic_update(GICState *s)
DPRINTF("Raised pending FIQ %d (cpu %d)\n",
best_irq, cpu);
fiq_level = 1;
+ trace_gic_update_set_irq(cpu, "fiq", fiq_level);
} else {
DPRINTF("Raised pending IRQ %d (cpu %d)\n",
best_irq, cpu);
irq_level = 1;
+ trace_gic_update_set_irq(cpu, "irq", irq_level);
}
}
}
@@ -197,6 +205,7 @@ static void gic_set_irq(void *opaque, int irq, int level)
} else {
gic_set_irq_generic(s, irq, level, cm, target);
}
+ trace_gic_set_irq(irq, level, cm, target);
gic_update(s);
}
@@ -332,6 +341,7 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs)
* is in the wrong group.
*/
irq = gic_get_current_pending_irq(s, cpu, attrs);
+ trace_gic_acknowledge_irq(cpu, irq);
if (irq >= GIC_MAXIRQ) {
DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq);
@@ -853,6 +863,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
if (!GIC_TEST_ENABLED(irq + i, cm)) {
DPRINTF("Enabled IRQ %d\n", irq + i);
+ trace_gic_enable_irq(irq + i);
}
GIC_SET_ENABLED(irq + i, cm);
/* If a raised level triggered IRQ enabled then mark
@@ -879,6 +890,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
if (GIC_TEST_ENABLED(irq + i, cm)) {
DPRINTF("Disabled IRQ %d\n", irq + i);
+ trace_gic_disable_irq(irq + i);
}
GIC_CLEAR_ENABLED(irq + i, cm);
}