mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
MIPS: perf: Add Octeon support for hardware perf.
Enable hardware counters for Octeon, and add the corresponding event mappings. Signed-off-by: David Daney <david.daney@cavium.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com> To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2790/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
82091564cf
commit
939991cff1
2 changed files with 148 additions and 1 deletions
|
@ -2101,7 +2101,7 @@ config NODES_SHIFT
|
||||||
|
|
||||||
config HW_PERF_EVENTS
|
config HW_PERF_EVENTS
|
||||||
bool "Enable hardware performance counter support for perf events"
|
bool "Enable hardware performance counter support for perf events"
|
||||||
depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1)
|
depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Enable hardware performance counter support for perf events. If
|
Enable hardware performance counter support for perf events. If
|
||||||
|
|
|
@ -841,6 +841,16 @@ static const struct mips_perf_event mipsxx74Kcore_event_map
|
||||||
[PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
|
[PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x2b, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_CACHE_MISSES] = { 0x2e, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x08, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = { 0x09, CNTR_ALL },
|
||||||
|
[PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL },
|
||||||
|
};
|
||||||
|
|
||||||
/* 24K/34K/1004K cores can share the same cache event map. */
|
/* 24K/34K/1004K cores can share the same cache event map. */
|
||||||
static const struct mips_perf_event mipsxxcore_cache_map
|
static const struct mips_perf_event mipsxxcore_cache_map
|
||||||
[PERF_COUNT_HW_CACHE_MAX]
|
[PERF_COUNT_HW_CACHE_MAX]
|
||||||
|
@ -1074,6 +1084,102 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const struct mips_perf_event octeon_cache_map
|
||||||
|
[PERF_COUNT_HW_CACHE_MAX]
|
||||||
|
[PERF_COUNT_HW_CACHE_OP_MAX]
|
||||||
|
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||||
|
[C(L1D)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { 0x2b, CNTR_ALL },
|
||||||
|
[C(RESULT_MISS)] = { 0x2e, CNTR_ALL },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { 0x30, CNTR_ALL },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(L1I)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { 0x18, CNTR_ALL },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { 0x19, CNTR_ALL },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(LL)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(DTLB)] = {
|
||||||
|
/*
|
||||||
|
* Only general DTLB misses are counted use the same event for
|
||||||
|
* read and write.
|
||||||
|
*/
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { 0x35, CNTR_ALL },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { 0x35, CNTR_ALL },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(ITLB)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { 0x37, CNTR_ALL },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(BPU)] = {
|
||||||
|
/* Using the same code for *HW_BRANCH* */
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
[C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_MT_SMP
|
#ifdef CONFIG_MIPS_MT_SMP
|
||||||
static void check_and_calc_range(struct perf_event *event,
|
static void check_and_calc_range(struct perf_event *event,
|
||||||
const struct mips_perf_event *pev)
|
const struct mips_perf_event *pev)
|
||||||
|
@ -1411,6 +1517,39 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
|
||||||
return &raw_event;
|
return &raw_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct mips_perf_event *octeon_pmu_map_raw_event(u64 config)
|
||||||
|
{
|
||||||
|
unsigned int raw_id = config & 0xff;
|
||||||
|
unsigned int base_id = raw_id & 0x7f;
|
||||||
|
|
||||||
|
|
||||||
|
raw_event.cntr_mask = CNTR_ALL;
|
||||||
|
raw_event.event_id = base_id;
|
||||||
|
|
||||||
|
if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
|
||||||
|
if (base_id > 0x42)
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
} else {
|
||||||
|
if (base_id > 0x3a)
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (base_id) {
|
||||||
|
case 0x00:
|
||||||
|
case 0x0f:
|
||||||
|
case 0x1e:
|
||||||
|
case 0x1f:
|
||||||
|
case 0x2f:
|
||||||
|
case 0x34:
|
||||||
|
case 0x3b ... 0x3f:
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &raw_event;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
init_hw_perf_events(void)
|
init_hw_perf_events(void)
|
||||||
{
|
{
|
||||||
|
@ -1470,6 +1609,14 @@ init_hw_perf_events(void)
|
||||||
mipspmu.general_event_map = &mipsxxcore_event_map;
|
mipspmu.general_event_map = &mipsxxcore_event_map;
|
||||||
mipspmu.cache_event_map = &mipsxxcore_cache_map;
|
mipspmu.cache_event_map = &mipsxxcore_cache_map;
|
||||||
break;
|
break;
|
||||||
|
case CPU_CAVIUM_OCTEON:
|
||||||
|
case CPU_CAVIUM_OCTEON_PLUS:
|
||||||
|
case CPU_CAVIUM_OCTEON2:
|
||||||
|
mipspmu.name = "octeon";
|
||||||
|
mipspmu.general_event_map = &octeon_event_map;
|
||||||
|
mipspmu.cache_event_map = &octeon_cache_map;
|
||||||
|
mipspmu.map_raw_event = octeon_pmu_map_raw_event;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_cont("Either hardware does not support performance "
|
pr_cont("Either hardware does not support performance "
|
||||||
"counters, or not yet implemented.\n");
|
"counters, or not yet implemented.\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue