xref: /openbmc/linux/tools/perf/pmu-events/empty-pmu-events.c (revision 1ba3752aec30c04bfb7c82b44332ff98294ec0b8)
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 	{
1457ae5c03aSIan Rogers 		.metric_expr	= "dcache_l2_all_hits + dcache_l2_all_miss",
1467ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_All",
1477ae5c03aSIan Rogers 	},
1487ae5c03aSIan Rogers 	{
1497ae5c03aSIan Rogers 		.metric_expr	= "d_ratio(dcache_l2_all_hits, dcache_l2_all)",
1507ae5c03aSIan Rogers 		.metric_name	= "DCache_L2_Hits",
1517ae5c03aSIan Rogers 	},
1527ae5c03aSIan Rogers 	{
1537ae5c03aSIan 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 
179*1ba3752aSIan Rogers /* Struct used to make the PMU event table implementation opaque to callers. */
180*1ba3752aSIan Rogers struct pmu_events_table {
181*1ba3752aSIan Rogers 	const struct pmu_event *entries;
182*1ba3752aSIan Rogers };
18329be2fe0SIan Rogers 
18429be2fe0SIan Rogers /*
18529be2fe0SIan Rogers  * Map a CPU to its table of PMU events. The CPU is identified by the
18629be2fe0SIan Rogers  * cpuid field, which is an arch-specific identifier for the CPU.
18729be2fe0SIan Rogers  * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
18829be2fe0SIan Rogers  * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
18929be2fe0SIan Rogers  *
19029be2fe0SIan Rogers  * The  cpuid can contain any character other than the comma.
19129be2fe0SIan Rogers  */
19229be2fe0SIan Rogers struct pmu_events_map {
19329be2fe0SIan Rogers 	const char *arch;
19429be2fe0SIan Rogers 	const char *cpuid;
195*1ba3752aSIan Rogers 	const struct pmu_events_table table;
19629be2fe0SIan Rogers };
19729be2fe0SIan Rogers 
19829be2fe0SIan Rogers /*
19929be2fe0SIan Rogers  * Global table mapping each known CPU for the architecture to its
20029be2fe0SIan Rogers  * table of PMU events.
20129be2fe0SIan Rogers  */
20229be2fe0SIan Rogers static const struct pmu_events_map pmu_events_map[] = {
20300facc76SIan Rogers 	{
204099b157cSIan Rogers 		.arch = "testarch",
20500facc76SIan Rogers 		.cpuid = "testcpu",
206*1ba3752aSIan Rogers 		.table = { pme_test_soc_cpu },
20700facc76SIan Rogers 	},
20800facc76SIan Rogers 	{
209099b157cSIan Rogers 		.arch = 0,
21000facc76SIan Rogers 		.cpuid = 0,
211*1ba3752aSIan Rogers 		.table = { 0 },
21200facc76SIan Rogers 	},
21300facc76SIan Rogers };
21400facc76SIan Rogers 
21500facc76SIan Rogers static const struct pmu_event pme_test_soc_sys[] = {
21600facc76SIan Rogers 	{
21700facc76SIan Rogers 		.name = "sys_ddr_pmu.write_cycles",
21800facc76SIan Rogers 		.event = "event=0x2b",
21900facc76SIan Rogers 		.desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ",
22000facc76SIan Rogers 		.compat = "v8",
22100facc76SIan Rogers 		.topic = "uncore",
22200facc76SIan Rogers 		.pmu = "uncore_sys_ddr_pmu",
22300facc76SIan Rogers 	},
22400facc76SIan Rogers 	{
22500facc76SIan Rogers 		.name = "sys_ccn_pmu.read_cycles",
22600facc76SIan Rogers 		.event = "config=0x2c",
22700facc76SIan Rogers 		.desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ",
22800facc76SIan Rogers 		.compat = "0x01",
22900facc76SIan Rogers 		.topic = "uncore",
23000facc76SIan Rogers 		.pmu = "uncore_sys_ccn_pmu",
23100facc76SIan Rogers 	},
23200facc76SIan Rogers 	{
23300facc76SIan Rogers 		.name = 0,
23400facc76SIan Rogers 		.event = 0,
23500facc76SIan Rogers 		.desc = 0,
23600facc76SIan Rogers 	},
23700facc76SIan Rogers };
23800facc76SIan Rogers 
2392519db2aSIan Rogers struct pmu_sys_events {
2402519db2aSIan Rogers 	const char *name;
241*1ba3752aSIan Rogers 	const struct pmu_events_table table;
2422519db2aSIan Rogers };
2432519db2aSIan Rogers 
2442519db2aSIan Rogers static const struct pmu_sys_events pmu_sys_event_tables[] = {
24500facc76SIan Rogers 	{
246*1ba3752aSIan Rogers 		.table = { pme_test_soc_sys },
24700facc76SIan Rogers 		.name = "pme_test_soc_sys",
24800facc76SIan Rogers 	},
24900facc76SIan Rogers 	{
250*1ba3752aSIan Rogers 		.table = { 0 }
25100facc76SIan Rogers 	},
25200facc76SIan Rogers };
2532519db2aSIan Rogers 
254*1ba3752aSIan Rogers int pmu_events_table_for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn,
255660842e4SIan Rogers 				    void *data)
256660842e4SIan Rogers {
257*1ba3752aSIan Rogers 	for (const struct pmu_event *pe = &table->entries[0];
258660842e4SIan Rogers 	     pe->name || pe->metric_group || pe->metric_name;
259660842e4SIan Rogers 	     pe++) {
260660842e4SIan Rogers 		int ret = fn(pe, table, data);
261660842e4SIan Rogers 
262660842e4SIan Rogers 		if (ret)
263660842e4SIan Rogers 			return ret;
264660842e4SIan Rogers 	}
265660842e4SIan Rogers 	return 0;
266660842e4SIan Rogers }
267660842e4SIan Rogers 
268*1ba3752aSIan Rogers const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu)
26929be2fe0SIan Rogers {
270*1ba3752aSIan Rogers 	const struct pmu_events_table *table = NULL;
27129be2fe0SIan Rogers 	char *cpuid = perf_pmu__getcpuid(pmu);
27229be2fe0SIan Rogers 	int i;
27329be2fe0SIan Rogers 
27429be2fe0SIan Rogers 	/* on some platforms which uses cpus map, cpuid can be NULL for
27529be2fe0SIan Rogers 	 * PMUs other than CORE PMUs.
27629be2fe0SIan Rogers 	 */
27729be2fe0SIan Rogers 	if (!cpuid)
27829be2fe0SIan Rogers 		return NULL;
27929be2fe0SIan Rogers 
28029be2fe0SIan Rogers 	i = 0;
28129be2fe0SIan Rogers 	for (;;) {
28229be2fe0SIan Rogers 		const struct pmu_events_map *map = &pmu_events_map[i++];
28329be2fe0SIan Rogers 
284*1ba3752aSIan Rogers 		if (!map->cpuid)
28529be2fe0SIan Rogers 			break;
28629be2fe0SIan Rogers 
28729be2fe0SIan Rogers 		if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
288*1ba3752aSIan Rogers 			table = &map->table;
28929be2fe0SIan Rogers 			break;
29029be2fe0SIan Rogers 		}
29129be2fe0SIan Rogers 	}
29229be2fe0SIan Rogers 	free(cpuid);
29329be2fe0SIan Rogers 	return table;
29429be2fe0SIan Rogers }
29529be2fe0SIan Rogers 
296*1ba3752aSIan Rogers const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
29729be2fe0SIan Rogers {
29829be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
299*1ba3752aSIan Rogers 	     tables->arch;
30029be2fe0SIan Rogers 	     tables++) {
30129be2fe0SIan Rogers 		if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
302*1ba3752aSIan Rogers 			return &tables->table;
30329be2fe0SIan Rogers 	}
30429be2fe0SIan Rogers 	return NULL;
30529be2fe0SIan Rogers }
30629be2fe0SIan Rogers 
30729be2fe0SIan Rogers int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
30829be2fe0SIan Rogers {
30929be2fe0SIan Rogers 	for (const struct pmu_events_map *tables = &pmu_events_map[0];
310*1ba3752aSIan Rogers 	     tables->arch;
31129be2fe0SIan Rogers 	     tables++) {
312*1ba3752aSIan Rogers 		int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
31329be2fe0SIan Rogers 
31429be2fe0SIan Rogers 		if (ret)
31529be2fe0SIan Rogers 			return ret;
31629be2fe0SIan Rogers 	}
31729be2fe0SIan Rogers 	return 0;
31829be2fe0SIan Rogers }
31929be2fe0SIan Rogers 
320*1ba3752aSIan Rogers const struct pmu_events_table *find_sys_events_table(const char *name)
3212519db2aSIan Rogers {
3222519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
3232519db2aSIan Rogers 	     tables->name;
3242519db2aSIan Rogers 	     tables++) {
3252519db2aSIan Rogers 		if (!strcmp(tables->name, name))
326*1ba3752aSIan Rogers 			return &tables->table;
3272519db2aSIan Rogers 	}
3282519db2aSIan Rogers 	return NULL;
3292519db2aSIan Rogers }
3302519db2aSIan Rogers 
3312519db2aSIan Rogers int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
3322519db2aSIan Rogers {
3332519db2aSIan Rogers 	for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
3342519db2aSIan Rogers 	     tables->name;
3352519db2aSIan Rogers 	     tables++) {
336*1ba3752aSIan Rogers 		int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
3372519db2aSIan Rogers 
3382519db2aSIan Rogers 		if (ret)
3392519db2aSIan Rogers 			return ret;
3402519db2aSIan Rogers 	}
3412519db2aSIan Rogers 	return 0;
3422519db2aSIan Rogers }
343