aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2014-11-03 21:52:24 -0500
committerNamhoon Kim <namhoonk@cs.unc.edu>2014-11-03 21:52:24 -0500
commit5c2112a210e8654d96e3f4c0395f1a326f28666f (patch)
tree409b6a5955b8f17014f6c2629fc4e4a83debd9ac
parent5b564e918add09d778ae347e9fdd005a36f8e879 (diff)
ARM timer support
-rw-r--r--include/litmus/clock.h48
-rw-r--r--include/litmus/feather_trace.h12
-rw-r--r--litmus/litmus.c53
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>
11extern struct clocksource mct_frc;
12
13static inline cycles_t mct_frc_read(void)
14{
15 cycle_t cycles = mct_frc.read(&mct_frc);
16 return cycles;
17}
18
19static 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
30static 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() */
44static inline unsigned long long ft_timestamp(void)
45{
46 return (unsigned long long)litmus_get_cycles();
47}
48
49#else
50
41static inline unsigned long long ft_timestamp(void) 51static 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)
608static 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
642static 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
602static int __init _init_litmus(void) 649static 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