1*61046927SAndroid Build Coastguard WorkerCOPYRIGHT = ''' 2*61046927SAndroid Build Coastguard Worker/* 3*61046927SAndroid Build Coastguard Worker * Copyright 2015-2019 Advanced Micro Devices, Inc. 4*61046927SAndroid Build Coastguard Worker * 5*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT 6*61046927SAndroid Build Coastguard Worker */ 7*61046927SAndroid Build Coastguard Worker''' 8*61046927SAndroid Build Coastguard Worker""" 9*61046927SAndroid Build Coastguard WorkerCreate the (combined) register header from register JSON. Use --help for usage. 10*61046927SAndroid Build Coastguard Worker""" 11*61046927SAndroid Build Coastguard Worker 12*61046927SAndroid Build Coastguard Workerimport argparse 13*61046927SAndroid Build Coastguard Workerfrom collections import defaultdict 14*61046927SAndroid Build Coastguard Workerimport itertools 15*61046927SAndroid Build Coastguard Workerimport json 16*61046927SAndroid Build Coastguard Workerimport re 17*61046927SAndroid Build Coastguard Workerimport sys 18*61046927SAndroid Build Coastguard Worker 19*61046927SAndroid Build Coastguard Workerfrom regdb import Object, RegisterDatabase, deduplicate_enums, deduplicate_register_types 20*61046927SAndroid Build Coastguard Worker 21*61046927SAndroid Build Coastguard Worker 22*61046927SAndroid Build Coastguard Worker######### BEGIN HARDCODED CONFIGURATION 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Worker# Chips are sorted chronologically 25*61046927SAndroid Build Coastguard WorkerCHIPS = [ 26*61046927SAndroid Build Coastguard Worker Object(name='gfx6', disambiguation='GFX6'), 27*61046927SAndroid Build Coastguard Worker Object(name='gfx7', disambiguation='GFX7'), 28*61046927SAndroid Build Coastguard Worker Object(name='gfx8', disambiguation='GFX8'), 29*61046927SAndroid Build Coastguard Worker Object(name='gfx81', disambiguation='GFX81'), 30*61046927SAndroid Build Coastguard Worker Object(name='gfx9', disambiguation='GFX9'), 31*61046927SAndroid Build Coastguard Worker Object(name='gfx940', disambiguation='GFX940'), 32*61046927SAndroid Build Coastguard Worker Object(name='gfx10', disambiguation='GFX10'), 33*61046927SAndroid Build Coastguard Worker Object(name='gfx103', disambiguation='GFX103'), 34*61046927SAndroid Build Coastguard Worker Object(name='gfx11', disambiguation='GFX11'), 35*61046927SAndroid Build Coastguard Worker Object(name='gfx115', disambiguation='GFX115'), 36*61046927SAndroid Build Coastguard Worker Object(name='gfx12', disambiguation='GFX12'), 37*61046927SAndroid Build Coastguard Worker] 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard Worker######### END HARDCODED CONFIGURATION 40*61046927SAndroid Build Coastguard Worker 41*61046927SAndroid Build Coastguard Workerdef get_chip_index(chip): 42*61046927SAndroid Build Coastguard Worker """ 43*61046927SAndroid Build Coastguard Worker Given a chip name, return its index in the global CHIPS list. 44*61046927SAndroid Build Coastguard Worker """ 45*61046927SAndroid Build Coastguard Worker return next(idx for idx, obj in enumerate(CHIPS) if obj.name == chip) 46*61046927SAndroid Build Coastguard Worker 47*61046927SAndroid Build Coastguard Workerdef get_disambiguation_suffix(chips): 48*61046927SAndroid Build Coastguard Worker """ 49*61046927SAndroid Build Coastguard Worker Disambiguation suffix to be used for an enum entry or field name that 50*61046927SAndroid Build Coastguard Worker is supported in the given set of chips. 51*61046927SAndroid Build Coastguard Worker """ 52*61046927SAndroid Build Coastguard Worker oldest_chip_index = min([get_chip_index(chip) for chip in chips]) 53*61046927SAndroid Build Coastguard Worker return CHIPS[oldest_chip_index].disambiguation 54*61046927SAndroid Build Coastguard Worker 55*61046927SAndroid Build Coastguard Workerdef get_chips_comment(chips, parent=None): 56*61046927SAndroid Build Coastguard Worker """ 57*61046927SAndroid Build Coastguard Worker Generate a user-friendly comment describing the given set of chips. 58*61046927SAndroid Build Coastguard Worker 59*61046927SAndroid Build Coastguard Worker The return value may be None, if such a comment is deemed unnecessary. 60*61046927SAndroid Build Coastguard Worker 61*61046927SAndroid Build Coastguard Worker parent is an optional set of chips supporting a parent structure, e.g. 62*61046927SAndroid Build Coastguard Worker where chips may be the set of chips supporting a specific enum value, 63*61046927SAndroid Build Coastguard Worker parent would be the set of chips supporting the field containing the enum, 64*61046927SAndroid Build Coastguard Worker the idea being that no comment is necessary if all chips that support the 65*61046927SAndroid Build Coastguard Worker parent also support the child. 66*61046927SAndroid Build Coastguard Worker """ 67*61046927SAndroid Build Coastguard Worker chipflags = [chip.name in chips for chip in CHIPS] 68*61046927SAndroid Build Coastguard Worker if all(chipflags): 69*61046927SAndroid Build Coastguard Worker return None 70*61046927SAndroid Build Coastguard Worker 71*61046927SAndroid Build Coastguard Worker if parent is not None: 72*61046927SAndroid Build Coastguard Worker parentflags = [chip.name in parent for chip in CHIPS] 73*61046927SAndroid Build Coastguard Worker if all(childflag or not parentflag for childflag, parentflag in zip(chipflags, parentflags)): 74*61046927SAndroid Build Coastguard Worker return None 75*61046927SAndroid Build Coastguard Worker 76*61046927SAndroid Build Coastguard Worker prefix = 0 77*61046927SAndroid Build Coastguard Worker for idx, chip, flag in zip(itertools.count(), CHIPS, chipflags): 78*61046927SAndroid Build Coastguard Worker if not flag: 79*61046927SAndroid Build Coastguard Worker break 80*61046927SAndroid Build Coastguard Worker prefix = idx + 1 81*61046927SAndroid Build Coastguard Worker 82*61046927SAndroid Build Coastguard Worker suffix = len(CHIPS) 83*61046927SAndroid Build Coastguard Worker for idx, chip, flag in zip(itertools.count(), reversed(CHIPS), reversed(chipflags)): 84*61046927SAndroid Build Coastguard Worker if not flag: 85*61046927SAndroid Build Coastguard Worker break 86*61046927SAndroid Build Coastguard Worker suffix = len(CHIPS) - idx - 1 87*61046927SAndroid Build Coastguard Worker 88*61046927SAndroid Build Coastguard Worker comment = [] 89*61046927SAndroid Build Coastguard Worker if prefix > 0: 90*61046927SAndroid Build Coastguard Worker comment.append('<= {0}'.format(CHIPS[prefix - 1].name)) 91*61046927SAndroid Build Coastguard Worker for chip, flag in zip(CHIPS[prefix:suffix], chipflags[prefix:suffix]): 92*61046927SAndroid Build Coastguard Worker if flag: 93*61046927SAndroid Build Coastguard Worker comment.append(chip.name) 94*61046927SAndroid Build Coastguard Worker if suffix < len(CHIPS): 95*61046927SAndroid Build Coastguard Worker comment.append('>= {0}'.format(CHIPS[suffix].name)) 96*61046927SAndroid Build Coastguard Worker 97*61046927SAndroid Build Coastguard Worker return ', '.join(comment) 98*61046927SAndroid Build Coastguard Worker 99*61046927SAndroid Build Coastguard Workerdef detect_conflict(regdb, field_in_type1, field_in_type2): 100*61046927SAndroid Build Coastguard Worker """ 101*61046927SAndroid Build Coastguard Worker Returns False if field_in_type1 and field_in_type2 can be merged 102*61046927SAndroid Build Coastguard Worker into a single field = if writing to field_in_type1 bits won't 103*61046927SAndroid Build Coastguard Worker overwrite adjacent fields in type2, and the other way around. 104*61046927SAndroid Build Coastguard Worker """ 105*61046927SAndroid Build Coastguard Worker for idx, type_refs in enumerate([field_in_type1.type_refs, field_in_type2.type_refs]): 106*61046927SAndroid Build Coastguard Worker ref = field_in_type2 if idx == 0 else field_in_type1 107*61046927SAndroid Build Coastguard Worker for type_ref in type_refs: 108*61046927SAndroid Build Coastguard Worker for field in regdb.register_type(type_ref).fields: 109*61046927SAndroid Build Coastguard Worker # If a different field in the other type starts in 110*61046927SAndroid Build Coastguard Worker # the tested field's bits[0, 1] interval 111*61046927SAndroid Build Coastguard Worker if (field.bits[0] > ref.bits[0] and 112*61046927SAndroid Build Coastguard Worker field.bits[0] <= ref.bits[1]): 113*61046927SAndroid Build Coastguard Worker return True 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Worker return False 116*61046927SAndroid Build Coastguard Worker 117*61046927SAndroid Build Coastguard Workerclass HeaderWriter(object): 118*61046927SAndroid Build Coastguard Worker def __init__(self, regdb, guard=None): 119*61046927SAndroid Build Coastguard Worker self.guard = guard 120*61046927SAndroid Build Coastguard Worker 121*61046927SAndroid Build Coastguard Worker # The following contain: Object(address, chips, name, regmap/field/enumentry) 122*61046927SAndroid Build Coastguard Worker self.register_lines = [] 123*61046927SAndroid Build Coastguard Worker self.field_lines = [] 124*61046927SAndroid Build Coastguard Worker self.value_lines = [] 125*61046927SAndroid Build Coastguard Worker 126*61046927SAndroid Build Coastguard Worker regtype_emit = defaultdict(set) 127*61046927SAndroid Build Coastguard Worker enum_emit = defaultdict(set) 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard Worker for regmap in regdb.register_mappings(): 130*61046927SAndroid Build Coastguard Worker type_ref = getattr(regmap, 'type_ref', None) 131*61046927SAndroid Build Coastguard Worker self.register_lines.append(Object( 132*61046927SAndroid Build Coastguard Worker address=regmap.map.at, 133*61046927SAndroid Build Coastguard Worker chips=set(regmap.chips), 134*61046927SAndroid Build Coastguard Worker name=regmap.name, 135*61046927SAndroid Build Coastguard Worker regmap=regmap, 136*61046927SAndroid Build Coastguard Worker type_refs=set([type_ref]) if type_ref else set(), 137*61046927SAndroid Build Coastguard Worker )) 138*61046927SAndroid Build Coastguard Worker 139*61046927SAndroid Build Coastguard Worker basename = re.sub(r'[0-9]+', '', regmap.name) 140*61046927SAndroid Build Coastguard Worker key = '{type_ref}::{basename}'.format(**locals()) 141*61046927SAndroid Build Coastguard Worker if type_ref is not None and regtype_emit[key].isdisjoint(regmap.chips): 142*61046927SAndroid Build Coastguard Worker regtype_emit[key].update(regmap.chips) 143*61046927SAndroid Build Coastguard Worker 144*61046927SAndroid Build Coastguard Worker regtype = regdb.register_type(type_ref) 145*61046927SAndroid Build Coastguard Worker for field in regtype.fields: 146*61046927SAndroid Build Coastguard Worker if field.name == 'RESERVED': 147*61046927SAndroid Build Coastguard Worker continue 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker enum_ref = getattr(field, 'enum_ref', None) 150*61046927SAndroid Build Coastguard Worker self.field_lines.append(Object( 151*61046927SAndroid Build Coastguard Worker address=regmap.map.at, 152*61046927SAndroid Build Coastguard Worker chips=set(regmap.chips), 153*61046927SAndroid Build Coastguard Worker name=field.name, 154*61046927SAndroid Build Coastguard Worker field=field, 155*61046927SAndroid Build Coastguard Worker bits=field.bits[:], 156*61046927SAndroid Build Coastguard Worker type_refs=set([type_ref]) if type_ref else set(), 157*61046927SAndroid Build Coastguard Worker enum_refs=set([enum_ref]) if enum_ref else set(), 158*61046927SAndroid Build Coastguard Worker )) 159*61046927SAndroid Build Coastguard Worker 160*61046927SAndroid Build Coastguard Worker key = '{type_ref}::{basename}::{enum_ref}'.format(**locals()) 161*61046927SAndroid Build Coastguard Worker if enum_ref is not None and enum_emit[key].isdisjoint(regmap.chips): 162*61046927SAndroid Build Coastguard Worker enum_emit[key].update(regmap.chips) 163*61046927SAndroid Build Coastguard Worker 164*61046927SAndroid Build Coastguard Worker enum = regdb.enum(enum_ref) 165*61046927SAndroid Build Coastguard Worker for entry in enum.entries: 166*61046927SAndroid Build Coastguard Worker self.value_lines.append(Object( 167*61046927SAndroid Build Coastguard Worker address=regmap.map.at, 168*61046927SAndroid Build Coastguard Worker chips=set(regmap.chips), 169*61046927SAndroid Build Coastguard Worker name=entry.name, 170*61046927SAndroid Build Coastguard Worker enumentry=entry, 171*61046927SAndroid Build Coastguard Worker enum_refs=set([enum_ref]) if enum_ref else set(), 172*61046927SAndroid Build Coastguard Worker )) 173*61046927SAndroid Build Coastguard Worker 174*61046927SAndroid Build Coastguard Worker # Merge register lines 175*61046927SAndroid Build Coastguard Worker lines = self.register_lines 176*61046927SAndroid Build Coastguard Worker lines.sort(key=lambda line: (line.address, line.name)) 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker self.register_lines = [] 179*61046927SAndroid Build Coastguard Worker for line in lines: 180*61046927SAndroid Build Coastguard Worker prev = self.register_lines[-1] if self.register_lines else None 181*61046927SAndroid Build Coastguard Worker if prev and prev.address == line.address and prev.name == line.name: 182*61046927SAndroid Build Coastguard Worker prev.chips.update(line.chips) 183*61046927SAndroid Build Coastguard Worker prev.type_refs.update(line.type_refs) 184*61046927SAndroid Build Coastguard Worker continue 185*61046927SAndroid Build Coastguard Worker self.register_lines.append(line) 186*61046927SAndroid Build Coastguard Worker 187*61046927SAndroid Build Coastguard Worker # Merge field lines 188*61046927SAndroid Build Coastguard Worker lines = self.field_lines 189*61046927SAndroid Build Coastguard Worker lines.sort(key=lambda line: (line.address, line.name)) 190*61046927SAndroid Build Coastguard Worker 191*61046927SAndroid Build Coastguard Worker self.field_lines = [] 192*61046927SAndroid Build Coastguard Worker for line in lines: 193*61046927SAndroid Build Coastguard Worker merged = False 194*61046927SAndroid Build Coastguard Worker for prev in reversed(self.field_lines): 195*61046927SAndroid Build Coastguard Worker if prev.address != line.address or prev.name != line.name: 196*61046927SAndroid Build Coastguard Worker break 197*61046927SAndroid Build Coastguard Worker 198*61046927SAndroid Build Coastguard Worker # Can merge fields if they have the same starting bit and the 199*61046927SAndroid Build Coastguard Worker # range of the field as intended by the current line does not 200*61046927SAndroid Build Coastguard Worker # conflict with any of the regtypes covered by prev. 201*61046927SAndroid Build Coastguard Worker if prev.bits[0] != line.bits[0]: 202*61046927SAndroid Build Coastguard Worker continue 203*61046927SAndroid Build Coastguard Worker 204*61046927SAndroid Build Coastguard Worker if prev.bits[1] != line.bits[1]: 205*61046927SAndroid Build Coastguard Worker # Current line's field extends beyond the range of prev. 206*61046927SAndroid Build Coastguard Worker # Need to check for conflicts 207*61046927SAndroid Build Coastguard Worker if detect_conflict(regdb, prev, line): 208*61046927SAndroid Build Coastguard Worker continue 209*61046927SAndroid Build Coastguard Worker 210*61046927SAndroid Build Coastguard Worker prev.bits[1] = max(prev.bits[1], line.bits[1]) 211*61046927SAndroid Build Coastguard Worker prev.chips.update(line.chips) 212*61046927SAndroid Build Coastguard Worker prev.type_refs.update(line.type_refs) 213*61046927SAndroid Build Coastguard Worker prev.enum_refs.update(line.enum_refs) 214*61046927SAndroid Build Coastguard Worker merged = True 215*61046927SAndroid Build Coastguard Worker break 216*61046927SAndroid Build Coastguard Worker if not merged: 217*61046927SAndroid Build Coastguard Worker self.field_lines.append(line) 218*61046927SAndroid Build Coastguard Worker 219*61046927SAndroid Build Coastguard Worker # Merge value lines 220*61046927SAndroid Build Coastguard Worker lines = self.value_lines 221*61046927SAndroid Build Coastguard Worker lines.sort(key=lambda line: (line.address, line.name)) 222*61046927SAndroid Build Coastguard Worker 223*61046927SAndroid Build Coastguard Worker self.value_lines = [] 224*61046927SAndroid Build Coastguard Worker for line in lines: 225*61046927SAndroid Build Coastguard Worker for prev in reversed(self.value_lines): 226*61046927SAndroid Build Coastguard Worker if prev.address == line.address and prev.name == line.name and\ 227*61046927SAndroid Build Coastguard Worker prev.enumentry.value == line.enumentry.value: 228*61046927SAndroid Build Coastguard Worker prev.chips.update(line.chips) 229*61046927SAndroid Build Coastguard Worker prev.enum_refs.update(line.enum_refs) 230*61046927SAndroid Build Coastguard Worker break 231*61046927SAndroid Build Coastguard Worker else: 232*61046927SAndroid Build Coastguard Worker self.value_lines.append(line) 233*61046927SAndroid Build Coastguard Worker 234*61046927SAndroid Build Coastguard Worker # Disambiguate field and value lines 235*61046927SAndroid Build Coastguard Worker for idx, line in enumerate(self.field_lines): 236*61046927SAndroid Build Coastguard Worker prev = self.field_lines[idx - 1] if idx > 0 else None 237*61046927SAndroid Build Coastguard Worker next = self.field_lines[idx + 1] if idx + 1 < len(self.field_lines) else None 238*61046927SAndroid Build Coastguard Worker if (prev and prev.address == line.address and prev.field.name == line.field.name) or\ 239*61046927SAndroid Build Coastguard Worker (next and next.address == line.address and next.field.name == line.field.name): 240*61046927SAndroid Build Coastguard Worker line.name += '_' + get_disambiguation_suffix(line.chips) 241*61046927SAndroid Build Coastguard Worker 242*61046927SAndroid Build Coastguard Worker for idx, line in enumerate(self.value_lines): 243*61046927SAndroid Build Coastguard Worker prev = self.value_lines[idx - 1] if idx > 0 else None 244*61046927SAndroid Build Coastguard Worker next = self.value_lines[idx + 1] if idx + 1 < len(self.value_lines) else None 245*61046927SAndroid Build Coastguard Worker if (prev and prev.address == line.address and prev.enumentry.name == line.enumentry.name) or\ 246*61046927SAndroid Build Coastguard Worker (next and next.address == line.address and next.enumentry.name == line.enumentry.name): 247*61046927SAndroid Build Coastguard Worker line.name += '_' + get_disambiguation_suffix(line.chips) 248*61046927SAndroid Build Coastguard Worker 249*61046927SAndroid Build Coastguard Worker def print(self, filp, sort='address'): 250*61046927SAndroid Build Coastguard Worker """ 251*61046927SAndroid Build Coastguard Worker Print out the entire register header. 252*61046927SAndroid Build Coastguard Worker """ 253*61046927SAndroid Build Coastguard Worker if sort == 'address': 254*61046927SAndroid Build Coastguard Worker self.register_lines.sort(key=lambda line: (line.address, line.name)) 255*61046927SAndroid Build Coastguard Worker else: 256*61046927SAndroid Build Coastguard Worker assert sort == 'name' 257*61046927SAndroid Build Coastguard Worker self.register_lines.sort(key=lambda line: (line.name, line.address)) 258*61046927SAndroid Build Coastguard Worker 259*61046927SAndroid Build Coastguard Worker # Collect and sort field lines by address 260*61046927SAndroid Build Coastguard Worker field_lines_by_address = defaultdict(list) 261*61046927SAndroid Build Coastguard Worker for line in self.field_lines: 262*61046927SAndroid Build Coastguard Worker field_lines_by_address[line.address].append(line) 263*61046927SAndroid Build Coastguard Worker for field_lines in field_lines_by_address.values(): 264*61046927SAndroid Build Coastguard Worker if sort == 'address': 265*61046927SAndroid Build Coastguard Worker field_lines.sort(key=lambda line: (line.bits[0], line.name)) 266*61046927SAndroid Build Coastguard Worker else: 267*61046927SAndroid Build Coastguard Worker field_lines.sort(key=lambda line: (line.name, line.bits[0])) 268*61046927SAndroid Build Coastguard Worker 269*61046927SAndroid Build Coastguard Worker # Collect and sort value lines by address 270*61046927SAndroid Build Coastguard Worker value_lines_by_address = defaultdict(list) 271*61046927SAndroid Build Coastguard Worker for line in self.value_lines: 272*61046927SAndroid Build Coastguard Worker value_lines_by_address[line.address].append(line) 273*61046927SAndroid Build Coastguard Worker for value_lines in value_lines_by_address.values(): 274*61046927SAndroid Build Coastguard Worker if sort == 'address': 275*61046927SAndroid Build Coastguard Worker value_lines.sort(key=lambda line: (line.enumentry.value, line.name)) 276*61046927SAndroid Build Coastguard Worker else: 277*61046927SAndroid Build Coastguard Worker value_lines.sort(key=lambda line: (line.name, line.enumentry.value)) 278*61046927SAndroid Build Coastguard Worker 279*61046927SAndroid Build Coastguard Worker print('/* Automatically generated by amd/registers/makeregheader.py */\n', file=filp) 280*61046927SAndroid Build Coastguard Worker print(file=filp) 281*61046927SAndroid Build Coastguard Worker print(COPYRIGHT.strip(), file=filp) 282*61046927SAndroid Build Coastguard Worker print(file=filp) 283*61046927SAndroid Build Coastguard Worker 284*61046927SAndroid Build Coastguard Worker if self.guard: 285*61046927SAndroid Build Coastguard Worker print('#ifndef {self.guard}'.format(**locals()), file=filp) 286*61046927SAndroid Build Coastguard Worker print('#define {self.guard}\n'.format(**locals()), file=filp) 287*61046927SAndroid Build Coastguard Worker 288*61046927SAndroid Build Coastguard Worker for register_line in self.register_lines: 289*61046927SAndroid Build Coastguard Worker comment = get_chips_comment(register_line.chips) 290*61046927SAndroid Build Coastguard Worker 291*61046927SAndroid Build Coastguard Worker address = '{0:X}'.format(register_line.address) 292*61046927SAndroid Build Coastguard Worker address = address.rjust(3 if register_line.regmap.map.to == 'pkt3' else 6, '0') 293*61046927SAndroid Build Coastguard Worker 294*61046927SAndroid Build Coastguard Worker define_name = 'R_{address}_{register_line.name}'.format(**locals()).ljust(63) 295*61046927SAndroid Build Coastguard Worker comment = ' /* {0} */'.format(comment) if comment else '' 296*61046927SAndroid Build Coastguard Worker print('#define {define_name} 0x{address}{comment}'.format(**locals()), file=filp) 297*61046927SAndroid Build Coastguard Worker 298*61046927SAndroid Build Coastguard Worker field_lines = field_lines_by_address[register_line.address] 299*61046927SAndroid Build Coastguard Worker field_idx = 0 300*61046927SAndroid Build Coastguard Worker while field_idx < len(field_lines): 301*61046927SAndroid Build Coastguard Worker field_line = field_lines[field_idx] 302*61046927SAndroid Build Coastguard Worker 303*61046927SAndroid Build Coastguard Worker if field_line.type_refs.isdisjoint(register_line.type_refs): 304*61046927SAndroid Build Coastguard Worker field_idx += 1 305*61046927SAndroid Build Coastguard Worker continue 306*61046927SAndroid Build Coastguard Worker del field_lines[field_idx] 307*61046927SAndroid Build Coastguard Worker 308*61046927SAndroid Build Coastguard Worker comment = get_chips_comment(field_line.chips, register_line.chips) 309*61046927SAndroid Build Coastguard Worker 310*61046927SAndroid Build Coastguard Worker mask = (1 << (field_line.bits[1] - field_line.bits[0] + 1)) - 1 311*61046927SAndroid Build Coastguard Worker define_name = '_{address}_{field_line.name}(x)'.format(**locals()).ljust(58) 312*61046927SAndroid Build Coastguard Worker comment = ' /* {0} */'.format(comment) if comment else '' 313*61046927SAndroid Build Coastguard Worker print( 314*61046927SAndroid Build Coastguard Worker '#define S{define_name} (((unsigned)(x) & 0x{mask:X}) << {field_line.bits[0]}){comment}' 315*61046927SAndroid Build Coastguard Worker .format(**locals()), file=filp) 316*61046927SAndroid Build Coastguard Worker print('#define G{define_name} (((x) >> {field_line.bits[0]}) & 0x{mask:X})' 317*61046927SAndroid Build Coastguard Worker .format(**locals()), file=filp) 318*61046927SAndroid Build Coastguard Worker 319*61046927SAndroid Build Coastguard Worker complement = ((1 << 32) - 1) ^ (mask << field_line.bits[0]) 320*61046927SAndroid Build Coastguard Worker define_name = '_{address}_{field_line.name}'.format(**locals()).ljust(58) 321*61046927SAndroid Build Coastguard Worker print('#define C{define_name} 0x{complement:08X}' 322*61046927SAndroid Build Coastguard Worker .format(**locals()), file=filp) 323*61046927SAndroid Build Coastguard Worker 324*61046927SAndroid Build Coastguard Worker value_lines = value_lines_by_address[register_line.address] 325*61046927SAndroid Build Coastguard Worker value_idx = 0 326*61046927SAndroid Build Coastguard Worker while value_idx < len(value_lines): 327*61046927SAndroid Build Coastguard Worker value_line = value_lines[value_idx] 328*61046927SAndroid Build Coastguard Worker 329*61046927SAndroid Build Coastguard Worker if value_line.enum_refs.isdisjoint(field_line.enum_refs): 330*61046927SAndroid Build Coastguard Worker value_idx += 1 331*61046927SAndroid Build Coastguard Worker continue 332*61046927SAndroid Build Coastguard Worker del value_lines[value_idx] 333*61046927SAndroid Build Coastguard Worker 334*61046927SAndroid Build Coastguard Worker comment = get_chips_comment(value_line.chips, field_line.chips) 335*61046927SAndroid Build Coastguard Worker 336*61046927SAndroid Build Coastguard Worker define_name = 'V_{address}_{value_line.name}'.format(**locals()).ljust(55) 337*61046927SAndroid Build Coastguard Worker comment = ' /* {0} */'.format(comment) if comment else '' 338*61046927SAndroid Build Coastguard Worker print('#define {define_name} {value_line.enumentry.value}{comment}' 339*61046927SAndroid Build Coastguard Worker .format(**locals()), file=filp) 340*61046927SAndroid Build Coastguard Worker 341*61046927SAndroid Build Coastguard Worker if self.guard: 342*61046927SAndroid Build Coastguard Worker print('\n#endif // {self.guard}'.format(**locals()), file=filp) 343*61046927SAndroid Build Coastguard Worker 344*61046927SAndroid Build Coastguard Worker 345*61046927SAndroid Build Coastguard Workerdef main(): 346*61046927SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 347*61046927SAndroid Build Coastguard Worker parser.add_argument('--chip', dest='chips', type=str, nargs='*', 348*61046927SAndroid Build Coastguard Worker help='Chip for which to generate the header (all chips if unspecified)') 349*61046927SAndroid Build Coastguard Worker parser.add_argument('--sort', choices=['name', 'address'], default='address', 350*61046927SAndroid Build Coastguard Worker help='Sort key for registers, fields, and enum values') 351*61046927SAndroid Build Coastguard Worker parser.add_argument('--guard', type=str, help='Name of the #include guard') 352*61046927SAndroid Build Coastguard Worker parser.add_argument('files', metavar='FILE', type=str, nargs='+', 353*61046927SAndroid Build Coastguard Worker help='Register database file') 354*61046927SAndroid Build Coastguard Worker args = parser.parse_args() 355*61046927SAndroid Build Coastguard Worker 356*61046927SAndroid Build Coastguard Worker regdb = None 357*61046927SAndroid Build Coastguard Worker for filename in args.files: 358*61046927SAndroid Build Coastguard Worker with open(filename, 'r') as filp: 359*61046927SAndroid Build Coastguard Worker db = RegisterDatabase.from_json(json.load(filp)) 360*61046927SAndroid Build Coastguard Worker if regdb is None: 361*61046927SAndroid Build Coastguard Worker regdb = db 362*61046927SAndroid Build Coastguard Worker else: 363*61046927SAndroid Build Coastguard Worker regdb.update(db) 364*61046927SAndroid Build Coastguard Worker 365*61046927SAndroid Build Coastguard Worker deduplicate_enums(regdb) 366*61046927SAndroid Build Coastguard Worker deduplicate_register_types(regdb) 367*61046927SAndroid Build Coastguard Worker 368*61046927SAndroid Build Coastguard Worker w = HeaderWriter(regdb, guard=args.guard) 369*61046927SAndroid Build Coastguard Worker w.print(sys.stdout, sort=args.sort) 370*61046927SAndroid Build Coastguard Worker 371*61046927SAndroid Build Coastguard Worker 372*61046927SAndroid Build Coastguard Workerif __name__ == '__main__': 373*61046927SAndroid Build Coastguard Worker main() 374*61046927SAndroid Build Coastguard Worker 375*61046927SAndroid Build Coastguard Worker# kate: space-indent on; indent-width 4; replace-tabs on; 376