xref: /linux/tools/perf/pmu-events/models.py (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1#!/usr/bin/env python3
2# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
3"""List model names from mapfile.csv files."""
4import argparse
5import csv
6import os
7import re
8from typing import List
9
10def main() -> None:
11    def dir_path(path: str) -> str:
12        """Validate path is a directory for argparse."""
13        if os.path.isdir(path):
14            return path
15        raise argparse.ArgumentTypeError(f'\'{path}\' is not a valid directory')
16
17    def find_archs(start_dir: str, arch: str) -> List[str]:
18        archs = []
19        for item in os.scandir(start_dir):
20            if not item.is_dir():
21                continue
22            if arch in (item.name, 'all'):
23                archs.append(item.name)
24
25        if len(archs) < 1:
26            raise IOError(f'Missing architecture directory \'{arch}\'')
27
28        return archs
29
30    def find_mapfiles(start_dir: str, archs: List[str]) -> List[str]:
31        result = []
32        for arch in archs:
33            for item in os.scandir(f'{start_dir}/{arch}'):
34                if item.is_dir():
35                    continue
36                if item.name == 'mapfile.csv':
37                    result.append(f'{start_dir}/{arch}/mapfile.csv')
38        return result
39
40    def find_cpuids(mapfiles: List[str], cpuids: str) -> List[str]:
41        result = []
42        for mapfile in mapfiles:
43            with open(mapfile, encoding='utf-8') as csvfile:
44                first = False
45                table = csv.reader(csvfile)
46                for row in table:
47                    if not first or len(row) == 0 or row[0].startswith('#'):
48                        first = True
49                        continue
50                    # Python regular expressions don't handle xdigit.
51                    regex = row[0].replace('[[:xdigit:]]', '[0-9a-fA-F]')
52                    for cpuid in cpuids.split(','):
53                        if re.match(regex, cpuid):
54                            result.append(row[2])
55        return result
56
57    ap = argparse.ArgumentParser()
58    ap.add_argument('arch', help='Architecture name like x86')
59    ap.add_argument('cpuid', default='all', help='List of cpuids to convert to model names')
60    ap.add_argument(
61        'starting_dir',
62        type=dir_path,
63        help='Root of tree containing architecture directories containing json files'
64    )
65    args = ap.parse_args()
66
67    archs = find_archs(args.starting_dir, args.arch)
68    mapfiles = find_mapfiles(args.starting_dir, archs)
69    models = find_cpuids(mapfiles, args.cpuid)
70    print(','.join(models))
71
72if __name__ == '__main__':
73    main()
74