jevents.py (660842e468dcefb5d1d4fb40ed3abe4d1388dff7) jevents.py (1ba3752aec30c04bfb7c82b44332ff98294ec0b8)
1#!/usr/bin/env python3
2# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
3"""Convert directories of JSON events to C code."""
4import argparse
5import csv
6import json
7import os
8import sys

--- 321 unchanged lines hidden (view full) ---

330 return
331
332 add_events_table_entries(item, get_topic(item.name))
333
334
335def print_mapping_table(archs: Sequence[str]) -> None:
336 """Read the mapfile and generate the struct from cpuid string to event table."""
337 _args.output_file.write("""
1#!/usr/bin/env python3
2# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
3"""Convert directories of JSON events to C code."""
4import argparse
5import csv
6import json
7import os
8import sys

--- 321 unchanged lines hidden (view full) ---

330 return
331
332 add_events_table_entries(item, get_topic(item.name))
333
334
335def print_mapping_table(archs: Sequence[str]) -> None:
336 """Read the mapfile and generate the struct from cpuid string to event table."""
337 _args.output_file.write("""
338/* Struct used to make the PMU event table implementation opaque to callers. */
339struct pmu_events_table {
340 const struct pmu_event *entries;
341};
342
338/*
339 * Map a CPU to its table of PMU events. The CPU is identified by the
340 * cpuid field, which is an arch-specific identifier for the CPU.
341 * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
342 * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
343 *
344 * The cpuid can contain any character other than the comma.
345 */
346struct pmu_events_map {
347 const char *arch;
348 const char *cpuid;
343/*
344 * Map a CPU to its table of PMU events. The CPU is identified by the
345 * cpuid field, which is an arch-specific identifier for the CPU.
346 * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
347 * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
348 *
349 * The cpuid can contain any character other than the comma.
350 */
351struct pmu_events_map {
352 const char *arch;
353 const char *cpuid;
349 const struct pmu_event *table;
354 struct pmu_events_table table;
350};
351
352/*
353 * Global table mapping each known CPU for the architecture to its
354 * table of PMU events.
355 */
356const struct pmu_events_map pmu_events_map[] = {
357""")
358 for arch in archs:
359 if arch == 'test':
360 _args.output_file.write("""{
361\t.arch = "testarch",
362\t.cpuid = "testcpu",
355};
356
357/*
358 * Global table mapping each known CPU for the architecture to its
359 * table of PMU events.
360 */
361const struct pmu_events_map pmu_events_map[] = {
362""")
363 for arch in archs:
364 if arch == 'test':
365 _args.output_file.write("""{
366\t.arch = "testarch",
367\t.cpuid = "testcpu",
363\t.table = pme_test_soc_cpu,
368\t.table = { pme_test_soc_cpu },
364},
365""")
366 else:
367 with open(f'{_args.starting_dir}/{arch}/mapfile.csv') as csvfile:
368 table = csv.reader(csvfile)
369 first = True
370 for row in table:
371 # Skip the first row or any row beginning with #.
372 if not first and len(row) > 0 and not row[0].startswith('#'):
373 tblname = file_name_to_table_name([], row[2].replace('/', '_'))
374 cpuid = row[0].replace('\\', '\\\\')
375 _args.output_file.write(f"""{{
376\t.arch = "{arch}",
377\t.cpuid = "{cpuid}",
369},
370""")
371 else:
372 with open(f'{_args.starting_dir}/{arch}/mapfile.csv') as csvfile:
373 table = csv.reader(csvfile)
374 first = True
375 for row in table:
376 # Skip the first row or any row beginning with #.
377 if not first and len(row) > 0 and not row[0].startswith('#'):
378 tblname = file_name_to_table_name([], row[2].replace('/', '_'))
379 cpuid = row[0].replace('\\', '\\\\')
380 _args.output_file.write(f"""{{
381\t.arch = "{arch}",
382\t.cpuid = "{cpuid}",
378\t.table = {tblname}
383\t.table = {{ {tblname} }}
379}},
380""")
381 first = False
382
383 _args.output_file.write("""{
384\t.arch = 0,
385\t.cpuid = 0,
384}},
385""")
386 first = False
387
388 _args.output_file.write("""{
389\t.arch = 0,
390\t.cpuid = 0,
386\t.table = 0,
391\t.table = { 0 },
387}
388};
389""")
390
391
392def print_system_mapping_table() -> None:
393 """C struct mapping table array for tables from /sys directories."""
394 _args.output_file.write("""
395struct pmu_sys_events {
396\tconst char *name;
392}
393};
394""")
395
396
397def print_system_mapping_table() -> None:
398 """C struct mapping table array for tables from /sys directories."""
399 _args.output_file.write("""
400struct pmu_sys_events {
401\tconst char *name;
397\tconst struct pmu_event *table;
402\tstruct pmu_events_table table;
398};
399
400static const struct pmu_sys_events pmu_sys_event_tables[] = {
401""")
402 for tblname in _sys_event_tables:
403 _args.output_file.write(f"""\t{{
403};
404
405static const struct pmu_sys_events pmu_sys_event_tables[] = {
406""")
407 for tblname in _sys_event_tables:
408 _args.output_file.write(f"""\t{{
404\t\t.table = {tblname},
409\t\t.table = {{ {tblname} }},
405\t\t.name = \"{tblname}\",
406\t}},
407""")
408 _args.output_file.write("""\t{
410\t\t.name = \"{tblname}\",
411\t}},
412""")
413 _args.output_file.write("""\t{
409\t\t.table = 0
414\t\t.table = { 0 }
410\t},
411};
412
415\t},
416};
417
413int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
418int pmu_events_table_for_each_event(const struct pmu_events_table *table, pmu_event_iter_fn fn,
414 void *data)
415{
419 void *data)
420{
416 for (const struct pmu_event *pe = &table[0];
421 for (const struct pmu_event *pe = &table->entries[0];
417 pe->name || pe->metric_group || pe->metric_name;
418 pe++) {
419 int ret = fn(pe, table, data);
420
421 if (ret)
422 return ret;
423 }
424 return 0;
425}
426
422 pe->name || pe->metric_group || pe->metric_name;
423 pe++) {
424 int ret = fn(pe, table, data);
425
426 if (ret)
427 return ret;
428 }
429 return 0;
430}
431
427const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu)
432const struct pmu_events_table *perf_pmu__find_table(struct perf_pmu *pmu)
428{
433{
429 const struct pmu_event *table = NULL;
434 const struct pmu_events_table *table = NULL;
430 char *cpuid = perf_pmu__getcpuid(pmu);
431 int i;
432
433 /* on some platforms which uses cpus map, cpuid can be NULL for
434 * PMUs other than CORE PMUs.
435 */
436 if (!cpuid)
437 return NULL;
438
439 i = 0;
440 for (;;) {
441 const struct pmu_events_map *map = &pmu_events_map[i++];
435 char *cpuid = perf_pmu__getcpuid(pmu);
436 int i;
437
438 /* on some platforms which uses cpus map, cpuid can be NULL for
439 * PMUs other than CORE PMUs.
440 */
441 if (!cpuid)
442 return NULL;
443
444 i = 0;
445 for (;;) {
446 const struct pmu_events_map *map = &pmu_events_map[i++];
442 if (!map->table)
447 if (!map->arch)
443 break;
444
445 if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
448 break;
449
450 if (!strcmp_cpuid_str(map->cpuid, cpuid)) {
446 table = map->table;
451 table = &map->table;
447 break;
448 }
449 }
450 free(cpuid);
451 return table;
452}
453
452 break;
453 }
454 }
455 free(cpuid);
456 return table;
457}
458
454const struct pmu_event *find_core_events_table(const char *arch, const char *cpuid)
459const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
455{
456 for (const struct pmu_events_map *tables = &pmu_events_map[0];
460{
461 for (const struct pmu_events_map *tables = &pmu_events_map[0];
457 tables->table;
462 tables->arch;
458 tables++) {
459 if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
463 tables++) {
464 if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
460 return tables->table;
465 return &tables->table;
461 }
462 return NULL;
463}
464
465int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
466{
467 for (const struct pmu_events_map *tables = &pmu_events_map[0];
466 }
467 return NULL;
468}
469
470int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
471{
472 for (const struct pmu_events_map *tables = &pmu_events_map[0];
468 tables->table;
473 tables->arch;
469 tables++) {
474 tables++) {
470 int ret = pmu_events_table_for_each_event(tables->table, fn, data);
475 int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
471
472 if (ret)
473 return ret;
474 }
475 return 0;
476}
477
476
477 if (ret)
478 return ret;
479 }
480 return 0;
481}
482
478const struct pmu_event *find_sys_events_table(const char *name)
483const struct pmu_events_table *find_sys_events_table(const char *name)
479{
480 for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
481 tables->name;
482 tables++) {
483 if (!strcmp(tables->name, name))
484{
485 for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
486 tables->name;
487 tables++) {
488 if (!strcmp(tables->name, name))
484 return tables->table;
489 return &tables->table;
485 }
486 return NULL;
487}
488
489int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
490{
491 for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
492 tables->name;
493 tables++) {
490 }
491 return NULL;
492}
493
494int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
495{
496 for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
497 tables->name;
498 tables++) {
494 int ret = pmu_events_table_for_each_event(tables->table, fn, data);
499 int ret = pmu_events_table_for_each_event(&tables->table, fn, data);
495
496 if (ret)
497 return ret;
498 }
499 return 0;
500}
501""")
502

--- 60 unchanged lines hidden ---
500
501 if (ret)
502 return ret;
503 }
504 return 0;
505}
506""")
507

--- 60 unchanged lines hidden ---