aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2017-02-06 07:37:45 -0500
committerJames Hogan <james.hogan@imgtec.com>2017-02-14 04:00:24 -0500
commit2654294bac83a64101c360eac4d42d5ac1b1b911 (patch)
treed9c935f7bfdd0451d05df9bdf68f4894201a3b09
parent573deec09436c9136fff6d78e0325e052a1ad6be (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.h33
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c55
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c40
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
102static struct mips_pmu mipspmu; 102static 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
38static int (*save_perf_irq)(void); 24static int (*save_perf_irq)(void);
39static int perfcount_irq; 25static 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
53static int cpu_has_mipsmt_pertccounters; 39static 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;