1b8e80941Smrg#encoding=utf-8 2b8e80941Smrg 3b8e80941Smrg# Copyright (C) 2016 Intel Corporation 4b8e80941Smrg# Copyright (C) 2016 Broadcom 5b8e80941Smrg# 6b8e80941Smrg# Permission is hereby granted, free of charge, to any person obtaining a 7b8e80941Smrg# copy of this software and associated documentation files (the "Software"), 8b8e80941Smrg# to deal in the Software without restriction, including without limitation 9b8e80941Smrg# the rights to use, copy, modify, merge, publish, distribute, sublicense, 10b8e80941Smrg# and/or sell copies of the Software, and to permit persons to whom the 11b8e80941Smrg# Software is furnished to do so, subject to the following conditions: 12b8e80941Smrg# 13b8e80941Smrg# The above copyright notice and this permission notice (including the next 14b8e80941Smrg# paragraph) shall be included in all copies or substantial portions of the 15b8e80941Smrg# Software. 16b8e80941Smrg# 17b8e80941Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18b8e80941Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19b8e80941Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20b8e80941Smrg# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21b8e80941Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22b8e80941Smrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23b8e80941Smrg# IN THE SOFTWARE. 24b8e80941Smrg 25b8e80941Smrgfrom __future__ import ( 26b8e80941Smrg absolute_import, division, print_function, unicode_literals 27b8e80941Smrg) 28b8e80941Smrgimport xml.parsers.expat 29b8e80941Smrgimport re 30b8e80941Smrgimport sys 31b8e80941Smrgimport copy 32b8e80941Smrg 33b8e80941Smrglicense = """/* Generated code, see packets.xml and gen_packet_header.py */ 34b8e80941Smrg""" 35b8e80941Smrg 36b8e80941Smrgpack_header = """%(license)s 37b8e80941Smrg 38b8e80941Smrg/* Packets, enums and structures for %(platform)s. 39b8e80941Smrg * 40b8e80941Smrg * This file has been generated, do not hand edit. 41b8e80941Smrg */ 42b8e80941Smrg 43b8e80941Smrg#ifndef %(guard)s 44b8e80941Smrg#define %(guard)s 45b8e80941Smrg 46b8e80941Smrg#include "cle/v3d_packet_helpers.h" 47b8e80941Smrg 48b8e80941Smrg""" 49b8e80941Smrg 50b8e80941Smrgdef to_alphanum(name): 51b8e80941Smrg substitutions = { 52b8e80941Smrg ' ': '_', 53b8e80941Smrg '/': '_', 54b8e80941Smrg '[': '', 55b8e80941Smrg ']': '', 56b8e80941Smrg '(': '', 57b8e80941Smrg ')': '', 58b8e80941Smrg '-': '_', 59b8e80941Smrg ':': '', 60b8e80941Smrg '.': '', 61b8e80941Smrg ',': '', 62b8e80941Smrg '=': '', 63b8e80941Smrg '>': '', 64b8e80941Smrg '#': '', 65b8e80941Smrg 'α': 'alpha', 66b8e80941Smrg '&': '', 67b8e80941Smrg '*': '', 68b8e80941Smrg '"': '', 69b8e80941Smrg '+': '', 70b8e80941Smrg '\'': '', 71b8e80941Smrg } 72b8e80941Smrg 73b8e80941Smrg for i, j in substitutions.items(): 74b8e80941Smrg name = name.replace(i, j) 75b8e80941Smrg 76b8e80941Smrg return name 77b8e80941Smrg 78b8e80941Smrgdef safe_name(name): 79b8e80941Smrg name = to_alphanum(name) 80b8e80941Smrg if not name[0].isalpha(): 81b8e80941Smrg name = '_' + name 82b8e80941Smrg 83b8e80941Smrg return name 84b8e80941Smrg 85b8e80941Smrgdef prefixed_upper_name(prefix, name): 86b8e80941Smrg if prefix: 87b8e80941Smrg name = prefix + "_" + name 88b8e80941Smrg return safe_name(name).upper() 89b8e80941Smrg 90b8e80941Smrgdef num_from_str(num_str): 91b8e80941Smrg if num_str.lower().startswith('0x'): 92b8e80941Smrg return int(num_str, base=16) 93b8e80941Smrg else: 94b8e80941Smrg assert(not num_str.startswith('0') and 'octals numbers not allowed') 95b8e80941Smrg return int(num_str) 96b8e80941Smrg 97b8e80941Smrgclass Field(object): 98b8e80941Smrg ufixed_pattern = re.compile(r"u(\d+)\.(\d+)") 99b8e80941Smrg sfixed_pattern = re.compile(r"s(\d+)\.(\d+)") 100b8e80941Smrg 101b8e80941Smrg def __init__(self, parser, attrs): 102b8e80941Smrg self.parser = parser 103b8e80941Smrg if "name" in attrs: 104b8e80941Smrg self.name = safe_name(attrs["name"]).lower() 105b8e80941Smrg 106b8e80941Smrg if str(attrs["start"]).endswith("b"): 107b8e80941Smrg self.start = int(attrs["start"][:-1]) * 8 108b8e80941Smrg else: 109b8e80941Smrg self.start = int(attrs["start"]) 110b8e80941Smrg # packet <field> entries in XML start from the bit after the 111b8e80941Smrg # opcode, so shift everything up by 8 since we'll also have a 112b8e80941Smrg # Field for the opcode. 113b8e80941Smrg if not parser.struct: 114b8e80941Smrg self.start += 8 115b8e80941Smrg 116b8e80941Smrg self.end = self.start + int(attrs["size"]) - 1 117b8e80941Smrg self.type = attrs["type"] 118b8e80941Smrg 119b8e80941Smrg if self.type == 'bool' and self.start != self.end: 120b8e80941Smrg print("#error Field {} has bool type but more than one bit of size".format(self.name)); 121b8e80941Smrg 122b8e80941Smrg if "prefix" in attrs: 123b8e80941Smrg self.prefix = safe_name(attrs["prefix"]).upper() 124b8e80941Smrg else: 125b8e80941Smrg self.prefix = None 126b8e80941Smrg 127b8e80941Smrg if "default" in attrs: 128b8e80941Smrg self.default = int(attrs["default"]) 129b8e80941Smrg else: 130b8e80941Smrg self.default = None 131b8e80941Smrg 132b8e80941Smrg if "minus_one" in attrs: 133b8e80941Smrg assert(attrs["minus_one"] == "true") 134b8e80941Smrg self.minus_one = True 135b8e80941Smrg else: 136b8e80941Smrg self.minus_one = False 137b8e80941Smrg 138b8e80941Smrg ufixed_match = Field.ufixed_pattern.match(self.type) 139b8e80941Smrg if ufixed_match: 140b8e80941Smrg self.type = 'ufixed' 141b8e80941Smrg self.fractional_size = int(ufixed_match.group(2)) 142b8e80941Smrg 143b8e80941Smrg sfixed_match = Field.sfixed_pattern.match(self.type) 144b8e80941Smrg if sfixed_match: 145b8e80941Smrg self.type = 'sfixed' 146b8e80941Smrg self.fractional_size = int(sfixed_match.group(2)) 147b8e80941Smrg 148b8e80941Smrg def emit_template_struct(self, dim): 149b8e80941Smrg if self.type == 'address': 150b8e80941Smrg type = '__gen_address_type' 151b8e80941Smrg elif self.type == 'bool': 152b8e80941Smrg type = 'bool' 153b8e80941Smrg elif self.type == 'float': 154b8e80941Smrg type = 'float' 155b8e80941Smrg elif self.type == 'f187': 156b8e80941Smrg type = 'float' 157b8e80941Smrg elif self.type == 'ufixed': 158b8e80941Smrg type = 'float' 159b8e80941Smrg elif self.type == 'sfixed': 160b8e80941Smrg type = 'float' 161b8e80941Smrg elif self.type == 'uint' and self.end - self.start > 32: 162b8e80941Smrg type = 'uint64_t' 163b8e80941Smrg elif self.type == 'offset': 164b8e80941Smrg type = 'uint64_t' 165b8e80941Smrg elif self.type == 'int': 166b8e80941Smrg type = 'int32_t' 167b8e80941Smrg elif self.type == 'uint': 168b8e80941Smrg type = 'uint32_t' 169b8e80941Smrg elif self.type in self.parser.structs: 170b8e80941Smrg type = 'struct ' + self.parser.gen_prefix(safe_name(self.type)) 171b8e80941Smrg elif self.type in self.parser.enums: 172b8e80941Smrg type = 'enum ' + self.parser.gen_prefix(safe_name(self.type)) 173b8e80941Smrg elif self.type == 'mbo': 174b8e80941Smrg return 175b8e80941Smrg else: 176b8e80941Smrg print("#error unhandled type: %s" % self.type) 177b8e80941Smrg type = "uint32_t" 178b8e80941Smrg 179b8e80941Smrg print(" %-36s %s%s;" % (type, self.name, dim)) 180b8e80941Smrg 181b8e80941Smrg for value in self.values: 182b8e80941Smrg name = prefixed_upper_name(self.prefix, value.name) 183b8e80941Smrg print("#define %-40s %d" % (name, value.value)) 184b8e80941Smrg 185b8e80941Smrg def overlaps(self, field): 186b8e80941Smrg return self != field and max(self.start, field.start) <= min(self.end, field.end) 187b8e80941Smrg 188b8e80941Smrg 189b8e80941Smrgclass Group(object): 190b8e80941Smrg def __init__(self, parser, parent, start, count): 191b8e80941Smrg self.parser = parser 192b8e80941Smrg self.parent = parent 193b8e80941Smrg self.start = start 194b8e80941Smrg self.count = count 195b8e80941Smrg self.size = 0 196b8e80941Smrg self.fields = [] 197b8e80941Smrg self.min_ver = 0 198b8e80941Smrg self.max_ver = 0 199b8e80941Smrg 200b8e80941Smrg def emit_template_struct(self, dim): 201b8e80941Smrg if self.count == 0: 202b8e80941Smrg print(" /* variable length fields follow */") 203b8e80941Smrg else: 204b8e80941Smrg if self.count > 1: 205b8e80941Smrg dim = "%s[%d]" % (dim, self.count) 206b8e80941Smrg 207b8e80941Smrg for field in self.fields: 208b8e80941Smrg field.emit_template_struct(dim) 209b8e80941Smrg 210b8e80941Smrg class Byte: 211b8e80941Smrg def __init__(self): 212b8e80941Smrg self.size = 8 213b8e80941Smrg self.fields = [] 214b8e80941Smrg self.address = None 215b8e80941Smrg 216b8e80941Smrg def collect_bytes(self, bytes): 217b8e80941Smrg for field in self.fields: 218b8e80941Smrg first_byte = field.start // 8 219b8e80941Smrg last_byte = field.end // 8 220b8e80941Smrg 221b8e80941Smrg for b in range(first_byte, last_byte + 1): 222b8e80941Smrg if not b in bytes: 223b8e80941Smrg bytes[b] = self.Byte() 224b8e80941Smrg 225b8e80941Smrg bytes[b].fields.append(field) 226b8e80941Smrg 227b8e80941Smrg if field.type == "address": 228b8e80941Smrg # assert bytes[index].address == None 229b8e80941Smrg bytes[b].address = field 230b8e80941Smrg 231b8e80941Smrg def emit_pack_function(self, start): 232b8e80941Smrg # Determine number of bytes in this group. 233b8e80941Smrg self.length = max(field.end // 8 for field in self.fields) + 1 234b8e80941Smrg 235b8e80941Smrg bytes = {} 236b8e80941Smrg self.collect_bytes(bytes) 237b8e80941Smrg 238b8e80941Smrg relocs_emitted = set() 239b8e80941Smrg memcpy_fields = set() 240b8e80941Smrg 241b8e80941Smrg for field in self.fields: 242b8e80941Smrg if field.minus_one: 243b8e80941Smrg print(" assert(values->%s >= 1);" % field.name) 244b8e80941Smrg 245b8e80941Smrg for index in range(self.length): 246b8e80941Smrg # Handle MBZ bytes 247b8e80941Smrg if not index in bytes: 248b8e80941Smrg print(" cl[%2d] = 0;" % index) 249b8e80941Smrg continue 250b8e80941Smrg byte = bytes[index] 251b8e80941Smrg 252b8e80941Smrg # Call out to the driver to note our relocations. Inside of the 253b8e80941Smrg # packet we only store offsets within the BOs, and we store the 254b8e80941Smrg # handle to the packet outside. Unlike Intel genxml, we don't 255b8e80941Smrg # need to have the other bits that will be stored together with 256b8e80941Smrg # the address during the reloc process, so there's no need for the 257b8e80941Smrg # complicated combine_address() function. 258b8e80941Smrg if byte.address and byte.address not in relocs_emitted: 259b8e80941Smrg print(" __gen_emit_reloc(data, &values->%s);" % byte.address.name) 260b8e80941Smrg relocs_emitted.add(byte.address) 261b8e80941Smrg 262b8e80941Smrg # Special case: floats can't have any other fields packed into 263b8e80941Smrg # them (since they'd change the meaning of the float), and the 264b8e80941Smrg # per-byte bitshifting math below bloats the pack code for floats, 265b8e80941Smrg # so just copy them directly here. Also handle 16/32-bit 266b8e80941Smrg # uints/ints with no merged fields. 267b8e80941Smrg if len(byte.fields) == 1: 268b8e80941Smrg field = byte.fields[0] 269b8e80941Smrg if field.type in ["float", "uint", "int"] and field.start % 8 == 0 and field.end - field.start == 31 and not field.minus_one: 270b8e80941Smrg if field in memcpy_fields: 271b8e80941Smrg continue 272b8e80941Smrg 273b8e80941Smrg if not any(field.overlaps(scan_field) for scan_field in self.fields): 274b8e80941Smrg assert(field.start == index * 8) 275b8e80941Smrg print("") 276b8e80941Smrg print(" memcpy(&cl[%d], &values->%s, sizeof(values->%s));" % 277b8e80941Smrg (index, field.name, field.name)) 278b8e80941Smrg memcpy_fields.add(field) 279b8e80941Smrg continue 280b8e80941Smrg 281b8e80941Smrg byte_start = index * 8 282b8e80941Smrg 283b8e80941Smrg v = None 284b8e80941Smrg prefix = " cl[%2d] =" % index 285b8e80941Smrg 286b8e80941Smrg field_index = 0 287b8e80941Smrg for field in byte.fields: 288b8e80941Smrg if field.type != "mbo": 289b8e80941Smrg name = field.name 290b8e80941Smrg 291b8e80941Smrg start = field.start 292b8e80941Smrg end = field.end 293b8e80941Smrg field_byte_start = (field.start // 8) * 8 294b8e80941Smrg start -= field_byte_start 295b8e80941Smrg end -= field_byte_start 296b8e80941Smrg extra_shift = 0 297b8e80941Smrg 298b8e80941Smrg value = "values->%s" % name 299b8e80941Smrg if field.minus_one: 300b8e80941Smrg value = "%s - 1" % value 301b8e80941Smrg 302b8e80941Smrg if field.type == "mbo": 303b8e80941Smrg s = "__gen_mbo(%d, %d)" % \ 304b8e80941Smrg (start, end) 305b8e80941Smrg elif field.type == "address": 306b8e80941Smrg extra_shift = (31 - (end - start)) // 8 * 8 307b8e80941Smrg s = "__gen_address_offset(&values->%s)" % byte.address.name 308b8e80941Smrg elif field.type == "uint": 309b8e80941Smrg s = "__gen_uint(%s, %d, %d)" % \ 310b8e80941Smrg (value, start, end) 311b8e80941Smrg elif field.type in self.parser.enums: 312b8e80941Smrg s = "__gen_uint(%s, %d, %d)" % \ 313b8e80941Smrg (value, start, end) 314b8e80941Smrg elif field.type == "int": 315b8e80941Smrg s = "__gen_sint(%s, %d, %d)" % \ 316b8e80941Smrg (value, start, end) 317b8e80941Smrg elif field.type == "bool": 318b8e80941Smrg s = "__gen_uint(%s, %d, %d)" % \ 319b8e80941Smrg (value, start, end) 320b8e80941Smrg elif field.type == "float": 321b8e80941Smrg s = "#error %s float value mixed in with other fields" % name 322b8e80941Smrg elif field.type == "f187": 323b8e80941Smrg s = "__gen_uint(fui(%s) >> 16, %d, %d)" % \ 324b8e80941Smrg (value, start, end) 325b8e80941Smrg elif field.type == "offset": 326b8e80941Smrg s = "__gen_offset(%s, %d, %d)" % \ 327b8e80941Smrg (value, start, end) 328b8e80941Smrg elif field.type == 'ufixed': 329b8e80941Smrg s = "__gen_ufixed(%s, %d, %d, %d)" % \ 330b8e80941Smrg (value, start, end, field.fractional_size) 331b8e80941Smrg elif field.type == 'sfixed': 332b8e80941Smrg s = "__gen_sfixed(%s, %d, %d, %d)" % \ 333b8e80941Smrg (value, start, end, field.fractional_size) 334b8e80941Smrg elif field.type in self.parser.structs: 335b8e80941Smrg s = "__gen_uint(v%d_%d, %d, %d)" % \ 336b8e80941Smrg (index, field_index, start, end) 337b8e80941Smrg field_index = field_index + 1 338b8e80941Smrg else: 339b8e80941Smrg print("/* unhandled field %s, type %s */\n" % (name, field.type)) 340b8e80941Smrg s = None 341b8e80941Smrg 342b8e80941Smrg if not s == None: 343b8e80941Smrg shift = byte_start - field_byte_start + extra_shift 344b8e80941Smrg if shift: 345b8e80941Smrg s = "%s >> %d" % (s, shift) 346b8e80941Smrg 347b8e80941Smrg if field == byte.fields[-1]: 348b8e80941Smrg print("%s %s;" % (prefix, s)) 349b8e80941Smrg else: 350b8e80941Smrg print("%s %s |" % (prefix, s)) 351b8e80941Smrg prefix = " " 352b8e80941Smrg 353b8e80941Smrg print("") 354b8e80941Smrg continue 355b8e80941Smrg 356b8e80941Smrg def emit_unpack_function(self, start): 357b8e80941Smrg for field in self.fields: 358b8e80941Smrg if field.type != "mbo": 359b8e80941Smrg convert = None 360b8e80941Smrg 361b8e80941Smrg args = [] 362b8e80941Smrg args.append('cl') 363b8e80941Smrg args.append(str(start + field.start)) 364b8e80941Smrg args.append(str(start + field.end)) 365b8e80941Smrg 366b8e80941Smrg if field.type == "address": 367b8e80941Smrg convert = "__gen_unpack_address" 368b8e80941Smrg elif field.type == "uint": 369b8e80941Smrg convert = "__gen_unpack_uint" 370b8e80941Smrg elif field.type in self.parser.enums: 371b8e80941Smrg convert = "__gen_unpack_uint" 372b8e80941Smrg elif field.type == "int": 373b8e80941Smrg convert = "__gen_unpack_sint" 374b8e80941Smrg elif field.type == "bool": 375b8e80941Smrg convert = "__gen_unpack_uint" 376b8e80941Smrg elif field.type == "float": 377b8e80941Smrg convert = "__gen_unpack_float" 378b8e80941Smrg elif field.type == "f187": 379b8e80941Smrg convert = "__gen_unpack_f187" 380b8e80941Smrg elif field.type == "offset": 381b8e80941Smrg convert = "__gen_unpack_offset" 382b8e80941Smrg elif field.type == 'ufixed': 383b8e80941Smrg args.append(str(field.fractional_size)) 384b8e80941Smrg convert = "__gen_unpack_ufixed" 385b8e80941Smrg elif field.type == 'sfixed': 386b8e80941Smrg args.append(str(field.fractional_size)) 387b8e80941Smrg convert = "__gen_unpack_sfixed" 388b8e80941Smrg else: 389b8e80941Smrg print("/* unhandled field %s, type %s */\n" % (field.name, field.type)) 390b8e80941Smrg s = None 391b8e80941Smrg 392b8e80941Smrg plusone = "" 393b8e80941Smrg if field.minus_one: 394b8e80941Smrg plusone = " + 1" 395b8e80941Smrg print(" values->%s = %s(%s)%s;" % \ 396b8e80941Smrg (field.name, convert, ', '.join(args), plusone)) 397b8e80941Smrg 398b8e80941Smrgclass Value(object): 399b8e80941Smrg def __init__(self, attrs): 400b8e80941Smrg self.name = attrs["name"] 401b8e80941Smrg self.value = int(attrs["value"]) 402b8e80941Smrg 403b8e80941Smrgclass Parser(object): 404b8e80941Smrg def __init__(self, ver): 405b8e80941Smrg self.parser = xml.parsers.expat.ParserCreate() 406b8e80941Smrg self.parser.StartElementHandler = self.start_element 407b8e80941Smrg self.parser.EndElementHandler = self.end_element 408b8e80941Smrg 409b8e80941Smrg self.packet = None 410b8e80941Smrg self.struct = None 411b8e80941Smrg self.structs = {} 412b8e80941Smrg # Set of enum names we've seen. 413b8e80941Smrg self.enums = set() 414b8e80941Smrg self.registers = {} 415b8e80941Smrg self.ver = ver 416b8e80941Smrg 417b8e80941Smrg def gen_prefix(self, name): 418b8e80941Smrg if name[0] == "_": 419b8e80941Smrg return 'V3D%s%s' % (self.ver, name) 420b8e80941Smrg else: 421b8e80941Smrg return 'V3D%s_%s' % (self.ver, name) 422b8e80941Smrg 423b8e80941Smrg def gen_guard(self): 424b8e80941Smrg return self.gen_prefix("PACK_H") 425b8e80941Smrg 426b8e80941Smrg def attrs_version_valid(self, attrs): 427b8e80941Smrg if "min_ver" in attrs and self.ver < attrs["min_ver"]: 428b8e80941Smrg return False 429b8e80941Smrg 430b8e80941Smrg if "max_ver" in attrs and self.ver > attrs["max_ver"]: 431b8e80941Smrg return False 432b8e80941Smrg 433b8e80941Smrg return True 434b8e80941Smrg 435b8e80941Smrg def group_enabled(self): 436b8e80941Smrg if self.group.min_ver != 0 and self.ver < self.group.min_ver: 437b8e80941Smrg return False 438b8e80941Smrg 439b8e80941Smrg if self.group.max_ver != 0 and self.ver > self.group.max_ver: 440b8e80941Smrg return False 441b8e80941Smrg 442b8e80941Smrg return True 443b8e80941Smrg 444b8e80941Smrg def start_element(self, name, attrs): 445b8e80941Smrg if name == "vcxml": 446b8e80941Smrg self.platform = "V3D {}.{}".format(self.ver[0], self.ver[1]) 447b8e80941Smrg print(pack_header % {'license': license, 'platform': self.platform, 'guard': self.gen_guard()}) 448b8e80941Smrg elif name in ("packet", "struct", "register"): 449b8e80941Smrg default_field = None 450b8e80941Smrg 451b8e80941Smrg object_name = self.gen_prefix(safe_name(attrs["name"].upper())) 452b8e80941Smrg if name == "packet": 453b8e80941Smrg self.packet = object_name 454b8e80941Smrg 455b8e80941Smrg # Add a fixed Field for the opcode. We only make <field>s in 456b8e80941Smrg # the XML for the fields listed in the spec, and all of those 457b8e80941Smrg # start from bit 0 after of the opcode. 458b8e80941Smrg default_field = { 459b8e80941Smrg "name" : "opcode", 460b8e80941Smrg "default" : attrs["code"], 461b8e80941Smrg "type" : "uint", 462b8e80941Smrg "start" : -8, 463b8e80941Smrg "size" : 8, 464b8e80941Smrg } 465b8e80941Smrg elif name == "struct": 466b8e80941Smrg self.struct = object_name 467b8e80941Smrg self.structs[attrs["name"]] = 1 468b8e80941Smrg elif name == "register": 469b8e80941Smrg self.register = object_name 470b8e80941Smrg self.reg_num = num_from_str(attrs["num"]) 471b8e80941Smrg self.registers[attrs["name"]] = 1 472b8e80941Smrg 473b8e80941Smrg self.group = Group(self, None, 0, 1) 474b8e80941Smrg if default_field: 475b8e80941Smrg field = Field(self, default_field) 476b8e80941Smrg field.values = [] 477b8e80941Smrg self.group.fields.append(field) 478b8e80941Smrg 479b8e80941Smrg if "min_ver" in attrs: 480b8e80941Smrg self.group.min_ver = attrs["min_ver"] 481b8e80941Smrg if "max_ver" in attrs: 482b8e80941Smrg self.group.max_ver = attrs["max_ver"] 483b8e80941Smrg 484b8e80941Smrg elif name == "field": 485b8e80941Smrg self.group.fields.append(Field(self, attrs)) 486b8e80941Smrg self.values = [] 487b8e80941Smrg elif name == "enum": 488b8e80941Smrg self.values = [] 489b8e80941Smrg self.enum = safe_name(attrs["name"]) 490b8e80941Smrg self.enums.add(attrs["name"]) 491b8e80941Smrg self.enum_enabled = self.attrs_version_valid(attrs) 492b8e80941Smrg if "prefix" in attrs: 493b8e80941Smrg self.prefix = attrs["prefix"] 494b8e80941Smrg else: 495b8e80941Smrg self.prefix= None 496b8e80941Smrg elif name == "value": 497b8e80941Smrg if self.attrs_version_valid(attrs): 498b8e80941Smrg self.values.append(Value(attrs)) 499b8e80941Smrg 500b8e80941Smrg def end_element(self, name): 501b8e80941Smrg if name == "packet": 502b8e80941Smrg self.emit_packet() 503b8e80941Smrg self.packet = None 504b8e80941Smrg self.group = None 505b8e80941Smrg elif name == "struct": 506b8e80941Smrg self.emit_struct() 507b8e80941Smrg self.struct = None 508b8e80941Smrg self.group = None 509b8e80941Smrg elif name == "register": 510b8e80941Smrg self.emit_register() 511b8e80941Smrg self.register = None 512b8e80941Smrg self.reg_num = None 513b8e80941Smrg self.group = None 514b8e80941Smrg elif name == "field": 515b8e80941Smrg self.group.fields[-1].values = self.values 516b8e80941Smrg elif name == "enum": 517b8e80941Smrg if self.enum_enabled: 518b8e80941Smrg self.emit_enum() 519b8e80941Smrg self.enum = None 520b8e80941Smrg elif name == "vcxml": 521b8e80941Smrg print('#endif /* %s */' % self.gen_guard()) 522b8e80941Smrg 523b8e80941Smrg def emit_template_struct(self, name, group): 524b8e80941Smrg print("struct %s {" % name) 525b8e80941Smrg group.emit_template_struct("") 526b8e80941Smrg print("};\n") 527b8e80941Smrg 528b8e80941Smrg def emit_pack_function(self, name, group): 529b8e80941Smrg print("static inline void\n%s_pack(__gen_user_data *data, uint8_t * restrict cl,\n%sconst struct %s * restrict values)\n{" % 530b8e80941Smrg (name, ' ' * (len(name) + 6), name)) 531b8e80941Smrg 532b8e80941Smrg group.emit_pack_function(0) 533b8e80941Smrg 534b8e80941Smrg print("}\n") 535b8e80941Smrg 536b8e80941Smrg print('#define %-33s %6d' % 537b8e80941Smrg (name + "_length", self.group.length)) 538b8e80941Smrg 539b8e80941Smrg def emit_unpack_function(self, name, group): 540b8e80941Smrg print("#ifdef __gen_unpack_address") 541b8e80941Smrg print("static inline void") 542b8e80941Smrg print("%s_unpack(const uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" % 543b8e80941Smrg (name, ' ' * (len(name) + 8), name)) 544b8e80941Smrg 545b8e80941Smrg group.emit_unpack_function(0) 546b8e80941Smrg 547b8e80941Smrg print("}\n#endif\n") 548b8e80941Smrg 549b8e80941Smrg def emit_header(self, name): 550b8e80941Smrg default_fields = [] 551b8e80941Smrg for field in self.group.fields: 552b8e80941Smrg if not type(field) is Field: 553b8e80941Smrg continue 554b8e80941Smrg if field.default == None: 555b8e80941Smrg continue 556b8e80941Smrg default_fields.append(" .%-35s = %6d" % (field.name, field.default)) 557b8e80941Smrg 558b8e80941Smrg print('#define %-40s\\' % (name + '_header')) 559b8e80941Smrg print(", \\\n".join(default_fields)) 560b8e80941Smrg print('') 561b8e80941Smrg 562b8e80941Smrg def emit_packet(self): 563b8e80941Smrg if not self.group_enabled(): 564b8e80941Smrg return 565b8e80941Smrg 566b8e80941Smrg name = self.packet 567b8e80941Smrg 568b8e80941Smrg assert(self.group.fields[0].name == "opcode") 569b8e80941Smrg print('#define %-33s %6d' % 570b8e80941Smrg (name + "_opcode", self.group.fields[0].default)) 571b8e80941Smrg 572b8e80941Smrg self.emit_header(name) 573b8e80941Smrg self.emit_template_struct(self.packet, self.group) 574b8e80941Smrg self.emit_pack_function(self.packet, self.group) 575b8e80941Smrg self.emit_unpack_function(self.packet, self.group) 576b8e80941Smrg 577b8e80941Smrg print('') 578b8e80941Smrg 579b8e80941Smrg def emit_register(self): 580b8e80941Smrg if not self.group_enabled(): 581b8e80941Smrg return 582b8e80941Smrg 583b8e80941Smrg name = self.register 584b8e80941Smrg if not self.reg_num == None: 585b8e80941Smrg print('#define %-33s 0x%04x' % 586b8e80941Smrg (self.gen_prefix(name + "_num"), self.reg_num)) 587b8e80941Smrg 588b8e80941Smrg self.emit_template_struct(self.register, self.group) 589b8e80941Smrg self.emit_pack_function(self.register, self.group) 590b8e80941Smrg self.emit_unpack_function(self.register, self.group) 591b8e80941Smrg 592b8e80941Smrg def emit_struct(self): 593b8e80941Smrg if not self.group_enabled(): 594b8e80941Smrg return 595b8e80941Smrg 596b8e80941Smrg name = self.struct 597b8e80941Smrg 598b8e80941Smrg self.emit_header(name) 599b8e80941Smrg self.emit_template_struct(self.struct, self.group) 600b8e80941Smrg self.emit_pack_function(self.struct, self.group) 601b8e80941Smrg self.emit_unpack_function(self.struct, self.group) 602b8e80941Smrg 603b8e80941Smrg print('') 604b8e80941Smrg 605b8e80941Smrg def emit_enum(self): 606b8e80941Smrg print('enum %s {' % self.gen_prefix(self.enum)) 607b8e80941Smrg for value in self.values: 608b8e80941Smrg name = value.name 609b8e80941Smrg if self.prefix: 610b8e80941Smrg name = self.prefix + "_" + name 611b8e80941Smrg name = safe_name(name).upper() 612b8e80941Smrg print(' % -36s = %6d,' % (name, value.value)) 613b8e80941Smrg print('};\n') 614b8e80941Smrg 615b8e80941Smrg def parse(self, filename): 616b8e80941Smrg file = open(filename, "rb") 617b8e80941Smrg self.parser.ParseFile(file) 618b8e80941Smrg file.close() 619b8e80941Smrg 620b8e80941Smrgif len(sys.argv) < 2: 621b8e80941Smrg print("No input xml file specified") 622b8e80941Smrg sys.exit(1) 623b8e80941Smrg 624b8e80941Smrginput_file = sys.argv[1] 625b8e80941Smrg 626b8e80941Smrgp = Parser(sys.argv[2]) 627b8e80941Smrgp.parse(input_file) 628