def buildStructMembers(chip, struct): # Write a single field def writeField(out, field): bit_width = field["bits"][chip][1] - field["bits"][chip][0] + 1 line = ("\t\t" + c_type + " " + field["name"]).ljust(38) + " : " + str(bit_width) + ";" access = field.get("access", None) if access: access = "(%s)" % access[chip] else: access = "" line += "\n" out.write(line) fields = struct["fields"] out = StringIO.StringIO() total_size = csr_utils.getSizeBits(struct, multipleOf=32) if total_size % 64 == 0: c_type = "u64" word_size = 64 else: c_type = "u32" word_size = 32 num_words = total_size / word_size for word in range(num_words): # Create a list of all fields in this word min_bit = word * word_size max_bit = min_bit + word_size - 1 word_fields = {} for name in fields: # Skip fields not in this chip if not chip in fields[name]["bits"]: continue # Add fields in this word to the word's field list bits = fields[name]["bits"][chip] if (bits[0] >= min_bit) and (bits[0] <= max_bit): if (bits[1] < min_bit) or (bits[1] > max_bit): csr_utils.raiseException(fields[name], "Struct: Field spans a word") word_fields[bits[0]] = fields[name] # Sort the fields into big endian order bits = word_fields.keys() bits.sort() # Write the bits in little endian order for bit in bits: writeField(out, word_fields[bit]) result = out.getvalue() out.close() return result
def _validateReg(root, name): reg = root[name] # Validate the type name if not re.match("^[a-z][a-z0-9#_]*$", name): raiseException(reg, "Reg: Illegal name \"%s\"" % name) # Count the number of parameters num_params = name.count("#") # Limit to MAX_CSR_PARAMS parameters as a sanity check. This can be raised # bu editing the C database code if num_params > chip_list.MAX_CSR_PARAMS: raiseException(reg, "Reg: Too many params, name \"%s\"" % name) # Make sure the address equation agrees on the number of params for chip in reg["address"]: eq = reg["address"][chip] if isinstance(eq, StringType): continue if len(eq) != num_params + 1: raiseException( reg, "Reg: Unexpected equation length for %s %s" % (chip, eq)) if len(reg["ranges"][chip]) != num_params: raiseException( reg, "Reg: Unexpected range length for %s %s" % (chip, reg["ranges"][chip])) # Check fields for n in reg["fields"]: if not re.match("^[a-z][a-z0-9_]*$", n): raiseException(reg, "Reg: Illegal field name \"%s\"" % n) # Find any missing bits chip_holes = csr_utils.findBitHoles(reg, multipleOf=32) # Create reserved fields for bits for chip in chip_holes: raiseException( reg, "Reg: Missing bits for chip %s %s" % (chip, chip_holes[chip])) # Sanity check the size. These can be changed without issue size = csr_utils.getSizeBits(reg, multipleOf=0) if (size != 32) and (size != 64): raiseException(struct, "Reg: Size not 32 or 64 bits")
def _validateStruct(root, name): struct = root[name] # Validate the type name if not re.match("^[a-z][a-z0-9_]*$", name): raiseException(struct, "Struct: Illegal name \"%s\"" % name) for n in struct["fields"]: if not re.match("^[a-z][a-z0-9_]*$", n): raiseException(struct, "Struct: Illegal field name \"%s\"" % n) # Find any missing bits chip_holes = csr_utils.findBitHoles(struct, multipleOf=32) # Create reserved fields for bits for chip in chip_holes: if ((getChild(struct["attributes"][chip], "allow_missing_bits", allowMissing=True) == "True") or (getChild(struct["attributes"][chip], "struct_not_64b_multiple", allowMissing=True) == "True")): for hole in chip_holes[chip]: n = csr_utils.getReservedName(hole) if not n in struct["fields"]: struct["fields"][n] = csr_data.StructField(n) assert not chip in struct["fields"][n]["bits"] struct["fields"][n]["bits"][chip] = hole else: raiseException( struct, "Struct: Missing bits for chip %s %s" % (chip, chip_holes[chip])) # Sanity check the size. These can be changed without issue size = csr_utils.getSizeBits(struct, multipleOf=0) if (size < 32): raiseException(struct, "Struct: Size smaller than 32 bits") if (size > 32) and (size % 64 != 0): raiseException(struct, "Struct: Must be multiple of 64 bits") if (size > 512 * 8): raiseException(struct, "Struct: Size smaller than 512 bytes")
def writeStruct(out, arch, struct, title="Structure"): out.write("\n") out.write("/**\n") out.write(" * %s %s\n" % (title, struct["name"])) description = getAnyField(struct, "description", arch) if description: out.write(" *\n") description = description.replace("<", "\<") description = description.replace(">", "\>") description = textwrap.dedent(description) description = textwrap.fill(description, 70) for l in description.split("\n"): l = l.rstrip() if l: out.write(" * %s\n" % l) else: out.write(" *\n") out.write(" */\n") struct_name = (PREFIX + struct["name"]).replace("#", "X").lower() out.write("union %s {\n" % struct_name) width = csr_utils.getSizeBits(struct, multipleOf=32) if width % 64 == 0: if width > 64: out.write("\tu64 u[%d];\n" % (width / 64)) else: out.write("\tu64 u;\n") else: if width % 32 != 0: csr_utils.raiseException( struct, "Struct: Size expected to be a multiple of 32") if width > 32: out.write("\tu32 u[%d];\n" % (width / 32)) else: out.write("\tu32 u;\n") # Create a dictionary of all per chip structures struct_items = {} for chip in struct["description"]: is_this_arch = csr_utils.isChipArch(arch, chip) if not is_this_arch: continue struct_items[chip] = buildStructMembers(chip, struct) # Consolidate all chips consolidateChips(struct_items) # Start writing structures with subset first written_structs = {} out.write("\tstruct %s_s {\n" % struct_name) subset = csr_utils.createSubset(arch, "s", struct) struct_chip = buildStructMembers("s", subset) written_structs[struct_chip] = struct_name + "_s" out.write(struct_chip) out.write("\t} s;\n") for chip in csr_data.iterChipOrder(struct_items): struct_chip = struct_items[chip] chip_member = chip_list.chipToStructName(chip) if struct_chip in written_structs: # Chip duplicates one we have already written out.write("\t/* struct %s %s; */\n" % (written_structs[struct_chip], chip_member)) else: # New structure name = "%s_%s" % (struct_name, chip_member) written_structs[struct_chip] = name out.write("\tstruct %s {\n" % name) out.write(struct_chip) out.write("\t} %s;\n" % chip_member) out.write("};\n")
def buildStructMembers(chip, struct): # Write a single field def writeField(out, field): bit_width = field["bits"][chip][1] - field["bits"][chip][0] + 1 line = (" " + c_type + " " + field["name"]).ljust(38) + " : " + str(bit_width) + ";" description = formatDescription(field["description"].get(chip, ""), 66) access = field.get("access", None) if access: access = "(%s)" % access[chip] else: access = "" if not csr_utils.isReserved(field["name"]): description = description.replace("<", "\<") description = description.replace(">", "\>") l = line.ljust(45) + "/**< [%3d:%3d]%s %s */" % ( field["bits"][chip][1], field["bits"][chip][0], access, description) line = "" for l in l.split("\n"): line += l.rstrip() + "\n" else: line += "\n" out.write(line) fields = struct["fields"] out = StringIO.StringIO() total_size = csr_utils.getSizeBits(struct, multipleOf=32) if total_size % 64 == 0: c_type = "uint64_t" word_size = 64 else: c_type = "uint32_t" word_size = 32 num_words = total_size / word_size for word in range(num_words): # Create a list of all fields in this word min_bit = word * word_size max_bit = min_bit + word_size - 1 word_fields = {} for name in fields: # Skip fields not in this chip if not chip in fields[name]["bits"]: continue # Add fields in this word to the word's field list bits = fields[name]["bits"][chip] if (bits[0] >= min_bit) and (bits[0] <= max_bit): if (bits[1] < min_bit) or (bits[1] > max_bit): csr_utils.raiseException(fields[name], "Struct: Field spans a word") word_fields[bits[0]] = fields[name] # Sort the fields into big endian order bits = word_fields.keys() bits.sort() bits.reverse() out.write( "#if __BYTE_ORDER == __BIG_ENDIAN /* Word %d - Big Endian */\n" % word) for bit in bits: writeField(out, word_fields[bit]) # Write the bits in big endian order out.write("#else /* Word %d - Little Endian */\n" % word) # Write the bits in little endian order bits.reverse() for bit in bits: writeField(out, word_fields[bit]) out.write("#endif /* Word %d - End */\n" % word) result = out.getvalue() out.close() return result
def writeDB(arch, regs): global globalStringTable global globalStringTableLookup global globalStringTableLen global globalNumberTable global globalNumberTableLen global globalFieldTable global globalFieldTableLen global globalFieldListTable global globalFieldListTableLen global globalRangeTable global globalRangeTableLen global globalParamIndexTable global globalParamIndexTableLen global globalCsrTable global globalCsrTableLen globalStringTable = {} globalStringTableLookup = {} globalStringTableLen = 0 globalNumberTable = {} globalNumberTableLen = 0 globalFieldTable = {} globalFieldTableLen = 0 globalFieldListTable = {} globalFieldListTableLen = 0 globalRangeTable = {} globalRangeTableLen = 0 globalParamIndexTable = {} globalParamIndexTableLen = 0 globalCsrTable = {} globalCsrTableLen = 0 filename = "output/%s/%s.c" % (arch, FILE_PREFIX) out = open(filename, "w") writeCopyrightBanner(out) out.write('#include <bdk.h>\n') out.write("\n") empty_range = getRangeTable([(-1,-1)]) # # Write the per chip CSR tables # null_csr_ranges = getParamIndexTable([0 for x in range(chip_list.MAX_CSR_PARAMS)]) null_csr = getCsrTable("{0, 0, 0, BDK_CSR_TYPE_NCB, 0, 0, %d, %d}" % (null_csr_ranges, null_csr_ranges)) for chip in chip_list.getChips(): if not csr_utils.isChipArch(arch, chip): continue # Skip minor passes as they are basically the same as the major pass if not chip.endswith("_0"): continue out.write("static const int16_t __bdk_csr_db_%s[] = {\n" % chip) names = regs.keys() names.sort() for name in names: reg = regs[name] if not chip in reg["description"]: continue # Don't insert CSRs that we couldn't simplify the equation if isinstance(reg["address"][chip], StringType): continue # Skip dv_uvm_no_create registers if (("attributes" in reg) and (chip in reg["attributes"]) and ("dv_uvm_no_create" in reg["attributes"][chip])): if reg["attributes"][chip]["dv_uvm_no_create"]: assert reg["attributes"][chip]["dv_uvm_no_create"] == "True", "dv_uvm_no_create is expected to be True" continue range_len = len(reg["ranges"][chip]) assert range_len <= chip_list.MAX_CSR_PARAMS, "Only support %d params for now" % chip_list.MAX_CSR_PARAMS range_list = [empty_range for x in range(chip_list.MAX_CSR_PARAMS)] param_inc = [0 for x in range(chip_list.MAX_CSR_PARAMS)] for i in range(range_len): range_list[i] = getRangeTable(reg["ranges"][chip][i]) param_inc[i] = getNumberTable(reg["address"][chip][i+1]) range_index = getParamIndexTable(range_list) param_index = getParamIndexTable(param_inc) csr_str = "{%5d, %4d, %d, BDK_CSR_TYPE_%s, %d, %d, %d, %d}" % ( getStringTable(name.replace("#", "X")), # Name index getNumberTable(reg["address"][chip][0]), # Base index 0, # Unused reg["bus"][chip], # Bus Type csr_utils.getSizeBits(reg, 32) / 8, # Width in bytes getFieldListTable(reg, chip), # Field index range_index, param_index) csr_index = getCsrTable(csr_str) out.write(" %d, /* %s */\n" % (csr_index, name)) out.write(" %s\n" % null_csr) out.write("};\n\n") # # Write the global CSR table # out.write("const __bdk_csr_db_type_t __bdk_csr_db_csr[] = {\n") keys = getKeysSorted(globalCsrTable) for key in keys: out.write(" %s, /* %d */\n" % (key, globalCsrTable[key])) out.write("};\n\n") # # Write the CSR fieldList table # out.write("const uint16_t __bdk_csr_db_fieldList[] = {\n") keys = getKeysSorted(globalFieldListTable) for key in keys: out.write(" %s, /* %d */\n" % (key, globalFieldListTable[key])) out.write("};\n\n") # # Write the CSR field table # out.write("const __bdk_csr_db_field_t __bdk_csr_db_field[] = {\n") keys = getKeysSorted(globalFieldTable) for key in keys: out.write(" %s, /* %d */\n" % (key, globalFieldTable[key])) out.write("};\n\n") # # Write the CSR range table # out.write("const int __bdk_csr_db_range[] = {\n") keys = getKeysSorted(globalRangeTable) for key in keys: out.write(" %s, /* %d */\n" % (key, globalRangeTable[key])) out.write("};\n\n") # # Write the CSR string table # out.write("const char __bdk_csr_db_string[] = ") keys = getKeysSorted(globalStringTable) for key in keys: if len(key) &1 == 0: out.write("\n \"%s\\0\\0\" /* %s/2 */" % (key, globalStringTable[key])) else: out.write("\n \"%s\\0\" /* %s/2 */" % (key, globalStringTable[key])) out.write("\n \"\";\n\n") # # Write the CSR number table # out.write("const uint64_t __bdk_csr_db_number[] = {\n") keys = getKeysSorted(globalNumberTable) for key in keys: out.write(" 0x%016xull, /* %s */\n" % (key, globalNumberTable[key])) out.write("};\n\n") # # Write the param index table # out.write("const uint16_t __bdk_csr_db_param_index[][BDK_CSR_DB_MAX_PARAM] = {\n") keys = getKeysSorted(globalParamIndexTable) for key in keys: out.write(" %s, /* %d */\n" % (key, globalParamIndexTable[key])) out.write("};\n\n") # # Write the chip id to CSR table map # out.write("const __bdk_csr_db_map_t __bdk_csr_db[] = {\n") for chip in chip_list.getChips(): if not csr_utils.isChipArch(arch, chip): continue # Skip minor passes as they are basically the same as the major pass if not chip.endswith("_0"): continue model_check = chip_list.chipToModelDefine(chip) assert model_check.endswith("_0"), model_check model_check = model_check[0:-2] + "_X" out.write(" {%s, __bdk_csr_db_%s},\n" % (model_check, chip)) out.write(" {0, NULL}\n") out.write("};\n\n") out.close()