예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
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)
예제 #4
0
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 + '}')
예제 #5
0
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')
예제 #6
0
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
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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')
예제 #10
0
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')