brintos

brintos / linux-shallow public Read only

0
0
Text · 26.1 KiB · c592079 Raw
665 lines · c
1 2/* SPDX-License-Identifier: GPL-2.0 */3/* THIS FILE WAS AUTOGENERATED BY jevents.py arch=none model=none ! */4 5#include <pmu-events/pmu-events.h>6#include "util/header.h"7#include "util/pmu.h"8#include <string.h>9#include <stddef.h>10 11struct compact_pmu_event {12        int offset;13};14 15struct pmu_table_entry {16        const struct compact_pmu_event *entries;17        uint32_t num_entries;18        struct compact_pmu_event pmu_name;19};20 21static const char *const big_c_string =22/* offset=0 */ "default_core\000"23/* offset=13 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000"24/* offset=72 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000"25/* offset=131 */ "l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000"26/* offset=226 */ "segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000"27/* offset=325 */ "dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000"28/* offset=455 */ "eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000"29/* offset=570 */ "hisi_sccl,ddrc\000"30/* offset=585 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000"31/* offset=671 */ "uncore_cbox\000"32/* offset=683 */ "unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000"33/* offset=914 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000"34/* offset=979 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000"35/* offset=1050 */ "hisi_sccl,l3c\000"36/* offset=1064 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000"37/* offset=1144 */ "uncore_imc_free_running\000"38/* offset=1168 */ "uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000"39/* offset=1263 */ "uncore_imc\000"40/* offset=1274 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000"41/* offset=1352 */ "uncore_sys_ddr_pmu\000"42/* offset=1371 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000"43/* offset=1444 */ "uncore_sys_ccn_pmu\000"44/* offset=1463 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000"45/* offset=1537 */ "uncore_sys_cmn_pmu\000"46/* offset=1556 */ "sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000"47/* offset=1696 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000"48/* offset=1718 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000"49/* offset=1781 */ "Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000"50/* offset=1947 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000"51/* offset=2011 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000"52/* offset=2078 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000"53/* offset=2149 */ "DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000"54/* offset=2243 */ "DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000"55/* offset=2377 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000"56/* offset=2441 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000"57/* offset=2509 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000"58/* offset=2579 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000"59/* offset=2601 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000"60/* offset=2623 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000"61/* offset=2643 */ "L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000"62;63 64static const struct compact_pmu_event pmu_events__test_soc_cpu_default_core[] = {65{ 13 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000 */66{ 72 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000 */67{ 325 }, /* dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000 */68{ 455 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000 */69{ 131 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000 */70{ 226 }, /* segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000 */71};72static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_ddrc[] = {73{ 585 }, /* uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000 */74};75static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_l3c[] = {76{ 1064 }, /* uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000 */77};78static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_cbox[] = {79{ 914 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000 */80{ 979 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000 */81{ 683 }, /* unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000 */82};83static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc[] = {84{ 1274 }, /* uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000 */85};86static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc_free_running[] = {87{ 1168 }, /* uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000 */88 89};90 91const struct pmu_table_entry pmu_events__test_soc_cpu[] = {92{93     .entries = pmu_events__test_soc_cpu_default_core,94     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_default_core),95     .pmu_name = { 0 /* default_core\000 */ },96},97{98     .entries = pmu_events__test_soc_cpu_hisi_sccl_ddrc,99     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_ddrc),100     .pmu_name = { 570 /* hisi_sccl,ddrc\000 */ },101},102{103     .entries = pmu_events__test_soc_cpu_hisi_sccl_l3c,104     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_l3c),105     .pmu_name = { 1050 /* hisi_sccl,l3c\000 */ },106},107{108     .entries = pmu_events__test_soc_cpu_uncore_cbox,109     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_cbox),110     .pmu_name = { 671 /* uncore_cbox\000 */ },111},112{113     .entries = pmu_events__test_soc_cpu_uncore_imc,114     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc),115     .pmu_name = { 1263 /* uncore_imc\000 */ },116},117{118     .entries = pmu_events__test_soc_cpu_uncore_imc_free_running,119     .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc_free_running),120     .pmu_name = { 1144 /* uncore_imc_free_running\000 */ },121},122};123 124static const struct compact_pmu_event pmu_metrics__test_soc_cpu_default_core[] = {125{ 1696 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */126{ 2377 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000 */127{ 2149 }, /* DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000 */128{ 2243 }, /* DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000 */129{ 2441 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000 */130{ 2509 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000 */131{ 1781 }, /* Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000 */132{ 1718 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000 */133{ 2643 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000 */134{ 2579 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */135{ 2601 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */136{ 2623 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */137{ 2078 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000 */138{ 1947 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */139{ 2011 }, /* icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */140 141};142 143const struct pmu_table_entry pmu_metrics__test_soc_cpu[] = {144{145     .entries = pmu_metrics__test_soc_cpu_default_core,146     .num_entries = ARRAY_SIZE(pmu_metrics__test_soc_cpu_default_core),147     .pmu_name = { 0 /* default_core\000 */ },148},149};150 151static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ccn_pmu[] = {152{ 1463 }, /* sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000 */153};154static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_cmn_pmu[] = {155{ 1556 }, /* sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000 */156};157static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ddr_pmu[] = {158{ 1371 }, /* sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000 */159 160};161 162const struct pmu_table_entry pmu_events__test_soc_sys[] = {163{164     .entries = pmu_events__test_soc_sys_uncore_sys_ccn_pmu,165     .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ccn_pmu),166     .pmu_name = { 1444 /* uncore_sys_ccn_pmu\000 */ },167},168{169     .entries = pmu_events__test_soc_sys_uncore_sys_cmn_pmu,170     .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_cmn_pmu),171     .pmu_name = { 1537 /* uncore_sys_cmn_pmu\000 */ },172},173{174     .entries = pmu_events__test_soc_sys_uncore_sys_ddr_pmu,175     .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ddr_pmu),176     .pmu_name = { 1352 /* uncore_sys_ddr_pmu\000 */ },177},178};179 180 181/* Struct used to make the PMU event table implementation opaque to callers. */182struct pmu_events_table {183        const struct pmu_table_entry *pmus;184        uint32_t num_pmus;185};186 187/* Struct used to make the PMU metric table implementation opaque to callers. */188struct pmu_metrics_table {189        const struct pmu_table_entry *pmus;190        uint32_t num_pmus;191};192 193/*194 * Map a CPU to its table of PMU events. The CPU is identified by the195 * cpuid field, which is an arch-specific identifier for the CPU.196 * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile197 * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)198 *199 * The  cpuid can contain any character other than the comma.200 */201struct pmu_events_map {202        const char *arch;203        const char *cpuid;204        struct pmu_events_table event_table;205        struct pmu_metrics_table metric_table;206};207 208/*209 * Global table mapping each known CPU for the architecture to its210 * table of PMU events.211 */212const struct pmu_events_map pmu_events_map[] = {213{214	.arch = "testarch",215	.cpuid = "testcpu",216	.event_table = {217		.pmus = pmu_events__test_soc_cpu,218		.num_pmus = ARRAY_SIZE(pmu_events__test_soc_cpu),219	},220	.metric_table = {221		.pmus = pmu_metrics__test_soc_cpu,222		.num_pmus = ARRAY_SIZE(pmu_metrics__test_soc_cpu),223	}224},225{226	.arch = 0,227	.cpuid = 0,228	.event_table = { 0, 0 },229	.metric_table = { 0, 0 },230}231};232 233struct pmu_sys_events {234	const char *name;235	struct pmu_events_table event_table;236	struct pmu_metrics_table metric_table;237};238 239static const struct pmu_sys_events pmu_sys_event_tables[] = {240	{241		.event_table = {242			.pmus = pmu_events__test_soc_sys,243			.num_pmus = ARRAY_SIZE(pmu_events__test_soc_sys)244		},245		.name = "pmu_events__test_soc_sys",246	},247	{248		.event_table = { 0, 0 },249		.metric_table = { 0, 0 },250	},251};252 253static void decompress_event(int offset, struct pmu_event *pe)254{255	const char *p = &big_c_string[offset];256 257	pe->name = (*p == '\0' ? NULL : p);258	while (*p++);259	pe->topic = (*p == '\0' ? NULL : p);260	while (*p++);261	pe->desc = (*p == '\0' ? NULL : p);262	while (*p++);263	pe->event = (*p == '\0' ? NULL : p);264	while (*p++);265	pe->compat = (*p == '\0' ? NULL : p);266	while (*p++);267	pe->deprecated = *p - '0';268	p++;269	pe->perpkg = *p - '0';270	p++;271	pe->unit = (*p == '\0' ? NULL : p);272	while (*p++);273	pe->long_desc = (*p == '\0' ? NULL : p);274}275 276static void decompress_metric(int offset, struct pmu_metric *pm)277{278	const char *p = &big_c_string[offset];279 280	pm->metric_name = (*p == '\0' ? NULL : p);281	while (*p++);282	pm->metric_group = (*p == '\0' ? NULL : p);283	while (*p++);284	pm->metric_expr = (*p == '\0' ? NULL : p);285	while (*p++);286	pm->metric_threshold = (*p == '\0' ? NULL : p);287	while (*p++);288	pm->desc = (*p == '\0' ? NULL : p);289	while (*p++);290	pm->long_desc = (*p == '\0' ? NULL : p);291	while (*p++);292	pm->unit = (*p == '\0' ? NULL : p);293	while (*p++);294	pm->compat = (*p == '\0' ? NULL : p);295	while (*p++);296	pm->metricgroup_no_group = (*p == '\0' ? NULL : p);297	while (*p++);298	pm->default_metricgroup_name = (*p == '\0' ? NULL : p);299	while (*p++);300	pm->aggr_mode = *p - '0';301	p++;302	pm->event_grouping = *p - '0';303}304 305static int pmu_events_table__for_each_event_pmu(const struct pmu_events_table *table,306                                                const struct pmu_table_entry *pmu,307                                                pmu_event_iter_fn fn,308                                                void *data)309{310        int ret;311        struct pmu_event pe = {312                .pmu = &big_c_string[pmu->pmu_name.offset],313        };314 315        for (uint32_t i = 0; i < pmu->num_entries; i++) {316                decompress_event(pmu->entries[i].offset, &pe);317                if (!pe.name)318                        continue;319                ret = fn(&pe, table, data);320                if (ret)321                        return ret;322        }323        return 0;324 }325 326static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table,327                                            const struct pmu_table_entry *pmu,328                                            const char *name,329                                            pmu_event_iter_fn fn,330                                            void *data)331{332        struct pmu_event pe = {333                .pmu = &big_c_string[pmu->pmu_name.offset],334        };335        int low = 0, high = pmu->num_entries - 1;336 337        while (low <= high) {338                int cmp, mid = (low + high) / 2;339 340                decompress_event(pmu->entries[mid].offset, &pe);341 342                if (!pe.name && !name)343                        goto do_call;344 345                if (!pe.name && name) {346                        low = mid + 1;347                        continue;348                }349                if (pe.name && !name) {350                        high = mid - 1;351                        continue;352                }353 354                cmp = strcasecmp(pe.name, name);355                if (cmp < 0) {356                        low = mid + 1;357                        continue;358                }359                if (cmp > 0) {360                        high = mid - 1;361                        continue;362                }363  do_call:364                return fn ? fn(&pe, table, data) : 0;365        }366        return PMU_EVENTS__NOT_FOUND;367}368 369int pmu_events_table__for_each_event(const struct pmu_events_table *table,370                                    struct perf_pmu *pmu,371                                    pmu_event_iter_fn fn,372                                    void *data)373{374        for (size_t i = 0; i < table->num_pmus; i++) {375                const struct pmu_table_entry *table_pmu = &table->pmus[i];376                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];377                int ret;378 379                if (pmu && !pmu__name_match(pmu, pmu_name))380                        continue;381 382                ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data);383                if (pmu || ret)384                        return ret;385        }386        return 0;387}388 389int pmu_events_table__find_event(const struct pmu_events_table *table,390                                 struct perf_pmu *pmu,391                                 const char *name,392                                 pmu_event_iter_fn fn,393                                 void *data)394{395        for (size_t i = 0; i < table->num_pmus; i++) {396                const struct pmu_table_entry *table_pmu = &table->pmus[i];397                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];398                int ret;399 400                if (!pmu__name_match(pmu, pmu_name))401                        continue;402 403                ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);404                if (ret != PMU_EVENTS__NOT_FOUND)405                        return ret;406        }407        return PMU_EVENTS__NOT_FOUND;408}409 410size_t pmu_events_table__num_events(const struct pmu_events_table *table,411                                    struct perf_pmu *pmu)412{413        size_t count = 0;414 415        for (size_t i = 0; i < table->num_pmus; i++) {416                const struct pmu_table_entry *table_pmu = &table->pmus[i];417                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];418 419                if (pmu__name_match(pmu, pmu_name))420                        count += table_pmu->num_entries;421        }422        return count;423}424 425static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics_table *table,426                                                const struct pmu_table_entry *pmu,427                                                pmu_metric_iter_fn fn,428                                                void *data)429{430        int ret;431        struct pmu_metric pm = {432                .pmu = &big_c_string[pmu->pmu_name.offset],433        };434 435        for (uint32_t i = 0; i < pmu->num_entries; i++) {436                decompress_metric(pmu->entries[i].offset, &pm);437                if (!pm.metric_expr)438                        continue;439                ret = fn(&pm, table, data);440                if (ret)441                        return ret;442        }443        return 0;444}445 446int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,447                                     pmu_metric_iter_fn fn,448                                     void *data)449{450        for (size_t i = 0; i < table->num_pmus; i++) {451                int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i],452                                                                 fn, data);453 454                if (ret)455                        return ret;456        }457        return 0;458}459 460static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)461{462        static struct {463                const struct pmu_events_map *map;464                struct perf_pmu *pmu;465        } last_result;466        static struct {467                const struct pmu_events_map *map;468                char *cpuid;469        } last_map_search;470        static bool has_last_result, has_last_map_search;471        const struct pmu_events_map *map = NULL;472        char *cpuid = NULL;473        size_t i;474 475        if (has_last_result && last_result.pmu == pmu)476                return last_result.map;477 478        cpuid = perf_pmu__getcpuid(pmu);479 480        /*481         * On some platforms which uses cpus map, cpuid can be NULL for482         * PMUs other than CORE PMUs.483         */484        if (!cpuid)485                goto out_update_last_result;486 487        if (has_last_map_search && !strcmp(last_map_search.cpuid, cpuid)) {488                map = last_map_search.map;489                free(cpuid);490        } else {491                i = 0;492                for (;;) {493                        map = &pmu_events_map[i++];494 495                        if (!map->arch) {496                                map = NULL;497                                break;498                        }499 500                        if (!strcmp_cpuid_str(map->cpuid, cpuid))501                                break;502               }503               free(last_map_search.cpuid);504               last_map_search.cpuid = cpuid;505               last_map_search.map = map;506               has_last_map_search = true;507        }508out_update_last_result:509        last_result.pmu = pmu;510        last_result.map = map;511        has_last_result = true;512        return map;513}514 515const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)516{517        const struct pmu_events_map *map = map_for_pmu(pmu);518 519        if (!map)520                return NULL;521 522        if (!pmu)523                return &map->event_table;524 525        for (size_t i = 0; i < map->event_table.num_pmus; i++) {526                const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i];527                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];528 529                if (pmu__name_match(pmu, pmu_name))530                         return &map->event_table;531        }532        return NULL;533}534 535const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)536{537        const struct pmu_events_map *map = map_for_pmu(pmu);538 539        if (!map)540                return NULL;541 542        if (!pmu)543                return &map->metric_table;544 545        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {546                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];547                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];548 549                if (pmu__name_match(pmu, pmu_name))550                           return &map->metric_table;551        }552        return NULL;553}554 555const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)556{557        for (const struct pmu_events_map *tables = &pmu_events_map[0];558             tables->arch;559             tables++) {560                if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))561                        return &tables->event_table;562        }563        return NULL;564}565 566const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid)567{568        for (const struct pmu_events_map *tables = &pmu_events_map[0];569             tables->arch;570             tables++) {571                if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))572                        return &tables->metric_table;573        }574        return NULL;575}576 577int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)578{579        for (const struct pmu_events_map *tables = &pmu_events_map[0];580             tables->arch;581             tables++) {582                int ret = pmu_events_table__for_each_event(&tables->event_table,583                                                           /*pmu=*/ NULL, fn, data);584 585                if (ret)586                        return ret;587        }588        return 0;589}590 591int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data)592{593        for (const struct pmu_events_map *tables = &pmu_events_map[0];594             tables->arch;595             tables++) {596                int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data);597 598                if (ret)599                        return ret;600        }601        return 0;602}603 604const struct pmu_events_table *find_sys_events_table(const char *name)605{606        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];607             tables->name;608             tables++) {609                if (!strcmp(tables->name, name))610                        return &tables->event_table;611        }612        return NULL;613}614 615int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)616{617        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];618             tables->name;619             tables++) {620                int ret = pmu_events_table__for_each_event(&tables->event_table,621                                                           /*pmu=*/ NULL, fn, data);622 623                if (ret)624                        return ret;625        }626        return 0;627}628 629int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data)630{631        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];632             tables->name;633             tables++) {634                int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data);635 636                if (ret)637                        return ret;638        }639        return 0;640}641 642static const int metricgroups[][2] = {643 644};645 646const char *describe_metricgroup(const char *group)647{648        int low = 0, high = (int)ARRAY_SIZE(metricgroups) - 1;649 650        while (low <= high) {651                int mid = (low + high) / 2;652                const char *mgroup = &big_c_string[metricgroups[mid][0]];653                int cmp = strcmp(mgroup, group);654 655                if (cmp == 0) {656                        return &big_c_string[metricgroups[mid][1]];657                } else if (cmp < 0) {658                        low = mid + 1;659                } else {660                        high = mid - 1;661                }662        }663        return NULL;664}665