def print_workqueue_state_3_10(self, ram_dump): cpu_worker_pools_addr = ram_dump.addr_lookup('cpu_worker_pools') busy_hash_offset = ram_dump.field_offset( 'struct worker_pool', 'busy_hash') worker_entry_offset = ram_dump.field_offset('struct worker', 'entry') work_entry_offset = ram_dump.field_offset( 'struct work_struct', 'entry') work_hentry_offset = ram_dump.field_offset('struct worker', 'hentry') pool_idle_offset = ram_dump.field_offset( 'struct worker_pool', 'idle_list') worker_pool_size = ram_dump.sizeof('struct worker_pool') pending_work_offset = ram_dump.field_offset( 'struct worker_pool', 'worklist') hash_size = 2 ** self.ramdump.gdbmi.get_value_of('BUSY_WORKER_HASH_ORDER') s = '<' if ram_dump.arm64: pool_char = 'Q' else: pool_char = 'I' for a in range(0, hash_size): s = s + pool_char for i in ram_dump.iter_cpus(): busy_hash = [] worker_pool = cpu_worker_pools_addr + ram_dump.per_cpu_offset(i) print_out_str('\nCPU {0}'.format(i)) n_pools = self.ramdump.gdbmi.get_value_of('NR_STD_WORKER_POOLS') for k in range(0, n_pools): print_out_str('pool {0}'.format(k)) worker_pool_i = worker_pool + k * worker_pool_size busy_hashi = ram_dump.read_string( worker_pool_i + busy_hash_offset, s) for a in busy_hashi: busy_hash.append(a) for k in range(0, hash_size): next_busy_worker = busy_hash[k] if busy_hash[k] != 0: busy_list_walker = linux_list.ListWalker(ram_dump, next_busy_worker, work_hentry_offset) busy_list_walker.walk(next_busy_worker, self.walk_workers, 'BUSY') idle_list_addr = worker_pool_i + pool_idle_offset idle_list_walker = linux_list.ListWalker(ram_dump, idle_list_addr, worker_entry_offset) idle_list_walker.walk(self.ramdump.read_word(idle_list_addr), self.walk_workers, 'IDLE') worklist_addr = worker_pool_i + pending_work_offset pending_list = linux_list.ListWalker(ram_dump, worklist_addr, work_entry_offset) pending_list.walk(self.ramdump.read_word(worklist_addr), self.pending_list_walk)
def ftrace_events_func(self, ftrace_list, ram_dump): event_offset = ram_dump.field_offset('struct ftrace_event_call', 'event') fmt_offset = ram_dump.field_offset('struct ftrace_event_call', 'print_fmt') class_offset = ram_dump.field_offset('struct ftrace_event_call', 'class') flags_offset = ram_dump.field_offset('struct ftrace_event_call', 'flags') flags = ram_dump.read_word(ftrace_list + flags_offset) if (ram_dump.kernel_version >= (3, 18) and (flags & TRACE_EVENT_FL_TRACEPOINT)): tp_offset = ram_dump.field_offset('struct ftrace_event_call', 'tp') tp_name_offset = ram_dump.field_offset('struct tracepoint', 'name') tp = ram_dump.read_word(ftrace_list + tp_offset) name = ram_dump.read_word(tp + tp_name_offset) else: name_offset = ram_dump.field_offset('struct ftrace_event_call', 'name') name = ram_dump.read_word(ftrace_list + name_offset) type_offset = ram_dump.field_offset('struct trace_event', 'type') fields_offset = ram_dump.field_offset('struct ftrace_event_class', 'fields') common_field_list = ram_dump.address_of('ftrace_common_fields') field_next_offset = ram_dump.field_offset('struct ftrace_event_field', 'link') name_str = ram_dump.read_cstring(name, 512) event_id = ram_dump.read_word(ftrace_list + event_offset + type_offset) fmt = ram_dump.read_word(ftrace_list + fmt_offset) fmt_str = ram_dump.read_cstring(fmt, 2048) self.formats_out.write("name: {0}\n".format(name_str)) self.formats_out.write("ID: {0}\n".format(event_id)) self.formats_out.write("format:\n") list_walker = llist.ListWalker(ram_dump, common_field_list, field_next_offset) list_walker.walk_prev(common_field_list, self.ftrace_field_func, ram_dump) self.formats_out.write("\n") event_class = ram_dump.read_word(ftrace_list + class_offset) field_list = event_class + fields_offset list_walker = llist.ListWalker(ram_dump, field_list, field_next_offset) list_walker.walk_prev(field_list, self.ftrace_field_func, ram_dump) self.formats_out.write("\n") self.formats_out.write("print fmt: {0}\n".format(fmt_str))
def print_modules(self): module_out = self.ramdump.open_file('modules.txt') self.module_out = module_out next_mod_offset = self.ramdump.field_offset('struct module','list') if (self.ramdump.mod_start is None): self.module_out.write("module variable not valid") module_out.close() return self.module_out.write("Module list\n") self.module_out.write("-----------\n\n\n") self.name_offset = self.ramdump.field_offset('struct module', 'name') if (re.search('3.14.77', self.ramdump.version) is not None or (self.ramdump.kernel_version[0], self.ramdump.kernel_version[1]) >= (4, 4)): self.kallsyms_offset = self.ramdump.field_offset('struct module', 'kallsyms') self.module_symtab_offset = self.ramdump.field_offset('struct mod_kallsyms','symtab') self.module_strtab_offset = self.ramdump.field_offset('struct mod_kallsyms','strtab') self.module_symtab_count_offset = self.ramdump.field_offset('struct mod_kallsyms','num_symtab') else: self.module_symtab_offset = self.ramdump.field_offset('struct module','symtab') self.module_strtab_offset = self.ramdump.field_offset('struct module','strtab') self.module_symtab_count_offset = self.ramdump.field_offset('struct module','num_symtab') if(self.ramdump.isELF64()): self.symtab_st_shndx_offset = self.ramdump.field_offset('struct elf64_sym', 'st_shndx') self.symtab_st_value_offset = self.ramdump.field_offset('struct elf64_sym', 'st_value') self.symtab_st_info_offset = self.ramdump.field_offset('struct elf64_sym', 'st_info') self.symtab_st_name_offset = self.ramdump.field_offset('struct elf64_sym', 'st_name') self.symtab_st_size_offset = self.ramdump.field_offset('struct elf64_sym', 'st_size') else: self.symtab_st_shndx_offset = self.ramdump.field_offset('struct elf32_sym', 'st_shndx') self.symtab_st_value_offset = self.ramdump.field_offset('struct elf32_sym', 'st_value') self.symtab_st_info_offset = self.ramdump.field_offset('struct elf32_sym', 'st_info') self.symtab_st_name_offset = self.ramdump.field_offset('struct elf32_sym', 'st_name') self.symtab_st_size_offset = self.ramdump.field_offset('struct elf32_sym', 'st_size') if(self.ramdump.isELF64()): self.symtab_size = self.ramdump.sizeof('struct elf64_sym') else: self.symtab_size = self.ramdump.sizeof('struct elf32_sym') #simple walk through to get address of module name_list_walker = llist.ListWalker(self.ramdump, self.ramdump.mod_start, next_mod_offset) name_list_walker.walk(self.ramdump.mod_start, self.mod_light_func) list_walker = llist.ListWalker(self.ramdump, self.ramdump.mod_start, next_mod_offset) list_walker.walk(self.ramdump.mod_start, self.mod_list_func) module_out.close()
def iommu_domain_func(self, node): domain_num_addr = (node - self.node_offset) + self.domain_num_offset domain_num = self.ramdump.read_word(domain_num_addr) domain_addr = (node - self.node_offset) + self.domain_offset domain = self.ramdump.read_word(domain_addr) priv_ptr = self.ramdump.read_word(domain + self.priv_offset) if self.client_name_offset is not None: client_name_ptr = self.ramdump.read_word(priv_ptr + self.client_name_offset) if client_name_ptr != 0: client_name = self.ramdump.read_cstring(client_name_ptr, 100) else: client_name = '(null)' else: client_name = 'unknown' if self.list_attached_offset is not None: list_attached = self.ramdump.read_word(priv_ptr + self.list_attached_offset) else: list_attached = None if self.priv_pt_offset is not None: pg_table = self.ramdump.read_word(priv_ptr + self.priv_pt_offset + self.pgtable_offset) redirect = self.ramdump.read_word(priv_ptr + self.priv_pt_offset + self.redirect_offset) else: #On some builds we are unable to look up the offsets so hardcode the offsets. pg_table = self.ramdump.read_word(priv_ptr + 0) redirect = self.ramdump.read_word(priv_ptr + 4) #Note: On some code bases we don't have this pg_table and redirect in the priv structure (see msm_iommu_sec.c). It only #contains list_attached. If this is the case we can detect that by checking whether #pg_table == redirect (prev == next pointers of the attached list). if pg_table == redirect: #This is a secure domain. We don't have access to the page tables. pg_table = 0 redirect = None if list_attached is not None and list_attached != 0: list_walker = llist.ListWalker(self.ramdump, list_attached, self.ctxdrvdata_attached_offset, self.list_next_offset, self.list_prev_offset) list_walker.walk(list_attached, self.list_func) dom = self.Domain() dom.domain_num = domain_num dom.pg_table = pg_table dom.redirect = redirect dom.ctx_list = self.ctx_list dom.client_name = client_name self.ctx_list = [] self.domain_list.append(dom)
def calculate_vmalloc(self): next_offset = self.ramdump.field_offset('struct vmap_area', 'list') vmlist = self.ramdump.read_word('vmap_area_list') vm_offset = self.ramdump.field_offset('struct vmap_area', 'vm') self.vm_offset = vm_offset list_walker = llist.ListWalker(self.ramdump, vmlist, next_offset) list_walker.walk(vmlist, self.list_func) self.vmalloc_size = self.bytes_to_mb(self.vmalloc_size)
def iterate_vec(self, type, base): vec_addr = base + self.ramdump.field_offset(self.tvec_base, type) for i in range(0, self.vectors[type]): index = self.ramdump.array_index(vec_addr, 'struct list_head', i) self.head = index node_offset = self.ramdump.field_offset('struct list_head', 'next') timer_list_walker = linux_list.ListWalker(self.ramdump, index, node_offset) timer_list_walker.walk(index, self.timer_list_walker, type, i, base)
def get_clocks(self): clocks = self.ramdump.address_of('clocks') if clocks is None: self.output_file.write("NOTE: 'clocks' list not found to extract the clocks information") return head = self.ramdump.read_word(clocks, True) self.head = clocks node_offset = self.ramdump.field_offset('struct clk_lookup', 'node') clocks_walker = linux_list.ListWalker(self.ramdump, head, node_offset) clocks_walker.walk(head, self.clocks_walker)
def collect_ftrace_format(self, ram_dump): formats = os.path.join('qtf', 'map_files', 'formats.txt') formats_out = ram_dump.open_file(formats) self.formats_out = formats_out ftrace_events_list = ram_dump.address_of('ftrace_events') next_offset = ram_dump.field_offset(self.event_call, 'list') list_walker = llist.ListWalker(ram_dump, ftrace_events_list, next_offset) list_walker.walk_prev(ftrace_events_list, self.ftrace_events_func, ram_dump) self.formats_out.close
def dump_consumer(self, consumer_head): tmp = "" tmp += "\nConsumers:\n" tmp += "%-48s%-10s%-10s%-10s\n" % ("Device-Supply", "EN", "Min_Uv", "Max_Uv") self.output.append(tmp) node_offset = self.ramdump.field_offset('struct regulator', 'list') self.consumer_head = consumer_head c_w = linux_list.ListWalker(self.ramdump, consumer_head, node_offset) c_w.walk(consumer_head, self.consumer_walker) self.output.append("\n")
def print_vmalloc_info_3_10(self, out_path): vmalloc_out = self.ramdump.open_file('vmalloc.txt') next_offset = self.ramdump.field_offset('struct vmap_area', 'list') vmlist = self.ramdump.read_word('vmap_area_list') orig_vmlist = vmlist list_walker = llist.ListWalker(self.ramdump, vmlist, next_offset) self.vmalloc_out = vmalloc_out list_walker.walk(vmlist, self.list_func) print_out_str('---wrote vmalloc to vmalloc.txt') vmalloc_out.close()
def print_modules(self): module_out = self.ramdump.open_file('modules.txt') self.module_out = module_out next_mod_offset = self.ramdump.field_offset('struct module','list') mod_start = self.ramdump.read_word('modules') self.module_out.write("Module list\n") self.module_out.write("-----------\n") self.module_out.write("Address Name\n") self.module_out.write("------------------------\n") list_walker = llist.ListWalker(self.ramdump, mod_start, next_mod_offset) list_walker.walk(mod_start, self.mod_list_func) module_out.close()
def get_cpr(self): # Return if the cpr_regulator_list is not available cpr = self.ramdump.address_of('cpr_regulator_list') if cpr is None: self.output_file.write( "NOTE: 'cpr_regulator_list' list not found to extract cpr information" ) return head = self.ramdump.read_word(cpr) self.head = cpr node_offset = self.ramdump.field_offset('struct cpr_regulator', 'list') cpr_walker = linux_list.ListWalker(self.ramdump, head, node_offset) cpr_walker.walk(head, self.cpr_walker)
def ftrace_events_func(self, ftrace_list, ram_dump): name_offset = ram_dump.field_offset('struct ftrace_event_call', 'name') event_offset = ram_dump.field_offset('struct ftrace_event_call', 'event') fmt_offset = ram_dump.field_offset('struct ftrace_event_call', 'print_fmt') class_offset = ram_dump.field_offset('struct ftrace_event_call', 'class') type_offset = ram_dump.field_offset('struct trace_event', 'type') fields_offset = ram_dump.field_offset('struct ftrace_event_class', 'fields') common_field_list = ram_dump.addr_lookup('ftrace_common_fields') field_next_offset = ram_dump.field_offset('struct ftrace_event_field', 'link') name = ram_dump.read_word(ftrace_list + name_offset) name_str = ram_dump.read_cstring(name, 512) event_id = ram_dump.read_word(ftrace_list + event_offset + type_offset) fmt = ram_dump.read_word(ftrace_list + fmt_offset) fmt_str = ram_dump.read_cstring(fmt, 2048) self.formats_out.write("name: {0}\n".format(name_str)) self.formats_out.write("ID: {0}\n".format(event_id)) self.formats_out.write("format:\n") list_walker = llist.ListWalker(ram_dump, common_field_list, field_next_offset) list_walker.walk_prev(common_field_list, self.ftrace_field_func, ram_dump) self.formats_out.write("\n") event_class = ram_dump.read_word(ftrace_list + class_offset) field_list = event_class + fields_offset list_walker = llist.ListWalker(ram_dump, field_list, field_next_offset) list_walker.walk_prev(field_list, self.ftrace_field_func, ram_dump) self.formats_out.write("\n") self.formats_out.write("print fmt: {0}\n".format(fmt_str))
def get_clk_providers(self): clocks = self.ramdump.address_of('of_clk_providers') if clocks is None: self.output_file.write("NOTE: 'of_clk_providers' list not found to extract the clocks information") return self.enabled_clocks = [] self.disabled_clocks = [] self.prepared_clocks = [] self.head = clocks head = self.ramdump.read_word(clocks, True) node_offset = self.ramdump.field_offset('struct clk_lookup', 'node') clk_providers_walker = linux_list.ListWalker(self.ramdump, head, node_offset) clk_providers_walker.walk(head, self.clk_providers_walker)
def get_clusters(self): lpm_root_node = self.ramdump.read_word( self.ramdump.address_of('lpm_root_node'), True) if lpm_root_node is None: self.output_file.write("NOTE: 'lpm_root_node' not found\n") return self.clusters.append(lpm_root_node) offset = self.ramdump.field_offset('struct lpm_cluster', 'child') lpm_cluster = self.ramdump.read_word(lpm_root_node + offset, True) self.head = lpm_root_node + offset offset = self.ramdump.field_offset('struct lpm_cluster', 'list') lpm_walker = linux_list.ListWalker(self.ramdump, lpm_cluster, offset) lpm_walker.walk(lpm_cluster, self.lpm_walker)
def get_kryo(self): kryo_addr = self.ramdump.address_of('kryo_regulator_list') if kryo_addr is None: print("NOTE: 'kryo_regulator_list' list " + "not found to extract kryo_addr information") return head = self.ramdump.read_word(kryo_addr) self.head = kryo_addr node_offset = self.ramdump.field_offset('struct kryo_regulator', 'link') k_w = linux_list.ListWalker(self.ramdump, head, node_offset) tmp = "=" * 80 + "\n" tmp += "Kryo Regulator (LDO/BHS management)\n" tmp += "=" * 80 + "\n" self.output.append(tmp) k_w.walk(head, self.kryo_walker)
def get_spm(self): lpm_root_node = self.ramdump.read_word( self.ramdump.address_of('lpm_root_node'), True) if lpm_root_node is None: self.output_file.write("NOTE: 'lpm_root_node' not found\n") return offset = self.ramdump.field_offset('struct lpm_cluster', 'lpm_dev') lpm_dev = self.ramdump.read_word(lpm_root_node + offset, True) offset = self.ramdump.field_offset('struct low_power_ops', 'spm') spm = self.ramdump.read_word(lpm_dev + offset, True) self.head = lpm_dev + offset offset = self.ramdump.field_offset('struct msm_spm_device', 'list') spm_walker = linux_list.ListWalker(self.ramdump, spm, offset) spm_walker.walk(spm, self.spm_walker)
def print_vmalloc_info_v2(self, out_path): vmalloc_out = self.ramdump.open_file('vmalloc.txt') next_offset = self.ramdump.field_offset('struct vmap_area', 'list') vmlist = self.ramdump.read_word('vmap_area_list') orig_vmlist = vmlist list_walker = llist.ListWalker(self.ramdump, vmlist, next_offset) self.vmalloc_out = vmalloc_out vmalloc_str = 'Memory mapped region allocated by Vmalloc\n\n' vmalloc_str = vmalloc_str + '{0:42} {1:36} {2:6} {3:12} {4:46} {5:8}'\ .format('VM_STRUCT','ADDRESS_RANGE','SIZE','PHYS_ADDR','CALLER', 'Flag') vmalloc_str = vmalloc_str + '\n' self.vmalloc_out.write(vmalloc_str) list_walker.walk(vmlist, self.list_func) print_out_str('---wrote vmalloc to vmalloc.txt') vmalloc_out.close()
def parse(self): self.vidc_info = self.ramdump.open_file('vidc_info.txt') if (self.ramdump.kernel_version < (4, 9, 0)): self.vidc_info.write('Kernel version 4.9 \ and above are supported, current version {0}.\ {1}'.format(self.ramdump.kernel_version[0], self.ramdump.kernel_version[1])) self.vidc_info.close() return vidc_driver_addr = self.ramdump.read_word( self.ramdump.address_of('vidc_driver')) head_core = vidc_driver_addr + self.ramdump.field_offset( 'struct msm_vidc_drv', 'cores') offset_core = self.ramdump.field_offset('struct msm_vidc_core', 'list') core_walker = llist.ListWalker(self.ramdump, head_core, offset_core) head_core = core_walker.next() core_walker.walk(head_core, self.core_walker) self.vidc_info.close()
def __init__(self, ramdump): self.ramdump = ramdump self.domain_list = [] root = self.ramdump.read_word('domain_root') list_head_attachments = self.ramdump.read_pointer( 'iommu_debug_attachments') if list_head_attachments is not None: list_head_arm_addr = self.ramdump.read_structure_field( list_head_attachments, 'struct list_head', 'prev') list_walker = llist.ListWalker( self.ramdump, list_head_arm_addr, self.ramdump.field_offset('struct iommu_debug_attachment', 'list')) list_walker.walk(list_head_attachments, self._iommu_domain_find_default, self.domain_list) if root is not None: rb_walker = rb_tree.RbTreeWalker(self.ramdump) rb_walker.walk(root, self._iommu_domain_func, self.domain_list)
def _iommu_domain_func(self, node, domain_list): domain_num = self.ramdump.read_u32( self.ramdump.sibling_field_addr(node, 'struct msm_iova_data', 'node', 'domain_num')) domain = self.ramdump.read_word( self.ramdump.sibling_field_addr(node, 'struct msm_iova_data', 'node', 'domain')) priv_ptr = self.ramdump.read_word( domain + self.ramdump.field_offset('struct iommu_domain', 'priv')) client_name_offset = self.ramdump.field_offset('struct msm_iommu_priv', 'client_name') if client_name_offset is not None: client_name_ptr = self.ramdump.read_word( priv_ptr + self.ramdump.field_offset('struct msm_iommu_priv', 'client_name')) if client_name_ptr != 0: client_name = self.ramdump.read_cstring(client_name_ptr, 100) else: client_name = '(null)' else: client_name = 'unknown' list_attached_offset = self.ramdump.field_offset( 'struct msm_iommu_priv', 'list_attached') if list_attached_offset is not None: list_attached = self.ramdump.read_word(priv_ptr + list_attached_offset) else: list_attached = None priv_pt_offset = self.ramdump.field_offset('struct msm_iommu_priv', 'pt') pgtable_offset = self.ramdump.field_offset('struct msm_iommu_pt', 'fl_table') redirect_offset = self.ramdump.field_offset('struct msm_iommu_pt', 'redirect') if priv_pt_offset is not None: pg_table = self.ramdump.read_word(priv_ptr + priv_pt_offset + pgtable_offset) redirect = self.ramdump.read_u32(priv_ptr + priv_pt_offset + redirect_offset) else: # On some builds we are unable to look up the offsets so hardcode # the offsets. pg_table = self.ramdump.read_word(priv_ptr + 0) redirect = self.ramdump.read_u32(priv_ptr + self.ramdump.sizeof('void *')) # Note: On some code bases we don't have this pg_table and redirect # in the priv structure (see msm_iommu_sec.c). It only contains # list_attached. If this is the case we can detect that by checking # whether pg_table == redirect (prev == next pointers of the # attached list). if pg_table == redirect: # This is a secure domain. We don't have access to the page # tables. pg_table = 0 redirect = None ctx_list = [] if list_attached is not None and list_attached != 0: list_walker = llist.ListWalker( self.ramdump, list_attached, self.ramdump.field_offset('struct msm_iommu_ctx_drvdata', 'attached_elm')) list_walker.walk(list_attached, self._iommu_list_func, ctx_list) if (self.ramdump.is_config_defined('CONFIG_IOMMU_AARCH64')): domain_create = Domain(pg_table, redirect, ctx_list, client_name, MSM_SMMU_AARCH64_DOMAIN, domain_num=domain_num) else: domain_create = Domain(pg_table, redirect, ctx_list, client_name, MSM_SMMU_DOMAIN, domain_num=domain_num) domain_list.append(domain_create)
def core_walker(self, head): self.vidc_info.write('\n========CORE STATS========\n') self.vidc_info.write( 'Core Addr: \t0x{:1x}\n'.format(head).expandtabs(20)) core_id = self.ramdump.read_structure_field(head, 'struct msm_vidc_core', 'id') self.vidc_info.write('core: \t{0}\n'.format(core_id).expandtabs(20)) state = self.ramdump.read_structure_field(head, 'struct msm_vidc_core', 'state') self.vidc_info.write('state: \t{0}\n'.format(state).expandtabs(20)) hfi_type = self.ramdump.read_structure_field(head, 'struct msm_vidc_core', 'hfi_type') self.vidc_info.write( 'hfi_type: \t{0}\n'.format(hfi_type).expandtabs(20)) codec_count = self.ramdump.read_structure_field( head, 'struct msm_vidc_core', 'codec_count') self.vidc_info.write( 'codec_count: \t{0}\n'.format(codec_count).expandtabs(20)) smmu_fault_handled_addr = head + self.ramdump.field_offset( 'struct msm_vidc_core', 'trigger_ssr') smmu_fault_handled = self.ramdump.read_bool(smmu_fault_handled_addr) self.vidc_info.write( 'smmu_fault_handled: {0}\n'.format(smmu_fault_handled)) trigger_ssr_addr = head + self.ramdump.field_offset( 'struct msm_vidc_core', 'trigger_ssr') trigger_ssr = self.ramdump.read_bool(trigger_ssr_addr) self.vidc_info.write( 'trigger_ssr: \t{0}\n'.format(trigger_ssr).expandtabs(20)) min_freq = self.ramdump.read_structure_field(head, 'struct msm_vidc_core', 'min_freq') self.vidc_info.write( 'min freq: \t{0}\n'.format(min_freq).expandtabs(20)) curr_freq = self.ramdump.read_structure_field(head, 'struct msm_vidc_core', 'curr_freq') self.vidc_info.write( 'curr_freq: \t{0}\n'.format(curr_freq).expandtabs(20)) self.vidc_info.write('\nCompletions:\n------------\n') for i in range(0, 27): completion = head + self.ramdump.field_offset('struct msm_vidc_core',\ 'completions['+str(i)+']') done = self.ramdump.read_structure_field(head, 'struct completion', 'done') self.vidc_info.write('[{0:02d}]: {1} '.format( i, 'done' if done else 'pending')) if (i + 1) % 9 == 0 or i == 26: self.vidc_info.write('\n') self.vidc_info.write('\n=======DEVICE STATS=======\n') head_hfi_device_data = self.ramdump.read_structure_field( head, 'struct msm_vidc_core', 'device') head_hfi_device_data = self.ramdump.read_word(head_hfi_device_data) self.vidc_info.write('Device Addr: \t0x{:1x}\n'.format( head_hfi_device_data).expandtabs(20)) self.get_hfi_device(head_hfi_device_data) head_inst = head + self.ramdump.field_offset('struct msm_vidc_core', 'instances') offset_inst = self.ramdump.field_offset('struct msm_vidc_inst', 'list') inst_walker = llist.ListWalker(self.ramdump, head_inst, offset_inst) head_inst = inst_walker.next() inst_walker.walk(head_inst, self.inst_walker)
def inst_walker(self, head): self.vidc_info.write('\n========INST STATS========\n') self.vidc_info.write( 'Instance Addr: \t0x{:1x}\n'.format(head).expandtabs(20)) in_reconfig_addr = head + self.ramdump.field_offset( 'struct msm_vidc_inst', 'in_reconfig') in_reconfig = self.ramdump.read_bool(in_reconfig_addr) self.vidc_info.write( 'Reconfig: \t{0}\n'.format(in_reconfig).expandtabs(20)) reconfig_width = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'reconfig_width') self.vidc_info.write( 'Reconfig width: \t{0}\n'.format(reconfig_width).expandtabs(20)) reconfig_height = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'reconfig_height') self.vidc_info.write( 'Reconfig height: \t{0}\n'.format(reconfig_height).expandtabs(20)) session_type = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'session_type') self.vidc_info.write('Session Type: \t{0}\n'\ .format('DECODER' if session_type else 'ENCODER').expandtabs(20)) session_addr = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'session') session_id = (session_addr >> 32) ^ (session_addr & 0x00000000FFFFFFFF) self.vidc_info.write( 'Session_id: \t0x{:1x}\n'.format(session_id).expandtabs(20)) state = self.ramdump.read_structure_field(head, 'struct msm_vidc_inst', 'state') state_str = self.inst_state_dict[format(state, '#06x')] self.vidc_info.write('State: \t{0}\n'.format(state_str).expandtabs(20)) in_flush_addr = head + self.ramdump.field_offset( 'struct msm_vidc_inst', 'in_flush') in_flush = self.ramdump.read_bool(in_flush_addr) self.vidc_info.write( 'In flush: \t{0}\n'.format(in_flush).expandtabs(20)) pic_struct = self.ramdump.read_structure_field(head, 'struct msm_vidc_inst', 'pic_struct') self.vidc_info.write( 'Pic Struct: \t{0}\n'.format(pic_struct).expandtabs(20)) colour_space = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'colour_space') self.vidc_info.write( 'Colour Space: \t{0}\n'.format(colour_space).expandtabs(20)) profile = self.ramdump.read_structure_field(head, 'struct msm_vidc_inst', 'profile') self.vidc_info.write('Profile: \t{0}\n'.format(profile).expandtabs(20)) level = self.ramdump.read_structure_field(head, 'struct msm_vidc_inst', 'level') self.vidc_info.write('Level: \t{:1x}\n'.format(level).expandtabs(20)) entropy_mode = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'entropy_mode') self.vidc_info.write( 'Entropy Mode: \t{0}\n'.format(entropy_mode).expandtabs(20)) smem_client = self.ramdump.read_structure_field( head, 'struct msm_vidc_inst', 'mem_client') client = self.ramdump.read_structure_field(smem_client, 'struct smem_client', 'clnt') display_name = self.ramdump.read_structure_cstring( client, 'struct ion_client', 'display_name') self.vidc_info.write( 'Client: \t{0}\n'.format(display_name).expandtabs(20)) output_fmt = head + self.ramdump.field_offset('struct msm_vidc_inst', 'fmts[0]') description_addr = output_fmt +self.ramdump.field_offset('struct msm_vidc_format', 'description') desc_out = self.ramdump.read_cstring(description_addr) caputre_fmt = head + self.ramdump.field_offset('struct msm_vidc_inst', 'fmts[1]') description_addr = caputre_fmt +self.ramdump.field_offset('struct msm_vidc_format', 'description') desc_cap = self.ramdump.read_cstring(description_addr) session_prop = head + self.ramdump.field_offset( 'struct msm_vidc_inst', 'prop') fps = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'fps') self.vidc_info.write('FPS: \t{0}\n'.format(fps).expandtabs(20)) bitrate = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'bitrate') self.vidc_info.write('Bitrate: \t{0}\n'.format(bitrate).expandtabs(20)) width_out = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'width[0]') height_out = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'height[0]') bufq_out = head + self.ramdump.field_offset('struct msm_vidc_inst', 'bufq[0]') num_planes_out = self.ramdump.read_structure_field( bufq_out, 'struct buf_queue', 'num_planes') plane_sizes_out = [] for i in range(0, num_planes_out): plane_sizes_out.append( self.ramdump.read_structure_field( bufq_out, 'struct buf_queue', 'plane_sizes[' + str(i) + ']')) width_cap = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'width[1]') height_cap = self.ramdump.read_structure_field(session_prop, 'struct session_prop', 'height[1]') bufq_cap = head + self.ramdump.field_offset('struct msm_vidc_inst', 'bufq[1]') num_planes_cap = self.ramdump.read_structure_field( bufq_cap, 'struct buf_queue', 'num_planes') plane_sizes_cap = [] for i in range(0, num_planes_cap): plane_sizes_cap.append( self.ramdump.read_structure_field( bufq_cap, 'struct buf_queue', 'plane_sizes[' + str(i) + ']')) self.vidc_info.write('\nPORT\tWIDTH\tHEIGHT\t'.expandtabs(20)+'FMT\t'\ .expandtabs(30) +'NUM_PLANES\tPLANE_SIZES\n'\ .expandtabs(20) + '-'*140 + '\n') self.vidc_info.write('OUTPUT\t{}\t{}\t'.format(width_out,height_out)\ .expandtabs(20)+'{}\t'.format(desc_out).expandtabs(30)\ +'{}\t{}\n'.format(num_planes_out,plane_sizes_out)\ .expandtabs(20)) self.vidc_info.write('CAPUTRE\t{}\t{}\t'.format(width_cap,height_cap)\ .expandtabs(20)+ '{0}\t'.format(desc_cap).expandtabs(30)\ +'{}\t{}\n'.format(num_planes_cap,plane_sizes_cap) .expandtabs(20)) session_crop = session_prop + self.ramdump.field_offset( 'struct session_prop', 'crop_info') left = self.ramdump.read_structure_field(session_crop, 'struct session_crop', 'left') top = self.ramdump.read_structure_field(session_crop, 'struct session_crop', 'top') width = self.ramdump.read_structure_field(session_crop, 'struct session_crop', 'width') height = self.ramdump.read_structure_field(session_crop, 'struct session_crop', 'height') self.vidc_info.write('\nCROP_INFO\n=========\nLeft: \t{0}\ \nTop: \t{1}\nWidth: \t{2}\nHeight: \t{3}\ \n'.format(left, top, width, height).expandtabs(20)) buf_count = head + self.ramdump.field_offset('struct msm_vidc_inst', 'count') etb = self.ramdump.read_structure_field(buf_count, 'struct buf_count', 'etb') ftb = self.ramdump.read_structure_field(buf_count, 'struct buf_count', 'ftb') ebd = self.ramdump.read_structure_field(buf_count, 'struct buf_count', 'ebd') fbd = self.ramdump.read_structure_field(buf_count, 'struct buf_count', 'fbd') self.vidc_info.write('\nBUFFER_COUNTS\n=============\nETB: \t{0}\ \nFTB: \t{1}\nEBD: \t{2}\nFBD: \t{3}\n'\ .format(etb,ftb,ebd,fbd).expandtabs(20)) self.vidc_info.write('\nBUFFER REQUIREMENTS\n===================\n') self.vidc_info.write('TYPE\t'.expandtabs(40)) self.vidc_info.write('SIZE\tREGION_SIZE\tCOUNT_MIN\t'.expandtabs(20)) self.vidc_info.write( 'COUNT_MIN_HOST\tCOUNT_ACTUAL\tCONTIGUOUS\tALIGNMENT\n'.expandtabs( 20)) self.vidc_info.write('-' * 180 + '\n') buff_req = head + self.ramdump.field_offset('struct msm_vidc_inst', 'buff_req') for i in range(0, 14): #HAL_BUFFER_MAX = 14 buff_req_i = buff_req +self.ramdump.field_offset('struct buffer_requirements', 'buffer[' + str(i) + ']') self.buff_requirements(buff_req_i) i = i + 1 self.vidc_info.write('\nBUFFER INFO\n===========\n') offset_vidc_list = self.ramdump.field_offset('struct msm_vidc_list', 'list') scratchbufs = head + self.ramdump.field_offset('struct msm_vidc_inst', 'scratchbufs') internal_buf_walker = llist.ListWalker(self.ramdump, scratchbufs, offset_vidc_list) self.vidc_info.write('\nScratch Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (internal_buf_walker.is_empty()): scratchbufs = internal_buf_walker.next() self.vidc_info.write('Type\t'.expandtabs(40)) self.vidc_info.write('Device_Addr\tSize\tFlags\n'.expandtabs(10) + '-' * 80 + '\n') internal_buf_walker.walk(scratchbufs, self.internal_buf_walker) else: self.vidc_info.write('NONE\n') persistbufs = head + self.ramdump.field_offset('struct msm_vidc_inst', 'persistbufs') internal_buf_walker = llist.ListWalker(self.ramdump, persistbufs, offset_vidc_list) self.vidc_info.write('\nPersist Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (internal_buf_walker.is_empty()): persistbufs = internal_buf_walker.next() self.vidc_info.write('Type\t'.expandtabs(40)) self.vidc_info.write('Device_Addr\tSize\tFlags\n'.expandtabs(10) + '-' * 80 + '\n') internal_buf_walker.walk(persistbufs, self.internal_buf_walker) else: self.vidc_info.write('NONE\n') pending_getpropq = head +self.ramdump.field_offset('struct msm_vidc_inst', 'pending_getpropq') getprop_buf_walker = llist.ListWalker(self.ramdump, pending_getpropq, offset_vidc_list) self.vidc_info.write('\nPending Getpropq Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (getprop_buf_walker.is_empty()): pending_getpropq = getprop_buf_walker.next() getprop_buf_walker.walk(pending_getpropq, self.getprop_buf_walker) else: self.vidc_info.write('NONE\n') outputbufs = head + self.ramdump.field_offset('struct msm_vidc_inst', 'outputbufs') internal_buf_walker = llist.ListWalker(self.ramdump, outputbufs, offset_vidc_list) self.vidc_info.write('\nOutput Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (internal_buf_walker.is_empty()): outputbufs = internal_buf_walker.next() self.vidc_info.write('Type\t'.expandtabs(40)) self.vidc_info.write('Device_Addr\tSize\tFlags\n'.expandtabs(10) + '-' * 80 + '\n') internal_buf_walker.walk(outputbufs, self.internal_buf_walker) else: self.vidc_info.write('NONE\n') reconbufs = head + self.ramdump.field_offset('struct msm_vidc_inst', 'reconbufs') recon_buf_walker = llist.ListWalker(self.ramdump, reconbufs, offset_vidc_list) self.vidc_info.write('\nReconstruction Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (recon_buf_walker.is_empty()): reconbufs = recon_buf_walker.next() self.vidc_info.write('Index\tCR\tCF\n'.expandtabs(10) + '-' * 30 + '\n') recon_buf_walker.walk(reconbufs, self.recon_buf_walker) else: self.vidc_info.write('NONE\n') eosbufs = head + self.ramdump.field_offset('struct msm_vidc_inst', 'eosbufs') eos_buf_walker = llist.ListWalker(self.ramdump, eosbufs, offset_vidc_list) self.vidc_info.write('\nEOS Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (eos_buf_walker.is_empty()): eosbufs = eos_buf_walker.next() self.vidc_info.write('Type\t'.expandtabs(40)) self.vidc_info.write('Device_Addr\tSize\tFlags\tRefCnt\tFd\tOffset\n'\ .expandtabs(10)+'-'*120+'\n') eos_buf_walker.walk(eosbufs, self.eos_buf_walker) else: self.vidc_info.write('NONE\n') registeredbufs = head + self.ramdump.field_offset( 'struct msm_vidc_inst', 'registeredbufs') vidc_buf_walker = llist.ListWalker(self.ramdump, registeredbufs, offset_vidc_list) self.vidc_info.write('\nRegistered Buffers:\n') self.vidc_info.write('=' * 40 + '\n') if not (vidc_buf_walker.is_empty()): registeredbufs = vidc_buf_walker.next() self.vidc_info.write('Vb2_Idx\tPlane\t'.expandtabs(10)) self.vidc_info.write('Type\t'.expandtabs(40)) self.vidc_info.write( 'Device_Addr\tSize\tFlags\tRefCnt\tFd\tOffset\n'.expandtabs( 10) + '-' * 140 + '\n') vidc_buf_walker.walk(registeredbufs, self.vidc_buf_walker) else: self.vidc_info.write('NONE\n')