From 545188de55cecfeafce9f7a8797b8416239bbce6 Mon Sep 17 00:00:00 2001 From: Alexei Colin Date: Tue, 31 Oct 2017 23:10:25 +0000 Subject: [PATCH] enable user-mode access to CNTVCT timer register CNTVCT: Virtual Count Register -- a 64-bit counter part of Virtual Memory System Architecture. Section B4.1.34 in ARM Architecture Reference Manual ARMv7-A/ARMv7-R FFTW library, for example, already has support for this cycle counter, so it would be nice to enable it from here. Tested both the existing PMU code and the new CNTVCT code on XU4. Signed-off-by: Alexei Colin --- README.md | 5 ++++- ko/enable_arm_pmu.c | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6fcbef..5055818 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# User-mode access to ARM PMU cycle counters +# User-mode access to cycle counters in ARM PMU and CNTVCT timer This repository contains a kernel module and library. @@ -25,6 +25,9 @@ $ sudo make runtests * ODROID-U2 * Exynos 4 Quad, 1.7gHz Cortex-A9 * Ubuntu/Linaro 12.10 derivative + * ODROID-XU4 + * Exynos 5422 4xA15+4xA7 Octa big.LITTLE, 2GHz + * Arch Linux on ARM TBD: PandaBoard. diff --git a/ko/enable_arm_pmu.c b/ko/enable_arm_pmu.c index 34a1d20..f8ba479 100644 --- a/ko/enable_arm_pmu.c +++ b/ko/enable_arm_pmu.c @@ -19,9 +19,14 @@ #define PERF_OPT_RESET_CYCLES (2 | 4) #define PERF_OPT_DIV64 (8) +// ARMv7-A Architecture Reference Manual B4.1.26 +#define CNTKCTL_PL0VCTEN 0x2 + static void enable_cpu_counters(void* data) { + uint32_t r; + printk(KERN_INFO "[" DRVR_NAME "] enabling user-mode PMU access on CPU #%d", smp_processor_id()); @@ -30,11 +35,18 @@ enable_cpu_counters(void* data) /* Program PMU and enable all counters */ asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(PERF_DEF_OPTS)); asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f)); + + /* Enable user-mode access to CNTVCT generic timer counter in co-processor CP15 */ + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r"(r)); /* Read CNTKCTL to Rt */ + r |= CNTKCTL_PL0VCTEN; + asm volatile("mcr p15, 0, %0, c14, c1, 0" :: "r"(r)); /* Write Rt to CNTKCTL */ } static void disable_cpu_counters(void* data) { + uint32_t r; + printk(KERN_INFO "[" DRVR_NAME "] disabling user-mode PMU access on CPU #%d", smp_processor_id()); @@ -43,6 +55,11 @@ disable_cpu_counters(void* data) asm volatile("mcr p15, 0, %0, c9, c12, 2" :: "r"(0x8000000f)); /* Disable user-mode access to counters. */ asm volatile("mcr p15, 0, %0, c9, c14, 0" :: "r"(0)); + + /* Disable user-mode access to CNTVCT generic timer counter in co-processor CP15 */ + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r"(r)); /* Read CNTKCTL to Rt */ + r &= ~CNTKCTL_PL0VCTEN; + asm volatile("mcr p15, 0, %0, c14, c1, 0" :: "r"(r)); /* Write Rt to CNTKCTL */ } static int __init @@ -62,7 +79,7 @@ fini(void) MODULE_AUTHOR("Austin Seipp "); MODULE_LICENSE("Dual MIT/GPL"); -MODULE_DESCRIPTION("Enables user-mode access to ARMv7 PMU counters"); +MODULE_DESCRIPTION("Enables user-mode access to cycle counters in PMU and CNTVCT timer on ARMv7"); MODULE_VERSION("0:0.1-dev"); module_init(init); module_exit(fini);