Signed-off-by: Andrew Jones <[email protected]>
---
 arm/timer.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/arm/timer.c b/arm/timer.c
index ec110ee08d97..89f4c9400ab6 100644
--- a/arm/timer.c
+++ b/arm/timer.c
@@ -17,6 +17,21 @@
 
 static u32 vtimer_irq, vtimer_irq_flags;
 static void *gic_ispendr;
+static bool vtimer_irq_received;
+
+static void irq_handler(struct pt_regs *regs)
+{
+       u32 irqstat = gic_read_iar();
+       u32 irqnr = gic_iar_irqnr(irqstat);
+
+       if (irqnr != GICC_INT_SPURIOUS)
+               gic_write_eoir(irqstat);
+
+       if (irqnr == PPI(vtimer_irq)) {
+               write_sysreg(CNTV_CTL_IMASK, cntv_ctl_el0);
+               ++vtimer_irq_received;
+       }
+}
 
 static bool gic_vtimer_pending(void)
 {
@@ -64,7 +79,7 @@ static void test_vtimer(void)
 
        report("not pending before", !gic_vtimer_pending());
        report("latency within 10 ms", test_cval_10msec());
-       report("pending after", gic_vtimer_pending());
+       report("interrupt received", vtimer_irq_received);
 
        /* Disable the timer again */
        write_sysreg(0, cntv_ctl_el0);
@@ -92,12 +107,17 @@ static void test_init(void)
 
        switch (gic_version()) {
        case 2:
+               writel(1 << PPI(vtimer_irq), gicv2_dist_base() + GICD_ISENABLER 
+ 0);
                gic_ispendr = gicv2_dist_base() + GICD_ISPENDR;
                break;
        case 3:
+               writel(1 << PPI(vtimer_irq), gicv3_sgi_base() + 
GICR_ISENABLER0);
                gic_ispendr = gicv3_sgi_base() + GICD_ISPENDR;
                break;
        }
+
+       install_irq_handler(EL1H_IRQ, irq_handler);
+       local_irq_enable();
 }
 
 int main(void)
-- 
2.9.4

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to