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