c0fc47fd8b4e526439aa36690b246c72e070cf2e
3 import xml
.parsers
.expat
7 class Error(Exception):
8 def __init__(self
, message
):
12 def __init__(self
, name
):
19 for (name
, value
) in self
.values
:
23 print("enum %s {" % self
.name
)
24 for (name
, value
) in self
.values
:
26 print("\t%s = 0x%08x," % (name
, value
))
28 print("\t%s = %d," % (name
, value
))
31 def dump_pack_struct(self
):
35 def __init__(self
, name
, low
, high
, shr
, type, parser
):
42 builtin_types
= [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ]
44 if low
< 0 or low
> 31:
45 raise parser
.error("low attribute out of range: %d" % low
)
46 if high
< 0 or high
> 31:
47 raise parser
.error("high attribute out of range: %d" % high
)
49 raise parser
.error("low is greater than high: low=%d, high=%d" % (low
, high
))
50 if self
.type == "boolean" and not low
== high
:
51 raise parser
.error("booleans should be 1 bit fields");
52 elif self
.type == "float" and not (high
- low
== 31 or high
- low
== 15):
53 raise parser
.error("floats should be 16 or 32 bit fields")
54 elif not self
.type in builtin_types
and not self
.type in parser
.enums
:
55 raise parser
.error("unknown type '%s'" % self
.type);
57 def ctype(self
, var_name
):
61 elif self
.type == "boolean":
64 elif self
.type == "uint" or self
.type == "hex" or self
.type == "a3xx_regid":
67 elif self
.type == "int":
70 elif self
.type == "fixed":
72 val
= "((int32_t)(%s * %d.0))" % (var_name
, 1 << self
.radix
)
73 elif self
.type == "ufixed":
75 val
= "((uint32_t)(%s * %d.0))" % (var_name
, 1 << self
.radix
)
76 elif self
.type == "float" and self
.high
- self
.low
== 31:
78 val
= "fui(%s)" % var_name
79 elif self
.type == "float" and self
.high
- self
.low
== 15:
81 val
= "util_float_to_half(%s)" % var_name
82 elif self
.type in [ "address", "waddress" ]:
86 type = "enum %s" % self
.type
90 val
= "(%s >> %d)" % (val
, self
.shr
)
94 def tab_to(name
, value
):
95 tab_count
= (68 - (len(name
) & ~
7)) // 8
98 print(name
+ ('\t' * tab_count
) + value
)
101 return ((0xffffffff >> (32 - (high
+ 1 - low
))) << low
)
103 class Bitset(object):
104 def __init__(self
, name
, template
):
108 self
.fields
= template
.fields
112 def dump_pack_struct(self
, prefix
=None, array
=None):
113 def field_name(prefix
, name
):
115 name
= f
.name
.lower()
117 name
= prefix
.lower()
119 if (name
in [ "double", "float", "int" ]) or not (name
[0].isalpha()):
129 print("struct %s {" % prefix
)
130 for f
in self
.fields
:
131 if f
.type in [ "address", "waddress" ]:
132 tab_to(" __bo_type", "bo;")
133 tab_to(" uint32_t", "bo_offset;")
135 name
= field_name(prefix
, f
.name
)
137 type, val
= f
.ctype("var")
139 tab_to(" %s" % type, "%s;" % name
)
140 tab_to(" uint32_t", "unknown;")
141 tab_to(" uint32_t", "dword;")
145 for f
in self
.fields
:
146 if f
.type in [ "address", "waddress" ]:
149 print("static inline struct fd_reg_pair\npack_%s(uint32_t i, struct %s fields)\n{" %
152 print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" %
155 print("#ifndef NDEBUG")
157 for f
in self
.fields
:
158 known_mask |
= mask(f
.low
, f
.high
)
159 if f
.type in [ "boolean", "address", "waddress" ]:
161 type, val
= f
.ctype("fields.%s" % field_name(prefix
, f
.name
))
162 print(" assert((%-40s & 0x%08x) == 0);" % (val
, 0xffffffff ^
mask(0 , f
.high
- f
.low
)))
163 print(" assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask
))
166 print(" return (struct fd_reg_pair) {")
168 print(" .reg = REG_%s(i)," % prefix
)
170 print(" .reg = REG_%s," % prefix
)
173 for f
in self
.fields
:
174 if f
.type in [ "address", "waddress" ]:
177 type, val
= f
.ctype("fields.%s" % field_name(prefix
, f
.name
))
178 print(" (%-40s << %2d) |" % (val
, f
.low
))
179 print(" fields.unknown | fields.dword,")
182 print(" .is_address = true,")
183 print(" .bo = fields.bo,")
184 if f
.type == "waddress":
185 print(" .bo_write = true,")
186 print(" .bo_offset = fields.bo_offset,")
187 print(" .bo_shift = %d" % address
.shr
)
192 skip
= ", { .reg = 0 }"
197 print("#define %s(i, ...) pack_%s(i, (struct %s) { __VA_ARGS__ })%s\n" %
198 (prefix
, prefix
, prefix
, skip
))
200 print("#define %s(...) pack_%s((struct %s) { __VA_ARGS__ })%s\n" %
201 (prefix
, prefix
, prefix
, skip
))
204 def dump(self
, prefix
=None):
207 for f
in self
.fields
:
209 name
= prefix
+ "_" + f
.name
213 if not f
.name
and f
.low
== 0 and f
.shr
== 0 and not f
.type in ["float", "fixed", "ufixed"]:
215 elif f
.type == "boolean" or (f
.type == None and f
.low
== f
.high
):
216 tab_to("#define %s" % name
, "0x%08x" % (1 << f
.low
))
218 tab_to("#define %s__MASK" % name
, "0x%08x" % mask(f
.low
, f
.high
))
219 tab_to("#define %s__SHIFT" % name
, "%d" % f
.low
)
220 type, val
= f
.ctype("val")
222 print("static inline uint32_t %s(%s val)\n{" % (name
, type))
224 print("\tassert(!(val & 0x%x));" % mask(0, f
.shr
- 1))
225 print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val
, name
, name
))
229 def __init__(self
, attrs
, domain
):
231 self
.name
= attrs
["name"]
235 self
.offset
= int(attrs
["offset"], 0)
236 self
.stride
= int(attrs
["stride"], 0)
237 self
.length
= int(attrs
["length"], 0)
240 print("static inline uint32_t REG_%s_%s(uint32_t i0) { return 0x%08x + 0x%x*i0; }\n" % (self
.domain
, self
.name
, self
.offset
, self
.stride
))
242 def dump_pack_struct(self
):
246 def __init__(self
, attrs
, domain
, array
, bit_size
):
247 self
.name
= attrs
["name"]
250 self
.offset
= int(attrs
["offset"], 0)
252 self
.bit_size
= bit_size
255 self
.full_name
= self
.domain
+ "_" + self
.array
.name
+ "_" + self
.name
257 self
.full_name
= self
.domain
+ "_" + self
.name
261 offset
= self
.array
.offset
+ self
.offset
262 print("static inline uint32_t REG_%s(uint32_t i0) { return 0x%08x + 0x%x*i0; }" % (self
.full_name
, offset
, self
.array
.stride
))
264 tab_to("#define REG_%s" % self
.full_name
, "0x%08x" % self
.offset
)
266 if self
.bitset
.inline
:
267 self
.bitset
.dump(self
.full_name
)
270 def dump_pack_struct(self
):
271 if self
.bitset
.inline
:
272 self
.bitset
.dump_pack_struct(self
.full_name
, not self
.array
== None)
275 def parse_variants(attrs
):
276 if not "variants" in attrs
:
278 variant
= attrs
["variants"].split(",")[0]
280 variant
= variant
[:variant
.index("-")]
284 class Parser(object):
286 self
.current_array
= None
287 self
.current_domain
= None
288 self
.current_prefix
= None
289 self
.current_stripe
= None
290 self
.current_bitset
= None
295 def error(self
, message
):
296 parser
, filename
= self
.stack
[-1]
297 return Error("%s:%d:%d: %s" % (filename
, parser
.CurrentLineNumber
, parser
.CurrentColumnNumber
, message
))
300 if self
.current_stripe
:
301 return self
.current_stripe
+ "_" + self
.current_domain
302 elif self
.current_prefix
:
303 return self
.current_prefix
+ "_" + self
.current_domain
305 return self
.current_domain
307 def parse_field(self
, name
, attrs
):
310 high
= low
= int(attrs
["pos"], 0)
311 elif "high" in attrs
and "low" in attrs
:
312 high
= int(attrs
["high"], 0)
313 low
= int(attrs
["low"], 0)
324 shr
= int(attrs
["shr"], 0)
328 b
= Field(name
, low
, high
, shr
, type, self
)
330 if type == "fixed" or type == "ufixed":
331 b
.radix
= int(attrs
["radix"], 0)
333 self
.current_bitset
.fields
.append(b
)
334 except ValueError as e
:
337 def do_parse(self
, filename
):
339 file = open(filename
, "rb")
340 except FileNotFoundError
as e
:
341 # Look for the file in the parent directory if not
342 # found in same directory:
343 path
= os
.path
.dirname(filename
)
344 base
= os
.path
.basename(filename
)
345 file = open(path
+ "/../" + base
, "rb")
346 parser
= xml
.parsers
.expat
.ParserCreate()
347 self
.stack
.append((parser
, filename
))
348 parser
.StartElementHandler
= self
.start_element
349 parser
.EndElementHandler
= self
.end_element
350 parser
.ParseFile(file)
354 def parse(self
, filename
):
355 self
.path
= os
.path
.dirname(filename
)
357 self
.do_parse(filename
)
359 def parse_reg(self
, attrs
, bit_size
):
360 if "type" in attrs
and attrs
["type"] in self
.bitsets
:
361 self
.current_bitset
= self
.bitsets
[attrs
["type"]]
363 self
.current_bitset
= Bitset(attrs
["name"], None)
364 self
.current_bitset
.inline
= True
366 self
.parse_field(None, attrs
)
368 self
.current_reg
= Reg(attrs
, self
.prefix(), self
.current_array
, bit_size
)
369 self
.current_reg
.bitset
= self
.current_bitset
371 if len(self
.stack
) == 1:
372 self
.file.append(self
.current_reg
)
374 def start_element(self
, name
, attrs
):
376 filename
= os
.path
.basename(attrs
["file"])
377 self
.do_parse(os
.path
.join(self
.path
, filename
))
378 elif name
== "domain":
379 self
.current_domain
= attrs
["name"]
380 if "prefix" in attrs
and attrs
["prefix"] == "chip":
381 self
.current_prefix
= parse_variants(attrs
)
382 elif name
== "stripe":
383 self
.current_stripe
= parse_variants(attrs
)
385 self
.current_enum_value
= 0
386 self
.current_enum
= Enum(attrs
["name"])
387 self
.enums
[attrs
["name"]] = self
.current_enum
388 if len(self
.stack
) == 1:
389 self
.file.append(self
.current_enum
)
390 elif name
== "value":
392 value
= int(attrs
["value"], 0)
394 value
= self
.current_enum_value
395 self
.current_enum
.values
.append((attrs
["name"], value
))
396 # self.current_enum_value = value + 1
397 elif name
== "reg32":
398 self
.parse_reg(attrs
, 32)
399 elif name
== "reg64":
400 self
.parse_reg(attrs
, 64)
401 elif name
== "array":
402 self
.current_array
= Array(attrs
, self
.prefix())
403 if len(self
.stack
) == 1:
404 self
.file.append(self
.current_array
)
405 elif name
== "bitset":
406 self
.current_bitset
= Bitset(attrs
["name"], None)
407 if "inline" in attrs
and attrs
["inline"] == "yes":
408 self
.current_bitset
.inline
= True
409 self
.bitsets
[self
.current_bitset
.name
] = self
.current_bitset
410 if len(self
.stack
) == 1 and not self
.current_bitset
.inline
:
411 self
.file.append(self
.current_bitset
)
412 elif name
== "bitfield" and self
.current_bitset
:
413 self
.parse_field(attrs
["name"], attrs
)
415 def end_element(self
, name
):
417 self
.current_domain
= None
418 self
.current_prefix
= None
419 elif name
== "stripe":
420 self
.current_stripe
= None
421 elif name
== "bitset":
422 self
.current_bitset
= None
423 elif name
== "reg32":
424 self
.current_reg
= None
425 elif name
== "array":
426 self
.current_array
= None;
428 self
.current_enum
= None
435 if isinstance(e
, Enum
):
437 elif isinstance(e
, Bitset
):
442 for e
in enums
+ bitsets
+ regs
:
445 def dump_structs(self
):
452 xml_file
= sys
.argv
[1]
453 if len(sys
.argv
) > 2 and sys
.argv
[2] == '--pack-structs':
455 guard
= str.replace(os
.path
.basename(xml_file
), '.', '_').upper() + '_STRUCTS'
458 guard
= str.replace(os
.path
.basename(xml_file
), '.', '_').upper()
460 print("#ifndef %s\n#define %s\n" % (guard
, guard
))
473 print("\n#endif /* %s */" % guard
)
475 if __name__
== '__main__':