Commit 2654294b authored by James Hogan's avatar James Hogan

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: default avatarJames 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: default avatarJames Hogan <james.hogan@imgtec.com>
parent 573deec0
...@@ -685,6 +685,39 @@ ...@@ -685,6 +685,39 @@
#define MIPS_WATCHHI_W (_ULCAST_(1) << 0) #define MIPS_WATCHHI_W (_ULCAST_(1) << 0)
#define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0) #define MIPS_WATCHHI_IRW (_ULCAST_(0x7) << 0)
/* PerfCnt control register definitions */
#define MIPS_PERFCTRL_EXL (_ULCAST_(1) << 0)
#define MIPS_PERFCTRL_K (_ULCAST_(1) << 1)
#define MIPS_PERFCTRL_S (_ULCAST_(1) << 2)
#define MIPS_PERFCTRL_U (_ULCAST_(1) << 3)
#define MIPS_PERFCTRL_IE (_ULCAST_(1) << 4)
#define MIPS_PERFCTRL_EVENT_S 5
#define MIPS_PERFCTRL_EVENT (_ULCAST_(0x3ff) << MIPS_PERFCTRL_EVENT_S)
#define MIPS_PERFCTRL_PCTD (_ULCAST_(1) << 15)
#define MIPS_PERFCTRL_EC (_ULCAST_(0x3) << 23)
#define MIPS_PERFCTRL_EC_R (_ULCAST_(0) << 23)
#define MIPS_PERFCTRL_EC_RI (_ULCAST_(1) << 23)
#define MIPS_PERFCTRL_EC_G (_ULCAST_(2) << 23)
#define MIPS_PERFCTRL_EC_GRI (_ULCAST_(3) << 23)
#define MIPS_PERFCTRL_W (_ULCAST_(1) << 30)
#define MIPS_PERFCTRL_M (_ULCAST_(1) << 31)
/* PerfCnt control register MT extensions used by MIPS cores */
#define MIPS_PERFCTRL_VPEID_S 16
#define MIPS_PERFCTRL_VPEID (_ULCAST_(0xf) << MIPS_PERFCTRL_VPEID_S)
#define MIPS_PERFCTRL_TCID_S 22
#define MIPS_PERFCTRL_TCID (_ULCAST_(0xff) << MIPS_PERFCTRL_TCID_S)
#define MIPS_PERFCTRL_MT_EN (_ULCAST_(0x3) << 20)
#define MIPS_PERFCTRL_MT_EN_ALL (_ULCAST_(0) << 20)
#define MIPS_PERFCTRL_MT_EN_VPE (_ULCAST_(1) << 20)
#define MIPS_PERFCTRL_MT_EN_TC (_ULCAST_(2) << 20)
/* PerfCnt control register MT extensions used by BMIPS5000 */
#define BRCM_PERFCTRL_TC (_ULCAST_(1) << 30)
/* PerfCnt control register MT extensions used by Netlogic XLR */
#define XLR_PERFCTRL_ALLTHREADS (_ULCAST_(1) << 13)
/* MAAR bit definitions */ /* MAAR bit definitions */
#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
#define MIPS_MAAR_ADDR_SHIFT 12 #define MIPS_MAAR_ADDR_SHIFT 12
......
...@@ -101,40 +101,31 @@ struct mips_pmu { ...@@ -101,40 +101,31 @@ struct mips_pmu {
static struct mips_pmu mipspmu; static struct mips_pmu mipspmu;
#define M_PERFCTL_EXL (1 << 0) #define M_PERFCTL_EVENT(event) (((event) << MIPS_PERFCTRL_EVENT_S) & \
#define M_PERFCTL_KERNEL (1 << 1) MIPS_PERFCTRL_EVENT)
#define M_PERFCTL_SUPERVISOR (1 << 2) #define M_PERFCTL_VPEID(vpe) ((vpe) << MIPS_PERFCTRL_VPEID_S)
#define M_PERFCTL_USER (1 << 3)
#define M_PERFCTL_INTERRUPT_ENABLE (1 << 4)
#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
#ifdef CONFIG_CPU_BMIPS5000 #ifdef CONFIG_CPU_BMIPS5000
#define M_PERFCTL_MT_EN(filter) 0 #define M_PERFCTL_MT_EN(filter) 0
#else /* !CONFIG_CPU_BMIPS5000 */ #else /* !CONFIG_CPU_BMIPS5000 */
#define M_PERFCTL_MT_EN(filter) ((filter) << 20) #define M_PERFCTL_MT_EN(filter) (filter)
#endif /* CONFIG_CPU_BMIPS5000 */ #endif /* CONFIG_CPU_BMIPS5000 */
#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) #define M_TC_EN_ALL M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_ALL)
#define M_TC_EN_VPE M_PERFCTL_MT_EN(1) #define M_TC_EN_VPE M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_VPE)
#define M_TC_EN_TC M_PERFCTL_MT_EN(2) #define M_TC_EN_TC M_PERFCTL_MT_EN(MIPS_PERFCTRL_MT_EN_TC)
#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
#define M_PERFCTL_WIDE (1 << 30)
#define M_PERFCTL_MORE (1 << 31)
#define M_PERFCTL_TC (1 << 30)
#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \ #define M_PERFCTL_COUNT_EVENT_WHENEVER (MIPS_PERFCTRL_EXL | \
M_PERFCTL_KERNEL | \ MIPS_PERFCTRL_K | \
M_PERFCTL_USER | \ MIPS_PERFCTRL_U | \
M_PERFCTL_SUPERVISOR | \ MIPS_PERFCTRL_S | \
M_PERFCTL_INTERRUPT_ENABLE) MIPS_PERFCTRL_IE)
#ifdef CONFIG_MIPS_MT_SMP #ifdef CONFIG_MIPS_MT_SMP
#define M_PERFCTL_CONFIG_MASK 0x3fff801f #define M_PERFCTL_CONFIG_MASK 0x3fff801f
#else #else
#define M_PERFCTL_CONFIG_MASK 0x1f #define M_PERFCTL_CONFIG_MASK 0x1f
#endif #endif
#define M_PERFCTL_EVENT_MASK 0xfe0
#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS #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,11 +336,11 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) | cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
(evt->config_base & M_PERFCTL_CONFIG_MASK) | (evt->config_base & M_PERFCTL_CONFIG_MASK) |
/* Make sure interrupt enabled. */ /* Make sure interrupt enabled. */
M_PERFCTL_INTERRUPT_ENABLE; MIPS_PERFCTRL_IE;
if (IS_ENABLED(CONFIG_CPU_BMIPS5000)) if (IS_ENABLED(CONFIG_CPU_BMIPS5000))
/* enable the counter for the calling thread */ /* enable the counter for the calling thread */
cpuc->saved_ctrl[idx] |= cpuc->saved_ctrl[idx] |=
(1 << (12 + vpe_id())) | M_PERFCTL_TC; (1 << (12 + vpe_id())) | BRCM_PERFCTRL_TC;
/* /*
* We do not actually let the counter run. Leave it until start(). * We do not actually let the counter run. Leave it until start().
...@@ -754,11 +745,11 @@ static int __n_counters(void) ...@@ -754,11 +745,11 @@ static int __n_counters(void)
{ {
if (!cpu_has_perf) if (!cpu_has_perf)
return 0; return 0;
if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl0() & MIPS_PERFCTRL_M))
return 1; return 1;
if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl1() & MIPS_PERFCTRL_M))
return 2; return 2;
if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl2() & MIPS_PERFCTRL_M))
return 3; return 3;
return 4; return 4;
...@@ -1339,7 +1330,7 @@ static int __hw_perf_event_init(struct perf_event *event) ...@@ -1339,7 +1330,7 @@ static int __hw_perf_event_init(struct perf_event *event)
* We allow max flexibility on how each individual counter shared * We allow max flexibility on how each individual counter shared
* by the single CPU operates (the mode exclusion and the range). * by the single CPU operates (the mode exclusion and the range).
*/ */
hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE; hwc->config_base = MIPS_PERFCTRL_IE;
/* Calculate range bits and validate it. */ /* Calculate range bits and validate it. */
if (num_possible_cpus() > 1) if (num_possible_cpus() > 1)
...@@ -1350,14 +1341,14 @@ static int __hw_perf_event_init(struct perf_event *event) ...@@ -1350,14 +1341,14 @@ static int __hw_perf_event_init(struct perf_event *event)
mutex_unlock(&raw_event_mutex); mutex_unlock(&raw_event_mutex);
if (!attr->exclude_user) if (!attr->exclude_user)
hwc->config_base |= M_PERFCTL_USER; hwc->config_base |= MIPS_PERFCTRL_U;
if (!attr->exclude_kernel) { if (!attr->exclude_kernel) {
hwc->config_base |= M_PERFCTL_KERNEL; hwc->config_base |= MIPS_PERFCTRL_K;
/* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */ /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */
hwc->config_base |= M_PERFCTL_EXL; hwc->config_base |= MIPS_PERFCTRL_EXL;
} }
if (!attr->exclude_hv) if (!attr->exclude_hv)
hwc->config_base |= M_PERFCTL_SUPERVISOR; hwc->config_base |= MIPS_PERFCTRL_S;
hwc->config_base &= M_PERFCTL_CONFIG_MASK; hwc->config_base &= M_PERFCTL_CONFIG_MASK;
/* /*
...@@ -1830,7 +1821,7 @@ init_hw_perf_events(void) ...@@ -1830,7 +1821,7 @@ init_hw_perf_events(void)
mipspmu.num_counters = counters; mipspmu.num_counters = counters;
mipspmu.irq = irq; mipspmu.irq = irq;
if (read_c0_perfctrl0() & M_PERFCTL_WIDE) { if (read_c0_perfctrl0() & MIPS_PERFCTRL_W) {
mipspmu.max_period = (1ULL << 63) - 1; mipspmu.max_period = (1ULL << 63) - 1;
mipspmu.valid_count = (1ULL << 63) - 1; mipspmu.valid_count = (1ULL << 63) - 1;
mipspmu.overflow = 1ULL << 63; mipspmu.overflow = 1ULL << 63;
......
...@@ -15,26 +15,12 @@ ...@@ -15,26 +15,12 @@
#include "op_impl.h" #include "op_impl.h"
#define M_PERFCTL_EXL (1UL << 0) #define M_PERFCTL_EVENT(event) (((event) << MIPS_PERFCTRL_EVENT_S) & \
#define M_PERFCTL_KERNEL (1UL << 1) MIPS_PERFCTRL_EVENT)
#define M_PERFCTL_SUPERVISOR (1UL << 2) #define M_PERFCTL_VPEID(vpe) ((vpe) << MIPS_PERFCTRL_VPEID_S)
#define M_PERFCTL_USER (1UL << 3)
#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
#define M_PERFCTL_WIDE (1UL << 30)
#define M_PERFCTL_MORE (1UL << 31)
#define M_COUNTER_OVERFLOW (1UL << 31) #define M_COUNTER_OVERFLOW (1UL << 31)
/* Netlogic XLR specific, count events in all threads in a core */
#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13)
static int (*save_perf_irq)(void); static int (*save_perf_irq)(void);
static int perfcount_irq; static int perfcount_irq;
...@@ -51,7 +37,7 @@ static int perfcount_irq; ...@@ -51,7 +37,7 @@ static int perfcount_irq;
#ifdef CONFIG_MIPS_MT_SMP #ifdef CONFIG_MIPS_MT_SMP
static int cpu_has_mipsmt_pertccounters; static int cpu_has_mipsmt_pertccounters;
#define WHAT (M_TC_EN_VPE | \ #define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \
M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ #define vpe_id() (cpu_has_mipsmt_pertccounters ? \
0 : cpu_data[smp_processor_id()].vpe_id) 0 : cpu_data[smp_processor_id()].vpe_id)
...@@ -161,15 +147,15 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) ...@@ -161,15 +147,15 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr)
continue; continue;
reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) | reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) |
M_PERFCTL_INTERRUPT_ENABLE; MIPS_PERFCTRL_IE;
if (ctr[i].kernel) if (ctr[i].kernel)
reg.control[i] |= M_PERFCTL_KERNEL; reg.control[i] |= MIPS_PERFCTRL_K;
if (ctr[i].user) if (ctr[i].user)
reg.control[i] |= M_PERFCTL_USER; reg.control[i] |= MIPS_PERFCTRL_U;
if (ctr[i].exl) if (ctr[i].exl)
reg.control[i] |= M_PERFCTL_EXL; reg.control[i] |= MIPS_PERFCTRL_EXL;
if (boot_cpu_type() == CPU_XLR) if (boot_cpu_type() == CPU_XLR)
reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS; reg.control[i] |= XLR_PERFCTRL_ALLTHREADS;
reg.counter[i] = 0x80000000 - ctr[i].count; reg.counter[i] = 0x80000000 - ctr[i].count;
} }
} }
...@@ -254,7 +240,7 @@ static int mipsxx_perfcount_handler(void) ...@@ -254,7 +240,7 @@ static int mipsxx_perfcount_handler(void)
case n + 1: \ case n + 1: \
control = r_c0_perfctrl ## n(); \ control = r_c0_perfctrl ## n(); \
counter = r_c0_perfcntr ## n(); \ counter = r_c0_perfcntr ## n(); \
if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \ if ((control & MIPS_PERFCTRL_IE) && \
(counter & M_COUNTER_OVERFLOW)) { \ (counter & M_COUNTER_OVERFLOW)) { \
oprofile_add_sample(get_irq_regs(), n); \ oprofile_add_sample(get_irq_regs(), n); \
w_c0_perfcntr ## n(reg.counter[n]); \ w_c0_perfcntr ## n(reg.counter[n]); \
...@@ -273,11 +259,11 @@ static inline int __n_counters(void) ...@@ -273,11 +259,11 @@ static inline int __n_counters(void)
{ {
if (!cpu_has_perf) if (!cpu_has_perf)
return 0; return 0;
if (!(read_c0_perfctrl0() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl0() & MIPS_PERFCTRL_M))
return 1; return 1;
if (!(read_c0_perfctrl1() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl1() & MIPS_PERFCTRL_M))
return 2; return 2;
if (!(read_c0_perfctrl2() & M_PERFCTL_MORE)) if (!(read_c0_perfctrl2() & MIPS_PERFCTRL_M))
return 3; return 3;
return 4; return 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment