xref: /aosp_15_r20/external/mesa3d/src/amd/registers/parseheader.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker#
2*61046927SAndroid Build Coastguard Worker# Copyright 2017-2019 Advanced Micro Devices, Inc.
3*61046927SAndroid Build Coastguard Worker#
4*61046927SAndroid Build Coastguard Worker# SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker#
6*61046927SAndroid Build Coastguard Worker"""
7*61046927SAndroid Build Coastguard WorkerHelper script that parses a register header and produces a register database
8*61046927SAndroid Build Coastguard Workeras output. Use as:
9*61046927SAndroid Build Coastguard Worker
10*61046927SAndroid Build Coastguard Worker  python3 parseheader.py ADDRESS_SPACE < header.h
11*61046927SAndroid Build Coastguard Worker
12*61046927SAndroid Build Coastguard WorkerThis script is included for reference -- we should be able to remove this in
13*61046927SAndroid Build Coastguard Workerthe future.
14*61046927SAndroid Build Coastguard Worker"""
15*61046927SAndroid Build Coastguard Worker
16*61046927SAndroid Build Coastguard Workerimport json
17*61046927SAndroid Build Coastguard Workerimport math
18*61046927SAndroid Build Coastguard Workerimport re
19*61046927SAndroid Build Coastguard Workerimport sys
20*61046927SAndroid Build Coastguard Worker
21*61046927SAndroid Build Coastguard Workerfrom regdb import Object, RegisterDatabase, deduplicate_enums, deduplicate_register_types
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard WorkerRE_comment = re.compile(r'(/\*(.*)\*/)$|(//(.*))$')
25*61046927SAndroid Build Coastguard WorkerRE_prefix = re.compile(r'([RSV])_([0-9a-fA-F]+)_')
26*61046927SAndroid Build Coastguard WorkerRE_set_value = re.compile(r'\(\(\(unsigned\)\(x\) & ([0-9a-fA-Fx]+)\) << ([0-9]+)\)')
27*61046927SAndroid Build Coastguard WorkerRE_set_value_no_shift = re.compile(r'\((\(unsigned\))?\(x\) & ([0-9a-fA-Fx]+)\)')
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Workerclass HeaderParser(object):
30*61046927SAndroid Build Coastguard Worker    def __init__(self, address_space):
31*61046927SAndroid Build Coastguard Worker        self.regdb = RegisterDatabase()
32*61046927SAndroid Build Coastguard Worker        self.chips = ['gfx6', 'gfx7', 'gfx8', 'fiji', 'stoney', 'gfx9']
33*61046927SAndroid Build Coastguard Worker        self.address_space = address_space
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker    def __fini_field(self):
36*61046927SAndroid Build Coastguard Worker        if self.__field is None:
37*61046927SAndroid Build Coastguard Worker            return
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker        if self.__enumentries:
40*61046927SAndroid Build Coastguard Worker            self.__field.enum_ref = self.__regmap.name + '__' + self.__field.name
41*61046927SAndroid Build Coastguard Worker            self.regdb.add_enum(self.__field.enum_ref, Object(
42*61046927SAndroid Build Coastguard Worker                entries=self.__enumentries
43*61046927SAndroid Build Coastguard Worker            ))
44*61046927SAndroid Build Coastguard Worker        self.__fields.append(self.__field)
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker        self.__enumentries = None
47*61046927SAndroid Build Coastguard Worker        self.__field = None
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker    def __fini_register(self):
50*61046927SAndroid Build Coastguard Worker        if self.__regmap is None:
51*61046927SAndroid Build Coastguard Worker            return
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker        if self.__fields:
54*61046927SAndroid Build Coastguard Worker            self.regdb.add_register_type(self.__regmap.name, Object(
55*61046927SAndroid Build Coastguard Worker                fields=self.__fields
56*61046927SAndroid Build Coastguard Worker            ))
57*61046927SAndroid Build Coastguard Worker            self.__regmap.type_ref = self.__regmap.name
58*61046927SAndroid Build Coastguard Worker        self.regdb.add_register_mapping(self.__regmap)
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker        self.__regmap = None
61*61046927SAndroid Build Coastguard Worker        self.__fields = None
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker    def parse_header(self, filp):
64*61046927SAndroid Build Coastguard Worker        regdb = RegisterDatabase()
65*61046927SAndroid Build Coastguard Worker        chips = ['gfx6', 'gfx7', 'gfx8', 'fiji', 'stoney', 'gfx9']
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker        self.__regmap = None
68*61046927SAndroid Build Coastguard Worker        self.__fields = None
69*61046927SAndroid Build Coastguard Worker        self.__field = None
70*61046927SAndroid Build Coastguard Worker        self.__enumentries = None
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker        for line in filp:
73*61046927SAndroid Build Coastguard Worker            if not line.startswith('#define '):
74*61046927SAndroid Build Coastguard Worker                continue
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker            line = line[8:].strip()
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker            comment = None
79*61046927SAndroid Build Coastguard Worker            m = RE_comment.search(line)
80*61046927SAndroid Build Coastguard Worker            if m is not None:
81*61046927SAndroid Build Coastguard Worker                comment = m.group(2) or m.group(4)
82*61046927SAndroid Build Coastguard Worker                comment = comment.strip()
83*61046927SAndroid Build Coastguard Worker                line = line[:m.span()[0]].strip()
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker            split = line.split(None, 1)
86*61046927SAndroid Build Coastguard Worker            name = split[0]
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker            m = RE_prefix.match(name)
89*61046927SAndroid Build Coastguard Worker            if m is None:
90*61046927SAndroid Build Coastguard Worker                continue
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker            prefix = m.group(1)
93*61046927SAndroid Build Coastguard Worker            prefix_address = int(m.group(2), 16)
94*61046927SAndroid Build Coastguard Worker            name = name[m.span()[1]:]
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker            if prefix == 'V':
97*61046927SAndroid Build Coastguard Worker                value = int(split[1], 0)
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker                for entry in self.__enumentries:
100*61046927SAndroid Build Coastguard Worker                    if name == entry.name:
101*61046927SAndroid Build Coastguard Worker                        sys.exit('Duplicate value define: name = {0}'.format(name))
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker                entry = Object(name=name, value=value)
104*61046927SAndroid Build Coastguard Worker                if comment is not None:
105*61046927SAndroid Build Coastguard Worker                    entry.comment = comment
106*61046927SAndroid Build Coastguard Worker                self.__enumentries.append(entry)
107*61046927SAndroid Build Coastguard Worker                continue
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker            if prefix == 'S':
110*61046927SAndroid Build Coastguard Worker                self.__fini_field()
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker                if not name.endswith('(x)'):
113*61046927SAndroid Build Coastguard Worker                    sys.exit('Missing (x) in S line: {0}'.line)
114*61046927SAndroid Build Coastguard Worker                name = name[:-3]
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker                for field in self.__fields:
117*61046927SAndroid Build Coastguard Worker                    if name == field.name:
118*61046927SAndroid Build Coastguard Worker                        sys.exit('Duplicate field define: {0}'.format(name))
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker                m = RE_set_value.match(split[1])
121*61046927SAndroid Build Coastguard Worker                if m is not None:
122*61046927SAndroid Build Coastguard Worker                    unshifted_mask = int(m.group(1), 0)
123*61046927SAndroid Build Coastguard Worker                    shift = int(m.group(2), 0)
124*61046927SAndroid Build Coastguard Worker                else:
125*61046927SAndroid Build Coastguard Worker                    m = RE_set_value_no_shift.match(split[1])
126*61046927SAndroid Build Coastguard Worker                    if m is not None:
127*61046927SAndroid Build Coastguard Worker                        unshifted_mask = int(m.group(2), 0)
128*61046927SAndroid Build Coastguard Worker                        shift = 0
129*61046927SAndroid Build Coastguard Worker                    else:
130*61046927SAndroid Build Coastguard Worker                        sys.exit('Bad S_xxx_xxx define: {0}'.format(line))
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker                num_bits = int(math.log2(unshifted_mask + 1))
133*61046927SAndroid Build Coastguard Worker                if unshifted_mask != (1 << num_bits) - 1:
134*61046927SAndroid Build Coastguard Worker                    sys.exit('Bad unshifted mask in {0}'.format(line))
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker                self.__field = Object(
137*61046927SAndroid Build Coastguard Worker                    name=name,
138*61046927SAndroid Build Coastguard Worker                    bits=[shift, shift + num_bits - 1],
139*61046927SAndroid Build Coastguard Worker                )
140*61046927SAndroid Build Coastguard Worker                if comment is not None:
141*61046927SAndroid Build Coastguard Worker                    self.__field.comment = comment
142*61046927SAndroid Build Coastguard Worker                self.__enumentries = []
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker            if prefix == 'R':
145*61046927SAndroid Build Coastguard Worker                self.__fini_field()
146*61046927SAndroid Build Coastguard Worker                self.__fini_register()
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker                if regdb.register_mappings_by_name(name):
149*61046927SAndroid Build Coastguard Worker                    sys.exit('Duplicate register define: {0}'.format(name))
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker                address = int(split[1], 0)
152*61046927SAndroid Build Coastguard Worker                if address != prefix_address:
153*61046927SAndroid Build Coastguard Worker                    sys.exit('Inconsistent register address: {0}'.format(line))
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker                self.__regmap = Object(
156*61046927SAndroid Build Coastguard Worker                    name=name,
157*61046927SAndroid Build Coastguard Worker                    chips=self.chips,
158*61046927SAndroid Build Coastguard Worker                    map=Object(to=self.address_space, at=address),
159*61046927SAndroid Build Coastguard Worker                )
160*61046927SAndroid Build Coastguard Worker                self.__fields = []
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker        self.__fini_field()
163*61046927SAndroid Build Coastguard Worker        self.__fini_register()
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Workerdef main():
166*61046927SAndroid Build Coastguard Worker    map_to = sys.argv[1]
167*61046927SAndroid Build Coastguard Worker
168*61046927SAndroid Build Coastguard Worker    parser = HeaderParser(map_to)
169*61046927SAndroid Build Coastguard Worker    parser.parse_header(sys.stdin)
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker    deduplicate_enums(parser.regdb)
172*61046927SAndroid Build Coastguard Worker    deduplicate_register_types(parser.regdb)
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker    print(parser.regdb.encode_json_pretty())
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Workerif __name__ == '__main__':
178*61046927SAndroid Build Coastguard Worker    main()
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker# kate: space-indent on; indent-width 4; replace-tabs on;
181