diff options
author | James Hogan <james.hogan@imgtec.com> | 2017-02-06 07:37:45 -0500 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2017-02-14 04:00:24 -0500 |
commit | 2654294bac83a64101c360eac4d42d5ac1b1b911 (patch) | |
tree | d9c935f7bfdd0451d05df9bdf68f4894201a3b09 | |
parent | 573deec09436c9136fff6d78e0325e052a1ad6be (diff) |
MIPS: Unify perf counter register definitions
Unify definitions for MIPS performance counter register fields in
mipsregs.h rather than duplicating them in perf_events and oprofile.
This will allow future patches to use them to expose performance
counters to KVM guests.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Robert Richter <rric@kernel.org>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Cc: oprofile-list@lists.sf.net
Patchwork: https://patchwork.linux-mips.org/patch/15212/
Signed-off-by: James Hogan <james.hogan@imgtec.com>
-rw-r--r-- | arch/mips/include/asm/mipsregs.h | 33 | ||||
-rw-r--r-- | arch/mips/kernel/perf_event_mipsxx.c | 55 | ||||
-rw-r--r-- | arch/mips/oprofile/op_model_mipsxx.c | 40 |
3 files changed, 69 insertions, 59 deletions
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index df78b2ca70eb..f8d1d2f1d80d 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -685,6 +685,39 @@ | |||
685 | #define MIPS_WATCHHI_W (_ULCAST_(1) << 0) | 685 | #define MIPS_WATCHHI_W (_ULCAST_(1) << 0) |
686 | #define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0) | 686 | #define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0) |
687 | 687 | ||
688 | /* PerfCnt control register definitions */ | ||
689 | #define MIPS_PERFCTRL_EXL (_ULCAST_(1) << 0) | ||
690 | #define MIPS_PERFCTRL_K (_ULCAST_(1) << 1) | ||
691 | #define MIPS_PERFCTRL_S (_ULCAST_(1) << 2) | ||
692 | #define MIPS_PERFCTRL_U (_ULCAST_(1) << 3) | ||
693 | #define MIPS_PERFCTRL_IE (_ULCAST_(1) << 4) | ||
694 | #define MIPS_PERFCTRL_EVENT_S 5 | ||
695 | #define MIPS_PERFCTRL_EVENT (_ULCAST_(0x3ff) << MIPS_PERFCTRL_EVENT_S) | ||
696 | #define MIPS_PERFCTRL_PCTD (_ULCAST_(1) << 15) | ||
697 | #define MIPS_PERFCTRL_EC (_ULCAST_(0x3) << 23) | ||
698 | #define MIPS_PERFCTRL_EC_R (_ULCAST_(0) << 23) | ||
699 | #define MIPS_PERFCTRL_EC_RI (_ULCAST_(1) << 23) | ||
700 | #define MIPS_PERFCTRL_EC_G (_ULCAST_(2) << 23) | ||
701 | #define MIPS_PERFCTRL_EC_GRI (_ULCAST_(3) << 23) | ||
702 | #define MIPS_PERFCTRL_W (_ULCAST_(1) << 30) | ||
703 | #define MIPS_PERFCTRL_M (_ULCAST_(1) << 31) | ||
704 | |||
705 | /* PerfCnt control register MT extensions used by MIPS cores */ | ||
706 | #define MIPS_PERFCTRL_VPEID_S 16 | ||
707 | #define MIPS_PERFCTRL_VPEID (_ULCAST_(0xf) << MIPS_PERFCTRL_VPEID_S) | ||
708 | #define MIPS_PERFCTRL_TCID_S 22 | ||
709 | #define MIPS_PERFCTRL_TCID (_ULCAST_(0xff) << MIPS_PERFCTRL_TCID_S) | ||
710 | #define MIPS_PERFCTRL_MT_EN (_ULCAST_(0x3) << 20) | ||
711 | #define MIPS_PERFCTRL_MT_EN_ALL (_ULCAST_(0) << 20) | ||
712 | #define MIPS_PERFCTRL_MT_EN_VPE (_ULCAST_(1) << 20) | ||
713 | #define MIPS_PERFCTRL_MT_EN_TC (_ULCAST_(2) << 20) | ||
714 | |||
715 | /* PerfCnt control register MT extensions used by BMIPS5000 */ | ||
716 | #define BRCM_PERFCTRL_TC (_ULCAST_(1) << 30) | ||
717 | |||
718 | /* PerfCnt control register MT extensions used by Netlogic XLR */ | ||
719 | #define XLR_PERFCTRL_ALLTHREADS (_ULCAST_(1) << 13) | ||
720 | |||
688 | /* MAAR bit definitions */ | 721 | /* MAAR bit definitions */ |
689 | #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) | 722 | #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) |
690 | #define MIPS_MAAR_ADDR_SHIFT 12 | 723 | #define MIPS_MAAR_ADDR_SHIFT 12 |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index d3ba9f4105b5..8c35b3152e1e 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -101,40 +101,31 @@ struct mips_pmu { | |||
101 | 101 | ||
102 | static struct mips_pmu mipspmu; | 102 | static struct mips_pmu mipspmu; |
103 | 103 | ||
104 | #define M_PERFCTL_EXL (1 << 0) | 104 | #define M_PERFCTL_EVENT(event) (((event) << MIPS_PERFCTRL_EVENT_S) & \ |
105 | #define M_PERFCTL_KERNEL (1 << 1) | 105 | MIPS_PERFCTRL_EVENT) |
106 | #define M_PERFCTL_SUPERVISOR (1 << 2) | 106 | #define M_PERFCTL_VPEID(vpe) ((vpe) << MIPS_PERFCTRL_VPEID_S) |
107 | #define M_PERFCTL_USER (1 << 3) | ||
108 | #define M_PERFCTL_INTERRUPT_ENABLE (1 << 4) | ||
109 | #define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) | ||
110 | #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) | ||
111 | 107 | ||
112 | #ifdef CONFIG_CPU_BMIPS5000 | 108 | #ifdef CONFIG_CPU_BMIPS5000 |
113 | #define M_PERFCTL_MT_EN(filter) 0 | 109 | #define M_PERFCTL_MT_EN(filter) 0 |
114 | #else /* !CONFIG_CPU_BMIPS5000 */ | 110 | #else /* !CONFIG_CPU_BMIPS5000 */ |
115 | #define M_PERFCTL_MT_EN(filter) ((filter) << 20) | 111 | #define M_PERFCTL_MT_EN(filter) (filter) |
116 | #endif /* CONFIG_CPU_BMIPS5000 */ | 112 | #endif /* CONFIG_CPU_BMIPS5000 */ |
117 | 113 | ||
118 | #define M_TC_EN_ALL M_PERFCTL_MT_EN(0) | 114 | #define M_TC_EN_ALL M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_ALL) |
119 | #define M_TC_EN_VPE M_PERFCTL_MT_EN(1) | 115 | #define M_TC_EN_VPE M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_VPE) |
120 | #define M_TC_EN_TC M_PERFCTL_MT_EN(2) | 116 | #define M_TC_EN_TC M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_TC) |
121 | #define M_PERFCTL_TCID(tcid) ((tcid) << 22) | ||
122 | #define M_PERFCTL_WIDE (1 << 30) | ||
123 | #define M_PERFCTL_MORE (1 << 31) | ||
124 | #define M_PERFCTL_TC (1 << 30) | ||
125 | 117 | ||
126 | #define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ | 118 | #define M_PERFCTL_COUNT_EVENT_WHENEVER (MIPS_PERFCTRL_EXL | \ |
127 | M_PERFCTL_KERNEL | \ | 119 | MIPS_PERFCTRL_K | \ |
128 | M_PERFCTL_USER | \ | 120 | MIPS_PERFCTRL_U | \ |
129 | M_PERFCTL_SUPERVISOR | \ | 121 | MIPS_PERFCTRL_S | \ |
130 | M_PERFCTL_INTERRUPT_ENABLE) | 122 | MIPS_PERFCTRL_IE) |
131 | 123 | ||
132 | #ifdef CONFIG_MIPS_MT_SMP | 124 | #ifdef CONFIG_MIPS_MT_SMP |
133 | #define M_PERFCTL_CONFIG_MASK 0x3fff801f | 125 | #define M_PERFCTL_CONFIG_MASK 0x3fff801f |
134 | #else | 126 | #else |
135 | #define M_PERFCTL_CONFIG_MASK 0x1f | 127 | #define M_PERFCTL_CONFIG_MASK 0x1f |
136 | #endif | 128 | #endif |
137 | #define M_PERFCTL_EVENT_MASK 0xfe0 | ||
138 | 129 | ||
139 | 130 | ||
140 | #ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS | 131 | #ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS |
@@ -345,11 +336,11 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx) | |||
345 | cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | | 336 | cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | |
346 | (evt->config_base & M_PERFCTL_CONFIG_MASK) | | 337 | (evt->config_base & M_PERFCTL_CONFIG_MASK) | |
347 | /* Make sure interrupt enabled. */ | 338 | /* Make sure interrupt enabled. */ |
348 | M_PERFCTL_INTERRUPT_ENABLE; | 339 | MIPS_PERFCTRL_IE; |
349 | if (IS_ENABLED(CONFIG_CPU_BMIPS5000)) | 340 | if (IS_ENABLED(CONFIG_CPU_BMIPS5000)) |
350 | /* enable the counter for the calling thread */ | 341 | /* enable the counter for the calling thread */ |
351 | cpuc->saved_ctrl[idx] |= | 342 | cpuc->saved_ctrl[idx] |= |
352 | (1 << (12 + vpe_id())) | M_PERFCTL_TC; | 343 | (1 << (12 + vpe_id())) | BRCM_PERFCTRL_TC; |
353 | 344 | ||
354 | /* | 345 | /* |
355 | * We do not actually let the counter run. Leave it until start(). | 346 | * We do not actually let the counter run. Leave it until start(). |
@@ -754,11 +745,11 @@ static int __n_counters(void) | |||
754 | { | 745 | { |
755 | if (!cpu_has_perf) | 746 | if (!cpu_has_perf) |
756 | return 0; | 747 | return 0; |
757 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | 748 | if (!(read_c0_perfctrl0() & MIPS_PERFCTRL_M)) |
758 | return 1; | 749 | return 1; |
759 | if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) | 750 | if (!(read_c0_perfctrl1() & MIPS_PERFCTRL_M)) |
760 | return 2; | 751 | return 2; |
761 | if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) | 752 | if (!(read_c0_perfctrl2() & MIPS_PERFCTRL_M)) |
762 | return 3; | 753 | return 3; |
763 | 754 | ||
764 | return 4; | 755 | return 4; |
@@ -1339,7 +1330,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1339 | * We allow max flexibility on how each individual counter shared | 1330 | * We allow max flexibility on how each individual counter shared |
1340 | * by the single CPU operates (the mode exclusion and the range). | 1331 | * by the single CPU operates (the mode exclusion and the range). |
1341 | */ | 1332 | */ |
1342 | hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE; | 1333 | hwc->config_base = MIPS_PERFCTRL_IE; |
1343 | 1334 | ||
1344 | /* Calculate range bits and validate it. */ | 1335 | /* Calculate range bits and validate it. */ |
1345 | if (num_possible_cpus() > 1) | 1336 | if (num_possible_cpus() > 1) |
@@ -1350,14 +1341,14 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1350 | mutex_unlock(&raw_event_mutex); | 1341 | mutex_unlock(&raw_event_mutex); |
1351 | 1342 | ||
1352 | if (!attr->exclude_user) | 1343 | if (!attr->exclude_user) |
1353 | hwc->config_base |= M_PERFCTL_USER; | 1344 | hwc->config_base |= MIPS_PERFCTRL_U; |
1354 | if (!attr->exclude_kernel) { | 1345 | if (!attr->exclude_kernel) { |
1355 | hwc->config_base |= M_PERFCTL_KERNEL; | 1346 | hwc->config_base |= MIPS_PERFCTRL_K; |
1356 | /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */ | 1347 | /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */ |
1357 | hwc->config_base |= M_PERFCTL_EXL; | 1348 | hwc->config_base |= MIPS_PERFCTRL_EXL; |
1358 | } | 1349 | } |
1359 | if (!attr->exclude_hv) | 1350 | if (!attr->exclude_hv) |
1360 | hwc->config_base |= M_PERFCTL_SUPERVISOR; | 1351 | hwc->config_base |= MIPS_PERFCTRL_S; |
1361 | 1352 | ||
1362 | hwc->config_base &= M_PERFCTL_CONFIG_MASK; | 1353 | hwc->config_base &= M_PERFCTL_CONFIG_MASK; |
1363 | /* | 1354 | /* |
@@ -1830,7 +1821,7 @@ init_hw_perf_events(void) | |||
1830 | mipspmu.num_counters = counters; | 1821 | mipspmu.num_counters = counters; |
1831 | mipspmu.irq = irq; | 1822 | mipspmu.irq = irq; |
1832 | 1823 | ||
1833 | if (read_c0_perfctrl0() & M_PERFCTL_WIDE) { | 1824 | if (read_c0_perfctrl0() & MIPS_PERFCTRL_W) { |
1834 | mipspmu.max_period = (1ULL << 63) - 1; | 1825 | mipspmu.max_period = (1ULL << 63) - 1; |
1835 | mipspmu.valid_count = (1ULL << 63) - 1; | 1826 | mipspmu.valid_count = (1ULL << 63) - 1; |
1836 | mipspmu.overflow = 1ULL << 63; | 1827 | mipspmu.overflow = 1ULL << 63; |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 45cb27469fba..c57da6f13929 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -15,26 +15,12 @@ | |||
15 | 15 | ||
16 | #include "op_impl.h" | 16 | #include "op_impl.h" |
17 | 17 | ||
18 | #define M_PERFCTL_EXL (1UL << 0) | 18 | #define M_PERFCTL_EVENT(event) (((event) << MIPS_PERFCTRL_EVENT_S) & \ |
19 | #define M_PERFCTL_KERNEL (1UL << 1) | 19 | MIPS_PERFCTRL_EVENT) |
20 | #define M_PERFCTL_SUPERVISOR (1UL << 2) | 20 | #define M_PERFCTL_VPEID(vpe) ((vpe) << MIPS_PERFCTRL_VPEID_S) |
21 | #define M_PERFCTL_USER (1UL << 3) | ||
22 | #define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) | ||
23 | #define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) | ||
24 | #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) | ||
25 | #define M_PERFCTL_MT_EN(filter) ((filter) << 20) | ||
26 | #define M_TC_EN_ALL M_PERFCTL_MT_EN(0) | ||
27 | #define M_TC_EN_VPE M_PERFCTL_MT_EN(1) | ||
28 | #define M_TC_EN_TC M_PERFCTL_MT_EN(2) | ||
29 | #define M_PERFCTL_TCID(tcid) ((tcid) << 22) | ||
30 | #define M_PERFCTL_WIDE (1UL << 30) | ||
31 | #define M_PERFCTL_MORE (1UL << 31) | ||
32 | 21 | ||
33 | #define M_COUNTER_OVERFLOW (1UL << 31) | 22 | #define M_COUNTER_OVERFLOW (1UL << 31) |
34 | 23 | ||
35 | /* Netlogic XLR specific, count events in all threads in a core */ | ||
36 | #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) | ||
37 | |||
38 | static int (*save_perf_irq)(void); | 24 | static int (*save_perf_irq)(void); |
39 | static int perfcount_irq; | 25 | static int perfcount_irq; |
40 | 26 | ||
@@ -51,7 +37,7 @@ static int perfcount_irq; | |||
51 | 37 | ||
52 | #ifdef CONFIG_MIPS_MT_SMP | 38 | #ifdef CONFIG_MIPS_MT_SMP |
53 | static int cpu_has_mipsmt_pertccounters; | 39 | static int cpu_has_mipsmt_pertccounters; |
54 | #define WHAT (M_TC_EN_VPE | \ | 40 | #define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ |
55 | M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) | 41 | M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) |
56 | #define vpe_id() (cpu_has_mipsmt_pertccounters ? \ | 42 | #define vpe_id() (cpu_has_mipsmt_pertccounters ? \ |
57 | 0 : cpu_data[smp_processor_id()].vpe_id) | 43 | 0 : cpu_data[smp_processor_id()].vpe_id) |
@@ -161,15 +147,15 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) | |||
161 | continue; | 147 | continue; |
162 | 148 | ||
163 | reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) | | 149 | reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) | |
164 | M_PERFCTL_INTERRUPT_ENABLE; | 150 | MIPS_PERFCTRL_IE; |
165 | if (ctr[i].kernel) | 151 | if (ctr[i].kernel) |
166 | reg.control[i] |= M_PERFCTL_KERNEL; | 152 | reg.control[i] |= MIPS_PERFCTRL_K; |
167 | if (ctr[i].user) | 153 | if (ctr[i].user) |
168 | reg.control[i] |= M_PERFCTL_USER; | 154 | reg.control[i] |= MIPS_PERFCTRL_U; |
169 | if (ctr[i].exl) | 155 | if (ctr[i].exl) |
170 | reg.control[i] |= M_PERFCTL_EXL; | 156 | reg.control[i] |= MIPS_PERFCTRL_EXL; |
171 | if (boot_cpu_type() == CPU_XLR) | 157 | if (boot_cpu_type() == CPU_XLR) |
172 | reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS; | 158 | reg.control[i] |= XLR_PERFCTRL_ALLTHREADS; |
173 | reg.counter[i] = 0x80000000 - ctr[i].count; | 159 | reg.counter[i] = 0x80000000 - ctr[i].count; |
174 | } | 160 | } |
175 | } | 161 | } |
@@ -254,7 +240,7 @@ static int mipsxx_perfcount_handler(void) | |||
254 | case n + 1: \ | 240 | case n + 1: \ |
255 | control = r_c0_perfctrl ## n(); \ | 241 | control = r_c0_perfctrl ## n(); \ |
256 | counter = r_c0_perfcntr ## n(); \ | 242 | counter = r_c0_perfcntr ## n(); \ |
257 | if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \ | 243 | if ((control & MIPS_PERFCTRL_IE) && \ |
258 | (counter & M_COUNTER_OVERFLOW)) { \ | 244 | (counter & M_COUNTER_OVERFLOW)) { \ |
259 | oprofile_add_sample(get_irq_regs(), n); \ | 245 | oprofile_add_sample(get_irq_regs(), n); \ |
260 | w_c0_perfcntr ## n(reg.counter[n]); \ | 246 | w_c0_perfcntr ## n(reg.counter[n]); \ |
@@ -273,11 +259,11 @@ static inline int __n_counters(void) | |||
273 | { | 259 | { |
274 | if (!cpu_has_perf) | 260 | if (!cpu_has_perf) |
275 | return 0; | 261 | return 0; |
276 | if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) | 262 | if (!(read_c0_perfctrl0() & MIPS_PERFCTRL_M)) |
277 | return 1; | 263 | return 1; |
278 | if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) | 264 | if (!(read_c0_perfctrl1() & MIPS_PERFCTRL_M)) |
279 | return 2; | 265 | return 2; |
280 | if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) | 266 | if (!(read_c0_perfctrl2() & MIPS_PERFCTRL_M)) |
281 | return 3; | 267 | return 3; |
282 | 268 | ||
283 | return 4; | 269 | return 4; |