]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
inmates: arm: Enhance gic-demo with latency statistics
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 15 Dec 2014 17:02:49 +0000 (18:02 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 8 Jan 2015 12:01:23 +0000 (13:01 +0100)
Original version by Johann Pfefferl: This transfers the apic-demo to
ARM by letting the timer tick at 10 Hz and print jitter statistics on
each event. In addition, this also lets the green LED on the Banana Pi
blink.

CC: Johann Pfefferl <johann.pfefferl@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/arm/include/asm/sysregs.h
inmates/demos/arm/gic-demo.c

index 3cdd634bf73602d290f9e41ae3b05710cac9bd82..d1f63b34c912806f36da52d206025196baed5d27 100644 (file)
@@ -61,6 +61,8 @@
 #define CNTV_CTL_EL0   SYSREG_32(0, c14, c3, 1)
 #define CNTV_CVAL_EL0  SYSREG_64(3, c14)
 
+#define CNTPCT         SYSREG_64(0, c14)
+
 /*
  * AArch32-specific registers: they are 64bit on AArch64, and will need some
  * helpers if used frequently.
index 7a0f37fa571a7c27f465a36e37b40f1f51e76c4b..823f69d6542ffd11505d6d8dac4179b14a1649c4 100644 (file)
 #include <inmates/inmate.h>
 #include <mach/timer.h>
 
-static u64 tval;
-static u64 jiffies = 0;
+#define BEATS_PER_SEC          10
+#define TICKS_PER_BEAT         (TIMER_FREQ / BEATS_PER_SEC)
 
-static void timer_arm(void)
+static volatile u64 expected_ticks;
+
+static void timer_arm(u64 timeout)
 {
-       arm_write_sysreg(CNTV_TVAL_EL0, tval);
+       arm_write_sysreg(CNTV_TVAL_EL0, timeout);
        arm_write_sysreg(CNTV_CTL_EL0, 1);
 }
 
-static int timer_init(void)
+static u64 get_actual_ticks(void)
 {
-       u32 freq = TIMER_FREQ;
+       u64 pct64;
+
+       arm_read_sysreg(CNTPCT, pct64);
+       return pct64;
+}
 
-       tval = freq / 1000;
-       timer_arm();
+static unsigned long emul_division(u64 val, u64 div)
+{
+       unsigned long cnt = 0;
+
+       while (val > div) {
+               val -= div;
+               cnt++;
+       }
+       return cnt;
+}
 
-       return 0;
+static inline unsigned long ticks_to_ns(u64 ticks)
+{
+       return emul_division(ticks * 1000, TIMER_FREQ / 1000 / 1000);
 }
 
 static void handle_IRQ(unsigned int irqn)
 {
-       if (irqn == TIMER_IRQ) {
-               printk("J=%d\n", (u32)jiffies++);
-               timer_arm();
-       }
+       static u64 min_delta = ~0ULL, max_delta = 0;
+       u64 delta;
+
+       if (irqn != TIMER_IRQ)
+               return;
+
+       delta = get_actual_ticks() - expected_ticks;
+       if (delta < min_delta)
+               min_delta = delta;
+       if (delta > max_delta)
+               max_delta = delta;
+
+       printk("Timer fired, jitter: %6ld ns, min: %6ld ns, max: %6ld ns\n",
+              ticks_to_ns(delta), ticks_to_ns(min_delta),
+              ticks_to_ns(max_delta));
+
+#ifdef CONFIG_ARCH_SUN7I
+       /* let green LED on Banana Pi blink */
+       #define LED_REG (void *)(0x1c20800 + 7*0x24 + 0x10)
+       mmio_write32(LED_REG, mmio_read32(LED_REG) ^ (1<<24));
+#endif
+
+       expected_ticks = get_actual_ticks() + TICKS_PER_BEAT;
+       timer_arm(TICKS_PER_BEAT);
 }
 
 void inmate_main(void)
@@ -49,7 +85,9 @@ void inmate_main(void)
        gic_enable_irq(TIMER_IRQ);
 
        printk("Initializing the timer...\n");
-       timer_init();
+       expected_ticks = get_actual_ticks() + TICKS_PER_BEAT;
+       timer_arm(TICKS_PER_BEAT);
 
-       while (1);
+       while (1)
+               asm volatile("wfi" : : : "memory");
 }