aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c103
1 files changed, 102 insertions, 1 deletions
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index cb213089ed2b..a9b995dcf691 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -28,6 +28,8 @@
28#include <asm/time.h> /* For perf_irq */ 28#include <asm/time.h> /* For perf_irq */
29 29
30#define MIPS_MAX_HWEVENTS 4 30#define MIPS_MAX_HWEVENTS 4
31#define MIPS_TCS_PER_COUNTER 2
32#define MIPS_CPUID_TO_COUNTER_MASK (MIPS_TCS_PER_COUNTER - 1)
31 33
32struct cpu_hw_events { 34struct cpu_hw_events {
33 /* Array of events on this cpu. */ 35 /* Array of events on this cpu. */
@@ -108,13 +110,20 @@ static struct mips_pmu mipspmu;
108#define M_PERFCTL_INTERRUPT_ENABLE (1 << 4) 110#define M_PERFCTL_INTERRUPT_ENABLE (1 << 4)
109#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5) 111#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
110#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) 112#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
113
114#ifdef CONFIG_CPU_BMIPS5000
115#define M_PERFCTL_MT_EN(filter) 0
116#else /* !CONFIG_CPU_BMIPS5000 */
111#define M_PERFCTL_MT_EN(filter) ((filter) << 20) 117#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
118#endif /* CONFIG_CPU_BMIPS5000 */
119
112#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) 120#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
113#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) 121#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
114#define M_TC_EN_TC M_PERFCTL_MT_EN(2) 122#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
115#define M_PERFCTL_TCID(tcid) ((tcid) << 22) 123#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
116#define M_PERFCTL_WIDE (1 << 30) 124#define M_PERFCTL_WIDE (1 << 30)
117#define M_PERFCTL_MORE (1 << 31) 125#define M_PERFCTL_MORE (1 << 31)
126#define M_PERFCTL_TC (1 << 30)
118 127
119#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ 128#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \
120 M_PERFCTL_KERNEL | \ 129 M_PERFCTL_KERNEL | \
@@ -135,12 +144,17 @@ static int cpu_has_mipsmt_pertccounters;
135 144
136static DEFINE_RWLOCK(pmuint_rwlock); 145static DEFINE_RWLOCK(pmuint_rwlock);
137 146
147#if defined(CONFIG_CPU_BMIPS5000)
148#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
149 0 : (smp_processor_id() & MIPS_CPUID_TO_COUNTER_MASK))
150#else
138/* 151/*
139 * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because 152 * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
140 * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs. 153 * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
141 */ 154 */
142#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ 155#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
143 0 : smp_processor_id()) 156 0 : smp_processor_id())
157#endif
144 158
145/* Copied from op_model_mipsxx.c */ 159/* Copied from op_model_mipsxx.c */
146static unsigned int vpe_shift(void) 160static unsigned int vpe_shift(void)
@@ -334,6 +348,11 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
334 (evt->config_base & M_PERFCTL_CONFIG_MASK) | 348 (evt->config_base & M_PERFCTL_CONFIG_MASK) |
335 /* Make sure interrupt enabled. */ 349 /* Make sure interrupt enabled. */
336 M_PERFCTL_INTERRUPT_ENABLE; 350 M_PERFCTL_INTERRUPT_ENABLE;
351 if (IS_ENABLED(CONFIG_CPU_BMIPS5000))
352 /* enable the counter for the calling thread */
353 cpuc->saved_ctrl[idx] |=
354 (1 << (12 + vpe_id())) | M_PERFCTL_TC;
355
337 /* 356 /*
338 * We do not actually let the counter run. Leave it until start(). 357 * We do not actually let the counter run. Leave it until start().
339 */ 358 */
@@ -814,6 +833,13 @@ static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
814 [PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL }, 833 [PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL },
815}; 834};
816 835
836static const struct mips_perf_event bmips5000_event_map
837 [PERF_COUNT_HW_MAX] = {
838 [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, T },
839 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
840 [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
841};
842
817/* 24K/34K/1004K cores can share the same cache event map. */ 843/* 24K/34K/1004K cores can share the same cache event map. */
818static const struct mips_perf_event mipsxxcore_cache_map 844static const struct mips_perf_event mipsxxcore_cache_map
819 [PERF_COUNT_HW_CACHE_MAX] 845 [PERF_COUNT_HW_CACHE_MAX]
@@ -966,6 +992,65 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
966}, 992},
967}; 993};
968 994
995/* BMIPS5000 */
996static const struct mips_perf_event bmips5000_cache_map
997 [PERF_COUNT_HW_CACHE_MAX]
998 [PERF_COUNT_HW_CACHE_OP_MAX]
999 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
1000[C(L1D)] = {
1001 /*
1002 * Like some other architectures (e.g. ARM), the performance
1003 * counters don't differentiate between read and write
1004 * accesses/misses, so this isn't strictly correct, but it's the
1005 * best we can do. Writes and reads get combined.
1006 */
1007 [C(OP_READ)] = {
1008 [C(RESULT_ACCESS)] = { 12, CNTR_EVEN, T },
1009 [C(RESULT_MISS)] = { 12, CNTR_ODD, T },
1010 },
1011 [C(OP_WRITE)] = {
1012 [C(RESULT_ACCESS)] = { 12, CNTR_EVEN, T },
1013 [C(RESULT_MISS)] = { 12, CNTR_ODD, T },
1014 },
1015},
1016[C(L1I)] = {
1017 [C(OP_READ)] = {
1018 [C(RESULT_ACCESS)] = { 10, CNTR_EVEN, T },
1019 [C(RESULT_MISS)] = { 10, CNTR_ODD, T },
1020 },
1021 [C(OP_WRITE)] = {
1022 [C(RESULT_ACCESS)] = { 10, CNTR_EVEN, T },
1023 [C(RESULT_MISS)] = { 10, CNTR_ODD, T },
1024 },
1025 [C(OP_PREFETCH)] = {
1026 [C(RESULT_ACCESS)] = { 23, CNTR_EVEN, T },
1027 /*
1028 * Note that MIPS has only "hit" events countable for
1029 * the prefetch operation.
1030 */
1031 },
1032},
1033[C(LL)] = {
1034 [C(OP_READ)] = {
1035 [C(RESULT_ACCESS)] = { 28, CNTR_EVEN, P },
1036 [C(RESULT_MISS)] = { 28, CNTR_ODD, P },
1037 },
1038 [C(OP_WRITE)] = {
1039 [C(RESULT_ACCESS)] = { 28, CNTR_EVEN, P },
1040 [C(RESULT_MISS)] = { 28, CNTR_ODD, P },
1041 },
1042},
1043[C(BPU)] = {
1044 /* Using the same code for *HW_BRANCH* */
1045 [C(OP_READ)] = {
1046 [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
1047 },
1048 [C(OP_WRITE)] = {
1049 [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
1050 },
1051},
1052};
1053
969 1054
970static const struct mips_perf_event octeon_cache_map 1055static const struct mips_perf_event octeon_cache_map
971 [PERF_COUNT_HW_CACHE_MAX] 1056 [PERF_COUNT_HW_CACHE_MAX]
@@ -1240,6 +1325,11 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
1240#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47) 1325#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47)
1241#endif 1326#endif
1242 1327
1328/* BMIPS5000 */
1329#define IS_BOTH_COUNTERS_BMIPS5000_EVENT(b) \
1330 ((b) == 0 || (b) == 1)
1331
1332
1243/* 1333/*
1244 * User can use 0-255 raw events, where 0-127 for the events of even 1334 * User can use 0-255 raw events, where 0-127 for the events of even
1245 * counters, and 128-255 for odd counters. Note that bit 7 is used to 1335 * counters, and 128-255 for odd counters. Note that bit 7 is used to
@@ -1310,6 +1400,12 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
1310 raw_event.range = T; 1400 raw_event.range = T;
1311#endif 1401#endif
1312 break; 1402 break;
1403 case CPU_BMIPS5000:
1404 if (IS_BOTH_COUNTERS_BMIPS5000_EVENT(base_id))
1405 raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
1406 else
1407 raw_event.cntr_mask =
1408 raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
1313 } 1409 }
1314 1410
1315 return &raw_event; 1411 return &raw_event;
@@ -1421,6 +1517,11 @@ init_hw_perf_events(void)
1421 mipspmu.cache_event_map = &octeon_cache_map; 1517 mipspmu.cache_event_map = &octeon_cache_map;
1422 mipspmu.map_raw_event = octeon_pmu_map_raw_event; 1518 mipspmu.map_raw_event = octeon_pmu_map_raw_event;
1423 break; 1519 break;
1520 case CPU_BMIPS5000:
1521 mipspmu.name = "BMIPS5000";
1522 mipspmu.general_event_map = &bmips5000_event_map;
1523 mipspmu.cache_event_map = &bmips5000_cache_map;
1524 break;
1424 default: 1525 default:
1425 pr_cont("Either hardware does not support performance " 1526 pr_cont("Either hardware does not support performance "
1426 "counters, or not yet implemented.\n"); 1527 "counters, or not yet implemented.\n");