101e04c3fSmrg#encoding=utf-8 201e04c3fSmrg 301e04c3fSmrg# Copyright (C) 2016 Intel Corporation 401e04c3fSmrg# Copyright (C) 2016 Broadcom 501e04c3fSmrg# 601e04c3fSmrg# Permission is hereby granted, free of charge, to any person obtaining a 701e04c3fSmrg# copy of this software and associated documentation files (the "Software"), 801e04c3fSmrg# to deal in the Software without restriction, including without limitation 901e04c3fSmrg# the rights to use, copy, modify, merge, publish, distribute, sublicense, 1001e04c3fSmrg# and/or sell copies of the Software, and to permit persons to whom the 1101e04c3fSmrg# Software is furnished to do so, subject to the following conditions: 1201e04c3fSmrg# 1301e04c3fSmrg# The above copyright notice and this permission notice (including the next 1401e04c3fSmrg# paragraph) shall be included in all copies or substantial portions of the 1501e04c3fSmrg# Software. 1601e04c3fSmrg# 1701e04c3fSmrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1801e04c3fSmrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1901e04c3fSmrg# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2001e04c3fSmrg# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2101e04c3fSmrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2201e04c3fSmrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2301e04c3fSmrg# IN THE SOFTWARE. 2401e04c3fSmrg 2501e04c3fSmrgimport xml.parsers.expat 2601e04c3fSmrgimport re 2701e04c3fSmrgimport sys 2801e04c3fSmrgimport copy 2901e04c3fSmrg 307ec681f3Smrglicense = """/* Generated code, see v3d_packet_v21.xml, v3d_packet_v33.xml and gen_pack_header.py */ 3101e04c3fSmrg""" 3201e04c3fSmrg 3301e04c3fSmrgpack_header = """%(license)s 3401e04c3fSmrg 3501e04c3fSmrg/* Packets, enums and structures for %(platform)s. 3601e04c3fSmrg * 3701e04c3fSmrg * This file has been generated, do not hand edit. 3801e04c3fSmrg */ 3901e04c3fSmrg 4001e04c3fSmrg#ifndef %(guard)s 4101e04c3fSmrg#define %(guard)s 4201e04c3fSmrg 4301e04c3fSmrg#include "cle/v3d_packet_helpers.h" 4401e04c3fSmrg 4501e04c3fSmrg""" 4601e04c3fSmrg 4701e04c3fSmrgdef to_alphanum(name): 4801e04c3fSmrg substitutions = { 4901e04c3fSmrg ' ': '_', 5001e04c3fSmrg '/': '_', 5101e04c3fSmrg '[': '', 5201e04c3fSmrg ']': '', 5301e04c3fSmrg '(': '', 5401e04c3fSmrg ')': '', 5501e04c3fSmrg '-': '_', 5601e04c3fSmrg ':': '', 5701e04c3fSmrg '.': '', 5801e04c3fSmrg ',': '', 5901e04c3fSmrg '=': '', 6001e04c3fSmrg '>': '', 6101e04c3fSmrg '#': '', 6201e04c3fSmrg '&': '', 6301e04c3fSmrg '*': '', 6401e04c3fSmrg '"': '', 6501e04c3fSmrg '+': '', 6601e04c3fSmrg '\'': '', 6701e04c3fSmrg } 6801e04c3fSmrg 6901e04c3fSmrg for i, j in substitutions.items(): 7001e04c3fSmrg name = name.replace(i, j) 7101e04c3fSmrg 7201e04c3fSmrg return name 7301e04c3fSmrg 7401e04c3fSmrgdef safe_name(name): 7501e04c3fSmrg name = to_alphanum(name) 7601e04c3fSmrg if not name[0].isalpha(): 7701e04c3fSmrg name = '_' + name 7801e04c3fSmrg 7901e04c3fSmrg return name 8001e04c3fSmrg 8101e04c3fSmrgdef prefixed_upper_name(prefix, name): 8201e04c3fSmrg if prefix: 8301e04c3fSmrg name = prefix + "_" + name 8401e04c3fSmrg return safe_name(name).upper() 8501e04c3fSmrg 8601e04c3fSmrgdef num_from_str(num_str): 8701e04c3fSmrg if num_str.lower().startswith('0x'): 8801e04c3fSmrg return int(num_str, base=16) 8901e04c3fSmrg else: 9001e04c3fSmrg assert(not num_str.startswith('0') and 'octals numbers not allowed') 9101e04c3fSmrg return int(num_str) 9201e04c3fSmrg 9301e04c3fSmrgclass Field(object): 9401e04c3fSmrg ufixed_pattern = re.compile(r"u(\d+)\.(\d+)") 9501e04c3fSmrg sfixed_pattern = re.compile(r"s(\d+)\.(\d+)") 9601e04c3fSmrg 9701e04c3fSmrg def __init__(self, parser, attrs): 9801e04c3fSmrg self.parser = parser 9901e04c3fSmrg if "name" in attrs: 10001e04c3fSmrg self.name = safe_name(attrs["name"]).lower() 10101e04c3fSmrg 10201e04c3fSmrg if str(attrs["start"]).endswith("b"): 10301e04c3fSmrg self.start = int(attrs["start"][:-1]) * 8 10401e04c3fSmrg else: 10501e04c3fSmrg self.start = int(attrs["start"]) 10601e04c3fSmrg # packet <field> entries in XML start from the bit after the 10701e04c3fSmrg # opcode, so shift everything up by 8 since we'll also have a 10801e04c3fSmrg # Field for the opcode. 10901e04c3fSmrg if not parser.struct: 11001e04c3fSmrg self.start += 8 11101e04c3fSmrg 11201e04c3fSmrg self.end = self.start + int(attrs["size"]) - 1 11301e04c3fSmrg self.type = attrs["type"] 11401e04c3fSmrg 11501e04c3fSmrg if self.type == 'bool' and self.start != self.end: 11601e04c3fSmrg print("#error Field {} has bool type but more than one bit of size".format(self.name)); 11701e04c3fSmrg 11801e04c3fSmrg if "prefix" in attrs: 11901e04c3fSmrg self.prefix = safe_name(attrs["prefix"]).upper() 12001e04c3fSmrg else: 12101e04c3fSmrg self.prefix = None 12201e04c3fSmrg 12301e04c3fSmrg if "default" in attrs: 12401e04c3fSmrg self.default = int(attrs["default"]) 12501e04c3fSmrg else: 12601e04c3fSmrg self.default = None 12701e04c3fSmrg 12801e04c3fSmrg if "minus_one" in attrs: 12901e04c3fSmrg assert(attrs["minus_one"] == "true") 13001e04c3fSmrg self.minus_one = True 13101e04c3fSmrg else: 13201e04c3fSmrg self.minus_one = False 13301e04c3fSmrg 13401e04c3fSmrg ufixed_match = Field.ufixed_pattern.match(self.type) 13501e04c3fSmrg if ufixed_match: 13601e04c3fSmrg self.type = 'ufixed' 13701e04c3fSmrg self.fractional_size = int(ufixed_match.group(2)) 13801e04c3fSmrg 13901e04c3fSmrg sfixed_match = Field.sfixed_pattern.match(self.type) 14001e04c3fSmrg if sfixed_match: 14101e04c3fSmrg self.type = 'sfixed' 14201e04c3fSmrg self.fractional_size = int(sfixed_match.group(2)) 14301e04c3fSmrg 14401e04c3fSmrg def emit_template_struct(self, dim): 14501e04c3fSmrg if self.type == 'address': 14601e04c3fSmrg type = '__gen_address_type' 14701e04c3fSmrg elif self.type == 'bool': 14801e04c3fSmrg type = 'bool' 14901e04c3fSmrg elif self.type == 'float': 15001e04c3fSmrg type = 'float' 15101e04c3fSmrg elif self.type == 'f187': 15201e04c3fSmrg type = 'float' 15301e04c3fSmrg elif self.type == 'ufixed': 15401e04c3fSmrg type = 'float' 15501e04c3fSmrg elif self.type == 'sfixed': 15601e04c3fSmrg type = 'float' 15701e04c3fSmrg elif self.type == 'uint' and self.end - self.start > 32: 15801e04c3fSmrg type = 'uint64_t' 15901e04c3fSmrg elif self.type == 'offset': 16001e04c3fSmrg type = 'uint64_t' 16101e04c3fSmrg elif self.type == 'int': 16201e04c3fSmrg type = 'int32_t' 16301e04c3fSmrg elif self.type == 'uint': 16401e04c3fSmrg type = 'uint32_t' 16501e04c3fSmrg elif self.type in self.parser.structs: 16601e04c3fSmrg type = 'struct ' + self.parser.gen_prefix(safe_name(self.type)) 16701e04c3fSmrg elif self.type in self.parser.enums: 16801e04c3fSmrg type = 'enum ' + self.parser.gen_prefix(safe_name(self.type)) 16901e04c3fSmrg elif self.type == 'mbo': 17001e04c3fSmrg return 17101e04c3fSmrg else: 17201e04c3fSmrg print("#error unhandled type: %s" % self.type) 17301e04c3fSmrg type = "uint32_t" 17401e04c3fSmrg 17501e04c3fSmrg print(" %-36s %s%s;" % (type, self.name, dim)) 17601e04c3fSmrg 17701e04c3fSmrg for value in self.values: 17801e04c3fSmrg name = prefixed_upper_name(self.prefix, value.name) 17901e04c3fSmrg print("#define %-40s %d" % (name, value.value)) 18001e04c3fSmrg 18101e04c3fSmrg def overlaps(self, field): 18201e04c3fSmrg return self != field and max(self.start, field.start) <= min(self.end, field.end) 18301e04c3fSmrg 18401e04c3fSmrg 18501e04c3fSmrgclass Group(object): 18601e04c3fSmrg def __init__(self, parser, parent, start, count): 18701e04c3fSmrg self.parser = parser 18801e04c3fSmrg self.parent = parent 18901e04c3fSmrg self.start = start 19001e04c3fSmrg self.count = count 19101e04c3fSmrg self.size = 0 19201e04c3fSmrg self.fields = [] 19301e04c3fSmrg self.min_ver = 0 19401e04c3fSmrg self.max_ver = 0 19501e04c3fSmrg 19601e04c3fSmrg def emit_template_struct(self, dim): 19701e04c3fSmrg if self.count == 0: 19801e04c3fSmrg print(" /* variable length fields follow */") 19901e04c3fSmrg else: 20001e04c3fSmrg if self.count > 1: 20101e04c3fSmrg dim = "%s[%d]" % (dim, self.count) 20201e04c3fSmrg 20301e04c3fSmrg for field in self.fields: 20401e04c3fSmrg field.emit_template_struct(dim) 20501e04c3fSmrg 20601e04c3fSmrg class Byte: 20701e04c3fSmrg def __init__(self): 20801e04c3fSmrg self.size = 8 20901e04c3fSmrg self.fields = [] 21001e04c3fSmrg self.address = None 21101e04c3fSmrg 21201e04c3fSmrg def collect_bytes(self, bytes): 21301e04c3fSmrg for field in self.fields: 21401e04c3fSmrg first_byte = field.start // 8 21501e04c3fSmrg last_byte = field.end // 8 21601e04c3fSmrg 21701e04c3fSmrg for b in range(first_byte, last_byte + 1): 21801e04c3fSmrg if not b in bytes: 21901e04c3fSmrg bytes[b] = self.Byte() 22001e04c3fSmrg 22101e04c3fSmrg bytes[b].fields.append(field) 22201e04c3fSmrg 22301e04c3fSmrg if field.type == "address": 22401e04c3fSmrg # assert bytes[index].address == None 22501e04c3fSmrg bytes[b].address = field 22601e04c3fSmrg 22701e04c3fSmrg def emit_pack_function(self, start): 22801e04c3fSmrg # Determine number of bytes in this group. 22901e04c3fSmrg self.length = max(field.end // 8 for field in self.fields) + 1 23001e04c3fSmrg 23101e04c3fSmrg bytes = {} 23201e04c3fSmrg self.collect_bytes(bytes) 23301e04c3fSmrg 23401e04c3fSmrg relocs_emitted = set() 23501e04c3fSmrg memcpy_fields = set() 23601e04c3fSmrg 23701e04c3fSmrg for field in self.fields: 23801e04c3fSmrg if field.minus_one: 23901e04c3fSmrg print(" assert(values->%s >= 1);" % field.name) 24001e04c3fSmrg 24101e04c3fSmrg for index in range(self.length): 24201e04c3fSmrg # Handle MBZ bytes 24301e04c3fSmrg if not index in bytes: 24401e04c3fSmrg print(" cl[%2d] = 0;" % index) 24501e04c3fSmrg continue 24601e04c3fSmrg byte = bytes[index] 24701e04c3fSmrg 24801e04c3fSmrg # Call out to the driver to note our relocations. Inside of the 24901e04c3fSmrg # packet we only store offsets within the BOs, and we store the 25001e04c3fSmrg # handle to the packet outside. Unlike Intel genxml, we don't 25101e04c3fSmrg # need to have the other bits that will be stored together with 25201e04c3fSmrg # the address during the reloc process, so there's no need for the 25301e04c3fSmrg # complicated combine_address() function. 25401e04c3fSmrg if byte.address and byte.address not in relocs_emitted: 25501e04c3fSmrg print(" __gen_emit_reloc(data, &values->%s);" % byte.address.name) 25601e04c3fSmrg relocs_emitted.add(byte.address) 25701e04c3fSmrg 25801e04c3fSmrg # Special case: floats can't have any other fields packed into 25901e04c3fSmrg # them (since they'd change the meaning of the float), and the 26001e04c3fSmrg # per-byte bitshifting math below bloats the pack code for floats, 26101e04c3fSmrg # so just copy them directly here. Also handle 16/32-bit 26201e04c3fSmrg # uints/ints with no merged fields. 26301e04c3fSmrg if len(byte.fields) == 1: 26401e04c3fSmrg field = byte.fields[0] 26501e04c3fSmrg if field.type in ["float", "uint", "int"] and field.start % 8 == 0 and field.end - field.start == 31 and not field.minus_one: 26601e04c3fSmrg if field in memcpy_fields: 26701e04c3fSmrg continue 26801e04c3fSmrg 26901e04c3fSmrg if not any(field.overlaps(scan_field) for scan_field in self.fields): 27001e04c3fSmrg assert(field.start == index * 8) 27101e04c3fSmrg print("") 27201e04c3fSmrg print(" memcpy(&cl[%d], &values->%s, sizeof(values->%s));" % 27301e04c3fSmrg (index, field.name, field.name)) 27401e04c3fSmrg memcpy_fields.add(field) 27501e04c3fSmrg continue 27601e04c3fSmrg 27701e04c3fSmrg byte_start = index * 8 27801e04c3fSmrg 27901e04c3fSmrg v = None 28001e04c3fSmrg prefix = " cl[%2d] =" % index 28101e04c3fSmrg 28201e04c3fSmrg field_index = 0 28301e04c3fSmrg for field in byte.fields: 28401e04c3fSmrg if field.type != "mbo": 28501e04c3fSmrg name = field.name 28601e04c3fSmrg 28701e04c3fSmrg start = field.start 28801e04c3fSmrg end = field.end 28901e04c3fSmrg field_byte_start = (field.start // 8) * 8 29001e04c3fSmrg start -= field_byte_start 29101e04c3fSmrg end -= field_byte_start 29201e04c3fSmrg extra_shift = 0 29301e04c3fSmrg 29401e04c3fSmrg value = "values->%s" % name 29501e04c3fSmrg if field.minus_one: 29601e04c3fSmrg value = "%s - 1" % value 29701e04c3fSmrg 29801e04c3fSmrg if field.type == "mbo": 29901e04c3fSmrg s = "__gen_mbo(%d, %d)" % \ 30001e04c3fSmrg (start, end) 30101e04c3fSmrg elif field.type == "address": 30201e04c3fSmrg extra_shift = (31 - (end - start)) // 8 * 8 30301e04c3fSmrg s = "__gen_address_offset(&values->%s)" % byte.address.name 30401e04c3fSmrg elif field.type == "uint": 30501e04c3fSmrg s = "__gen_uint(%s, %d, %d)" % \ 30601e04c3fSmrg (value, start, end) 30701e04c3fSmrg elif field.type in self.parser.enums: 30801e04c3fSmrg s = "__gen_uint(%s, %d, %d)" % \ 30901e04c3fSmrg (value, start, end) 31001e04c3fSmrg elif field.type == "int": 31101e04c3fSmrg s = "__gen_sint(%s, %d, %d)" % \ 31201e04c3fSmrg (value, start, end) 31301e04c3fSmrg elif field.type == "bool": 31401e04c3fSmrg s = "__gen_uint(%s, %d, %d)" % \ 31501e04c3fSmrg (value, start, end) 31601e04c3fSmrg elif field.type == "float": 31701e04c3fSmrg s = "#error %s float value mixed in with other fields" % name 31801e04c3fSmrg elif field.type == "f187": 31901e04c3fSmrg s = "__gen_uint(fui(%s) >> 16, %d, %d)" % \ 32001e04c3fSmrg (value, start, end) 32101e04c3fSmrg elif field.type == "offset": 32201e04c3fSmrg s = "__gen_offset(%s, %d, %d)" % \ 32301e04c3fSmrg (value, start, end) 32401e04c3fSmrg elif field.type == 'ufixed': 32501e04c3fSmrg s = "__gen_ufixed(%s, %d, %d, %d)" % \ 32601e04c3fSmrg (value, start, end, field.fractional_size) 32701e04c3fSmrg elif field.type == 'sfixed': 32801e04c3fSmrg s = "__gen_sfixed(%s, %d, %d, %d)" % \ 32901e04c3fSmrg (value, start, end, field.fractional_size) 33001e04c3fSmrg elif field.type in self.parser.structs: 33101e04c3fSmrg s = "__gen_uint(v%d_%d, %d, %d)" % \ 33201e04c3fSmrg (index, field_index, start, end) 33301e04c3fSmrg field_index = field_index + 1 33401e04c3fSmrg else: 33501e04c3fSmrg print("/* unhandled field %s, type %s */\n" % (name, field.type)) 33601e04c3fSmrg s = None 33701e04c3fSmrg 33801e04c3fSmrg if not s == None: 33901e04c3fSmrg shift = byte_start - field_byte_start + extra_shift 34001e04c3fSmrg if shift: 34101e04c3fSmrg s = "%s >> %d" % (s, shift) 34201e04c3fSmrg 34301e04c3fSmrg if field == byte.fields[-1]: 34401e04c3fSmrg print("%s %s;" % (prefix, s)) 34501e04c3fSmrg else: 34601e04c3fSmrg print("%s %s |" % (prefix, s)) 34701e04c3fSmrg prefix = " " 34801e04c3fSmrg 34901e04c3fSmrg print("") 35001e04c3fSmrg continue 35101e04c3fSmrg 35201e04c3fSmrg def emit_unpack_function(self, start): 35301e04c3fSmrg for field in self.fields: 35401e04c3fSmrg if field.type != "mbo": 35501e04c3fSmrg convert = None 35601e04c3fSmrg 35701e04c3fSmrg args = [] 35801e04c3fSmrg args.append('cl') 35901e04c3fSmrg args.append(str(start + field.start)) 36001e04c3fSmrg args.append(str(start + field.end)) 36101e04c3fSmrg 36201e04c3fSmrg if field.type == "address": 36301e04c3fSmrg convert = "__gen_unpack_address" 36401e04c3fSmrg elif field.type == "uint": 36501e04c3fSmrg convert = "__gen_unpack_uint" 36601e04c3fSmrg elif field.type in self.parser.enums: 36701e04c3fSmrg convert = "__gen_unpack_uint" 36801e04c3fSmrg elif field.type == "int": 36901e04c3fSmrg convert = "__gen_unpack_sint" 37001e04c3fSmrg elif field.type == "bool": 37101e04c3fSmrg convert = "__gen_unpack_uint" 37201e04c3fSmrg elif field.type == "float": 37301e04c3fSmrg convert = "__gen_unpack_float" 37401e04c3fSmrg elif field.type == "f187": 37501e04c3fSmrg convert = "__gen_unpack_f187" 37601e04c3fSmrg elif field.type == "offset": 37701e04c3fSmrg convert = "__gen_unpack_offset" 37801e04c3fSmrg elif field.type == 'ufixed': 37901e04c3fSmrg args.append(str(field.fractional_size)) 38001e04c3fSmrg convert = "__gen_unpack_ufixed" 38101e04c3fSmrg elif field.type == 'sfixed': 38201e04c3fSmrg args.append(str(field.fractional_size)) 38301e04c3fSmrg convert = "__gen_unpack_sfixed" 38401e04c3fSmrg else: 38501e04c3fSmrg print("/* unhandled field %s, type %s */\n" % (field.name, field.type)) 38601e04c3fSmrg s = None 38701e04c3fSmrg 38801e04c3fSmrg plusone = "" 38901e04c3fSmrg if field.minus_one: 39001e04c3fSmrg plusone = " + 1" 39101e04c3fSmrg print(" values->%s = %s(%s)%s;" % \ 39201e04c3fSmrg (field.name, convert, ', '.join(args), plusone)) 39301e04c3fSmrg 39401e04c3fSmrgclass Value(object): 39501e04c3fSmrg def __init__(self, attrs): 39601e04c3fSmrg self.name = attrs["name"] 39701e04c3fSmrg self.value = int(attrs["value"]) 39801e04c3fSmrg 39901e04c3fSmrgclass Parser(object): 40001e04c3fSmrg def __init__(self, ver): 40101e04c3fSmrg self.parser = xml.parsers.expat.ParserCreate() 40201e04c3fSmrg self.parser.StartElementHandler = self.start_element 40301e04c3fSmrg self.parser.EndElementHandler = self.end_element 40401e04c3fSmrg 40501e04c3fSmrg self.packet = None 40601e04c3fSmrg self.struct = None 40701e04c3fSmrg self.structs = {} 40801e04c3fSmrg # Set of enum names we've seen. 40901e04c3fSmrg self.enums = set() 41001e04c3fSmrg self.registers = {} 41101e04c3fSmrg self.ver = ver 41201e04c3fSmrg 41301e04c3fSmrg def gen_prefix(self, name): 41401e04c3fSmrg if name[0] == "_": 41501e04c3fSmrg return 'V3D%s%s' % (self.ver, name) 41601e04c3fSmrg else: 41701e04c3fSmrg return 'V3D%s_%s' % (self.ver, name) 41801e04c3fSmrg 41901e04c3fSmrg def gen_guard(self): 42001e04c3fSmrg return self.gen_prefix("PACK_H") 42101e04c3fSmrg 42201e04c3fSmrg def attrs_version_valid(self, attrs): 42301e04c3fSmrg if "min_ver" in attrs and self.ver < attrs["min_ver"]: 42401e04c3fSmrg return False 42501e04c3fSmrg 42601e04c3fSmrg if "max_ver" in attrs and self.ver > attrs["max_ver"]: 42701e04c3fSmrg return False 42801e04c3fSmrg 42901e04c3fSmrg return True 43001e04c3fSmrg 43101e04c3fSmrg def group_enabled(self): 43201e04c3fSmrg if self.group.min_ver != 0 and self.ver < self.group.min_ver: 43301e04c3fSmrg return False 43401e04c3fSmrg 43501e04c3fSmrg if self.group.max_ver != 0 and self.ver > self.group.max_ver: 43601e04c3fSmrg return False 43701e04c3fSmrg 43801e04c3fSmrg return True 43901e04c3fSmrg 44001e04c3fSmrg def start_element(self, name, attrs): 44101e04c3fSmrg if name == "vcxml": 44201e04c3fSmrg self.platform = "V3D {}.{}".format(self.ver[0], self.ver[1]) 44301e04c3fSmrg print(pack_header % {'license': license, 'platform': self.platform, 'guard': self.gen_guard()}) 44401e04c3fSmrg elif name in ("packet", "struct", "register"): 44501e04c3fSmrg default_field = None 44601e04c3fSmrg 44701e04c3fSmrg object_name = self.gen_prefix(safe_name(attrs["name"].upper())) 44801e04c3fSmrg if name == "packet": 44901e04c3fSmrg self.packet = object_name 45001e04c3fSmrg 45101e04c3fSmrg # Add a fixed Field for the opcode. We only make <field>s in 45201e04c3fSmrg # the XML for the fields listed in the spec, and all of those 45301e04c3fSmrg # start from bit 0 after of the opcode. 45401e04c3fSmrg default_field = { 45501e04c3fSmrg "name" : "opcode", 45601e04c3fSmrg "default" : attrs["code"], 45701e04c3fSmrg "type" : "uint", 45801e04c3fSmrg "start" : -8, 45901e04c3fSmrg "size" : 8, 46001e04c3fSmrg } 46101e04c3fSmrg elif name == "struct": 46201e04c3fSmrg self.struct = object_name 46301e04c3fSmrg self.structs[attrs["name"]] = 1 46401e04c3fSmrg elif name == "register": 46501e04c3fSmrg self.register = object_name 46601e04c3fSmrg self.reg_num = num_from_str(attrs["num"]) 46701e04c3fSmrg self.registers[attrs["name"]] = 1 46801e04c3fSmrg 46901e04c3fSmrg self.group = Group(self, None, 0, 1) 47001e04c3fSmrg if default_field: 47101e04c3fSmrg field = Field(self, default_field) 47201e04c3fSmrg field.values = [] 47301e04c3fSmrg self.group.fields.append(field) 47401e04c3fSmrg 47501e04c3fSmrg if "min_ver" in attrs: 47601e04c3fSmrg self.group.min_ver = attrs["min_ver"] 47701e04c3fSmrg if "max_ver" in attrs: 47801e04c3fSmrg self.group.max_ver = attrs["max_ver"] 47901e04c3fSmrg 48001e04c3fSmrg elif name == "field": 48101e04c3fSmrg self.group.fields.append(Field(self, attrs)) 48201e04c3fSmrg self.values = [] 48301e04c3fSmrg elif name == "enum": 48401e04c3fSmrg self.values = [] 48501e04c3fSmrg self.enum = safe_name(attrs["name"]) 48601e04c3fSmrg self.enums.add(attrs["name"]) 48701e04c3fSmrg self.enum_enabled = self.attrs_version_valid(attrs) 48801e04c3fSmrg if "prefix" in attrs: 48901e04c3fSmrg self.prefix = attrs["prefix"] 49001e04c3fSmrg else: 49101e04c3fSmrg self.prefix= None 49201e04c3fSmrg elif name == "value": 49301e04c3fSmrg if self.attrs_version_valid(attrs): 49401e04c3fSmrg self.values.append(Value(attrs)) 49501e04c3fSmrg 49601e04c3fSmrg def end_element(self, name): 49701e04c3fSmrg if name == "packet": 49801e04c3fSmrg self.emit_packet() 49901e04c3fSmrg self.packet = None 50001e04c3fSmrg self.group = None 50101e04c3fSmrg elif name == "struct": 50201e04c3fSmrg self.emit_struct() 50301e04c3fSmrg self.struct = None 50401e04c3fSmrg self.group = None 50501e04c3fSmrg elif name == "register": 50601e04c3fSmrg self.emit_register() 50701e04c3fSmrg self.register = None 50801e04c3fSmrg self.reg_num = None 50901e04c3fSmrg self.group = None 51001e04c3fSmrg elif name == "field": 51101e04c3fSmrg self.group.fields[-1].values = self.values 51201e04c3fSmrg elif name == "enum": 51301e04c3fSmrg if self.enum_enabled: 51401e04c3fSmrg self.emit_enum() 51501e04c3fSmrg self.enum = None 51601e04c3fSmrg elif name == "vcxml": 51701e04c3fSmrg print('#endif /* %s */' % self.gen_guard()) 51801e04c3fSmrg 51901e04c3fSmrg def emit_template_struct(self, name, group): 52001e04c3fSmrg print("struct %s {" % name) 52101e04c3fSmrg group.emit_template_struct("") 52201e04c3fSmrg print("};\n") 52301e04c3fSmrg 52401e04c3fSmrg def emit_pack_function(self, name, group): 52501e04c3fSmrg print("static inline void\n%s_pack(__gen_user_data *data, uint8_t * restrict cl,\n%sconst struct %s * restrict values)\n{" % 52601e04c3fSmrg (name, ' ' * (len(name) + 6), name)) 52701e04c3fSmrg 52801e04c3fSmrg group.emit_pack_function(0) 52901e04c3fSmrg 53001e04c3fSmrg print("}\n") 53101e04c3fSmrg 53201e04c3fSmrg print('#define %-33s %6d' % 53301e04c3fSmrg (name + "_length", self.group.length)) 53401e04c3fSmrg 53501e04c3fSmrg def emit_unpack_function(self, name, group): 53601e04c3fSmrg print("#ifdef __gen_unpack_address") 53701e04c3fSmrg print("static inline void") 53801e04c3fSmrg print("%s_unpack(const uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" % 53901e04c3fSmrg (name, ' ' * (len(name) + 8), name)) 54001e04c3fSmrg 54101e04c3fSmrg group.emit_unpack_function(0) 54201e04c3fSmrg 54301e04c3fSmrg print("}\n#endif\n") 54401e04c3fSmrg 54501e04c3fSmrg def emit_header(self, name): 54601e04c3fSmrg default_fields = [] 54701e04c3fSmrg for field in self.group.fields: 54801e04c3fSmrg if not type(field) is Field: 54901e04c3fSmrg continue 55001e04c3fSmrg if field.default == None: 55101e04c3fSmrg continue 55201e04c3fSmrg default_fields.append(" .%-35s = %6d" % (field.name, field.default)) 55301e04c3fSmrg 55401e04c3fSmrg print('#define %-40s\\' % (name + '_header')) 55501e04c3fSmrg print(", \\\n".join(default_fields)) 55601e04c3fSmrg print('') 55701e04c3fSmrg 55801e04c3fSmrg def emit_packet(self): 55901e04c3fSmrg if not self.group_enabled(): 56001e04c3fSmrg return 56101e04c3fSmrg 56201e04c3fSmrg name = self.packet 56301e04c3fSmrg 56401e04c3fSmrg assert(self.group.fields[0].name == "opcode") 56501e04c3fSmrg print('#define %-33s %6d' % 56601e04c3fSmrg (name + "_opcode", self.group.fields[0].default)) 56701e04c3fSmrg 56801e04c3fSmrg self.emit_header(name) 56901e04c3fSmrg self.emit_template_struct(self.packet, self.group) 57001e04c3fSmrg self.emit_pack_function(self.packet, self.group) 57101e04c3fSmrg self.emit_unpack_function(self.packet, self.group) 57201e04c3fSmrg 57301e04c3fSmrg print('') 57401e04c3fSmrg 57501e04c3fSmrg def emit_register(self): 57601e04c3fSmrg if not self.group_enabled(): 57701e04c3fSmrg return 57801e04c3fSmrg 57901e04c3fSmrg name = self.register 58001e04c3fSmrg if not self.reg_num == None: 58101e04c3fSmrg print('#define %-33s 0x%04x' % 58201e04c3fSmrg (self.gen_prefix(name + "_num"), self.reg_num)) 58301e04c3fSmrg 58401e04c3fSmrg self.emit_template_struct(self.register, self.group) 58501e04c3fSmrg self.emit_pack_function(self.register, self.group) 58601e04c3fSmrg self.emit_unpack_function(self.register, self.group) 58701e04c3fSmrg 58801e04c3fSmrg def emit_struct(self): 58901e04c3fSmrg if not self.group_enabled(): 59001e04c3fSmrg return 59101e04c3fSmrg 59201e04c3fSmrg name = self.struct 59301e04c3fSmrg 59401e04c3fSmrg self.emit_header(name) 59501e04c3fSmrg self.emit_template_struct(self.struct, self.group) 59601e04c3fSmrg self.emit_pack_function(self.struct, self.group) 59701e04c3fSmrg self.emit_unpack_function(self.struct, self.group) 59801e04c3fSmrg 59901e04c3fSmrg print('') 60001e04c3fSmrg 60101e04c3fSmrg def emit_enum(self): 60201e04c3fSmrg print('enum %s {' % self.gen_prefix(self.enum)) 60301e04c3fSmrg for value in self.values: 60401e04c3fSmrg name = value.name 60501e04c3fSmrg if self.prefix: 60601e04c3fSmrg name = self.prefix + "_" + name 60701e04c3fSmrg name = safe_name(name).upper() 60801e04c3fSmrg print(' % -36s = %6d,' % (name, value.value)) 60901e04c3fSmrg print('};\n') 61001e04c3fSmrg 61101e04c3fSmrg def parse(self, filename): 61201e04c3fSmrg file = open(filename, "rb") 61301e04c3fSmrg self.parser.ParseFile(file) 61401e04c3fSmrg file.close() 61501e04c3fSmrg 61601e04c3fSmrgif len(sys.argv) < 2: 61701e04c3fSmrg print("No input xml file specified") 61801e04c3fSmrg sys.exit(1) 61901e04c3fSmrg 62001e04c3fSmrginput_file = sys.argv[1] 62101e04c3fSmrg 62201e04c3fSmrgp = Parser(sys.argv[2]) 62301e04c3fSmrgp.parse(input_file) 624