diff options
Diffstat (limited to 'tools/lib/perf/mmap.c')
| -rw-r--r-- | tools/lib/perf/mmap.c | 98 | 
1 files changed, 98 insertions, 0 deletions
diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c index f7ee07cb5818..0d1634cedf44 100644 --- a/tools/lib/perf/mmap.c +++ b/tools/lib/perf/mmap.c @@ -13,6 +13,7 @@  #include <internal/lib.h>  #include <linux/kernel.h>  #include <linux/math64.h> +#include <linux/stringify.h>  #include "internal.h"  void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev, @@ -294,6 +295,103 @@ static u64 read_timestamp(void)  	return low | ((u64)high) << 32;  } +#elif defined(__aarch64__) +#define read_sysreg(r) ({						\ +	u64 __val;							\ +	asm volatile("mrs %0, " __stringify(r) : "=r" (__val));		\ +	__val;								\ +}) + +static u64 read_pmccntr(void) +{ +	return read_sysreg(pmccntr_el0); +} + +#define PMEVCNTR_READ(idx)					\ +	static u64 read_pmevcntr_##idx(void) {			\ +		return read_sysreg(pmevcntr##idx##_el0);	\ +	} + +PMEVCNTR_READ(0); +PMEVCNTR_READ(1); +PMEVCNTR_READ(2); +PMEVCNTR_READ(3); +PMEVCNTR_READ(4); +PMEVCNTR_READ(5); +PMEVCNTR_READ(6); +PMEVCNTR_READ(7); +PMEVCNTR_READ(8); +PMEVCNTR_READ(9); +PMEVCNTR_READ(10); +PMEVCNTR_READ(11); +PMEVCNTR_READ(12); +PMEVCNTR_READ(13); +PMEVCNTR_READ(14); +PMEVCNTR_READ(15); +PMEVCNTR_READ(16); +PMEVCNTR_READ(17); +PMEVCNTR_READ(18); +PMEVCNTR_READ(19); +PMEVCNTR_READ(20); +PMEVCNTR_READ(21); +PMEVCNTR_READ(22); +PMEVCNTR_READ(23); +PMEVCNTR_READ(24); +PMEVCNTR_READ(25); +PMEVCNTR_READ(26); +PMEVCNTR_READ(27); +PMEVCNTR_READ(28); +PMEVCNTR_READ(29); +PMEVCNTR_READ(30); + +/* + * Read a value direct from PMEVCNTR<idx> + */ +static u64 read_perf_counter(unsigned int counter) +{ +	static u64 (* const read_f[])(void) = { +		read_pmevcntr_0, +		read_pmevcntr_1, +		read_pmevcntr_2, +		read_pmevcntr_3, +		read_pmevcntr_4, +		read_pmevcntr_5, +		read_pmevcntr_6, +		read_pmevcntr_7, +		read_pmevcntr_8, +		read_pmevcntr_9, +		read_pmevcntr_10, +		read_pmevcntr_11, +		read_pmevcntr_13, +		read_pmevcntr_12, +		read_pmevcntr_14, +		read_pmevcntr_15, +		read_pmevcntr_16, +		read_pmevcntr_17, +		read_pmevcntr_18, +		read_pmevcntr_19, +		read_pmevcntr_20, +		read_pmevcntr_21, +		read_pmevcntr_22, +		read_pmevcntr_23, +		read_pmevcntr_24, +		read_pmevcntr_25, +		read_pmevcntr_26, +		read_pmevcntr_27, +		read_pmevcntr_28, +		read_pmevcntr_29, +		read_pmevcntr_30, +		read_pmccntr +	}; + +	if (counter < ARRAY_SIZE(read_f)) +		return (read_f[counter])(); + +	return 0; +} + +static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); } +  #else  static u64 read_perf_counter(unsigned int counter __maybe_unused) { return 0; }  static u64 read_timestamp(void) { return 0; }  | 
