Path: blob/master/arch/powerpc/perf/generic-compat-pmu.c
26424 views
// SPDX-License-Identifier: GPL-2.0+1//2// Copyright 2019 Madhavan Srinivasan, IBM Corporation.34#define pr_fmt(fmt) "generic-compat-pmu: " fmt56#include "isa207-common.h"78/*9* Raw event encoding:10*11* 60 56 52 48 44 40 36 3212* | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |13*14* 28 24 20 16 12 8 4 015* | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |16* [ pmc ] [ pmcxsel ]17*/1819/*20* Event codes defined in ISA v3.0B21*/22#define EVENT(_name, _code) _name = _code,2324enum {25/* Cycles, alternate code */26EVENT(PM_CYC_ALT, 0x100f0)27/* One or more instructions completed in a cycle */28EVENT(PM_CYC_INST_CMPL, 0x100f2)29/* Floating-point instruction completed */30EVENT(PM_FLOP_CMPL, 0x100f4)31/* Instruction ERAT/L1-TLB miss */32EVENT(PM_L1_ITLB_MISS, 0x100f6)33/* All instructions completed and none available */34EVENT(PM_NO_INST_AVAIL, 0x100f8)35/* A load-type instruction completed (ISA v3.0+) */36EVENT(PM_LD_CMPL, 0x100fc)37/* Instruction completed, alternate code (ISA v3.0+) */38EVENT(PM_INST_CMPL_ALT, 0x100fe)39/* A store-type instruction completed */40EVENT(PM_ST_CMPL, 0x200f0)41/* Instruction Dispatched */42EVENT(PM_INST_DISP, 0x200f2)43/* Run_cycles */44EVENT(PM_RUN_CYC, 0x200f4)45/* Data ERAT/L1-TLB miss/reload */46EVENT(PM_L1_DTLB_RELOAD, 0x200f6)47/* Taken branch completed */48EVENT(PM_BR_TAKEN_CMPL, 0x200fa)49/* Demand iCache Miss */50EVENT(PM_L1_ICACHE_MISS, 0x200fc)51/* L1 Dcache reload from memory */52EVENT(PM_L1_RELOAD_FROM_MEM, 0x200fe)53/* L1 Dcache store miss */54EVENT(PM_ST_MISS_L1, 0x300f0)55/* Alternate code for PM_INST_DISP */56EVENT(PM_INST_DISP_ALT, 0x300f2)57/* Branch direction or target mispredicted */58EVENT(PM_BR_MISPREDICT, 0x300f6)59/* Data TLB miss/reload */60EVENT(PM_DTLB_MISS, 0x300fc)61/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */62EVENT(PM_DATA_FROM_L3MISS, 0x300fe)63/* L1 Dcache load miss */64EVENT(PM_LD_MISS_L1, 0x400f0)65/* Cycle when instruction(s) dispatched */66EVENT(PM_CYC_INST_DISP, 0x400f2)67/* Branch or branch target mispredicted */68EVENT(PM_BR_MPRED_CMPL, 0x400f6)69/* Instructions completed with run latch set */70EVENT(PM_RUN_INST_CMPL, 0x400fa)71/* Instruction TLB miss/reload */72EVENT(PM_ITLB_MISS, 0x400fc)73/* Load data not cached */74EVENT(PM_LD_NOT_CACHED, 0x400fe)75/* Instructions */76EVENT(PM_INST_CMPL, 0x500fa)77/* Cycles */78EVENT(PM_CYC, 0x600f4)79};8081#undef EVENT8283/* Table of alternatives, sorted in increasing order of column 0 */84/* Note that in each row, column 0 must be the smallest */85static const unsigned int generic_event_alternatives[][MAX_ALT] = {86{ PM_CYC_ALT, PM_CYC },87{ PM_INST_CMPL_ALT, PM_INST_CMPL },88{ PM_INST_DISP, PM_INST_DISP_ALT },89};9091static int generic_get_alternatives(u64 event, unsigned int flags, u64 alt[])92{93int num_alt = 0;9495num_alt = isa207_get_alternatives(event, alt,96ARRAY_SIZE(generic_event_alternatives), flags,97generic_event_alternatives);9899return num_alt;100}101102GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC);103GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL);104GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_NO_INST_AVAIL);105GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL);106GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1);107108CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1);109CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1);110CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS);111CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS);112CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL);113CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS);114CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);115116static struct attribute *generic_compat_events_attr[] = {117GENERIC_EVENT_PTR(PM_CYC),118GENERIC_EVENT_PTR(PM_INST_CMPL),119GENERIC_EVENT_PTR(PM_NO_INST_AVAIL),120GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL),121GENERIC_EVENT_PTR(PM_LD_MISS_L1),122CACHE_EVENT_PTR(PM_LD_MISS_L1),123CACHE_EVENT_PTR(PM_ST_MISS_L1),124CACHE_EVENT_PTR(PM_L1_ICACHE_MISS),125CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS),126CACHE_EVENT_PTR(PM_BR_MPRED_CMPL),127CACHE_EVENT_PTR(PM_DTLB_MISS),128CACHE_EVENT_PTR(PM_ITLB_MISS),129NULL130};131132static const struct attribute_group generic_compat_pmu_events_group = {133.name = "events",134.attrs = generic_compat_events_attr,135};136137PMU_FORMAT_ATTR(event, "config:0-19");138PMU_FORMAT_ATTR(pmcxsel, "config:0-7");139PMU_FORMAT_ATTR(pmc, "config:16-19");140141static struct attribute *generic_compat_pmu_format_attr[] = {142&format_attr_event.attr,143&format_attr_pmcxsel.attr,144&format_attr_pmc.attr,145NULL,146};147148static const struct attribute_group generic_compat_pmu_format_group = {149.name = "format",150.attrs = generic_compat_pmu_format_attr,151};152153static struct attribute *generic_compat_pmu_caps_attrs[] = {154NULL155};156157static struct attribute_group generic_compat_pmu_caps_group = {158.name = "caps",159.attrs = generic_compat_pmu_caps_attrs,160};161162static const struct attribute_group *generic_compat_pmu_attr_groups[] = {163&generic_compat_pmu_format_group,164&generic_compat_pmu_events_group,165&generic_compat_pmu_caps_group,166NULL,167};168169static int compat_generic_events[] = {170[PERF_COUNT_HW_CPU_CYCLES] = PM_CYC,171[PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL,172[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_NO_INST_AVAIL,173[PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,174[PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1,175};176177#define C(x) PERF_COUNT_HW_CACHE_##x178179/*180* Table of generalized cache-related events.181* 0 means not supported, -1 means nonsensical, other values182* are event codes.183*/184static u64 generic_compat_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {185[ C(L1D) ] = {186[ C(OP_READ) ] = {187[ C(RESULT_ACCESS) ] = 0,188[ C(RESULT_MISS) ] = PM_LD_MISS_L1,189},190[ C(OP_WRITE) ] = {191[ C(RESULT_ACCESS) ] = 0,192[ C(RESULT_MISS) ] = PM_ST_MISS_L1,193},194[ C(OP_PREFETCH) ] = {195[ C(RESULT_ACCESS) ] = 0,196[ C(RESULT_MISS) ] = 0,197},198},199[ C(L1I) ] = {200[ C(OP_READ) ] = {201[ C(RESULT_ACCESS) ] = 0,202[ C(RESULT_MISS) ] = PM_L1_ICACHE_MISS,203},204[ C(OP_WRITE) ] = {205[ C(RESULT_ACCESS) ] = 0,206[ C(RESULT_MISS) ] = -1,207},208[ C(OP_PREFETCH) ] = {209[ C(RESULT_ACCESS) ] = 0,210[ C(RESULT_MISS) ] = 0,211},212},213[ C(LL) ] = {214[ C(OP_READ) ] = {215[ C(RESULT_ACCESS) ] = 0,216[ C(RESULT_MISS) ] = PM_DATA_FROM_L3MISS,217},218[ C(OP_WRITE) ] = {219[ C(RESULT_ACCESS) ] = 0,220[ C(RESULT_MISS) ] = 0,221},222[ C(OP_PREFETCH) ] = {223[ C(RESULT_ACCESS) ] = 0,224[ C(RESULT_MISS) ] = 0,225},226},227[ C(DTLB) ] = {228[ C(OP_READ) ] = {229[ C(RESULT_ACCESS) ] = 0,230[ C(RESULT_MISS) ] = PM_DTLB_MISS,231},232[ C(OP_WRITE) ] = {233[ C(RESULT_ACCESS) ] = -1,234[ C(RESULT_MISS) ] = -1,235},236[ C(OP_PREFETCH) ] = {237[ C(RESULT_ACCESS) ] = -1,238[ C(RESULT_MISS) ] = -1,239},240},241[ C(ITLB) ] = {242[ C(OP_READ) ] = {243[ C(RESULT_ACCESS) ] = 0,244[ C(RESULT_MISS) ] = PM_ITLB_MISS,245},246[ C(OP_WRITE) ] = {247[ C(RESULT_ACCESS) ] = -1,248[ C(RESULT_MISS) ] = -1,249},250[ C(OP_PREFETCH) ] = {251[ C(RESULT_ACCESS) ] = -1,252[ C(RESULT_MISS) ] = -1,253},254},255[ C(BPU) ] = {256[ C(OP_READ) ] = {257[ C(RESULT_ACCESS) ] = 0,258[ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL,259},260[ C(OP_WRITE) ] = {261[ C(RESULT_ACCESS) ] = -1,262[ C(RESULT_MISS) ] = -1,263},264[ C(OP_PREFETCH) ] = {265[ C(RESULT_ACCESS) ] = -1,266[ C(RESULT_MISS) ] = -1,267},268},269[ C(NODE) ] = {270[ C(OP_READ) ] = {271[ C(RESULT_ACCESS) ] = -1,272[ C(RESULT_MISS) ] = -1,273},274[ C(OP_WRITE) ] = {275[ C(RESULT_ACCESS) ] = -1,276[ C(RESULT_MISS) ] = -1,277},278[ C(OP_PREFETCH) ] = {279[ C(RESULT_ACCESS) ] = -1,280[ C(RESULT_MISS) ] = -1,281},282},283};284285#undef C286287/*288* We set MMCR0[CC5-6RUN] so we can use counters 5 and 6 for289* PM_INST_CMPL and PM_CYC.290*/291static int generic_compute_mmcr(u64 event[], int n_ev,292unsigned int hwc[], struct mmcr_regs *mmcr,293struct perf_event *pevents[], u32 flags)294{295int ret;296297ret = isa207_compute_mmcr(event, n_ev, hwc, mmcr, pevents, flags);298if (!ret)299mmcr->mmcr0 |= MMCR0_C56RUN;300return ret;301}302303static struct power_pmu generic_compat_pmu = {304.name = "ISAv3",305.n_counter = MAX_PMU_COUNTERS,306.add_fields = ISA207_ADD_FIELDS,307.test_adder = ISA207_TEST_ADDER,308.compute_mmcr = generic_compute_mmcr,309.get_constraint = isa207_get_constraint,310.get_alternatives = generic_get_alternatives,311.disable_pmc = isa207_disable_pmc,312.flags = PPMU_HAS_SIER | PPMU_ARCH_207S,313.n_generic = ARRAY_SIZE(compat_generic_events),314.generic_events = compat_generic_events,315.cache_events = &generic_compat_cache_events,316.attr_groups = generic_compat_pmu_attr_groups,317};318319int __init init_generic_compat_pmu(void)320{321int rc = 0;322323/*324* From ISA v2.07 on, PMU features are architected;325* we require >= v3.0 because (a) that has PM_LD_CMPL and326* PM_INST_CMPL_ALT, which v2.07 doesn't have, and327* (b) we don't expect any non-IBM Power ISA328* implementations that conform to v2.07 but not v3.0.329*/330if (!cpu_has_feature(CPU_FTR_ARCH_300))331return -ENODEV;332333rc = register_power_pmu(&generic_compat_pmu);334if (rc)335return rc;336337/* Tell userspace that EBB is supported */338cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;339340return 0;341}342343344