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" 929be2fe0SIan Rogers #include "util/header.h" 1029be2fe0SIan Rogers #include "util/pmu.h" 112519db2aSIan Rogers #include <string.h> 122519db2aSIan Rogers #include <stddef.h> 1300facc76SIan Rogers 1496d2a746SIan Rogers static const struct pmu_event pmu_events__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 { 10996d2a746SIan Rogers .name = 0, 11096d2a746SIan Rogers .event = 0, 11196d2a746SIan Rogers .desc = 0, 11296d2a746SIan Rogers }, 11396d2a746SIan Rogers }; 11496d2a746SIan Rogers 11596d2a746SIan Rogers static const struct pmu_metric pmu_metrics__test_soc_cpu[] = { 11696d2a746SIan Rogers { 1177ae5c03aSIan Rogers .metric_expr = "1 / IPC", 1187ae5c03aSIan Rogers .metric_name = "CPI", 1197ae5c03aSIan Rogers }, 1207ae5c03aSIan Rogers { 1217ae5c03aSIan Rogers .metric_expr = "inst_retired.any / cpu_clk_unhalted.thread", 1227ae5c03aSIan Rogers .metric_name = "IPC", 1237ae5c03aSIan Rogers .metric_group = "group1", 1247ae5c03aSIan Rogers }, 1257ae5c03aSIan Rogers { 1267ae5c03aSIan Rogers .metric_expr = "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * " 1277ae5c03aSIan Rogers "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))", 1287ae5c03aSIan Rogers .metric_name = "Frontend_Bound_SMT", 1297ae5c03aSIan Rogers }, 1307ae5c03aSIan Rogers { 1317ae5c03aSIan Rogers .metric_expr = "l1d\\-loads\\-misses / inst_retired.any", 1327ae5c03aSIan Rogers .metric_name = "dcache_miss_cpi", 1337ae5c03aSIan Rogers }, 1347ae5c03aSIan Rogers { 1357ae5c03aSIan Rogers .metric_expr = "l1i\\-loads\\-misses / inst_retired.any", 1367ae5c03aSIan Rogers .metric_name = "icache_miss_cycles", 1377ae5c03aSIan Rogers }, 1387ae5c03aSIan Rogers { 1397ae5c03aSIan Rogers .metric_expr = "(dcache_miss_cpi + icache_miss_cycles)", 1407ae5c03aSIan Rogers .metric_name = "cache_miss_cycles", 1417ae5c03aSIan Rogers .metric_group = "group1", 1427ae5c03aSIan Rogers }, 1437ae5c03aSIan Rogers { 1447ae5c03aSIan Rogers .metric_expr = "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit", 1457ae5c03aSIan Rogers .metric_name = "DCache_L2_All_Hits", 1467ae5c03aSIan Rogers }, 1477ae5c03aSIan Rogers { 1487ae5c03aSIan Rogers .metric_expr = "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + " 1497ae5c03aSIan Rogers "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", 1507ae5c03aSIan Rogers .metric_name = "DCache_L2_All_Miss", 1517ae5c03aSIan Rogers }, 1527ae5c03aSIan Rogers { 1530e407915SIan Rogers .metric_expr = "DCache_L2_All_Hits + DCache_L2_All_Miss", 1547ae5c03aSIan Rogers .metric_name = "DCache_L2_All", 1557ae5c03aSIan Rogers }, 1567ae5c03aSIan Rogers { 1570e407915SIan Rogers .metric_expr = "d_ratio(DCache_L2_All_Hits, DCache_L2_All)", 1587ae5c03aSIan Rogers .metric_name = "DCache_L2_Hits", 1597ae5c03aSIan Rogers }, 1607ae5c03aSIan Rogers { 1610e407915SIan Rogers .metric_expr = "d_ratio(DCache_L2_All_Miss, DCache_L2_All)", 1627ae5c03aSIan Rogers .metric_name = "DCache_L2_Misses", 1637ae5c03aSIan Rogers }, 1647ae5c03aSIan Rogers { 1657ae5c03aSIan Rogers .metric_expr = "ipc + M2", 1667ae5c03aSIan Rogers .metric_name = "M1", 1677ae5c03aSIan Rogers }, 1687ae5c03aSIan Rogers { 1697ae5c03aSIan Rogers .metric_expr = "ipc + M1", 1707ae5c03aSIan Rogers .metric_name = "M2", 1717ae5c03aSIan Rogers }, 1727ae5c03aSIan Rogers { 1737ae5c03aSIan Rogers .metric_expr = "1/M3", 1747ae5c03aSIan Rogers .metric_name = "M3", 1757ae5c03aSIan Rogers }, 1767ae5c03aSIan Rogers { 1777ae5c03aSIan Rogers .metric_expr = "64 * l1d.replacement / 1000000000 / duration_time", 1787ae5c03aSIan Rogers .metric_name = "L1D_Cache_Fill_BW", 1797ae5c03aSIan Rogers }, 1807ae5c03aSIan Rogers { 18196d2a746SIan Rogers .metric_expr = 0, 18296d2a746SIan Rogers .metric_name = 0, 18300facc76SIan Rogers }, 18400facc76SIan Rogers }; 18500facc76SIan Rogers 1861ba3752aSIan Rogers /* Struct used to make the PMU event table implementation opaque to callers. */ 1871ba3752aSIan Rogers struct pmu_events_table { 1881ba3752aSIan Rogers const struct pmu_event *entries; 1891ba3752aSIan Rogers }; 19029be2fe0SIan Rogers 191db95818eSIan Rogers /* Struct used to make the PMU metric table implementation opaque to callers. */ 192db95818eSIan Rogers struct pmu_metrics_table { 193db95818eSIan Rogers const struct pmu_metric *entries; 194db95818eSIan Rogers }; 195db95818eSIan Rogers 19629be2fe0SIan Rogers /* 19729be2fe0SIan Rogers * Map a CPU to its table of PMU events. The CPU is identified by the 19829be2fe0SIan Rogers * cpuid field, which is an arch-specific identifier for the CPU. 19929be2fe0SIan Rogers * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile 20029be2fe0SIan Rogers * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c) 20129be2fe0SIan Rogers * 20229be2fe0SIan Rogers * The cpuid can contain any character other than the comma. 20329be2fe0SIan Rogers */ 20429be2fe0SIan Rogers struct pmu_events_map { 20529be2fe0SIan Rogers const char *arch; 20629be2fe0SIan Rogers const char *cpuid; 20796d2a746SIan Rogers const struct pmu_events_table event_table; 20896d2a746SIan Rogers const struct pmu_metrics_table metric_table; 20929be2fe0SIan Rogers }; 21029be2fe0SIan Rogers 21129be2fe0SIan Rogers /* 21229be2fe0SIan Rogers * Global table mapping each known CPU for the architecture to its 21329be2fe0SIan Rogers * table of PMU events. 21429be2fe0SIan Rogers */ 21529be2fe0SIan Rogers static const struct pmu_events_map pmu_events_map[] = { 21600facc76SIan Rogers { 217099b157cSIan Rogers .arch = "testarch", 21800facc76SIan Rogers .cpuid = "testcpu", 21996d2a746SIan Rogers .event_table = { pmu_events__test_soc_cpu }, 22096d2a746SIan Rogers .metric_table = { pmu_metrics__test_soc_cpu }, 22100facc76SIan Rogers }, 22200facc76SIan Rogers { 223099b157cSIan Rogers .arch = 0, 22400facc76SIan Rogers .cpuid = 0, 22596d2a746SIan Rogers .event_table = { 0 }, 22696d2a746SIan Rogers .metric_table = { 0 }, 22700facc76SIan Rogers }, 22800facc76SIan Rogers }; 22900facc76SIan Rogers 23007fc5921SIan Rogers static const struct pmu_event pmu_events__test_soc_sys[] = { 23100facc76SIan Rogers { 23200facc76SIan Rogers .name = "sys_ddr_pmu.write_cycles", 23300facc76SIan Rogers .event = "event=0x2b", 23400facc76SIan Rogers .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", 23500facc76SIan Rogers .compat = "v8", 23600facc76SIan Rogers .topic = "uncore", 23700facc76SIan Rogers .pmu = "uncore_sys_ddr_pmu", 23800facc76SIan Rogers }, 23900facc76SIan Rogers { 24000facc76SIan Rogers .name = "sys_ccn_pmu.read_cycles", 24100facc76SIan Rogers .event = "config=0x2c", 24200facc76SIan Rogers .desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", 24300facc76SIan Rogers .compat = "0x01", 24400facc76SIan Rogers .topic = "uncore", 24500facc76SIan Rogers .pmu = "uncore_sys_ccn_pmu", 24600facc76SIan Rogers }, 24700facc76SIan Rogers { 24800facc76SIan Rogers .name = 0, 24900facc76SIan Rogers .event = 0, 25000facc76SIan Rogers .desc = 0, 25100facc76SIan Rogers }, 25200facc76SIan Rogers }; 25300facc76SIan Rogers 2542519db2aSIan Rogers struct pmu_sys_events { 2552519db2aSIan Rogers const char *name; 2561ba3752aSIan Rogers const struct pmu_events_table table; 2572519db2aSIan Rogers }; 2582519db2aSIan Rogers 2592519db2aSIan Rogers static const struct pmu_sys_events pmu_sys_event_tables[] = { 26000facc76SIan Rogers { 26107fc5921SIan Rogers .table = { pmu_events__test_soc_sys }, 26207fc5921SIan Rogers .name = "pmu_events__test_soc_sys", 26300facc76SIan Rogers }, 26400facc76SIan Rogers { 2651ba3752aSIan Rogers .table = { 0 } 26600facc76SIan Rogers }, 26700facc76SIan Rogers }; 2682519db2aSIan Rogers 269e3edd6cfSIan Rogers int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu, 270e3edd6cfSIan Rogers pmu_event_iter_fn fn, void *data) 271660842e4SIan Rogers { 27296d2a746SIan Rogers for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 273e3edd6cfSIan Rogers int ret; 274660842e4SIan Rogers 275e3edd6cfSIan Rogers if (pmu && !pmu__name_match(pmu, pe->pmu)) 276e3edd6cfSIan Rogers continue; 277e3edd6cfSIan Rogers 278e3edd6cfSIan Rogers ret = fn(pe, table, data); 279db95818eSIan Rogers if (ret) 280db95818eSIan Rogers return ret; 281db95818eSIan Rogers } 282db95818eSIan Rogers return 0; 283db95818eSIan Rogers } 284db95818eSIan Rogers 2853d504549SIan Rogers int pmu_events_table__find_event(const struct pmu_events_table *table, 2863d504549SIan Rogers struct perf_pmu *pmu, 2873d504549SIan Rogers const char *name, 2883d504549SIan Rogers pmu_event_iter_fn fn, 2893d504549SIan Rogers void *data) 2903d504549SIan Rogers { 2913d504549SIan Rogers for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 2923d504549SIan Rogers if (pmu && !pmu__name_match(pmu, pe->pmu)) 2933d504549SIan Rogers continue; 2943d504549SIan Rogers 2953d504549SIan Rogers if (!strcasecmp(pe->name, name)) 2963d504549SIan Rogers return fn(pe, table, data); 2973d504549SIan Rogers } 2983d504549SIan Rogers return -1000; 2993d504549SIan Rogers } 3003d504549SIan Rogers 301*e6ff1eedSIan Rogers size_t pmu_events_table__num_events(const struct pmu_events_table *table, 302*e6ff1eedSIan Rogers struct perf_pmu *pmu) 303*e6ff1eedSIan Rogers { 304*e6ff1eedSIan Rogers size_t count = 0; 305*e6ff1eedSIan Rogers 306*e6ff1eedSIan Rogers for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 307*e6ff1eedSIan Rogers if (pmu && !pmu__name_match(pmu, pe->pmu)) 308*e6ff1eedSIan Rogers continue; 309*e6ff1eedSIan Rogers 310*e6ff1eedSIan Rogers count++; 311*e6ff1eedSIan Rogers } 312*e6ff1eedSIan Rogers return count; 313*e6ff1eedSIan Rogers } 314*e6ff1eedSIan Rogers 3154000519eSIan Rogers int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, 316db95818eSIan Rogers void *data) 317db95818eSIan Rogers { 31896d2a746SIan Rogers for (const struct pmu_metric *pm = &table->entries[0]; pm->metric_expr; pm++) { 319f8ea2c15SIan Rogers int ret = fn(pm, table, data); 320db95818eSIan Rogers 321660842e4SIan Rogers if (ret) 322660842e4SIan Rogers return ret; 323660842e4SIan Rogers } 324660842e4SIan Rogers return 0; 325660842e4SIan Rogers } 326660842e4SIan Rogers 32796d2a746SIan Rogers const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) 32829be2fe0SIan Rogers { 3291ba3752aSIan Rogers const struct pmu_events_table *table = NULL; 33029be2fe0SIan Rogers char *cpuid = perf_pmu__getcpuid(pmu); 33129be2fe0SIan Rogers int i; 33229be2fe0SIan Rogers 33329be2fe0SIan Rogers /* on some platforms which uses cpus map, cpuid can be NULL for 33429be2fe0SIan Rogers * PMUs other than CORE PMUs. 33529be2fe0SIan Rogers */ 33629be2fe0SIan Rogers if (!cpuid) 33729be2fe0SIan Rogers return NULL; 33829be2fe0SIan Rogers 33929be2fe0SIan Rogers i = 0; 34029be2fe0SIan Rogers for (;;) { 34129be2fe0SIan Rogers const struct pmu_events_map *map = &pmu_events_map[i++]; 34229be2fe0SIan Rogers 3431ba3752aSIan Rogers if (!map->cpuid) 34429be2fe0SIan Rogers break; 34529be2fe0SIan Rogers 34629be2fe0SIan Rogers if (!strcmp_cpuid_str(map->cpuid, cpuid)) { 34796d2a746SIan Rogers table = &map->event_table; 34896d2a746SIan Rogers break; 34996d2a746SIan Rogers } 35096d2a746SIan Rogers } 35196d2a746SIan Rogers free(cpuid); 35296d2a746SIan Rogers return table; 35396d2a746SIan Rogers } 35496d2a746SIan Rogers 355f8ea2c15SIan Rogers const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu) 35696d2a746SIan Rogers { 357f8ea2c15SIan Rogers const struct pmu_metrics_table *table = NULL; 35896d2a746SIan Rogers char *cpuid = perf_pmu__getcpuid(pmu); 35996d2a746SIan Rogers int i; 36096d2a746SIan Rogers 36196d2a746SIan Rogers /* on some platforms which uses cpus map, cpuid can be NULL for 36296d2a746SIan Rogers * PMUs other than CORE PMUs. 36396d2a746SIan Rogers */ 36496d2a746SIan Rogers if (!cpuid) 36596d2a746SIan Rogers return NULL; 36696d2a746SIan Rogers 36796d2a746SIan Rogers i = 0; 36896d2a746SIan Rogers for (;;) { 36996d2a746SIan Rogers const struct pmu_events_map *map = &pmu_events_map[i++]; 37096d2a746SIan Rogers 37196d2a746SIan Rogers if (!map->cpuid) 37296d2a746SIan Rogers break; 37396d2a746SIan Rogers 37496d2a746SIan Rogers if (!strcmp_cpuid_str(map->cpuid, cpuid)) { 375f8ea2c15SIan Rogers table = &map->metric_table; 37629be2fe0SIan Rogers break; 37729be2fe0SIan Rogers } 37829be2fe0SIan Rogers } 37929be2fe0SIan Rogers free(cpuid); 38029be2fe0SIan Rogers return table; 38129be2fe0SIan Rogers } 38229be2fe0SIan Rogers 3831ba3752aSIan Rogers const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid) 38429be2fe0SIan Rogers { 38529be2fe0SIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; 3861ba3752aSIan Rogers tables->arch; 38729be2fe0SIan Rogers tables++) { 38829be2fe0SIan Rogers if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 38996d2a746SIan Rogers return &tables->event_table; 39096d2a746SIan Rogers } 39196d2a746SIan Rogers return NULL; 39296d2a746SIan Rogers } 39396d2a746SIan Rogers 394f8ea2c15SIan Rogers const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid) 39596d2a746SIan Rogers { 39696d2a746SIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; 39796d2a746SIan Rogers tables->arch; 39896d2a746SIan Rogers tables++) { 39996d2a746SIan Rogers if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 400f8ea2c15SIan Rogers return &tables->metric_table; 40129be2fe0SIan Rogers } 40229be2fe0SIan Rogers return NULL; 40329be2fe0SIan Rogers } 40429be2fe0SIan Rogers 40529be2fe0SIan Rogers int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) 40629be2fe0SIan Rogers { 407db95818eSIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; tables->arch; tables++) { 408e3edd6cfSIan Rogers int ret = pmu_events_table__for_each_event(&tables->event_table, 409e3edd6cfSIan Rogers /*pmu=*/ NULL, fn, data); 410db95818eSIan Rogers 411db95818eSIan Rogers if (ret) 412db95818eSIan Rogers return ret; 413db95818eSIan Rogers } 414db95818eSIan Rogers return 0; 415db95818eSIan Rogers } 416db95818eSIan Rogers 417db95818eSIan Rogers int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data) 418db95818eSIan Rogers { 41929be2fe0SIan Rogers for (const struct pmu_events_map *tables = &pmu_events_map[0]; 4201ba3752aSIan Rogers tables->arch; 42129be2fe0SIan Rogers tables++) { 4224000519eSIan Rogers int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); 42329be2fe0SIan Rogers 42429be2fe0SIan Rogers if (ret) 42529be2fe0SIan Rogers return ret; 42629be2fe0SIan Rogers } 42729be2fe0SIan Rogers return 0; 42829be2fe0SIan Rogers } 42929be2fe0SIan Rogers 4301ba3752aSIan Rogers const struct pmu_events_table *find_sys_events_table(const char *name) 4312519db2aSIan Rogers { 4322519db2aSIan Rogers for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 4332519db2aSIan Rogers tables->name; 4342519db2aSIan Rogers tables++) { 4352519db2aSIan Rogers if (!strcmp(tables->name, name)) 4361ba3752aSIan Rogers return &tables->table; 4372519db2aSIan Rogers } 4382519db2aSIan Rogers return NULL; 4392519db2aSIan Rogers } 4402519db2aSIan Rogers 4412519db2aSIan Rogers int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) 4422519db2aSIan Rogers { 4432519db2aSIan Rogers for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 4442519db2aSIan Rogers tables->name; 4452519db2aSIan Rogers tables++) { 446e3edd6cfSIan Rogers int ret = pmu_events_table__for_each_event(&tables->table, /*pmu=*/ NULL, fn, data); 4472519db2aSIan Rogers 4482519db2aSIan Rogers if (ret) 4492519db2aSIan Rogers return ret; 4502519db2aSIan Rogers } 4512519db2aSIan Rogers return 0; 4522519db2aSIan Rogers } 453db95818eSIan Rogers 454db95818eSIan Rogers int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __maybe_unused) 455db95818eSIan Rogers { 456db95818eSIan Rogers return 0; 457db95818eSIan Rogers } 45866c6e0c1SIan Rogers 45966c6e0c1SIan Rogers const char *describe_metricgroup(const char *group __maybe_unused) 46066c6e0c1SIan Rogers { 46166c6e0c1SIan Rogers return NULL; 46266c6e0c1SIan Rogers } 463