100facc76SIan Rogers // SPDX-License-Identifier: GPL-2.0 200facc76SIan Rogers /* 300facc76SIan Rogers * An empty pmu-events.c file used when there is no architecture json files in 400facc76SIan Rogers * arch or when the jevents.py script cannot be run. 500facc76SIan Rogers * 600facc76SIan Rogers * The test cpu/soc is provided for testing. 700facc76SIan Rogers */ 800facc76SIan Rogers #include "pmu-events/pmu-events.h" 9*29be2fe0SIan Rogers #include "util/header.h" 10*29be2fe0SIan Rogers #include "util/pmu.h" 112519db2aSIan Rogers #include <string.h> 122519db2aSIan Rogers #include <stddef.h> 1300facc76SIan Rogers 1400facc76SIan Rogers static const struct pmu_event pme_test_soc_cpu[] = { 1500facc76SIan Rogers { 1600facc76SIan Rogers .name = "l3_cache_rd", 1700facc76SIan Rogers .event = "event=0x40", 1800facc76SIan Rogers .desc = "L3 cache access, read", 1900facc76SIan Rogers .topic = "cache", 2000facc76SIan Rogers .long_desc = "Attributable Level 3 cache access, read", 2100facc76SIan Rogers }, 2200facc76SIan Rogers { 2300facc76SIan Rogers .name = "segment_reg_loads.any", 2400facc76SIan Rogers .event = "event=0x6,period=200000,umask=0x80", 2500facc76SIan Rogers .desc = "Number of segment register loads", 2600facc76SIan Rogers .topic = "other", 2700facc76SIan Rogers }, 2800facc76SIan Rogers { 2900facc76SIan Rogers .name = "dispatch_blocked.any", 3000facc76SIan Rogers .event = "event=0x9,period=200000,umask=0x20", 3100facc76SIan Rogers .desc = "Memory cluster signals to block micro-op dispatch for any reason", 3200facc76SIan Rogers .topic = "other", 3300facc76SIan Rogers }, 3400facc76SIan Rogers { 3500facc76SIan Rogers .name = "eist_trans", 3600facc76SIan Rogers .event = "event=0x3a,period=200000,umask=0x0", 3700facc76SIan Rogers .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", 3800facc76SIan Rogers .topic = "other", 3900facc76SIan Rogers }, 4000facc76SIan Rogers { 4100facc76SIan Rogers .name = "uncore_hisi_ddrc.flux_wcmd", 4200facc76SIan Rogers .event = "event=0x2", 4300facc76SIan Rogers .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", 4400facc76SIan Rogers .topic = "uncore", 4500facc76SIan Rogers .long_desc = "DDRC write commands", 4600facc76SIan Rogers .pmu = "hisi_sccl,ddrc", 4700facc76SIan Rogers }, 4800facc76SIan Rogers { 4900facc76SIan Rogers .name = "unc_cbo_xsnp_response.miss_eviction", 5000facc76SIan Rogers .event = "event=0x22,umask=0x81", 5100facc76SIan Rogers .desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core. Unit: uncore_cbox ", 5200facc76SIan Rogers .topic = "uncore", 5300facc76SIan Rogers .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", 5400facc76SIan Rogers .pmu = "uncore_cbox", 5500facc76SIan Rogers }, 5600facc76SIan Rogers { 5700facc76SIan Rogers .name = "event-hyphen", 5800facc76SIan Rogers .event = "event=0xe0,umask=0x00", 5900facc76SIan Rogers .desc = "UNC_CBO_HYPHEN. Unit: uncore_cbox ", 6000facc76SIan Rogers .topic = "uncore", 6100facc76SIan Rogers .long_desc = "UNC_CBO_HYPHEN", 6200facc76SIan Rogers .pmu = "uncore_cbox", 6300facc76SIan Rogers }, 6400facc76SIan Rogers { 6500facc76SIan Rogers .name = "event-two-hyph", 6600facc76SIan Rogers .event = "event=0xc0,umask=0x00", 6700facc76SIan Rogers .desc = "UNC_CBO_TWO_HYPH. Unit: uncore_cbox ", 6800facc76SIan Rogers .topic = "uncore", 6900facc76SIan Rogers .long_desc = "UNC_CBO_TWO_HYPH", 7000facc76SIan Rogers .pmu = "uncore_cbox", 7100facc76SIan Rogers }, 7200facc76SIan Rogers { 7300facc76SIan Rogers .name = "uncore_hisi_l3c.rd_hit_cpipe", 7400facc76SIan Rogers .event = "event=0x7", 7500facc76SIan Rogers .desc = "Total read hits. Unit: hisi_sccl,l3c ", 7600facc76SIan Rogers .topic = "uncore", 7700facc76SIan Rogers .long_desc = "Total read hits", 7800facc76SIan Rogers .pmu = "hisi_sccl,l3c", 7900facc76SIan Rogers }, 8000facc76SIan Rogers { 8100facc76SIan Rogers .name = "uncore_imc_free_running.cache_miss", 8200facc76SIan Rogers .event = "event=0x12", 8300facc76SIan Rogers .desc = "Total cache misses. Unit: uncore_imc_free_running ", 8400facc76SIan Rogers .topic = "uncore", 8500facc76SIan Rogers .long_desc = "Total cache misses", 8600facc76SIan Rogers .pmu = "uncore_imc_free_running", 8700facc76SIan Rogers }, 8800facc76SIan Rogers { 8900facc76SIan Rogers .name = "uncore_imc.cache_hits", 9000facc76SIan Rogers .event = "event=0x34", 9100facc76SIan Rogers .desc = "Total cache hits. Unit: uncore_imc ", 9200facc76SIan Rogers .topic = "uncore", 9300facc76SIan Rogers .long_desc = "Total cache hits", 9400facc76SIan Rogers .pmu = "uncore_imc", 9500facc76SIan Rogers }, 9600facc76SIan Rogers { 9700facc76SIan Rogers .name = "bp_l1_btb_correct", 9800facc76SIan Rogers .event = "event=0x8a", 9900facc76SIan Rogers .desc = "L1 BTB Correction", 10000facc76SIan Rogers .topic = "branch", 10100facc76SIan Rogers }, 10200facc76SIan Rogers { 10300facc76SIan Rogers .name = "bp_l2_btb_correct", 10400facc76SIan Rogers .event = "event=0x8b", 10500facc76SIan Rogers .desc = "L2 BTB Correction", 10600facc76SIan Rogers .topic = "branch", 10700facc76SIan Rogers }, 10800facc76SIan Rogers { 10900facc76SIan Rogers .name = 0, 11000facc76SIan Rogers .event = 0, 11100facc76SIan Rogers .desc = 0, 11200facc76SIan Rogers }, 11300facc76SIan Rogers }; 11400facc76SIan Rogers 115*29be2fe0SIan Rogers 116*29be2fe0SIan Rogers /* 117*29be2fe0SIan Rogers * Map a CPU to its table of PMU events. The CPU is identified by the 118*29be2fe0SIan Rogers * cpuid field, which is an arch-specific identifier for the CPU. 119*29be2fe0SIan Rogers * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile 120*29be2fe0SIan Rogers * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c) 121*29be2fe0SIan Rogers * 122*29be2fe0SIan Rogers * The cpuid can contain any character other than the comma. 123*29be2fe0SIan Rogers */ 124*29be2fe0SIan Rogers struct pmu_events_map { 125*29be2fe0SIan Rogers const char *arch; 126*29be2fe0SIan Rogers const char *cpuid; 127*29be2fe0SIan Rogers const struct pmu_event *table; 128*29be2fe0SIan Rogers }; 129*29be2fe0SIan Rogers 130*29be2fe0SIan Rogers /* 131*29be2fe0SIan Rogers * Global table mapping each known CPU for the architecture to its 132*29be2fe0SIan Rogers * table of PMU events. 133*29be2fe0SIan Rogers */ 134*29be2fe0SIan Rogers static const struct pmu_events_map pmu_events_map[] = { 13500facc76SIan Rogers { 136099b157cSIan Rogers .arch = "testarch", 13700facc76SIan Rogers .cpuid = "testcpu", 13800facc76SIan Rogers .table = pme_test_soc_cpu, 13900facc76SIan Rogers }, 14000facc76SIan Rogers { 141099b157cSIan Rogers .arch = 0, 14200facc76SIan Rogers .cpuid = 0, 14300facc76SIan Rogers .table = 0, 14400facc76SIan Rogers }, 14500facc76SIan Rogers }; 14600facc76SIan Rogers 14700facc76SIan Rogers static const struct pmu_event pme_test_soc_sys[] = { 14800facc76SIan Rogers { 14900facc76SIan Rogers .name = "sys_ddr_pmu.write_cycles", 15000facc76SIan Rogers .event = "event=0x2b", 15100facc76SIan Rogers .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", 15200facc76SIan Rogers .compat = "v8", 15300facc76SIan Rogers .topic = "uncore", 15400facc76SIan Rogers .pmu = "uncore_sys_ddr_pmu", 15500facc76SIan Rogers }, 15600facc76SIan Rogers { 15700facc76SIan Rogers .name = "sys_ccn_pmu.read_cycles", 15800facc76SIan Rogers .event = "config=0x2c", 15900facc76SIan Rogers .desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", 16000facc76SIan Rogers .compat = "0x01", 16100facc76SIan Rogers .topic = "uncore", 16200facc76SIan Rogers .pmu = "uncore_sys_ccn_pmu", 16300facc76SIan Rogers }, 16400facc76SIan Rogers { 16500facc76SIan Rogers .name = 0, 16600facc76SIan Rogers .event = 0, 16700facc76SIan Rogers .desc = 0, 16800facc76SIan Rogers }, 16900facc76SIan Rogers }; 17000facc76SIan Rogers 1712519db2aSIan Rogers struct pmu_sys_events { 1722519db2aSIan Rogers const char *name; 1732519db2aSIan Rogers const struct pmu_event *table; 1742519db2aSIan Rogers }; 1752519db2aSIan Rogers 1762519db2aSIan Rogers static const struct pmu_sys_events pmu_sys_event_tables[] = { 17700facc76SIan Rogers { 17800facc76SIan Rogers .table = pme_test_soc_sys, 17900facc76SIan Rogers .name = "pme_test_soc_sys", 18000facc76SIan Rogers }, 18100facc76SIan Rogers { 18200facc76SIan Rogers .table = 0 18300facc76SIan Rogers }, 18400facc76SIan Rogers }; 1852519db2aSIan Rogers 186*29be2fe0SIan Rogers const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) 187*29be2fe0SIan Rogers { 188*29be2fe0SIan Rogers const struct pmu_event *table = NULL; 189*29be2fe0SIan Rogers char *cpuid = perf_pmu__getcpuid(pmu); 190*29be2fe0SIan Rogers int i; 191*29be2fe0SIan Rogers 192*29be2fe0SIan Rogers /* on some platforms which uses cpus map, cpuid can be NULL for 193*29be2fe0SIan Rogers * PMUs other than CORE PMUs. 194*29be2fe0SIan Rogers */ 195*29be2fe0SIan Rogers if (!cpuid) 196*29be2fe0SIan Rogers return NULL; 197*29be2fe0SIan Rogers 198*29be2fe0SIan Rogers i = 0; 199*29be2fe0SIan Rogers for (;;) { 200*29be2fe0SIan Rogers const struct pmu_events_map *map = &pmu_events_map[i++]; 201*29be2fe0SIan Rogers 202*29be2fe0SIan Rogers if (!map->table) 203*29be2fe0SIan Rogers break; 204*29be2fe0SIan Rogers 205*29be2fe0SIan Rogers if (!strcmp_cpuid_str(map->cpuid, cpuid)) { 206*29be2fe0SIan Rogers table = map->table; 207*29be2fe0SIan Rogers break; 208*29be2fe0SIan Rogers } 209*29be2fe0SIan Rogers } 210*29be2fe0SIan Rogers free(cpuid); 211*29be2fe0SIan Rogers return table; 212*29be2fe0SIan Rogers } 213*29be2fe0SIan Rogers 214*29be2fe0SIan Rogers const struct pmu_event *find_core_events_table(const char *arch, const char *cpuid) 215*29be2fe0SIan Rogers { 216*29be2fe0SIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; 217*29be2fe0SIan Rogers tables->table; 218*29be2fe0SIan Rogers tables++) { 219*29be2fe0SIan Rogers if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 220*29be2fe0SIan Rogers return tables->table; 221*29be2fe0SIan Rogers } 222*29be2fe0SIan Rogers return NULL; 223*29be2fe0SIan Rogers } 224*29be2fe0SIan Rogers 225*29be2fe0SIan Rogers int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) 226*29be2fe0SIan Rogers { 227*29be2fe0SIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; 228*29be2fe0SIan Rogers tables->table; 229*29be2fe0SIan Rogers tables++) { 230*29be2fe0SIan Rogers for (const struct pmu_event *pe = &tables->table[0]; 231*29be2fe0SIan Rogers pe->name || pe->metric_group || pe->metric_name; 232*29be2fe0SIan Rogers pe++) { 233*29be2fe0SIan Rogers int ret = fn(pe, &tables->table[0], data); 234*29be2fe0SIan Rogers 235*29be2fe0SIan Rogers if (ret) 236*29be2fe0SIan Rogers return ret; 237*29be2fe0SIan Rogers } 238*29be2fe0SIan Rogers } 239*29be2fe0SIan Rogers return 0; 240*29be2fe0SIan Rogers } 241*29be2fe0SIan Rogers 2422519db2aSIan Rogers const struct pmu_event *find_sys_events_table(const char *name) 2432519db2aSIan Rogers { 2442519db2aSIan Rogers for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 2452519db2aSIan Rogers tables->name; 2462519db2aSIan Rogers tables++) { 2472519db2aSIan Rogers if (!strcmp(tables->name, name)) 2482519db2aSIan Rogers return tables->table; 2492519db2aSIan Rogers } 2502519db2aSIan Rogers return NULL; 2512519db2aSIan Rogers } 2522519db2aSIan Rogers 2532519db2aSIan Rogers int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) 2542519db2aSIan Rogers { 2552519db2aSIan Rogers for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 2562519db2aSIan Rogers tables->name; 2572519db2aSIan Rogers tables++) { 2582519db2aSIan Rogers for (const struct pmu_event *pe = &tables->table[0]; 2592519db2aSIan Rogers pe->name || pe->metric_group || pe->metric_name; 2602519db2aSIan Rogers pe++) { 261*29be2fe0SIan Rogers int ret = fn(pe, &tables->table[0], data); 2622519db2aSIan Rogers 2632519db2aSIan Rogers if (ret) 2642519db2aSIan Rogers return ret; 2652519db2aSIan Rogers } 2662519db2aSIan Rogers } 2672519db2aSIan Rogers return 0; 2682519db2aSIan Rogers } 269