def _parseStruct(root, yaml, chip, block): # Check that yaml doesn't have any unexpected tags checkChildren( yaml, [ "name", # Name of the structure (text) "title", # Short description (text) "description", # Optional description (text) "fields", # Structure fields (sub tree) "internal", # Optional internal (text) "attributes" ]) # Optional attributes (sub tree) # Make the type name is lower case name = getChild(yaml, "name").lower() attributes = getChild(yaml, "attributes", allowMissing=True) if attributes: align = getChild(attributes, "struct_alignment_size", allowMissing=True) if align == "0": #print "\t%s: Skipping %s due to mis-alignment" % (chip, name) return if name in root: work_struct = root[name] else: work_struct = csr_data.Struct(name) # Add this chip and YAML work_struct.addChip(chip, yaml) work_struct["block"] = block root[name] = work_struct # Iterate all yaml fields fields = getChild(yaml, "fields") for f in fields: # Check that yaml doesn't have any unexpected tags checkChildren( f, [ "name", # Field name (text) "description", # Optional description (text) "bits", # w#(#) or w#(#..#) "internal", # Optional internal (text) "attributes" ]) # Optional attributes (sub tree) name = getChild(f, "name").lower() bits = _parseBits(f) if csr_utils.isReserved(name): name = csr_utils.getReservedName(bits) if not name in work_struct["fields"]: work_struct["fields"][name] = csr_data.StructField(name) item = work_struct["fields"][name] item.addChip(chip, f) item["bits"][chip] = bits
def writeStruct(out, chip, struct): out.write("<table>\n") display_name = struct["name"].upper() out.write("<tr>" + TH("Name") + TD(display_name) + "</tr>\n") out.write("<tr>" + TH("Block") + TD(struct["block"]) + "</tr>\n") description = struct["description"][chip] out.write("<tr>" + TH("Description") + TD(description) + "</tr>\n") out.write("</table>\n") out.write("<br><br>\n") out.write("<table>\n") out.write("<tr>") out.write(TH("Bits")) out.write(TH("Name")) out.write(TH("Description")) out.write("</tr>\n") start_bits = {} for name in struct["fields"]: f = struct["fields"][name] if not chip in f["bits"]: continue start_bits[f["bits"][chip][0]] = f bits = sorted(start_bits, reverse=False) for bit in bits: f = start_bits[bit] if csr_utils.isReserved(f["name"]): color = BG_RESERVED else: color = None out.write("<tr>") bits = f["bits"][chip] if bits[0] == bits[1]: out.write(TD(str(bits[0]), bgcolor=color)) else: out.write(TD("%d:%d" % (bits[1], bits[0]), bgcolor=color)) out.write(TD(f["name"], bgcolor=color)) if chip in f["description"]: description = f["description"][chip] else: description = "" out.write(TD(description, bgcolor=color)) out.write("</tr>\n") out.write("</table>\n")
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)
def _parseReg(root, yaml, chip, yaml_root, block): # Skip deprecated registers attributes = getChild(yaml, "attributes", allowMissing=True) if attributes: deprecated = getChild(attributes, "deprecated", allowMissing=True) if deprecated: assert deprecated == "RAZ", "Deprecated is expected to be RAZ" return # Check that yaml doesn't have any unexpected tags checkChildren( yaml, [ "name", # CSR name (text with range info embedded) "fields", # Fields of the register (sub tree) "description", # Description of the register (text) "notes", # Extra notes after description (text) "title", # One line title/description (text) "address", # Address equation for register (text equation) "bus", # Type of the register (keyword) "attributes", # Optional attributes (sub tree) "bar", # Information about how to device the CSR space into PCIe BARs "internal" ]) # Internal description (text) # Make the type name is lower case name = getChild(yaml, "name").lower() # "(s)" in the name represents secure, change it to a "s" name = name.replace("(s)", "s") name, ranges = csr_utils.parseNameForRanges(name, yaml) if name in root: work_reg = root[name] else: work_reg = csr_data.Register(name) # Add this chip and YAML work_reg.addChip(chip, yaml) root[name] = work_reg work_reg["block"] = block work_reg["address"][chip] = parseAddress(yaml, "address", ranges) work_reg["ranges"][chip] = ranges work_reg["bus"][chip] = _parseBus(yaml) work_reg["bar"][chip] = getChild(yaml, "bar", True) if attributes: work_reg["attributes"][chip] = attributes # CN9XXX special check for PCIe config space. The hardware team removed # the PEM index from the PCIe config registers, which was exceedingly # useful for software. Since logical arguments to make software compatible # fail to move the hardware team, hack the registers as we load them. # Modify the address equation to contain the PEM number if (("CN9" in chip) or ("CNF9" in chip)) and (work_reg["bus"][chip] in [ "PCICONFIGEP", "PCICONFIGEP_SHADOW", "PCICONFIGEPVF", "PCICONFIGRC" ]): if work_reg["address"][chip][1] == 0: work_reg["address"][chip][1] = 0x100000000 # For RVU registers we need to determine the RVU_BLOCK_ID rvu_block_id = None if "RVU" in work_reg["bus"][chip]: attr = getChild(yaml, "attributes", allowMissing=True) if attr: rvu_block_id = getChild(attr, "rvu_block_id", allowMissing=True) if not rvu_block_id: attr = getChild(yaml_root[block], "attributes") rvu_block_id = getChild(attr, "rvu_block_id") rvu_block_id = rvu_block_id.split(":")[-1] assert work_reg["bar"][chip] == None if work_reg["bus"][chip] == "RVU_PF_BAR0": work_reg["bar"][chip] = "BAR0" else: assert "BAR2" in work_reg["bus"][chip] work_reg["bar"][chip] = "BAR2" work_reg["rvu_block_id"][chip] = rvu_block_id # Inherits should have been handled by csr3 inherits = getChild(yaml, "inherits", True) if inherits: raiseException(yaml, "Unexpected inherit") # Iterate all yaml fields fields = getChild(yaml, "fields") for f in fields: # Check that yaml doesn't have any unexpected tags checkChildren( f, [ "name", # Name of the field (text name) "bits", # Bits used. Either single number or "number..number" "access", # Access mode (RO, RW, etc) "reset", # Reset value of the fields "typical", # Typical value "description", # Description of the field (text) "internal", # Hardware team internal only notes "attributes" ]) # Optional attributes (sub tree) name = getChild(f, "name").lower() bits = _parseBits(f) if csr_utils.isReserved(name): name = csr_utils.getReservedName(bits) if not name in work_reg["fields"]: work_reg["fields"][name] = csr_data.RegisterField(name) item = work_reg["fields"][name] item.addChip(chip, f) item["bits"][chip] = bits item["access"][chip] = _parseAccess(f) item["reset"][chip] = _parseFieldValue(f, "reset") item["typical"][chip] = _parseFieldValue(f, "typical")
def diffReg(out, chip1, chip2, name, reg): def formatBoth(str1, str2): return formatDiff(chip1, str1, chip2, str2) out.write("<table>\n") display_name = reg["name"].replace("#", "x").upper() range1 = csr_utils.rangeToString(reg["ranges"].get(chip1, [])) range2 = csr_utils.rangeToString(reg["ranges"].get(chip2, [])) range = formatDiff(chip1, range1, chip2, range2, allowDiff=True) out.write("<tr>" + TH("Name") + TD(display_name + range) + "</tr>\n") out.write("<tr>" + TH("Block") + TD(reg["block"]) + "</tr>\n") description1 = reg["description"].get(chip1, "") description2 = reg["description"].get(chip2, "") description = formatDiff(chip1, description1, chip2, description2, allowDiff=True) out.write("<tr>" + TH("Description") + TD(description) + "</tr>\n") address_eq1 = csr_utils.addressToString(reg["address"].get(chip1, []), reg["ranges"].get(chip1, [])) address_eq2 = csr_utils.addressToString(reg["address"].get(chip2, []), reg["ranges"].get(chip2, [])) address_eq = formatDiff(chip1, address_eq1, chip2, address_eq2, allowDiff=True) out.write("<tr>" + TH("Address") + TD(address_eq) + "</tr>\n") bus1 = reg["bus"].get(chip1, "") bus2 = reg["bus"].get(chip2, "") bus = formatBoth(bus1, bus2) out.write("<tr>" + TH("Bus") + TD(bus) + "</tr>\n") bar1 = reg["bar"].get(chip1, "") if bar1 == None: bar1 = "" bar2 = reg["bar"].get(chip2, "") if bar2 == None: bar2 = "" bar = formatBoth(bar1, bar2) out.write("<tr>" + TH("Bar") + TD(bar) + "</tr>\n") out.write("</table>\n") out.write("<br><br>\n") out.write("<table>\n") out.write("<tr>") out.write(TH("Bits")) out.write(TH("Name")) out.write(TH("Access")) out.write(TH("Reset")) out.write(TH("Typical")) out.write(TH("Description")) out.write("</tr>\n") start_bits = {} filler = { "name": "", "bits": {}, "access": {}, "reset": {}, "typical": {}, "description": {} } for name in reg["fields"]: f = reg["fields"][name] if chip1 in f["bits"]: sb = f["bits"][chip1][0] if sb in start_bits: start_bits[sb] = (f, start_bits[sb][1]) else: start_bits[sb] = (f, filler) if chip2 in f["bits"]: sb = f["bits"][chip2][0] if sb in start_bits: start_bits[sb] = (start_bits[sb][0], f) else: start_bits[sb] = (filler, f) bits = sorted(start_bits, reverse=True) for bit in bits: f1, f2 = start_bits[bit] if (csr_utils.isReserved(f1["name"]) or (f1["name"] == "")) and (csr_utils.isReserved(f2["name"]) or (f2["name"] == "")): color = BG_RESERVED else: color = None out.write("<tr>") bits1 = f1["bits"].get(chip1, None) bits2 = f2["bits"].get(chip2, None) if bits1 == None: bits1 = "" elif bits1[0] == bits1[1]: bits1 = "%d" % bits1[0] else: bits1 = "%d:%d" % (bits1[1], bits1[0]) if bits2 == None: bits2 = "" elif bits2[0] == bits2[1]: bits2 = "%d" % bits2[0] else: bits2 = "%d:%d" % (bits2[1], bits2[0]) bits = formatBoth(bits1, bits2) out.write(TD(bits, bgcolor=color)) s = formatBoth(f1["name"], f2["name"]) out.write(TD(s, bgcolor=color)) s = formatBoth(f1["access"].get(chip1, ""), f2["access"].get(chip2, "")) out.write(TD(s, bgcolor=color)) s = formatBoth(f1["reset"].get(chip1, ""), f2["reset"].get(chip2, "")) out.write(TD(str(s), bgcolor=color)) s = formatBoth(f1["typical"].get(chip1, ""), f2["typical"].get(chip2, "")) out.write(TD(str(s), bgcolor=color)) description1 = f1["description"].get(chip1, "") description2 = f2["description"].get(chip2, "") description = formatDiff(chip1, description1, chip2, description2, allowDiff=True) out.write(TD(description, bgcolor=color)) out.write("</tr>\n") out.write("</table>\n")
def diffStruct(out, chip1, chip2, name, struct): def formatBoth(str1, str2): return formatDiff(chip1, str1, chip2, str2) out.write("<table>\n") display_name = struct["name"].upper() out.write("<tr>" + TH("Name") + TD(display_name) + "</tr>\n") out.write("<tr>" + TH("Block") + TD(struct["block"]) + "</tr>\n") description1 = struct["description"].get(chip1, "") description2 = struct["description"].get(chip2, "") description = formatDiff(chip1, description1, chip2, description2, allowDiff=True) out.write("<tr>" + TH("Description") + TD(description) + "</tr>\n") out.write("</table>\n") out.write("<br><br>\n") out.write("<table>\n") out.write("<tr>") out.write(TH("Bits")) out.write(TH("Name")) out.write(TH("Description")) out.write("</tr>\n") start_bits = {} filler = {"name": "", "bits": {}, "description": {}} for name in struct["fields"]: f = struct["fields"][name] if chip1 in f["bits"]: sb = f["bits"][chip1][0] if sb in start_bits: start_bits[sb] = (f, start_bits[sb][1]) else: start_bits[sb] = (f, filler) if chip2 in f["bits"]: sb = f["bits"][chip2][0] if sb in start_bits: start_bits[sb] = (start_bits[sb][0], f) else: start_bits[sb] = (filler, f) bits = sorted(start_bits, reverse=False) for bit in bits: f1, f2 = start_bits[bit] if (csr_utils.isReserved(f1["name"]) or (f1["name"] == "")) and (csr_utils.isReserved(f2["name"]) or (f2["name"] == "")): color = BG_RESERVED else: color = None out.write("<tr>") bits1 = f1["bits"].get(chip1, (bit, bit)) bits2 = f2["bits"].get(chip2, (bit, bit)) if bits1[0] == bits1[1]: bits1 = "%d" % bits1[0] else: bits1 = "%d:%d" % (bits1[1], bits1[0]) if bits2[0] == bits2[1]: bits2 = "%d" % bits2[0] else: bits2 = "%d:%d" % (bits2[1], bits2[0]) bits = formatBoth(bits1, bits2) out.write(TD(bits, bgcolor=color)) s = formatBoth(f1["name"], f2["name"]) out.write(TD(s, bgcolor=color)) description1 = f1["description"].get(chip1, "") description2 = f2["description"].get(chip2, "") description = formatDiff(chip1, description1, chip2, description2, allowDiff=True) out.write(TD(description, bgcolor=color)) out.write("</tr>\n") out.write("</table>\n")
def writeReg(out, chip, reg): out.write("<table>\n") display_name = reg["name"].replace("#", "x").upper() range = csr_utils.rangeToString(reg["ranges"][chip]) out.write("<tr>" + TH("Name") + TD(display_name + range) + "</tr>\n") out.write("<tr>" + TH("Block") + TD(reg["block"]) + "</tr>\n") description = reg["description"][chip] out.write("<tr>" + TH("Description") + TD(description) + "</tr>\n") address_eq = csr_utils.addressToString(reg["address"][chip], reg["ranges"][chip]) out.write("<tr>" + TH("Address") + TD(address_eq) + "</tr>\n") out.write("<tr>" + TH("Bus") + TD(reg["bus"][chip]) + "</tr>\n") rvu_block_id = reg["rvu_block_id"][chip] if rvu_block_id == None: rvu_block_id = "" out.write("<tr>" + TH("RVU Block") + TD(rvu_block_id) + "</tr>\n") bar = reg["bar"][chip] if bar == None: bar = "" out.write("<tr>" + TH("Bar") + TD(bar) + "</tr>\n") if reg["bar_size"][chip]: out.write("<tr>" + TH("Bar Size") + TD("%d bits" % reg["bar_size"][chip]) + "</tr>\n") address_eq = csr_utils.addressToString(reg["bar_offset"][chip], reg["bar_ranges"][chip]) out.write("<tr>" + TH("Bar Offset") + TD(address_eq) + "</tr>\n") out.write("<tr>" + TH("Reset") + TD("0x%x" % csr_utils.getResetValue(chip, reg)) + "</tr>\n") out.write("</table>\n") out.write("<br><br>\n") out.write("<table>\n") out.write("<tr>") out.write(TH("Bits")) out.write(TH("Name")) out.write(TH("Access")) out.write(TH("Reset")) out.write(TH("Typical")) out.write(TH("Description")) out.write("</tr>\n") start_bits = {} for name in reg["fields"]: f = reg["fields"][name] if not chip in f["bits"]: continue start_bits[f["bits"][chip][0]] = f bits = sorted(start_bits, reverse=True) for bit in bits: f = start_bits[bit] if csr_utils.isReserved(f["name"]): color = BG_RESERVED else: color = None out.write("<tr>") bits = f["bits"][chip] if bits[0] == bits[1]: out.write(TD(str(bits[0]), bgcolor=color)) else: out.write(TD("%d:%d" % (bits[1], bits[0]), bgcolor=color)) out.write(TD(f["name"], bgcolor=color)) out.write(TD(f["access"][chip], bgcolor=color)) out.write(TD(str(f["reset"][chip]), bgcolor=color)) out.write(TD(str(f["typical"][chip]), bgcolor=color)) if chip in f["description"]: description = f["description"][chip] else: description = "" out.write(TD(description, bgcolor=color)) out.write("</tr>\n") out.write("</table>\n")