import sys, struct, string #The known register fields in the device tree #These fields are printed as 64-bit little-endian words REGISTER_FIELDS = ["reg", "error-reflector", "encoding", "decoding", "interrupts", "resource-config", "reg-private", "acc-impl-tunables"] #The size of a name entry in the device tree NAME_SIZE = 0x20 #The size of a DWORD, in bytes DWORD_SIZE = 4 #The size of a QWORD, in bytes QWORD_SIZE = 8 #The threshold of unprintable characters, above which a field is considered "binary" HEX_SUSP_THRESH = 3 #CR, LF, VTAB, FF NEWLINES = ['\r','\n','\x0c','\x0b'] #The width of a printed line separator LINE_WIDTH = 100 class FileStream(object): ''' Simple stream abstraction for a data blob ''' def __init__(self, data): self.data = data self.index = 0 def read_bytes(self, size): buf = self.data[self.index:self.index+size] self.index += size return buf def read_dword(self): return struct.unpack("" % ord(x), raw_value.rstrip("\x00"))) #Align to a DWORD if (value_size % DWORD_SIZE) != 0: dt.read_bytes(DWORD_SIZE - (value_size % DWORD_SIZE)) #Is this a known binary field? if name in REGISTER_FIELDS: value = " ".join(["0x%016X" % struct.unpack(" HEX_SUSP_THRESH: value = "<%s>" % ("".join(["%02X" % ord(c) for c in raw_value])) #Printing the entry value = "".join(filter(lambda x: x not in NEWLINES, value)) print (" " * depth) + "%-32s %s" % (name, value) #Parsing all child nodes for i in range(0, num_children): print "-" * LINE_WIDTH parse_node(dt, depth + 1) def main(): if len(sys.argv) != 2: print "USAGE: %s " % sys.argv[0] return #Parsing the device tree device_tree = FileStream(open(sys.argv[1], "rb").read()) parse_node(device_tree) if __name__ == "__main__": main()