def stop(self): commandBuffer_sym,_ = gdb.lookup_symbol('commandBuffer') commandBuffer = commandBuffer_sym.value(gdb.newest_frame()) # offset, startOffset # physical offset = int(commandBuffer['offset']) startOffset = int(commandBuffer['startOffset']) physical = int(commandBuffer['physical'].cast(self.size_t_type)) # GPU address logical = int(commandBuffer['logical'].cast(self.size_t_type)) # CPU address buffer = indirect_memcpy(logical + startOffset, logical + offset) data = struct.unpack_from(b'%dI' % (len(buffer)/4), buffer) # "cast" byte-based buffer to uint32_t # iterate over buffer, one 32 bit word at a time f = sys.stdout if self.output is None else self.output f.write('viv_commit:\n') for rec in parse_command_buffer(data): if rec.state_info is not None: desc = self.format_state(rec.state_info.pos, rec.value, rec.state_info.format) else: desc = rec.desc f.write(' [%08x] %08x %s\n' % (physical + startOffset + rec.ptr*4, rec.value, desc)) f.flush() return self.do_stop
def stop(self): commandBuffer_sym,_ = gdb.lookup_symbol('commandBuffer') commandBuffer = commandBuffer_sym.value(gdb.newest_frame()) # offset, startOffset # physical offset = int(commandBuffer['offset']) startOffset = int(commandBuffer['startOffset']) physical = int(commandBuffer['physical'].cast(self.size_t_type)) # GPU address logical = int(commandBuffer['logical'].cast(self.size_t_type)) # CPU address buffer = indirect_memcpy(logical + startOffset, logical + offset) data = struct.unpack_from(b'%dL' % (len(buffer)/4), buffer) # "cast" byte-based buffer to uint32_t # iterate over buffer, one 32 bit word at a time f = sys.stdout if self.output is None else self.output f.write('viv_commit:\n') for rec in parse_command_buffer(data): if rec.state_info is not None: desc = self.format_state(rec.state_info.pos, rec.value, rec.state_info.format) else: desc = rec.desc f.write(' [%08x] %08x %s\n' % (physical + startOffset + rec.ptr*4, rec.value, desc)) f.flush() return self.do_stop
def dump_command_buffer(f, mem, addr, end_addr, depth, state_map): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') states = [] # list of (ptr, state_addr) tuples size = (end_addr - addr)//4 for rec in parse_command_buffer(iter_memory(mem, addr, end_addr)): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if rec.ptr != (size-1): f.write(", /* %s */\n" % desc) else: f.write(" /* %s */\n" % desc) f.write(indent + '}') if options.list_address_states: # Print addresses; useful for making a re-play program #f.write('\n' + indent + 'GPU addresses {\n') uniqaddr = defaultdict(list) for (ptr, pos, state_format, value) in states: try: path = state_map.lookup_address(pos) except KeyError: continue type = path[-1][0].type if isinstance(type, Domain): # type Domain refers to another memory space #f.write(indent) addrname = format_addr(value) #f.write(' {0x%x,0x%05X}, /* %s = 0x%08x (%s) */\n' % (ptr, pos, format_path(path), value, addrname)) uniqaddr[value].append(ptr) #f.write(indent + '},') f.write('\n' + indent + 'Grouped GPU addresses {\n') for (value, ptrs) in uniqaddr.iteritems(): lvalues = ' = '.join([('cmdbuf[0x%x]' % ptr) for ptr in ptrs]) f.write(indent + ' ' + lvalues + ' = ' + format_addr(value) + ('; /* 0x%x */' % value) + '\n') f.write(indent + '}') if options.dump_shaders: state_by_pos = {} for (ptr, pos, state_format, value) in states: state_by_pos[pos]=value # 0x04000 and 0x06000 contain shader instructions dump_shader(f, 'vs', state_by_pos, 0x04000, 0x05000) dump_shader(f, 'ps', state_by_pos, 0x06000, 0x07000) dump_shader(f, 'vs', state_by_pos, 0x0C000, 0x0D000) # gc2000 dump_shader(f, 'ps', state_by_pos, 0x0D000, 0x0E000) # XXX this offset is probably variable (gc2000)
def dump_command_buffer(f, buf, depth, state_map): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') size = len(buf) states = [] # list of (ptr, state_addr) tuples ptr = 0 for rec in parse_command_buffer(buf): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if ptr != (size-1): f.write(", /* %s */\n" % rec.desc) else: f.write(" /* %s */\n" % rec.desc) ptr += 1 f.write(indent + '}')
def main(): args = parse_arguments() state_xml = parse_rng_file(args.rules_file) state_map = state_xml.lookup_domain('VIVS') cmdstream_xml = parse_rng_file(args.cmdstream_file) fe_opcode = cmdstream_xml.lookup_type('FE_OPCODE') cmdstream_map = cmdstream_xml.lookup_domain('VIV_FE') cmdstream_info = CmdStreamInfo(fe_opcode, cmdstream_map) global options options = args import re if args.binary: with open(args.input_file,'rb') as f: data = f.read() assert((len(data) % 8)==0) values = bytes_to_words(data) else: with open(args.input_file,'r') as f: # parse ascii values = [] for line in f: value = line.strip() if value.startswith(':'): value = int(value[1:9], 16) values.append(value) recs = parse_command_buffer(values, cmdstream_info, initial_padding=0) if args.output_c_raw: dump_command_buffer_c_raw(sys.stdout, recs, state_map) elif args.output_c: dump_command_buffer_c(sys.stdout, recs, state_map) else: dump_command_buffer(sys.stdout, recs, [], state_map) sys.stdout.write('\n')
def dump_command_buffer(f, mem, addr, end_addr, depth, state_map, cmdstream_info): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') states = [] # list of (ptr, state_addr) tuples words = bytes_to_words(mem[addr:end_addr]) size = (end_addr - addr) // 4 for rec in parse_command_buffer(words, cmdstream_info): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if rec.ptr != (size - 1): f.write(", /* %s */\n" % desc) else: f.write(" /* %s */\n" % desc) f.write(indent + '}') if options.list_address_states: # Print addresses; useful for making a re-play program #f.write('\n' + indent + 'GPU addresses {\n') uniqaddr = defaultdict(list) for (ptr, pos, state_format, value) in states: try: path = state_map.lookup_address(pos) except KeyError: continue type = path[-1][0].type if isinstance( type, Domain): # type Domain refers to another memory space #f.write(indent) addrname = format_addr(value) #f.write(' {0x%x,0x%05X}, /* %s = 0x%08x (%s) */\n' % (ptr, pos, format_path(path), value, addrname)) uniqaddr[value].append(ptr) #f.write(indent + '},') f.write('\n' + indent + 'Grouped GPU addresses {\n') for (value, ptrs) in uniqaddr.iteritems(): lvalues = ' = '.join([('cmdbuf[0x%x]' % ptr) for ptr in ptrs]) f.write(indent + ' ' + lvalues + ' = ' + format_addr(value) + ('; /* 0x%x */' % value) + '\n') f.write(indent + '}') if options.dump_shaders: state_by_pos = {} for (ptr, pos, state_format, value) in states: state_by_pos[pos] = value # 0x04000 and 0x06000 contain shader instructions dump_shader(f, 'vs', state_by_pos, 0x04000, 0x05000) dump_shader(f, 'ps', state_by_pos, 0x06000, 0x07000) dump_shader(f, 'vs', state_by_pos, 0x08000, 0x09000) # gc3000 dump_shader(f, 'ps', state_by_pos, 0x09000, 0x0A000) dump_shader(f, 'vs', state_by_pos, 0x0C000, 0x0D000) # gc2000 dump_shader(f, 'ps', state_by_pos, 0x0D000, 0x0E000) # XXX this offset is probably variable (gc2000) if options.dump_cmdbufs: dump_buf(f, 'cmd', words) if options.output_c: f.write('\n') for rec in parse_command_buffer(words, cmdstream_info): if rec.state_info is not None: try: path = [(state_map, None)] + state_map.lookup_address( rec.state_info.pos) except KeyError: f.write('/* Warning: unknown state %05x */\n' % rec.state_info.pos) else: # could pipe this to clang-format to format and break up lines etc f.write('etna_set_state(stream, %s, %s);\n' % (format_path_c(path), describe_c(path, rec.value))) else: # Handle other commands? pass
def dump_command_buffer(f, mem, addr, end_addr, depth, state_map, cmdstream_info, tracking, txdesc_map): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') states = [] # list of (ptr, state_addr) tuples words = bytes_to_words(mem[addr:end_addr]) size = (end_addr - addr) // 4 texture_descriptors_dumped = set() describe = ValueDumper(tracking) for rec in parse_command_buffer(words, cmdstream_info, describe=describe): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map, describe) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if rec.ptr != (size - 1): f.write(", /* %s */\n" % desc) else: f.write(" /* %s */\n" % desc) if rec.state_info is not None: # Texture descriptor? Dump every texture descriptor only once, inline. if rec.state_info.pos >= 0x15C00 and rec.state_info.pos < 0x15E00 and not rec.value in texture_descriptors_dumped: dump_texture_descriptor(f, mem, depth + [None], rec.value, tracking, txdesc_map) texture_descriptors_dumped.add(rec.value) f.write(indent + '}') if options.list_address_states: # Print addresses; useful for making a re-play program uniqaddr = defaultdict(list) for (ptr, pos, state_format, value) in states: try: path = state_map.lookup_address(pos) except KeyError: continue type = path[-1][0].type if isinstance( type, Domain): # type Domain refers to another memory space addrname = tracking.format_addr(value) uniqaddr[value].append(ptr) f.write('\n' + indent + 'Grouped GPU addresses {\n') for (value, ptrs) in uniqaddr.iteritems(): lvalues = ' = '.join([('cmdbuf[0x%x]' % ptr) for ptr in ptrs]) f.write(indent + ' ' + lvalues + ' = ' + tracking.format_addr(value) + ('; /* 0x%x */' % value) + '\n') f.write(indent + '}') if options.dump_shaders: state_by_pos = {} for (ptr, pos, state_format, value) in states: state_by_pos[pos] = value # 0x04000 and 0x06000 contain shader instructions dump_shader(f, 'vs', state_by_pos, 0x04000, 0x05000, tracking) dump_shader(f, 'ps', state_by_pos, 0x06000, 0x07000, tracking) dump_shader(f, 'vs', state_by_pos, 0x08000, 0x09000, tracking) # gc3000 dump_shader(f, 'ps', state_by_pos, 0x09000, 0x0A000, tracking) dump_shader(f, 'vs', state_by_pos, 0x0C000, 0x0D000, tracking) # gc2000 dump_shader(f, 'ps', state_by_pos, 0x0D000, 0x0E000, tracking) # XXX this offset is probably variable (gc2000) try: dump_shader_icache(f, mem, 'vs', state_by_pos[0x0086C], state_by_pos[0x00874], state_by_pos[0x008BC], tracking) except KeyError: pass try: dump_shader_icache(f, mem, 'ps', state_by_pos[0x01028], state_by_pos[0x0087C], state_by_pos[0x01090], tracking) except KeyError: pass if options.dump_cmdbufs: dump_buf(f, 'cmd', words, tracking) if options.output_c: f.write('\n') dump_command_buffer_c(f, parse_command_buffer(words, cmdstream_info), state_map, tracking.format_addr)
def dump_command_buffer(f, mem, addr, end_addr, depth, state_map, cmdstream_info, tracking, txdesc_map): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') states = [] # list of (ptr, state_addr) tuples words = bytes_to_words(mem[addr:end_addr]) size = (end_addr - addr)//4 texture_descriptors_dumped = set() describe = ValueDumper(tracking) for rec in parse_command_buffer(words, cmdstream_info, describe=describe): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map, describe) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if rec.ptr != (size-1): f.write(", /* %s */\n" % desc) else: f.write(" /* %s */\n" % desc) if rec.state_info is not None: # Texture descriptor? Dump every texture descriptor only once, inline. if rec.state_info.pos >= 0x15C00 and rec.state_info.pos < 0x15E00 and not rec.value in texture_descriptors_dumped: dump_texture_descriptor(f, mem, depth + [None], rec.value, tracking, txdesc_map) texture_descriptors_dumped.add(rec.value) f.write(indent + '}') if options.list_address_states: # Print addresses; useful for making a re-play program uniqaddr = defaultdict(list) for (ptr, pos, state_format, value) in states: try: path = state_map.lookup_address(pos) except KeyError: continue type = path[-1][0].type if isinstance(type, Domain): # type Domain refers to another memory space addrname = tracking.format_addr(value) uniqaddr[value].append(ptr) f.write('\n' + indent + 'Grouped GPU addresses {\n') for (value, ptrs) in uniqaddr.iteritems(): lvalues = ' = '.join([('cmdbuf[0x%x]' % ptr) for ptr in ptrs]) f.write(indent + ' ' + lvalues + ' = ' + tracking.format_addr(value) + ('; /* 0x%x */' % value) + '\n') f.write(indent + '}') if options.dump_shaders: state_by_pos = {} for (ptr, pos, state_format, value) in states: state_by_pos[pos]=value # 0x04000 and 0x06000 contain shader instructions dump_shader(f, 'vs', state_by_pos, 0x04000, 0x05000, tracking) dump_shader(f, 'ps', state_by_pos, 0x06000, 0x07000, tracking) dump_shader(f, 'vs', state_by_pos, 0x08000, 0x09000, tracking) # gc3000 dump_shader(f, 'ps', state_by_pos, 0x09000, 0x0A000, tracking) dump_shader(f, 'vs', state_by_pos, 0x0C000, 0x0D000, tracking) # gc2000 dump_shader(f, 'ps', state_by_pos, 0x0D000, 0x0E000, tracking) # XXX this offset is probably variable (gc2000) try: dump_shader_icache(f, mem, 'vs', state_by_pos[0x0086C], state_by_pos[0x00874], state_by_pos[0x008BC], tracking) except KeyError: pass try: dump_shader_icache(f, mem, 'ps', state_by_pos[0x01028], state_by_pos[0x0087C], state_by_pos[0x01090], tracking) except KeyError: pass if options.dump_cmdbufs: dump_buf(f, 'cmd', words, tracking) if options.output_c: f.write('\n') dump_command_buffer_c(f, parse_command_buffer(words, cmdstream_info), state_map, tracking.format_addr)
def main(): args = parse_arguments() state_xml = parse_rng_file(args.rules_file) state_map = state_xml.lookup_domain('VIVS') cmdstream_xml = parse_rng_file(args.cmdstream_file) fe_opcode = cmdstream_xml.lookup_type('FE_OPCODE') cmdstream_map = cmdstream_xml.lookup_domain('VIV_FE') cmdstream_info = CmdStreamInfo(fe_opcode, cmdstream_map) global options options = args import re if args.binary: # Binary format with open(args.input_file, 'rb') as f: data = f.read() assert ((len(data) % 8) == 0) values = bytes_to_words(data) addrs = None tgtaddrs = None elif args.galcore: # Vivante kernel format values = [] addrs = [] tgtaddrs = set() with open(args.input_file, 'r') as f: for line in f: #value = line.strip() #if value.startswith(':'): # value = int(value[1:9], 16) # values.append(value) m = re.search('DMA Address 0x([0-9A-F]{8})', line) if m: tgtaddrs.add(int(m.group(1), 16)) m = re.search('([0-9A-F]{8}) : (([0-9A-F]{8} )*[0-9A-F]{8})$', line) # [ 309.029521] 3FD84000 : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 if m: addr = int(m.group(1), 16) for i, d in enumerate(m.group(2).split(' ')): addrs.append(addr + i * 4) values.append(int(d, 16)) else: # old etnaviv ASCII format values = [] addrs = None tgtaddrs = None with open(args.input_file, 'r') as f: for line in f: value = line.strip() if value.startswith(':'): value = int(value[1:9], 16) values.append(value) recs = parse_command_buffer(values, cmdstream_info, initial_padding=0) if args.output_c_raw: dump_command_buffer_c_raw(sys.stdout, recs, state_map) elif args.output_c: dump_command_buffer_c(sys.stdout, recs, state_map) else: dump_command_buffer(sys.stdout, recs, [], state_map, addrs, tgtaddrs) sys.stdout.write('\n')
def main(): args = parse_arguments() state_xml = parse_rng_file(args.rules_file) state_map = state_xml.lookup_domain('VIVS') cmdstream_xml = parse_rng_file(args.cmdstream_file) fe_opcode = cmdstream_xml.lookup_type('FE_OPCODE') cmdstream_map = cmdstream_xml.lookup_domain('VIV_FE') cmdstream_info = CmdStreamInfo(fe_opcode, cmdstream_map) global options options = args import re if args.binary: # Binary format with open(args.input_file,'rb') as f: data = f.read() assert((len(data) % 8)==0) values = bytes_to_words(data) addrs = None tgtaddrs = None elif args.galcore: # Vivante kernel format values = [] addrs = [] tgtaddrs = set() with open(args.input_file,'r') as f: for line in f: #value = line.strip() #if value.startswith(':'): # value = int(value[1:9], 16) # values.append(value) m = re.search('DMA Address 0x([0-9A-F]{8})', line) if m: tgtaddrs.add(int(m.group(1), 16)) m = re.search('([0-9A-F]{8}) ?: (([0-9A-F]{8} )*[0-9A-F]{8})$', line, flags=re.IGNORECASE) # Vendor kernel with vivante HAL # [ 309.029521] 3FD84000 : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 # Mainline kernel with etnaviv DRM # [ 2121.178339] cmd 00000000: 380000c8 00000000 40000002 00000000 if m: addr = int(m.group(1), 16) for i,d in enumerate(m.group(2).split(' ')): addrs.append(addr + i*4) values.append(int(d, 16)) else: # old etnaviv ASCII format values = [] addrs = None tgtaddrs = None with open(args.input_file,'r') as f: for line in f: value = line.strip() if value.startswith(':'): value = int(value[1:9], 16) values.append(value) recs = parse_command_buffer(values, cmdstream_info, initial_padding=0) if args.output_c_raw: dump_command_buffer_c_raw(sys.stdout, recs, state_map) elif args.output_c: dump_command_buffer_c(sys.stdout, recs, state_map) else: dump_command_buffer(sys.stdout, recs, [], state_map, addrs, tgtaddrs) sys.stdout.write('\n')