]> rtime.felk.cvut.cz Git - jailhouse.git/blob - inmates/demos/arm/gic-demo.c
inmates: arm: Enhance gic-demo with latency statistics
[jailhouse.git] / inmates / demos / arm / gic-demo.c
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) ARM Limited, 2014
5  *
6  * Authors:
7  *  Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include <asm/gic_common.h>
14 #include <asm/sysregs.h>
15 #include <inmates/inmate.h>
16 #include <mach/timer.h>
17
18 #define BEATS_PER_SEC           10
19 #define TICKS_PER_BEAT          (TIMER_FREQ / BEATS_PER_SEC)
20
21 static volatile u64 expected_ticks;
22
23 static void timer_arm(u64 timeout)
24 {
25         arm_write_sysreg(CNTV_TVAL_EL0, timeout);
26         arm_write_sysreg(CNTV_CTL_EL0, 1);
27 }
28
29 static u64 get_actual_ticks(void)
30 {
31         u64 pct64;
32
33         arm_read_sysreg(CNTPCT, pct64);
34         return pct64;
35 }
36
37 static unsigned long emul_division(u64 val, u64 div)
38 {
39         unsigned long cnt = 0;
40
41         while (val > div) {
42                 val -= div;
43                 cnt++;
44         }
45         return cnt;
46 }
47
48 static inline unsigned long ticks_to_ns(u64 ticks)
49 {
50         return emul_division(ticks * 1000, TIMER_FREQ / 1000 / 1000);
51 }
52
53 static void handle_IRQ(unsigned int irqn)
54 {
55         static u64 min_delta = ~0ULL, max_delta = 0;
56         u64 delta;
57
58         if (irqn != TIMER_IRQ)
59                 return;
60
61         delta = get_actual_ticks() - expected_ticks;
62         if (delta < min_delta)
63                 min_delta = delta;
64         if (delta > max_delta)
65                 max_delta = delta;
66
67         printk("Timer fired, jitter: %6ld ns, min: %6ld ns, max: %6ld ns\n",
68                ticks_to_ns(delta), ticks_to_ns(min_delta),
69                ticks_to_ns(max_delta));
70
71 #ifdef CONFIG_ARCH_SUN7I
72         /* let green LED on Banana Pi blink */
73         #define LED_REG (void *)(0x1c20800 + 7*0x24 + 0x10)
74         mmio_write32(LED_REG, mmio_read32(LED_REG) ^ (1<<24));
75 #endif
76
77         expected_ticks = get_actual_ticks() + TICKS_PER_BEAT;
78         timer_arm(TICKS_PER_BEAT);
79 }
80
81 void inmate_main(void)
82 {
83         printk("Initializing the GIC...\n");
84         gic_setup(handle_IRQ);
85         gic_enable_irq(TIMER_IRQ);
86
87         printk("Initializing the timer...\n");
88         expected_ticks = get_actual_ticks() + TICKS_PER_BEAT;
89         timer_arm(TICKS_PER_BEAT);
90
91         while (1)
92                 asm volatile("wfi" : : : "memory");
93 }