xref: /openbmc/linux/tools/perf/pmu-events/empty-pmu-events.c (revision db95818e888a927456686518880ed0145b1f20ce)
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 
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 	{
1097ae5c03aSIan Rogers 		.metric_expr	= "1 / IPC",
1107ae5c03aSIan Rogers 		.metric_name	= "CPI",
1117ae5c03aSIan Rogers 	},
1127ae5c03aSIan Rogers 	{
1137ae5c03aSIan Rogers 		.metric_expr	= "inst_retired.any / cpu_clk_unhalted.thread",
1147ae5c03aSIan Rogers 		.metric_name	= "IPC",
1157ae5c03aSIan Rogers 		.metric_group	= "group1",
1167ae5c03aSIan Rogers 	},
1177ae5c03aSIan Rogers 	{
1187ae5c03aSIan Rogers 		.metric_expr	= "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * "
1197ae5c03aSIan Rogers 		"( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))",
1207ae5c03aSIan Rogers 		.metric_name	= "Frontend_Bound_SMT",
1217ae5c03aSIan Rogers 	},
1227ae5c03aSIan Rogers 	{
1237ae5c03aSIan Rogers 		.metric_expr	= "l1d\\-loads\\-misses / inst_retired.any",
1247ae5c03aSIan Rogers 		.metric_name	= "dcache_miss_cpi",
1257ae5c03aSIan Rogers 	},
1267ae5c03aSIan Rogers 	{
1277ae5c03aSIan Rogers 		.metric_expr	= "l1i\\-loads\\-misses / inst_retired.any",
1287ae5c03aSIan Rogers 		.metric_name	= "icache_miss_cycles",
1297ae5c03aSIan Rogers 	},
1307ae5c03aSIan Rogers 	{
1317ae5c03aSIan Rogers 		.metric_expr	= "(dcache_miss_cpi + icache_miss_cycles)",
1327ae5c03aSIan Rogers 		.metric_name	= "cache_miss_cycles",
1337ae5c03aSIan Rogers 		.metric_group	= "group1",
1347ae5c03aSIan Rogers 	},
1357ae5c03aSIan Rogers 	{
1367ae5c03aSIan Rogers 		.metric_expr	= "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit",
1377ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_All_Hits",
1387ae5c03aSIan Rogers 	},
1397ae5c03aSIan Rogers 	{
1407ae5c03aSIan Rogers 		.metric_expr	= "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + "
1417ae5c03aSIan Rogers 		"l2_rqsts.pf_miss + l2_rqsts.rfo_miss",
1427ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_All_Miss",
1437ae5c03aSIan Rogers 	},
1447ae5c03aSIan Rogers 	{
1450e407915SIan Rogers 		.metric_expr	= "DCache_L2_All_Hits + DCache_L2_All_Miss",
1467ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_All",
1477ae5c03aSIan Rogers 	},
1487ae5c03aSIan Rogers 	{
1490e407915SIan Rogers 		.metric_expr	= "d_ratio(DCache_L2_All_Hits, DCache_L2_All)",
1507ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_Hits",
1517ae5c03aSIan Rogers 	},
1527ae5c03aSIan Rogers 	{
1530e407915SIan Rogers 		.metric_expr	= "d_ratio(DCache_L2_All_Miss, DCache_L2_All)",
1547ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_Misses",
1557ae5c03aSIan Rogers 	},
1567ae5c03aSIan Rogers 	{
1577ae5c03aSIan Rogers 		.metric_expr	= "ipc + M2",
1587ae5c03aSIan Rogers 		.metric_name	= "M1",
1597ae5c03aSIan Rogers 	},
1607ae5c03aSIan Rogers 	{
1617ae5c03aSIan Rogers 		.metric_expr	= "ipc + M1",
1627ae5c03aSIan Rogers 		.metric_name	= "M2",
1637ae5c03aSIan Rogers 	},
1647ae5c03aSIan Rogers 	{
1657ae5c03aSIan Rogers 		.metric_expr	= "1/M3",
1667ae5c03aSIan Rogers 		.metric_name	= "M3",
1677ae5c03aSIan Rogers 	},
1687ae5c03aSIan Rogers 	{
1697ae5c03aSIan Rogers 		.metric_expr	= "64 * l1d.replacement / 1000000000 / duration_time",
1707ae5c03aSIan Rogers 		.metric_name	= "L1D_Cache_Fill_BW",
1717ae5c03aSIan Rogers 	},
1727ae5c03aSIan Rogers 	{
17300facc76SIan Rogers 		.name = 0,
17400facc76SIan Rogers 		.event = 0,
17500facc76SIan Rogers 		.desc = 0,
17600facc76SIan Rogers 	},
17700facc76SIan Rogers };
17800facc76SIan Rogers 
1791ba3752aSIan Rogers /* Struct used to make the PMU event table implementation opaque to callers. */
1801ba3752aSIan Rogers struct pmu_events_table {
1811ba3752aSIan Rogers 	const struct pmu_event *entries;
1821ba3752aSIan Rogers };
18329be2fe0SIan Rogers 
184*db95818eSIan Rogers /* Struct used to make the PMU metric table implementation opaque to callers. */
185*db95818eSIan Rogers struct pmu_metrics_table {
186*db95818eSIan Rogers 	const struct pmu_metric *entries;
187*db95818eSIan Rogers };
188*db95818eSIan Rogers 
18929be2fe0SIan Rogers /*
19029be2fe0SIan Rogers  * Map a CPU to its table of PMU events. The CPU is identified by the
19129be2fe0SIan Rogers  * cpuid field, which is an arch-specific identifier for the CPU.
19229be2fe0SIan Rogers  * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
19329be2fe0SIan Rogers  * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
19429be2fe0SIan Rogers  *
19529be2fe0SIan Rogers  * The  cpuid can contain any character other than the comma.
19629be2fe0SIan Rogers  */
19729be2fe0SIan Rogers struct pmu_events_map {
19829be2fe0SIan Rogers 	const char *arch;
19929be2fe0SIan Rogers 	const char *cpuid;
2001ba3752aSIan Rogers 	const struct pmu_events_table table;
20129be2fe0SIan Rogers };
20229be2fe0SIan Rogers 
20329be2fe0SIan Rogers /*
20429be2fe0SIan Rogers  * Global table mapping each known CPU for the architecture to its
20529be2fe0SIan Rogers  * table of PMU events.
20629be2fe0SIan Rogers  */
20729be2fe0SIan Rogers static const struct pmu_events_map pmu_events_map[] = {
20800facc76SIan Rogers 	{
209099b157cSIan Rogers 		.arch = "testarch",
21000facc76SIan Rogers 		.cpuid = "testcpu",
2111ba3752aSIan Rogers 		.table = { pme_test_soc_cpu },
21200facc76SIan Rogers 	},
21300facc76SIan Rogers 	{
214099b157cSIan Rogers 		.arch = 0,
21500facc76SIan Rogers 		.cpuid = 0,
2161ba3752aSIan Rogers 		.table = { 0 },
21700facc76SIan Rogers 	},
21800facc76SIan Rogers };
21900facc76SIan Rogers 
22000facc76SIan Rogers static const struct pmu_event pme_test_soc_sys[] = {
22100facc76SIan Rogers 	{
22200facc76SIan Rogers 		.name = "sys_ddr_pmu.write_cycles",
22300facc76SIan Rogers 		.event = "event=0x2b",
22400facc76SIan Rogers 		.desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ",
22500facc76SIan Rogers 		.compat = "v8",
22600facc76SIan Rogers 		.topic = "uncore",
22700facc76SIan Rogers 		.pmu = "uncore_sys_ddr_pmu",
22800facc76SIan Rogers 	},
22900facc76SIan Rogers 	{
23000facc76SIan Rogers 		.name = "sys_ccn_pmu.read_cycles",
23100facc76SIan Rogers 		.event = "config=0x2c",
23200facc76SIan Rogers 		.desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ",
23300facc76SIan Rogers 		.compat = "0x01",
23400facc76SIan Rogers 		.topic = "uncore",
23500facc76SIan Rogers 		.pmu = "uncore_sys_ccn_pmu",
23600facc76SIan Rogers 	},
23700facc76SIan Rogers 	{
23800facc76SIan Rogers 		.name = 0,
23900facc76SIan Rogers 		.event = 0,
24000facc76SIan Rogers 		.desc = 0,
24100facc76SIan Rogers 	},
24200facc76SIan Rogers };
24300facc76SIan Rogers 
2442519db2aSIan Rogers struct pmu_sys_events {
2452519db2aSIan Rogers 	const char *name;
2461ba3752aSIan Rogers 	const struct pmu_events_table table;
2472519db2aSIan Rogers };
2482519db2aSIan Rogers 
2492519db2aSIan Rogers static const struct pmu_sys_events pmu_sys_event_tables[] = {
25000facc76SIan Rogers 	{
2511ba3752aSIan Rogers 		.table = { pme_test_soc_sys },
25200facc76SIan Rogers 		.name = "pme_test_soc_sys",
25300facc76SIan Rogers 	},
25400facc76SIan Rogers 	{
2551ba3752aSIan Rogers 		.table = { 0 }
25600facc76SIan Rogers 	},
25700facc76SIan Rogers };
2582519db2aSIan Rogers 
2591ba3752aSIan Rogers int pmu_events_table_for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn,
260660842e4SIan Rogers 				    void *data)
261660842e4SIan Rogers {
262*db95818eSIan Rogers 	for (const struct pmu_event *pe = &table->entries[0]; pe->name || pe->metric_expr; pe++) {
263*db95818eSIan Rogers 		int ret;
264660842e4SIan Rogers 
265*db95818eSIan Rogers 		if (!pe->name)
266*db95818eSIan Rogers 			continue;
267*db95818eSIan Rogers 		ret = fn(pe, table, data);
268*db95818eSIan Rogers 		if (ret)
269*db95818eSIan Rogers 			return ret;
270*db95818eSIan Rogers 	}
271*db95818eSIan Rogers 	return 0;
272*db95818eSIan Rogers }
273*db95818eSIan Rogers 
274*db95818eSIan Rogers int pmu_events_table_for_each_metric(const struct pmu_events_table *etable, pmu_metric_iter_fn fn,
275*db95818eSIan Rogers 				     void *data)
276*db95818eSIan Rogers {
277*db95818eSIan Rogers 	struct pmu_metrics_table *table = (struct pmu_metrics_table *)etable;
278*db95818eSIan Rogers 
279*db95818eSIan Rogers 	for (const struct pmu_metric *pm = &table->entries[0]; pm->name || pm->metric_expr; pm++) {
280*db95818eSIan Rogers 		int ret;
281*db95818eSIan Rogers 
282*db95818eSIan Rogers 		if (!pm->metric_expr)
283*db95818eSIan Rogers 			continue;
284*db95818eSIan Rogers 		ret = fn(pm, etable, data);
285660842e4SIan Rogers 		if (ret)
286660842e4SIan Rogers 			return ret;
287660842e4SIan Rogers 	}
288660842e4SIan Rogers 	return 0;
289660842e4SIan Rogers }
290660842e4SIan Rogers 
2911ba3752aSIan Rogers const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu)
29229be2fe0SIan Rogers {
2931ba3752aSIan Rogers 	const struct pmu_events_table *table = NULL;
29429be2fe0SIan Rogers 	char *cpuid = perf_pmu__getcpuid(pmu);
29529be2fe0SIan Rogers 	int i;
29629be2fe0SIan Rogers 
29729be2fe0SIan Rogers 	/* on some platforms which uses cpus map, cpuid can be NULL for
29829be2fe0SIan Rogers 	 * PMUs other than CORE PMUs.
29929be2fe0SIan Rogers 	 */
30029be2fe0SIan Rogers 	if (!cpuid)
30129be2fe0SIan Rogers 		return NULL;
30229be2fe0SIan Rogers 
30329be2fe0SIan Rogers 	i = 0;
30429be2fe0SIan Rogers 	for (;;) {
30529be2fe0SIan Rogers 		const struct pmu_events_map *map = &pmu_events_map[i++];
30629be2fe0SIan Rogers 
3071ba3752aSIan Rogers 		if (!map->cpuid)
30829be2fe0SIan Rogers 			break;
30929be2fe0SIan Rogers 
31029be2fe0SIan Rogers 		if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
3111ba3752aSIan Rogers 			table = &map->table;
31229be2fe0SIan Rogers 			break;
31329be2fe0SIan Rogers 		}
31429be2fe0SIan Rogers 	}
31529be2fe0SIan Rogers 	free(cpuid);
31629be2fe0SIan Rogers 	return table;
31729be2fe0SIan Rogers }
31829be2fe0SIan Rogers 
3191ba3752aSIan Rogers const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
32029be2fe0SIan Rogers {
32129be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
3221ba3752aSIan Rogers 	     tables->arch;
32329be2fe0SIan Rogers 	     tables++) {
32429be2fe0SIan Rogers 		if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
3251ba3752aSIan Rogers 			return &tables->table;
32629be2fe0SIan Rogers 	}
32729be2fe0SIan Rogers 	return NULL;
32829be2fe0SIan Rogers }
32929be2fe0SIan Rogers 
33029be2fe0SIan Rogers int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
33129be2fe0SIan Rogers {
332*db95818eSIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0]; tables->arch; tables++) {
333*db95818eSIan Rogers 		int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
334*db95818eSIan Rogers 
335*db95818eSIan Rogers 		if (ret)
336*db95818eSIan Rogers 			return ret;
337*db95818eSIan Rogers 	}
338*db95818eSIan Rogers 	return 0;
339*db95818eSIan Rogers }
340*db95818eSIan Rogers 
341*db95818eSIan Rogers int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data)
342*db95818eSIan Rogers {
34329be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
3441ba3752aSIan Rogers 	     tables->arch;
34529be2fe0SIan Rogers 	     tables++) {
346*db95818eSIan Rogers 		int ret = pmu_events_table_for_each_metric(&tables->table, fn, data);
34729be2fe0SIan Rogers 
34829be2fe0SIan Rogers 		if (ret)
34929be2fe0SIan Rogers 			return ret;
35029be2fe0SIan Rogers 	}
35129be2fe0SIan Rogers 	return 0;
35229be2fe0SIan Rogers }
35329be2fe0SIan Rogers 
3541ba3752aSIan Rogers const struct pmu_events_table *find_sys_events_table(const char *name)
3552519db2aSIan Rogers {
3562519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
3572519db2aSIan Rogers 	     tables->name;
3582519db2aSIan Rogers 	     tables++) {
3592519db2aSIan Rogers 		if (!strcmp(tables->name, name))
3601ba3752aSIan Rogers 			return &tables->table;
3612519db2aSIan Rogers 	}
3622519db2aSIan Rogers 	return NULL;
3632519db2aSIan Rogers }
3642519db2aSIan Rogers 
3652519db2aSIan Rogers int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
3662519db2aSIan Rogers {
3672519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
3682519db2aSIan Rogers 	     tables->name;
3692519db2aSIan Rogers 	     tables++) {
3701ba3752aSIan Rogers 		int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
3712519db2aSIan Rogers 
3722519db2aSIan Rogers 		if (ret)
3732519db2aSIan Rogers 			return ret;
3742519db2aSIan Rogers 	}
3752519db2aSIan Rogers 	return 0;
3762519db2aSIan Rogers }
377*db95818eSIan Rogers 
378*db95818eSIan Rogers int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __maybe_unused)
379*db95818eSIan Rogers {
380*db95818eSIan Rogers 	return 0;
381*db95818eSIan Rogers }
382