From f6e6460dfc3e1aec5a2110d785a40d8db83a979e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 5 Apr 2015 02:57:02 +0000 Subject: [PATCH] Add support for the MIPS74K SoC family performance counters events. These are similar to the mips24k performance counters - some are available on perfcnt0/3, some are available on perfcnt1/4. However, the events aren't all the same. * Add the events, named the same as from Linux oprofile. * Verify they're the same as "MIPS32(R) 74KTM Processor Core Family Software User's Manual"; Document Number: MD00519; Revision 01.05. * Rename INSTRUCTIONS to something else, so it doesn't clash with the alias INSTRUCTIONS. I'll try to tidy this up later; there are a few other aliases to add and shuffle around. Tested: * QCA9558 SoC (AP135 board) - MIPS74Kc core (no FPU.) * make universe; where it didn't fail for other reasons. TODO: * It'd be nice to support the four performance counters in at least this hardware, rather than just two. Reviewed by: bsdimp ("looks good; don't break world".) --- lib/libpmc/libpmc.c | 21 +++ sys/conf/files.mips | 1 + sys/dev/hwpmc/hwpmc_mips74k.c | 261 ++++++++++++++++++++++++++++++++++ sys/dev/hwpmc/pmc_events.h | 136 ++++++++++++++++++ 4 files changed, 419 insertions(+) create mode 100644 sys/dev/hwpmc/hwpmc_mips74k.c diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 17283d8f02d4..7d429ebd297c 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -159,6 +159,7 @@ PMC_CLASSDEP_TABLE(p6, P6); PMC_CLASSDEP_TABLE(xscale, XSCALE); PMC_CLASSDEP_TABLE(armv7, ARMV7); PMC_CLASSDEP_TABLE(mips24k, MIPS24K); +PMC_CLASSDEP_TABLE(mips74k, MIPS74K); PMC_CLASSDEP_TABLE(octeon, OCTEON); PMC_CLASSDEP_TABLE(ucf, UCF); PMC_CLASSDEP_TABLE(ppc7450, PPC7450); @@ -293,6 +294,7 @@ PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC); PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE); PMC_MDEP_TABLE(armv7, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); +PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K); PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450); PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970); @@ -360,6 +362,7 @@ PMC_CLASS_TABLE_DESC(armv7, ARMV7, armv7, armv7); #endif #if defined(__mips__) PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips); +PMC_CLASS_TABLE_DESC(mips74k, MIPS74K, mips74k, mips); PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips); #endif /* __mips__ */ #if defined(__powerpc__) @@ -2432,6 +2435,13 @@ static struct pmc_event_alias mips24k_aliases[] = { EV_ALIAS(NULL, NULL) }; +static struct pmc_event_alias mips74k_aliases[] = { + EV_ALIAS("instructions", "INSTR_EXECUTED"), + EV_ALIAS("branches", "BRANCH_INSNS"), + EV_ALIAS("branch-mispredicts", "MISPREDICTED_BRANCH_INSNS"), + EV_ALIAS(NULL, NULL) +}; + static struct pmc_event_alias octeon_aliases[] = { EV_ALIAS("instructions", "RET"), EV_ALIAS("branches", "BR"), @@ -2923,6 +2933,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = mips24k_event_table; count = PMC_EVENT_TABLE_SIZE(mips24k); break; + case PMC_CLASS_MIPS74K: + ev = mips74k_event_table; + count = PMC_EVENT_TABLE_SIZE(mips74k); + break; case PMC_CLASS_OCTEON: ev = octeon_event_table; count = PMC_EVENT_TABLE_SIZE(octeon); @@ -3213,6 +3227,10 @@ pmc_init(void) PMC_MDEP_INIT(mips24k); pmc_class_table[n] = &mips24k_class_table_descr; break; + case PMC_CPU_MIPS_74K: + PMC_MDEP_INIT(mips74k); + pmc_class_table[n] = &mips74k_class_table_descr; + break; case PMC_CPU_MIPS_OCTEON: PMC_MDEP_INIT(octeon); pmc_class_table[n] = &octeon_class_table_descr; @@ -3414,6 +3432,9 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) } else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) { ev = mips24k_event_table; evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k); + } else if (pe >= PMC_EV_MIPS74K_FIRST && pe <= PMC_EV_MIPS74K_LAST) { + ev = mips74k_event_table; + evfence = mips74k_event_table + PMC_EVENT_TABLE_SIZE(mips74k); } else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) { ev = octeon_event_table; evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon); diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 3677de43ae1b..4bc6775a1fd4 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -89,3 +89,4 @@ dev/nvram2env/nvram2env.c optional nvram2env # hwpmc support dev/hwpmc/hwpmc_mips.c optional hwpmc dev/hwpmc/hwpmc_mips24k.c optional hwpmc_mips24k +dev/hwpmc/hwpmc_mips74k.c optional hwpmc_mips74k diff --git a/sys/dev/hwpmc/hwpmc_mips74k.c b/sys/dev/hwpmc/hwpmc_mips74k.c new file mode 100644 index 000000000000..3a5ff3395bba --- /dev/null +++ b/sys/dev/hwpmc/hwpmc_mips74k.c @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2010 George V. Neville-Neil + * Copyright (c) 2015 Adrian Chadd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include + +#define MIPS74K_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \ + PMC_CAP_SYSTEM | PMC_CAP_EDGE | \ + PMC_CAP_THRESHOLD | PMC_CAP_READ | \ + PMC_CAP_WRITE | PMC_CAP_INVERT | \ + PMC_CAP_QUALIFIER) + +/* 0x1 - Exception_enable */ +#define MIPS74K_PMC_INTERRUPT_ENABLE 0x10 /* Enable interrupts */ +#define MIPS74K_PMC_USER_ENABLE 0x08 /* Count in USER mode */ +#define MIPS74K_PMC_SUPER_ENABLE 0x04 /* Count in SUPERVISOR mode */ +#define MIPS74K_PMC_KERNEL_ENABLE 0x02 /* Count in KERNEL mode */ +#define MIPS74K_PMC_ENABLE (MIPS74K_PMC_USER_ENABLE | \ + MIPS74K_PMC_SUPER_ENABLE | \ + MIPS74K_PMC_KERNEL_ENABLE) + +#define MIPS74K_PMC_SELECT 5 /* Which bit position the event starts at. */ + +const struct mips_event_code_map mips_event_codes[] = { + { PMC_EV_MIPS74K_CYCLES, MIPS_CTR_ALL, 0 }, + { PMC_EV_MIPS74K_INSTR_EXECUTED, MIPS_CTR_ALL, 1 }, + { PMC_EV_MIPS74K_PREDICTED_JR_31, MIPS_CTR_0, 2 }, + { PMC_EV_MIPS74K_JR_31_MISPREDICTIONS, MIPS_CTR_1, 2 }, + { PMC_EV_MIPS74K_REDIRECT_STALLS, MIPS_CTR_0, 3 }, + { PMC_EV_MIPS74K_JR_31_NO_PREDICTIONS, MIPS_CTR_1, 3 }, + { PMC_EV_MIPS74K_ITLB_ACCESSES, MIPS_CTR_0, 4 }, + { PMC_EV_MIPS74K_ITLB_MISSES, MIPS_CTR_1, 4 }, + { PMC_EV_MIPS74K_JTLB_INSN_MISSES, MIPS_CTR_1, 5 }, + { PMC_EV_MIPS74K_ICACHE_ACCESSES, MIPS_CTR_0, 6 }, + { PMC_EV_MIPS74K_ICACHE_MISSES, MIPS_CTR_1, 6 }, + { PMC_EV_MIPS74K_ICACHE_MISS_STALLS, MIPS_CTR_0, 7 }, + { PMC_EV_MIPS74K_UNCACHED_IFETCH_STALLS, MIPS_CTR_0, 8 }, + { PMC_EV_MIPS74K_PDTRACE_BACK_STALLS, MIPS_CTR_1, 8 }, + { PMC_EV_MIPS74K_IFU_REPLAYS, MIPS_CTR_0, 9 }, + { PMC_EV_MIPS74K_KILLED_FETCH_SLOTS, MIPS_CTR_1, 9 }, + { PMC_EV_MIPS74K_IFU_IDU_MISS_PRED_UPSTREAM_CYCLES, MIPS_CTR_0, 11 }, + { PMC_EV_MIPS74K_IFU_IDU_NO_FETCH_CYCLES, MIPS_CTR_1, 11 }, + { PMC_EV_MIPS74K_IFU_IDU_CLOGED_DOWNSTREAM_CYCLES, MIPS_CTR_0, 12 }, + { PMC_EV_MIPS74K_DDQ0_FULL_DR_STALLS, MIPS_CTR_0, 13 }, + { PMC_EV_MIPS74K_DDQ1_FULL_DR_STALLS, MIPS_CTR_1, 13 }, + { PMC_EV_MIPS74K_ALCB_FULL_DR_STALLS, MIPS_CTR_0, 14 }, + { PMC_EV_MIPS74K_AGCB_FULL_DR_STALLS, MIPS_CTR_1, 14 }, + { PMC_EV_MIPS74K_CLDQ_FULL_DR_STALLS, MIPS_CTR_0, 15 }, + { PMC_EV_MIPS74K_IODQ_FULL_DR_STALLS, MIPS_CTR_1, 15 }, + { PMC_EV_MIPS74K_ALU_EMPTY_CYCLES, MIPS_CTR_0, 16 }, + { PMC_EV_MIPS74K_AGEN_EMPTY_CYCLES, MIPS_CTR_1, 16 }, + { PMC_EV_MIPS74K_ALU_OPERANDS_NOT_READY_CYCLES, MIPS_CTR_0, 17 }, + { PMC_EV_MIPS74K_AGEN_OPERANDS_NOT_READY_CYCLES, MIPS_CTR_1, 17 }, + { PMC_EV_MIPS74K_ALU_NO_ISSUES_CYCLES, MIPS_CTR_0, 18 }, + { PMC_EV_MIPS74K_AGEN_NO_ISSUES_CYCLES, MIPS_CTR_1, 18 }, + { PMC_EV_MIPS74K_ALU_BUBBLE_CYCLES, MIPS_CTR_0, 19 }, + { PMC_EV_MIPS74K_AGEN_BUBBLE_CYCLES, MIPS_CTR_1, 19 }, + { PMC_EV_MIPS74K_SINGLE_ISSUE_CYCLES, MIPS_CTR_0, 20 }, + { PMC_EV_MIPS74K_DUAL_ISSUE_CYCLES, MIPS_CTR_1, 20 }, + { PMC_EV_MIPS74K_OOO_ALU_ISSUE_CYCLES, MIPS_CTR_0, 21 }, + { PMC_EV_MIPS74K_OOO_AGEN_ISSUE_CYCLES, MIPS_CTR_1, 21 }, + { PMC_EV_MIPS74K_JALR_JALR_HB_INSNS, MIPS_CTR_0, 22 }, + { PMC_EV_MIPS74K_DCACHE_LINE_REFILL_REQUESTS, MIPS_CTR_1, 22 }, + { PMC_EV_MIPS74K_DCACHE_LOAD_ACCESSES, MIPS_CTR_0, 23 }, + { PMC_EV_MIPS74K_DCACHE_ACCESSES, MIPS_CTR_1, 23 }, + { PMC_EV_MIPS74K_DCACHE_WRITEBACKS, MIPS_CTR_0, 24 }, + { PMC_EV_MIPS74K_DCACHE_MISSES, MIPS_CTR_1, 24 }, + { PMC_EV_MIPS74K_JTLB_DATA_ACCESSES, MIPS_CTR_0, 25 }, + { PMC_EV_MIPS74K_JTLB_DATA_MISSES, MIPS_CTR_1, 25 }, + { PMC_EV_MIPS74K_LOAD_STORE_REPLAYS, MIPS_CTR_0, 26 }, + { PMC_EV_MIPS74K_VA_TRANSALTION_CORNER_CASES, MIPS_CTR_1, 26 }, + { PMC_EV_MIPS74K_LOAD_STORE_BLOCKED_CYCLES, MIPS_CTR_0, 27 }, + { PMC_EV_MIPS74K_LOAD_STORE_NO_FILL_REQUESTS, MIPS_CTR_1, 27 }, + { PMC_EV_MIPS74K_L2_CACHE_WRITEBACKS, MIPS_CTR_0, 28 }, + { PMC_EV_MIPS74K_L2_CACHE_ACCESSES, MIPS_CTR_1, 28 }, + { PMC_EV_MIPS74K_L2_CACHE_MISSES, MIPS_CTR_0, 29 }, + { PMC_EV_MIPS74K_L2_CACHE_MISS_CYCLES, MIPS_CTR_1, 29 }, + { PMC_EV_MIPS74K_FSB_FULL_STALLS, MIPS_CTR_0, 30 }, + { PMC_EV_MIPS74K_FSB_OVER_50_FULL, MIPS_CTR_1, 30 }, + { PMC_EV_MIPS74K_LDQ_FULL_STALLS, MIPS_CTR_0, 31 }, + { PMC_EV_MIPS74K_LDQ_OVER_50_FULL, MIPS_CTR_1, 31 }, + { PMC_EV_MIPS74K_WBB_FULL_STALLS, MIPS_CTR_0, 32 }, + { PMC_EV_MIPS74K_WBB_OVER_50_FULL, MIPS_CTR_1, 32 }, + { PMC_EV_MIPS74K_LOAD_MISS_CONSUMER_REPLAYS, MIPS_CTR_0, 35 }, + { PMC_EV_MIPS74K_CP1_CP2_LOAD_INSNS, MIPS_CTR_1, 35 }, + { PMC_EV_MIPS74K_JR_NON_31_INSNS, MIPS_CTR_0, 36 }, + { PMC_EV_MIPS74K_MISPREDICTED_JR_31_INSNS, MIPS_CTR_1, 36 }, + { PMC_EV_MIPS74K_BRANCH_INSNS, MIPS_CTR_0, 37 }, + { PMC_EV_MIPS74K_CP1_CP2_COND_BRANCH_INSNS, MIPS_CTR_1, 37 }, + { PMC_EV_MIPS74K_BRANCH_LIKELY_INSNS, MIPS_CTR_0, 38 }, + { PMC_EV_MIPS74K_MISPREDICTED_BRANCH_LIKELY_INSNS, MIPS_CTR_1, 38 }, + { PMC_EV_MIPS74K_COND_BRANCH_INSNS, MIPS_CTR_0, 39 }, + { PMC_EV_MIPS74K_MISPREDICTED_BRANCH_INSNS, MIPS_CTR_1, 39 }, + { PMC_EV_MIPS74K_INTEGER_INSNS, MIPS_CTR_0, 40 }, + { PMC_EV_MIPS74K_FPU_INSNS, MIPS_CTR_1, 40 }, + { PMC_EV_MIPS74K_LOAD_INSNS, MIPS_CTR_0, 41 }, + { PMC_EV_MIPS74K_STORE_INSNS, MIPS_CTR_1, 41 }, + { PMC_EV_MIPS74K_J_JAL_INSNS, MIPS_CTR_0, 42 }, + { PMC_EV_MIPS74K_MIPS16_INSNS, MIPS_CTR_1, 42 }, + { PMC_EV_MIPS74K_NOP_INSNS, MIPS_CTR_0, 43 }, + { PMC_EV_MIPS74K_NT_MUL_DIV_INSNS, MIPS_CTR_1, 43 }, + { PMC_EV_MIPS74K_DSP_INSNS, MIPS_CTR_0, 44 }, + { PMC_EV_MIPS74K_ALU_DSP_SATURATION_INSNS, MIPS_CTR_1, 44 }, + { PMC_EV_MIPS74K_DSP_BRANCH_INSNS, MIPS_CTR_0, 45 }, + { PMC_EV_MIPS74K_MDU_DSP_SATURATION_INSNS, MIPS_CTR_1, 45 }, + { PMC_EV_MIPS74K_UNCACHED_LOAD_INSNS, MIPS_CTR_0, 46 }, + { PMC_EV_MIPS74K_UNCACHED_STORE_INSNS, MIPS_CTR_1, 46 }, + { PMC_EV_MIPS74K_EJTAG_INSN_TRIGGERS, MIPS_CTR_0, 49 }, + { PMC_EV_MIPS74K_CP1_BRANCH_MISPREDICTIONS, MIPS_CTR_0, 50 }, + { PMC_EV_MIPS74K_SC_INSNS, MIPS_CTR_0, 51 }, + { PMC_EV_MIPS74K_FAILED_SC_INSNS, MIPS_CTR_1, 51 }, + { PMC_EV_MIPS74K_PREFETCH_INSNS, MIPS_CTR_0, 52 }, + { PMC_EV_MIPS74K_CACHE_HIT_PREFETCH_INSNS, MIPS_CTR_1, 52 }, + { PMC_EV_MIPS74K_NO_INSN_CYCLES, MIPS_CTR_0, 53 }, + { PMC_EV_MIPS74K_LOAD_MISS_INSNS, MIPS_CTR_1, 53 }, + { PMC_EV_MIPS74K_ONE_INSN_CYCLES, MIPS_CTR_0, 54 }, + { PMC_EV_MIPS74K_TWO_INSNS_CYCLES, MIPS_CTR_1, 54 }, + { PMC_EV_MIPS74K_GFIFO_BLOCKED_CYCLES, MIPS_CTR_0, 55 }, + { PMC_EV_MIPS74K_CP1_CP2_STORE_INSNS, MIPS_CTR_1, 55 }, + { PMC_EV_MIPS74K_MISPREDICTION_STALLS, MIPS_CTR_0, 56 }, + { PMC_EV_MIPS74K_MISPREDICTED_BRANCH_INSNS_CYCLES, MIPS_CTR_0, 57 }, + { PMC_EV_MIPS74K_EXCEPTIONS_TAKEN, MIPS_CTR_0, 58 }, + { PMC_EV_MIPS74K_GRADUATION_REPLAYS, MIPS_CTR_1, 58 }, + { PMC_EV_MIPS74K_COREEXTEND_EVENTS, MIPS_CTR_0, 59 }, + { PMC_EV_MIPS74K_ISPRAM_EVENTS, MIPS_CTR_0, 62 }, + { PMC_EV_MIPS74K_DSPRAM_EVENTS, MIPS_CTR_1, 62 }, + { PMC_EV_MIPS74K_L2_CACHE_SINGLE_BIT_ERRORS, MIPS_CTR_0, 63 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_0, MIPS_CTR_0, 64 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_1, MIPS_CTR_1, 64 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_2, MIPS_CTR_0, 65 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_3, MIPS_CTR_1, 65 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_4, MIPS_CTR_0, 66 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_5, MIPS_CTR_1, 66 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_6, MIPS_CTR_0, 67 }, + { PMC_EV_MIPS74K_SYSTEM_EVENT_7, MIPS_CTR_1, 67 }, + { PMC_EV_MIPS74K_OCP_ALL_REQUESTS, MIPS_CTR_0, 68 }, + { PMC_EV_MIPS74K_OCP_ALL_CACHEABLE_REQUESTS, MIPS_CTR_1, 68 }, + { PMC_EV_MIPS74K_OCP_READ_REQUESTS, MIPS_CTR_0, 69 }, + { PMC_EV_MIPS74K_OCP_READ_CACHEABLE_REQUESTS, MIPS_CTR_1, 69 }, + { PMC_EV_MIPS74K_OCP_WRITE_REQUESTS, MIPS_CTR_0, 70 }, + { PMC_EV_MIPS74K_OCP_WRITE_CACHEABLE_REQUESTS, MIPS_CTR_1, 70 }, + { PMC_EV_MIPS74K_FSB_LESS_25_FULL, MIPS_CTR_0, 74 }, + { PMC_EV_MIPS74K_FSB_25_50_FULL, MIPS_CTR_1, 74 }, + { PMC_EV_MIPS74K_LDQ_LESS_25_FULL, MIPS_CTR_0, 75 }, + { PMC_EV_MIPS74K_LDQ_25_50_FULL, MIPS_CTR_1, 75 }, + { PMC_EV_MIPS74K_WBB_LESS_25_FULL, MIPS_CTR_0, 76 }, + { PMC_EV_MIPS74K_WBB_25_50_FULL, MIPS_CTR_1, 76 }, +}; + +const int mips_event_codes_size = + sizeof(mips_event_codes) / sizeof(mips_event_codes[0]); + +struct mips_pmc_spec mips_pmc_spec = { + .ps_cpuclass = PMC_CLASS_MIPS74K, + .ps_cputype = PMC_CPU_MIPS_74K, + .ps_capabilities = MIPS74K_PMC_CAPS, + .ps_counter_width = 32 +}; + +/* + * Performance Count Register N + */ +uint64_t +mips_pmcn_read(unsigned int pmc) +{ + uint32_t reg = 0; + + KASSERT(pmc < mips_npmcs, ("[mips74k,%d] illegal PMC number %d", + __LINE__, pmc)); + + /* The counter value is the next value after the control register. */ + switch (pmc) { + case 0: + reg = mips_rd_perfcnt1(); + break; + case 1: + reg = mips_rd_perfcnt3(); + break; + default: + return 0; + } + return (reg); +} + +uint64_t +mips_pmcn_write(unsigned int pmc, uint64_t reg) +{ + + KASSERT(pmc < mips_npmcs, ("[mips74k,%d] illegal PMC number %d", + __LINE__, pmc)); + + switch (pmc) { + case 0: + mips_wr_perfcnt1(reg); + break; + case 1: + mips_wr_perfcnt3(reg); + break; + default: + return 0; + } + return (reg); +} + +uint32_t +mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps) +{ + uint32_t config; + + config = event; + + config <<= MIPS74K_PMC_SELECT; + + if (caps & PMC_CAP_SYSTEM) + config |= (MIPS74K_PMC_SUPER_ENABLE | + MIPS74K_PMC_KERNEL_ENABLE); + if (caps & PMC_CAP_USER) + config |= MIPS74K_PMC_USER_ENABLE; + if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) + config |= MIPS74K_PMC_ENABLE; + if (caps & PMC_CAP_INTERRUPT) + config |= MIPS74K_PMC_INTERRUPT_ENABLE; + + PMCDBG(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config); + + return (config); +} diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 400a39401fab..f50c4124813c 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -4892,6 +4892,138 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H) #define PMC_EV_MIPS24K_FIRST PMC_EV_MIPS24K_CYCLE #define PMC_EV_MIPS24K_LAST PMC_EV_MIPS24K_WBB_FULL_PIPELINE_STALLS +/* + * MIPS74k events. Similar to MIPS24k, the arrangement + * is (0,2) then (1,3) events. + */ +#define __PMC_EV_MIPS74K() \ + __PMC_EV(MIPS74K, CYCLES) \ + __PMC_EV(MIPS74K, INSTR_EXECUTED) \ + __PMC_EV(MIPS74K, PREDICTED_JR_31) \ + __PMC_EV(MIPS74K, JR_31_MISPREDICTIONS) \ + __PMC_EV(MIPS74K, REDIRECT_STALLS) \ + __PMC_EV(MIPS74K, JR_31_NO_PREDICTIONS) \ + __PMC_EV(MIPS74K, ITLB_ACCESSES) \ + __PMC_EV(MIPS74K, ITLB_MISSES) \ + __PMC_EV(MIPS74K, JTLB_INSN_MISSES) \ + __PMC_EV(MIPS74K, ICACHE_ACCESSES) \ + __PMC_EV(MIPS74K, ICACHE_MISSES) \ + __PMC_EV(MIPS74K, ICACHE_MISS_STALLS) \ + __PMC_EV(MIPS74K, UNCACHED_IFETCH_STALLS) \ + __PMC_EV(MIPS74K, PDTRACE_BACK_STALLS) \ + __PMC_EV(MIPS74K, IFU_REPLAYS) \ + __PMC_EV(MIPS74K, KILLED_FETCH_SLOTS) \ + __PMC_EV(MIPS74K, IFU_IDU_MISS_PRED_UPSTREAM_CYCLES) \ + __PMC_EV(MIPS74K, IFU_IDU_NO_FETCH_CYCLES) \ + __PMC_EV(MIPS74K, IFU_IDU_CLOGED_DOWNSTREAM_CYCLES) \ + __PMC_EV(MIPS74K, DDQ0_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, DDQ1_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, ALCB_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, AGCB_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, CLDQ_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, IODQ_FULL_DR_STALLS) \ + __PMC_EV(MIPS74K, ALU_EMPTY_CYCLES) \ + __PMC_EV(MIPS74K, AGEN_EMPTY_CYCLES) \ + __PMC_EV(MIPS74K, ALU_OPERANDS_NOT_READY_CYCLES) \ + __PMC_EV(MIPS74K, AGEN_OPERANDS_NOT_READY_CYCLES) \ + __PMC_EV(MIPS74K, ALU_NO_ISSUES_CYCLES) \ + __PMC_EV(MIPS74K, AGEN_NO_ISSUES_CYCLES) \ + __PMC_EV(MIPS74K, ALU_BUBBLE_CYCLES) \ + __PMC_EV(MIPS74K, AGEN_BUBBLE_CYCLES) \ + __PMC_EV(MIPS74K, SINGLE_ISSUE_CYCLES) \ + __PMC_EV(MIPS74K, DUAL_ISSUE_CYCLES) \ + __PMC_EV(MIPS74K, OOO_ALU_ISSUE_CYCLES) \ + __PMC_EV(MIPS74K, OOO_AGEN_ISSUE_CYCLES) \ + __PMC_EV(MIPS74K, JALR_JALR_HB_INSNS) \ + __PMC_EV(MIPS74K, DCACHE_LINE_REFILL_REQUESTS) \ + __PMC_EV(MIPS74K, DCACHE_LOAD_ACCESSES) \ + __PMC_EV(MIPS74K, DCACHE_ACCESSES) \ + __PMC_EV(MIPS74K, DCACHE_WRITEBACKS) \ + __PMC_EV(MIPS74K, DCACHE_MISSES) \ + __PMC_EV(MIPS74K, JTLB_DATA_ACCESSES) \ + __PMC_EV(MIPS74K, JTLB_DATA_MISSES) \ + __PMC_EV(MIPS74K, LOAD_STORE_REPLAYS) \ + __PMC_EV(MIPS74K, VA_TRANSALTION_CORNER_CASES) \ + __PMC_EV(MIPS74K, LOAD_STORE_BLOCKED_CYCLES) \ + __PMC_EV(MIPS74K, LOAD_STORE_NO_FILL_REQUESTS) \ + __PMC_EV(MIPS74K, L2_CACHE_WRITEBACKS) \ + __PMC_EV(MIPS74K, L2_CACHE_ACCESSES) \ + __PMC_EV(MIPS74K, L2_CACHE_MISSES) \ + __PMC_EV(MIPS74K, L2_CACHE_MISS_CYCLES) \ + __PMC_EV(MIPS74K, FSB_FULL_STALLS) \ + __PMC_EV(MIPS74K, FSB_OVER_50_FULL) \ + __PMC_EV(MIPS74K, LDQ_FULL_STALLS) \ + __PMC_EV(MIPS74K, LDQ_OVER_50_FULL) \ + __PMC_EV(MIPS74K, WBB_FULL_STALLS) \ + __PMC_EV(MIPS74K, WBB_OVER_50_FULL) \ + __PMC_EV(MIPS74K, LOAD_MISS_CONSUMER_REPLAYS) \ + __PMC_EV(MIPS74K, CP1_CP2_LOAD_INSNS) \ + __PMC_EV(MIPS74K, JR_NON_31_INSNS) \ + __PMC_EV(MIPS74K, MISPREDICTED_JR_31_INSNS) \ + __PMC_EV(MIPS74K, BRANCH_INSNS) \ + __PMC_EV(MIPS74K, CP1_CP2_COND_BRANCH_INSNS) \ + __PMC_EV(MIPS74K, BRANCH_LIKELY_INSNS) \ + __PMC_EV(MIPS74K, MISPREDICTED_BRANCH_LIKELY_INSNS) \ + __PMC_EV(MIPS74K, COND_BRANCH_INSNS) \ + __PMC_EV(MIPS74K, MISPREDICTED_BRANCH_INSNS) \ + __PMC_EV(MIPS74K, INTEGER_INSNS) \ + __PMC_EV(MIPS74K, FPU_INSNS) \ + __PMC_EV(MIPS74K, LOAD_INSNS) \ + __PMC_EV(MIPS74K, STORE_INSNS) \ + __PMC_EV(MIPS74K, J_JAL_INSNS) \ + __PMC_EV(MIPS74K, MIPS16_INSNS) \ + __PMC_EV(MIPS74K, NOP_INSNS) \ + __PMC_EV(MIPS74K, NT_MUL_DIV_INSNS) \ + __PMC_EV(MIPS74K, DSP_INSNS) \ + __PMC_EV(MIPS74K, ALU_DSP_SATURATION_INSNS) \ + __PMC_EV(MIPS74K, DSP_BRANCH_INSNS) \ + __PMC_EV(MIPS74K, MDU_DSP_SATURATION_INSNS) \ + __PMC_EV(MIPS74K, UNCACHED_LOAD_INSNS) \ + __PMC_EV(MIPS74K, UNCACHED_STORE_INSNS) \ + __PMC_EV(MIPS74K, EJTAG_INSN_TRIGGERS) \ + __PMC_EV(MIPS74K, CP1_BRANCH_MISPREDICTIONS) \ + __PMC_EV(MIPS74K, SC_INSNS) \ + __PMC_EV(MIPS74K, FAILED_SC_INSNS) \ + __PMC_EV(MIPS74K, PREFETCH_INSNS) \ + __PMC_EV(MIPS74K, CACHE_HIT_PREFETCH_INSNS) \ + __PMC_EV(MIPS74K, NO_INSN_CYCLES) \ + __PMC_EV(MIPS74K, LOAD_MISS_INSNS) \ + __PMC_EV(MIPS74K, ONE_INSN_CYCLES) \ + __PMC_EV(MIPS74K, TWO_INSNS_CYCLES) \ + __PMC_EV(MIPS74K, GFIFO_BLOCKED_CYCLES) \ + __PMC_EV(MIPS74K, CP1_CP2_STORE_INSNS) \ + __PMC_EV(MIPS74K, MISPREDICTION_STALLS) \ + __PMC_EV(MIPS74K, MISPREDICTED_BRANCH_INSNS_CYCLES) \ + __PMC_EV(MIPS74K, EXCEPTIONS_TAKEN) \ + __PMC_EV(MIPS74K, GRADUATION_REPLAYS) \ + __PMC_EV(MIPS74K, COREEXTEND_EVENTS) \ + __PMC_EV(MIPS74K, ISPRAM_EVENTS) \ + __PMC_EV(MIPS74K, DSPRAM_EVENTS) \ + __PMC_EV(MIPS74K, L2_CACHE_SINGLE_BIT_ERRORS) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_0) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_1) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_2) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_3) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_4) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_5) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_6) \ + __PMC_EV(MIPS74K, SYSTEM_EVENT_7) \ + __PMC_EV(MIPS74K, OCP_ALL_REQUESTS) \ + __PMC_EV(MIPS74K, OCP_ALL_CACHEABLE_REQUESTS) \ + __PMC_EV(MIPS74K, OCP_READ_REQUESTS) \ + __PMC_EV(MIPS74K, OCP_READ_CACHEABLE_REQUESTS) \ + __PMC_EV(MIPS74K, OCP_WRITE_REQUESTS) \ + __PMC_EV(MIPS74K, OCP_WRITE_CACHEABLE_REQUESTS) \ + __PMC_EV(MIPS74K, FSB_LESS_25_FULL) \ + __PMC_EV(MIPS74K, FSB_25_50_FULL) \ + __PMC_EV(MIPS74K, LDQ_LESS_25_FULL) \ + __PMC_EV(MIPS74K, LDQ_25_50_FULL) \ + __PMC_EV(MIPS74K, WBB_LESS_25_FULL) \ + __PMC_EV(MIPS74K, WBB_25_50_FULL) + +#define PMC_EV_MIPS74K_FIRST PMC_EV_MIPS74K_CYCLES +#define PMC_EV_MIPS74K_LAST PMC_EV_MIPS74K_WBB_25_50_FULL + /* * Cavium Octeon counters. Obtained from cvmx-core.h */ @@ -5256,6 +5388,8 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H) * 0x11100 0x0100 INTEL Pentium Pro/P-II/P-III/Pentium-M events * 0x11200 0x00FF INTEL XScale events * 0x11300 0x00FF MIPS 24K events + * 0x11400 0x00FF Octeon events + * 0x11500 0x00FF MIPS 74K events * 0x14000 0x0100 ARMv7 events * 0x20000 0x1000 Software events */ @@ -5282,6 +5416,8 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H) __PMC_EV_MIPS24K() \ __PMC_EV_BLOCK(OCTEON, 0x11400) \ __PMC_EV_OCTEON() \ + __PMC_EV_BLOCK(MIPS74K, 0x11500) \ + __PMC_EV_MIPS74K() \ __PMC_EV_BLOCK(UCF, 0x12000) \ __PMC_EV_UCF() \ __PMC_EV_BLOCK(UCP, 0x12080) \