diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2014-11-03 21:52:24 -0500 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2014-11-03 21:52:24 -0500 |
commit | 5c2112a210e8654d96e3f4c0395f1a326f28666f (patch) | |
tree | 409b6a5955b8f17014f6c2629fc4e4a83debd9ac | |
parent | 5b564e918add09d778ae347e9fdd005a36f8e879 (diff) |
ARM timer support
-rw-r--r-- | include/litmus/clock.h | 48 | ||||
-rw-r--r-- | include/litmus/feather_trace.h | 12 | ||||
-rw-r--r-- | litmus/litmus.c | 53 |
3 files changed, 112 insertions, 1 deletions
diff --git a/include/litmus/clock.h b/include/litmus/clock.h new file mode 100644 index 000000000000..f8de7a3dfb5a --- /dev/null +++ b/include/litmus/clock.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef _LITMUS_CLOCK_H_ | ||
2 | #define _LITMUS_CLOCK_H_ | ||
3 | |||
4 | #if defined(CONFIG_EXYNOS_MCT) | ||
5 | |||
6 | /* | ||
7 | * Only used if we are using the EXYNOS MCT clock. | ||
8 | */ | ||
9 | |||
10 | #include <linux/clocksource.h> | ||
11 | extern struct clocksource mct_frc; | ||
12 | |||
13 | static inline cycles_t mct_frc_read(void) | ||
14 | { | ||
15 | cycle_t cycles = mct_frc.read(&mct_frc); | ||
16 | return cycles; | ||
17 | } | ||
18 | |||
19 | static inline s64 litmus_cycles_to_ns(cycles_t cycles) | ||
20 | { | ||
21 | return clocksource_cyc2ns(cycles, mct_frc.mult, mct_frc.shift); | ||
22 | } | ||
23 | |||
24 | #define litmus_get_cycles mct_frc_read | ||
25 | |||
26 | #elif defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) | ||
27 | |||
28 | #include <asm/timex.h> | ||
29 | |||
30 | static inline cycles_t v7_get_cycles (void) | ||
31 | { | ||
32 | u32 value; | ||
33 | /* read CCNT register */ | ||
34 | asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(value)); | ||
35 | return value; | ||
36 | } | ||
37 | |||
38 | #define litmus_get_cycles v7_get_cycles | ||
39 | |||
40 | #else | ||
41 | #include <asm/timex.h> | ||
42 | |||
43 | #define litmus_get_cycles get_cycles | ||
44 | |||
45 | #endif | ||
46 | |||
47 | #endif | ||
48 | |||
diff --git a/include/litmus/feather_trace.h b/include/litmus/feather_trace.h index dbeca46c01f5..cc4396e7fbe4 100644 --- a/include/litmus/feather_trace.h +++ b/include/litmus/feather_trace.h | |||
@@ -38,11 +38,23 @@ static inline void ft_atomic_dec(int *val) | |||
38 | /* provide default implementation */ | 38 | /* provide default implementation */ |
39 | #include <linux/timex.h> /* for get_cycles() */ | 39 | #include <linux/timex.h> /* for get_cycles() */ |
40 | 40 | ||
41 | #if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) | ||
42 | |||
43 | #include <litmus/clock.h> /* for litmus_get_cycles() */ | ||
44 | static inline unsigned long long ft_timestamp(void) | ||
45 | { | ||
46 | return (unsigned long long)litmus_get_cycles(); | ||
47 | } | ||
48 | |||
49 | #else | ||
50 | |||
41 | static inline unsigned long long ft_timestamp(void) | 51 | static inline unsigned long long ft_timestamp(void) |
42 | { | 52 | { |
43 | return get_cycles(); | 53 | return get_cycles(); |
44 | } | 54 | } |
45 | 55 | ||
56 | #endif | ||
57 | |||
46 | #define feather_callback | 58 | #define feather_callback |
47 | 59 | ||
48 | #define MAX_EVENTS 1024 | 60 | #define MAX_EVENTS 1024 |
diff --git a/litmus/litmus.c b/litmus/litmus.c index a061343ab769..14b1031fc6c7 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <litmus/rt_domain.h> | 20 | #include <litmus/rt_domain.h> |
21 | #include <litmus/litmus_proc.h> | 21 | #include <litmus/litmus_proc.h> |
22 | #include <litmus/sched_trace.h> | 22 | #include <litmus/sched_trace.h> |
23 | #include <litmus/clock.h> | ||
24 | |||
25 | #include <asm/cacheflush.h> | ||
23 | 26 | ||
24 | #ifdef CONFIG_SCHED_CPU_AFFINITY | 27 | #ifdef CONFIG_SCHED_CPU_AFFINITY |
25 | #include <litmus/affinity.h> | 28 | #include <litmus/affinity.h> |
@@ -303,9 +306,11 @@ asmlinkage long sys_null_call(cycles_t __user *ts) | |||
303 | cycles_t now; | 306 | cycles_t now; |
304 | 307 | ||
305 | if (ts) { | 308 | if (ts) { |
306 | now = get_cycles(); | 309 | now = litmus_get_cycles(); |
307 | ret = put_user(now, ts); | 310 | ret = put_user(now, ts); |
308 | } | 311 | } |
312 | else | ||
313 | flush_cache_all(); | ||
309 | 314 | ||
310 | return ret; | 315 | return ret; |
311 | } | 316 | } |
@@ -599,6 +604,48 @@ static struct notifier_block shutdown_notifier = { | |||
599 | .notifier_call = litmus_shutdown_nb, | 604 | .notifier_call = litmus_shutdown_nb, |
600 | }; | 605 | }; |
601 | 606 | ||
607 | #if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) | ||
608 | static void __init litmus_enable_perfcounters_v7(void *_ignore) | ||
609 | { | ||
610 | u32 enable_val = 0; | ||
611 | |||
612 | /* disable performance monitoring */ | ||
613 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (0x00000006)); | ||
614 | |||
615 | /* disable all events */ | ||
616 | asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (0xffffffff)); | ||
617 | |||
618 | /* write 1 to enable user-mode access to the performance counter */ | ||
619 | asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (1)); | ||
620 | |||
621 | /* disable counter overflow interrupts (just in case) */ | ||
622 | asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (0x8000000f)); | ||
623 | |||
624 | /* select event zero */ | ||
625 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (0)); | ||
626 | |||
627 | /* count cycles in the selected event zero */ | ||
628 | asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (0x00000011)); | ||
629 | |||
630 | enable_val |= 1; /* bit 1 enables the counters */ | ||
631 | enable_val |= 2; /* resets event counters to zero */ | ||
632 | enable_val |= 4; /* resets cycle counter to zero */ | ||
633 | //enable_val |= 8; /* enable "by 64" divider for CCNT. */ | ||
634 | |||
635 | /* performance monitor control register: enable all counters */ | ||
636 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(enable_val)); | ||
637 | |||
638 | /* enables counters (cycle counter and event 1) */ | ||
639 | asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(0x80000001)); | ||
640 | } | ||
641 | |||
642 | static void __init litmus_enable_perfcounters(void) | ||
643 | { | ||
644 | litmus_enable_perfcounters_v7(NULL); | ||
645 | smp_call_function(litmus_enable_perfcounters_v7, NULL, 0); | ||
646 | } | ||
647 | #endif | ||
648 | |||
602 | static int __init _init_litmus(void) | 649 | static int __init _init_litmus(void) |
603 | { | 650 | { |
604 | /* Common initializers, | 651 | /* Common initializers, |
@@ -628,6 +675,10 @@ static int __init _init_litmus(void) | |||
628 | 675 | ||
629 | register_reboot_notifier(&shutdown_notifier); | 676 | register_reboot_notifier(&shutdown_notifier); |
630 | 677 | ||
678 | #if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) | ||
679 | litmus_enable_perfcounters(); | ||
680 | #endif | ||
681 | |||
631 | return 0; | 682 | return 0; |
632 | } | 683 | } |
633 | 684 | ||