From 5c2112a210e8654d96e3f4c0395f1a326f28666f Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Mon, 3 Nov 2014 21:52:24 -0500 Subject: ARM timer support --- include/litmus/clock.h | 48 ++++++++++++++++++++++++++++++++++++++ include/litmus/feather_trace.h | 12 ++++++++++ litmus/litmus.c | 53 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 include/litmus/clock.h 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 @@ +#ifndef _LITMUS_CLOCK_H_ +#define _LITMUS_CLOCK_H_ + +#if defined(CONFIG_EXYNOS_MCT) + +/* + * Only used if we are using the EXYNOS MCT clock. + */ + +#include +extern struct clocksource mct_frc; + +static inline cycles_t mct_frc_read(void) +{ + cycle_t cycles = mct_frc.read(&mct_frc); + return cycles; +} + +static inline s64 litmus_cycles_to_ns(cycles_t cycles) +{ + return clocksource_cyc2ns(cycles, mct_frc.mult, mct_frc.shift); +} + +#define litmus_get_cycles mct_frc_read + +#elif defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) + +#include + +static inline cycles_t v7_get_cycles (void) +{ + u32 value; + /* read CCNT register */ + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(value)); + return value; +} + +#define litmus_get_cycles v7_get_cycles + +#else +#include + +#define litmus_get_cycles get_cycles + +#endif + +#endif + 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) /* provide default implementation */ #include /* for get_cycles() */ +#if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) + +#include /* for litmus_get_cycles() */ +static inline unsigned long long ft_timestamp(void) +{ + return (unsigned long long)litmus_get_cycles(); +} + +#else + static inline unsigned long long ft_timestamp(void) { return get_cycles(); } +#endif + #define feather_callback #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 @@ #include #include #include +#include + +#include #ifdef CONFIG_SCHED_CPU_AFFINITY #include @@ -303,9 +306,11 @@ asmlinkage long sys_null_call(cycles_t __user *ts) cycles_t now; if (ts) { - now = get_cycles(); + now = litmus_get_cycles(); ret = put_user(now, ts); } + else + flush_cache_all(); return ret; } @@ -599,6 +604,48 @@ static struct notifier_block shutdown_notifier = { .notifier_call = litmus_shutdown_nb, }; +#if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) +static void __init litmus_enable_perfcounters_v7(void *_ignore) +{ + u32 enable_val = 0; + + /* disable performance monitoring */ + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (0x00000006)); + + /* disable all events */ + asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (0xffffffff)); + + /* write 1 to enable user-mode access to the performance counter */ + asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (1)); + + /* disable counter overflow interrupts (just in case) */ + asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (0x8000000f)); + + /* select event zero */ + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (0)); + + /* count cycles in the selected event zero */ + asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (0x00000011)); + + enable_val |= 1; /* bit 1 enables the counters */ + enable_val |= 2; /* resets event counters to zero */ + enable_val |= 4; /* resets cycle counter to zero */ + //enable_val |= 8; /* enable "by 64" divider for CCNT. */ + + /* performance monitor control register: enable all counters */ + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(enable_val)); + + /* enables counters (cycle counter and event 1) */ + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(0x80000001)); +} + +static void __init litmus_enable_perfcounters(void) +{ + litmus_enable_perfcounters_v7(NULL); + smp_call_function(litmus_enable_perfcounters_v7, NULL, 0); +} +#endif + static int __init _init_litmus(void) { /* Common initializers, @@ -628,6 +675,10 @@ static int __init _init_litmus(void) register_reboot_notifier(&shutdown_notifier); +#if defined(CONFIG_CPU_V7) && !defined(CONFIG_HW_PERF_EVENTS) + litmus_enable_perfcounters(); +#endif + return 0; } -- cgit v1.2.2