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
))
32 def __init__(self
, name
, low
, high
, shr
, type, parser
):
39 builtin_types
= [ None, "boolean", "uint", "hex", "int", "fixed", "ufixed", "float" ]
41 if low
< 0 or low
> 31:
42 raise parser
.error("low attribute out of range: %d" % low
)
43 if high
< 0 or high
> 31:
44 raise parser
.error("high attribute out of range: %d" % high
)
46 raise parser
.error("low is greater than high: low=%d, high=%d" % (low
, high
))
47 if self
.type == "boolean" and not low
== high
:
48 raise parser
.error("booleans should be 1 bit fields");
49 elif self
.type == "float" and not (high
- low
== 31 or high
- low
== 15):
50 raise parser
.error("floats should be 16 or 32 bit fields")
51 elif not self
.type in builtin_types
and not self
.type in parser
.enums
:
52 raise parser
.error("unknown type '%s'" % self
.type);
58 elif self
.type == "boolean":
61 elif self
.type == "uint" or self
.type == "hex":
64 elif self
.type == "int":
67 elif self
.type == "fixed":
69 val
= "((int32_t)(val * %d.0))" % (1 << self
.radix
)
70 elif self
.type == "ufixed":
72 val
= "((uint32_t)(val * %d.0))" % (1 << self
.radix
)
73 elif self
.type == "float" and self
.high
- self
.low
== 31:
76 elif self
.type == "float" and self
.high
- self
.low
== 15:
78 val
= "util_float_to_half(val)"
80 type = "enum %s" % self
.type
84 val
= "%s >> %d" % (val
, self
.shr
)
88 def tab_to(name
, value
):
89 tab_count
= (68 - (len(name
) & ~
7)) // 8
92 print(name
+ ('\t' * tab_count
) + value
)
95 return ((0xffffffff >> (32 - (high
+ 1 - low
))) << low
)
98 def __init__(self
, name
, template
):
102 self
.fields
= template
.fields
106 def dump(self
, prefix
=None):
109 for f
in self
.fields
:
111 name
= prefix
+ "_" + f
.name
115 if not f
.name
and f
.low
== 0 and f
.shr
== 0 and not f
.type in ["float", "fixed", "ufixed"]:
117 elif f
.type == "boolean" or (f
.type == None and f
.low
== f
.high
):
118 tab_to("#define %s" % name
, "0x%08x" % (1 << f
.low
))
120 tab_to("#define %s__MASK" % name
, "0x%08x" % mask(f
.low
, f
.high
))
121 tab_to("#define %s__SHIFT" % name
, "%d" % f
.low
)
122 type, val
= f
.ctype()
124 print("static inline uint32_t %s(%s val)\n{" % (name
, type))
126 print("\tassert(!(val & 0x%x));" % mask(0, f
.shr
- 1))
127 print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val
, name
, name
))
130 def __init__(self
, attrs
, domain
):
131 self
.name
= attrs
["name"]
133 self
.offset
= int(attrs
["offset"], 0)
134 self
.stride
= int(attrs
["stride"], 0)
135 self
.length
= int(attrs
["length"], 0)
138 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
))
141 def __init__(self
, attrs
, domain
, array
):
142 self
.name
= attrs
["name"]
145 self
.offset
= int(attrs
["offset"], 0)
150 name
= self
.domain
+ "_" + self
.array
.name
+ "_" + self
.name
151 offset
= self
.array
.offset
+ self
.offset
152 print("static inline uint32_t REG_%s(uint32_t i0) { return 0x%08x + 0x%x*i0; }" % (name
, offset
, self
.array
.stride
))
154 name
= self
.domain
+ "_" + self
.name
155 tab_to("#define REG_%s" % name
, "0x%08x" % self
.offset
)
157 if self
.bitset
.inline
:
158 self
.bitset
.dump(name
)
161 def parse_variants(attrs
):
162 if not "variants" in attrs
:
164 variant
= attrs
["variants"].split(",")[0]
166 variant
= variant
[:variant
.index("-")]
170 class Parser(object):
172 self
.current_array
= None
173 self
.current_domain
= None
174 self
.current_prefix
= None
175 self
.current_stripe
= None
176 self
.current_bitset
= None
181 def error(self
, message
):
182 parser
, filename
= self
.stack
[-1]
183 return Error("%s:%d:%d: %s" % (filename
, parser
.CurrentLineNumber
, parser
.CurrentColumnNumber
, message
))
186 if self
.current_stripe
:
187 return self
.current_stripe
+ "_" + self
.current_domain
188 elif self
.current_prefix
:
189 return self
.current_prefix
+ "_" + self
.current_domain
191 return self
.current_domain
193 def parse_field(self
, name
, attrs
):
196 high
= low
= int(attrs
["pos"], 0)
197 elif "high" in attrs
and "low" in attrs
:
198 high
= int(attrs
["high"], 0)
199 low
= int(attrs
["low"], 0)
210 shr
= int(attrs
["shr"], 0)
214 b
= Field(name
, low
, high
, shr
, type, self
)
216 if type == "fixed" or type == "ufixed":
217 b
.radix
= int(attrs
["radix"], 0)
219 self
.current_bitset
.fields
.append(b
)
220 except ValueError as e
:
223 def do_parse(self
, filename
):
224 file = open(filename
, "rb")
225 parser
= xml
.parsers
.expat
.ParserCreate()
226 self
.stack
.append((parser
, filename
))
227 parser
.StartElementHandler
= self
.start_element
228 parser
.EndElementHandler
= self
.end_element
229 parser
.ParseFile(file)
233 def parse(self
, filename
):
234 self
.path
= os
.path
.dirname(filename
)
236 self
.do_parse(filename
)
238 def start_element(self
, name
, attrs
):
240 filename
= os
.path
.basename(attrs
["file"])
241 self
.do_parse(os
.path
.join(self
.path
, filename
))
242 elif name
== "domain":
243 self
.current_domain
= attrs
["name"]
244 if "prefix" in attrs
and attrs
["prefix"] == "chip":
245 self
.current_prefix
= parse_variants(attrs
)
246 elif name
== "stripe":
247 self
.current_stripe
= parse_variants(attrs
)
249 self
.current_enum_value
= 0
250 self
.current_enum
= Enum(attrs
["name"])
251 self
.enums
[attrs
["name"]] = self
.current_enum
252 if len(self
.stack
) == 1:
253 self
.file.append(self
.current_enum
)
254 elif name
== "value":
256 value
= int(attrs
["value"], 0)
258 value
= self
.current_enum_value
259 self
.current_enum
.values
.append((attrs
["name"], value
))
260 # self.current_enum_value = value + 1
261 elif name
== "reg32":
262 if "type" in attrs
and attrs
["type"] in self
.bitsets
:
263 self
.current_bitset
= self
.bitsets
[attrs
["type"]]
265 self
.current_bitset
= Bitset(attrs
["name"], None)
266 self
.current_bitset
.inline
= True
268 self
.parse_field(None, attrs
)
270 self
.current_reg
= Reg(attrs
, self
.prefix(), self
.current_array
)
271 self
.current_reg
.bitset
= self
.current_bitset
273 if len(self
.stack
) == 1:
274 self
.file.append(self
.current_reg
)
275 elif name
== "array":
276 self
.current_array
= Array(attrs
, self
.prefix())
277 if len(self
.stack
) == 1:
278 self
.file.append(self
.current_array
)
279 elif name
== "bitset":
280 self
.current_bitset
= Bitset(attrs
["name"], None)
281 if "inline" in attrs
and attrs
["inline"] == "yes":
282 self
.current_bitset
.inline
= True
283 self
.bitsets
[self
.current_bitset
.name
] = self
.current_bitset
284 if len(self
.stack
) == 1 and not self
.current_bitset
.inline
:
285 self
.file.append(self
.current_bitset
)
286 elif name
== "bitfield" and self
.current_bitset
:
287 self
.parse_field(attrs
["name"], attrs
)
289 def end_element(self
, name
):
291 self
.current_domain
= None
292 self
.current_prefix
= None
293 elif name
== "stripe":
294 self
.current_stripe
= None
295 elif name
== "bitset":
296 self
.current_bitset
= None
297 elif name
== "reg32":
298 self
.current_reg
= None
299 elif name
== "array":
300 self
.current_array
= None;
302 self
.current_enum
= None
309 if isinstance(e
, Enum
):
311 elif isinstance(e
, Bitset
):
316 for e
in enums
+ bitsets
+ regs
:
321 xml_file
= sys
.argv
[1]
323 guard
= str.replace(os
.path
.basename(xml_file
), '.', '_').upper()
324 print("#ifndef %s\n#define %s\n" % (guard
, guard
))
334 print("\n#endif /* %s */" % guard
)
336 if __name__
== '__main__':