xref: /openbmc/linux/tools/perf/pmu-events/empty-pmu-events.c (revision e3edd6cf6399f17114081d0e20f31ddadafb70b5)
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 
269*e3edd6cfSIan Rogers int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu,
270*e3edd6cfSIan Rogers 				     pmu_event_iter_fn fn, void *data)
271660842e4SIan Rogers {
27296d2a746SIan Rogers 	for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) {
273*e3edd6cfSIan Rogers 		int ret;
274660842e4SIan Rogers 
275*e3edd6cfSIan Rogers                 if (pmu && !pmu__name_match(pmu, pe->pmu))
276*e3edd6cfSIan Rogers                         continue;
277*e3edd6cfSIan Rogers 
278*e3edd6cfSIan Rogers 		ret = fn(pe, table, data);
279db95818eSIan Rogers 		if (ret)
280db95818eSIan Rogers 			return ret;
281db95818eSIan Rogers 	}
282db95818eSIan Rogers 	return 0;
283db95818eSIan Rogers }
284db95818eSIan Rogers 
2854000519eSIan Rogers int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn,
286db95818eSIan Rogers 				      void *data)
287db95818eSIan Rogers {
28896d2a746SIan Rogers 	for (const struct pmu_metric *pm = &table->entries[0]; pm->metric_expr; pm++) {
289f8ea2c15SIan Rogers 		int ret = fn(pm, table, data);
290db95818eSIan Rogers 
291660842e4SIan Rogers 		if (ret)
292660842e4SIan Rogers 			return ret;
293660842e4SIan Rogers 	}
294660842e4SIan Rogers 	return 0;
295660842e4SIan Rogers }
296660842e4SIan Rogers 
29796d2a746SIan Rogers const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
29829be2fe0SIan Rogers {
2991ba3752aSIan Rogers 	const struct pmu_events_table *table = NULL;
30029be2fe0SIan Rogers 	char *cpuid = perf_pmu__getcpuid(pmu);
30129be2fe0SIan Rogers 	int i;
30229be2fe0SIan Rogers 
30329be2fe0SIan Rogers 	/* on some platforms which uses cpus map, cpuid can be NULL for
30429be2fe0SIan Rogers 	 * PMUs other than CORE PMUs.
30529be2fe0SIan Rogers 	 */
30629be2fe0SIan Rogers 	if (!cpuid)
30729be2fe0SIan Rogers 		return NULL;
30829be2fe0SIan Rogers 
30929be2fe0SIan Rogers 	i = 0;
31029be2fe0SIan Rogers 	for (;;) {
31129be2fe0SIan Rogers 		const struct pmu_events_map *map = &pmu_events_map[i++];
31229be2fe0SIan Rogers 
3131ba3752aSIan Rogers 		if (!map->cpuid)
31429be2fe0SIan Rogers 			break;
31529be2fe0SIan Rogers 
31629be2fe0SIan Rogers 		if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
31796d2a746SIan Rogers 			table = &map->event_table;
31896d2a746SIan Rogers 			break;
31996d2a746SIan Rogers 		}
32096d2a746SIan Rogers 	}
32196d2a746SIan Rogers 	free(cpuid);
32296d2a746SIan Rogers 	return table;
32396d2a746SIan Rogers }
32496d2a746SIan Rogers 
325f8ea2c15SIan Rogers const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
32696d2a746SIan Rogers {
327f8ea2c15SIan Rogers 	const struct pmu_metrics_table *table = NULL;
32896d2a746SIan Rogers 	char *cpuid = perf_pmu__getcpuid(pmu);
32996d2a746SIan Rogers 	int i;
33096d2a746SIan Rogers 
33196d2a746SIan Rogers 	/* on some platforms which uses cpus map, cpuid can be NULL for
33296d2a746SIan Rogers 	 * PMUs other than CORE PMUs.
33396d2a746SIan Rogers 	 */
33496d2a746SIan Rogers 	if (!cpuid)
33596d2a746SIan Rogers 		return NULL;
33696d2a746SIan Rogers 
33796d2a746SIan Rogers 	i = 0;
33896d2a746SIan Rogers 	for (;;) {
33996d2a746SIan Rogers 		const struct pmu_events_map *map = &pmu_events_map[i++];
34096d2a746SIan Rogers 
34196d2a746SIan Rogers 		if (!map->cpuid)
34296d2a746SIan Rogers 			break;
34396d2a746SIan Rogers 
34496d2a746SIan Rogers 		if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
345f8ea2c15SIan Rogers 			table = &map->metric_table;
34629be2fe0SIan Rogers 			break;
34729be2fe0SIan Rogers 		}
34829be2fe0SIan Rogers 	}
34929be2fe0SIan Rogers 	free(cpuid);
35029be2fe0SIan Rogers 	return table;
35129be2fe0SIan Rogers }
35229be2fe0SIan Rogers 
3531ba3752aSIan Rogers const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
35429be2fe0SIan Rogers {
35529be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
3561ba3752aSIan Rogers 	     tables->arch;
35729be2fe0SIan Rogers 	     tables++) {
35829be2fe0SIan Rogers 		if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
35996d2a746SIan Rogers 			return &tables->event_table;
36096d2a746SIan Rogers 	}
36196d2a746SIan Rogers 	return NULL;
36296d2a746SIan Rogers }
36396d2a746SIan Rogers 
364f8ea2c15SIan Rogers const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid)
36596d2a746SIan Rogers {
36696d2a746SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
36796d2a746SIan Rogers 	     tables->arch;
36896d2a746SIan Rogers 	     tables++) {
36996d2a746SIan Rogers 		if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
370f8ea2c15SIan Rogers 			return &tables->metric_table;
37129be2fe0SIan Rogers 	}
37229be2fe0SIan Rogers 	return NULL;
37329be2fe0SIan Rogers }
37429be2fe0SIan Rogers 
37529be2fe0SIan Rogers int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
37629be2fe0SIan Rogers {
377db95818eSIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0]; tables->arch; tables++) {
378*e3edd6cfSIan Rogers 		int ret = pmu_events_table__for_each_event(&tables->event_table,
379*e3edd6cfSIan Rogers 							   /*pmu=*/ NULL, fn, data);
380db95818eSIan Rogers 
381db95818eSIan Rogers 		if (ret)
382db95818eSIan Rogers 			return ret;
383db95818eSIan Rogers 	}
384db95818eSIan Rogers 	return 0;
385db95818eSIan Rogers }
386db95818eSIan Rogers 
387db95818eSIan Rogers int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data)
388db95818eSIan Rogers {
38929be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
3901ba3752aSIan Rogers 	     tables->arch;
39129be2fe0SIan Rogers 	     tables++) {
3924000519eSIan Rogers 		int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data);
39329be2fe0SIan Rogers 
39429be2fe0SIan Rogers 		if (ret)
39529be2fe0SIan Rogers 			return ret;
39629be2fe0SIan Rogers 	}
39729be2fe0SIan Rogers 	return 0;
39829be2fe0SIan Rogers }
39929be2fe0SIan Rogers 
4001ba3752aSIan Rogers const struct pmu_events_table *find_sys_events_table(const char *name)
4012519db2aSIan Rogers {
4022519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
4032519db2aSIan Rogers 	     tables->name;
4042519db2aSIan Rogers 	     tables++) {
4052519db2aSIan Rogers 		if (!strcmp(tables->name, name))
4061ba3752aSIan Rogers 			return &tables->table;
4072519db2aSIan Rogers 	}
4082519db2aSIan Rogers 	return NULL;
4092519db2aSIan Rogers }
4102519db2aSIan Rogers 
4112519db2aSIan Rogers int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
4122519db2aSIan Rogers {
4132519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
4142519db2aSIan Rogers 	     tables->name;
4152519db2aSIan Rogers 	     tables++) {
416*e3edd6cfSIan Rogers 		int ret = pmu_events_table__for_each_event(&tables->table, /*pmu=*/ NULL, fn, data);
4172519db2aSIan Rogers 
4182519db2aSIan Rogers 		if (ret)
4192519db2aSIan Rogers 			return ret;
4202519db2aSIan Rogers 	}
4212519db2aSIan Rogers 	return 0;
4222519db2aSIan Rogers }
423db95818eSIan Rogers 
424db95818eSIan Rogers int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __maybe_unused)
425db95818eSIan Rogers {
426db95818eSIan Rogers 	return 0;
427db95818eSIan Rogers }
42866c6e0c1SIan Rogers 
42966c6e0c1SIan Rogers const char *describe_metricgroup(const char *group __maybe_unused)
43066c6e0c1SIan Rogers {
43166c6e0c1SIan Rogers 	return NULL;
43266c6e0c1SIan Rogers }
433