diff --git a/linux-ramdump-parser-v2/debug_image_v2.py b/linux-ramdump-parser-v2/debug_image_v2.py index 81e54907f5663a985d5fa654577c37075504450b..51539703c26f8c1c671ad02367f14143594d9328 100755 --- a/linux-ramdump-parser-v2/debug_image_v2.py +++ b/linux-ramdump-parser-v2/debug_image_v2.py @@ -31,7 +31,7 @@ from tlbdumplib import lookup_tlb_type from vsens import VsensData MEMDUMPV2_MAGIC = 0x42445953 -MAX_NUM_ENTRIES = 0x130 +MAX_NUM_ENTRIES = 0x140 TRACE_EVENT_FL_TRACEPOINT = 0x40 class client(object): @@ -54,11 +54,13 @@ class client(object): MSM_DUMP_DATA_L2_TLB = 0x120 MSM_DUMP_DATA_LLC_CACHE = 0x121 MSM_DUMP_DATA_SCANDUMP = 0xEB + MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130 MSM_DUMP_DATA_MAX = MAX_NUM_ENTRIES # Client functions will be executed in top-to-bottom order client_types = [ ('MSM_DUMP_DATA_SCANDUMP', 'parse_scandump'), + ('MSM_DUMP_DATA_SCANDUMP_PER_CPU', 'parse_scandump'), ('MSM_DUMP_DATA_CPU_CTX', 'parse_cpu_ctx'), ('MSM_DUMP_DATA_L1_INST_TLB', 'parse_tlb_common'), ('MSM_DUMP_DATA_L1_DATA_TLB', 'parse_tlb_common'), @@ -100,25 +102,36 @@ class DebugImage_v2(): self.event_class = 'struct ftrace_event_class' def parse_scandump(self, version, start, end, client_id, ram_dump): - scandump_file_prefix = "scandump" + scandump_file_prefix = "scandump_core" + core_bin_prefix = "core" try: scan_wrapper_path = local_settings.scandump_parser_path except AttributeError: print_out_str('Could not find scandump_parser_path . Please define scandump_parser_path in local_settings') return - output = os.path.join(ram_dump.outdir, scandump_file_prefix) - input = os.path.join(ram_dump.outdir, "vv_msg_4_header.bin") - print_out_str( - 'Parsing scandump context start {0:x} end {1:x} {2} {3}'.format(start, end, output, input)) if ram_dump.arm64: arch = "aarch64" + if client_id == client.MSM_DUMP_DATA_SCANDUMP: + output = os.path.join(ram_dump.outdir, scandump_file_prefix) + input = os.path.join(ram_dump.outdir, "core.bin") + elif client_id >= client.MSM_DUMP_DATA_SCANDUMP_PER_CPU: + core_num = client_id & 0xF + output = '{0}_{1:x}'.format(scandump_file_prefix, core_num) + output = os.path.join(ram_dump.outdir, output) + + input_filename = '{0}_{1:x}.bin'.format(core_bin_prefix, core_num) + input = os.path.join(ram_dump.outdir, input_filename) + print_out_str( + 'Parsing scandump context start {0:x} end {1:x} {2} {3}'.format(start, end, output, input)) header_bin = ram_dump.open_file(input) + it = range(start, end) for i in it: val = ram_dump.read_byte(i, False) header_bin.write(struct.pack("<B", val)) header_bin.close() subprocess.call('python {0} -d {1} -o {2} -f {3}'.format(scan_wrapper_path, input, output, arch)) + return def parse_cpu_ctx(self, version, start, end, client_id, ram_dump): core = client_id - client.MSM_DUMP_DATA_CPU_CTX @@ -504,6 +517,8 @@ class DebugImage_v2(): client.MSM_DUMP_DATA_L2_CACHE + i] = 'MSM_DUMP_DATA_L2_CACHE' self.dump_data_id_lookup_table[ client.MSM_DUMP_DATA_ETM_REG + i] = 'MSM_DUMP_DATA_ETM_REG' + self.dump_data_id_lookup_table[ + client.MSM_DUMP_DATA_SCANDUMP_PER_CPU + i] = 'MSM_DUMP_DATA_SCANDUMP_PER_CPU' for i in range(0, 4): self.dump_data_id_lookup_table[ diff --git a/linux-ramdump-parser-v2/mm.py b/linux-ramdump-parser-v2/mm.py index efca724830789ce95123989d4146d72c2f375acb..efcae528eb8e81a146fd5ec3eb274fdcae741c9f 100644 --- a/linux-ramdump-parser-v2/mm.py +++ b/linux-ramdump-parser-v2/mm.py @@ -271,7 +271,8 @@ def dont_map_hole_lowmem_page_address(ramdump, page): def normal_lowmem_page_address(ramdump, page): phys = page_to_pfn(ramdump, page) << 12 - return phys - ramdump.phys_offset + ramdump.page_offset + memstart_addr = ramdump.read_s64('memstart_addr') + return phys - memstart_addr + ramdump.page_offset def lowmem_page_address(ramdump, page): diff --git a/linux-ramdump-parser-v2/parsers/l1_cache_compare.py b/linux-ramdump-parser-v2/parsers/l1_cache_compare.py new file mode 100755 index 0000000000000000000000000000000000000000..c5dcea5c0689a83fbf1446f7b5f3a2247a5ffd32 --- /dev/null +++ b/linux-ramdump-parser-v2/parsers/l1_cache_compare.py @@ -0,0 +1,103 @@ +# Copyright (c) 2017 The Linux Foundation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 and +# only version 2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +import os +import re +from parser_util import register_parser, RamParser + + +file_names = ['MSM_DUMP_DATA_L1_DATA_CACHE_0x0', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x1', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x2', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x3', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x4', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x5', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x6', + 'MSM_DUMP_DATA_L1_DATA_CACHE_0x7'] + + +@register_parser('--l1-compare', 'Compare L1 Cache Data with DDR contents') +class L1_Cache_Compare(RamParser): + + def parse(self): + with self.ramdump.open_file('l1_cache.txt') as out_l1_cache: + + for file_name in file_names: + file_path = os.path.join(self.ramdump.outdir, file_name) + if os.path.isfile(file_path): + + out_l1_cache.write('\n-----begin ' + file_name + '-----\n') + + addr = None + values_from_file = None + values_from_dump = None + + fin = self.ramdump.open_file(file_path, 'r') + line_no = 0 + for line in fin: + line_no += 1 + if line == '': + continue + elif re.match('^Way Set P MOESI RAW_MOESI N.*', line): + continue + elif len(line) >= 195: + colm = line.split() + + # Read address value from file + addr = colm[6] + + # Read values from file + values_from_file = [] + for i in range(11, 27): + values_from_file.append(colm[i]) + + # Read values from dump + values_from_dump = [] + temp_addr = int(addr, 16) + val = None + if temp_addr > self.ramdump.phys_offset: + for i in range(0, 16): + try: + val = self.ramdump.read_physical( + temp_addr, 4) + except: + out_l1_cache.write( + 'Exception while reading {0:x}' + .format(temp_addr)) + + val = val[::-1] + val = val.encode('hex') + + values_from_dump.append(val) + temp_addr += 4 + + # compare both values + if values_from_dump != [] and \ + values_from_dump != values_from_file: + out_l1_cache.write( + 'phy addr: {0} Way:{1} Set:{2} P:{3} MOESI:{4}' + .format(addr, + colm[0], + colm[1], + colm[2], + colm[3]) + + '\n') + + out_l1_cache.write('Cache content: ' + + ' '.join(values_from_file) + + '\n') + out_l1_cache.write('DDR content : ' + + ' '.join(values_from_dump) + + '\n\n') + + fin.close() + + out_l1_cache.write('------end '+file_name+'------\n') diff --git a/linux-ramdump-parser-v2/parsers/slabsummary.py b/linux-ramdump-parser-v2/parsers/slabsummary.py index abe47dc90570ab320d1e25775b6e0fa12163187a..328cafd53d1872c9835d9a77dba14a035c3bb465 100644 --- a/linux-ramdump-parser-v2/parsers/slabsummary.py +++ b/linux-ramdump-parser-v2/parsers/slabsummary.py @@ -27,20 +27,20 @@ class Slabinfo_summary(RamParser): start, slab_lru_offset, max_page): page = self.ramdump.read_word(start) + totalfree = 0 if page == 0: - return + return totalfree seen = [] - totalfree = 0 mapcount = 0 total_objects = 0 inuse = 0 while page != start: if page is None: - return + return totalfree if page in seen: - return + return totalfree if page > max_page: - return + return totalfree seen.append(page) page = page - slab_lru_offset mapcount = self.ramdump.read_structure_field( diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py old mode 100755 new mode 100644 index e0a379cd4d5c11884d38dfd6e1c1885af2fab48c..8d126080e578ad26bf71c80875335732cd1a8ba1 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -804,6 +804,23 @@ class RamDump(): print_out_str('!!! Could not lookup saved command line address') return False + def print_socinfo(self): + content_socinfo = hex(self.read_pointer('socinfo')) + content_socinfo = content_socinfo.strip('L') + sernum_offset = self.field_offset('struct socinfo_v10', 'serial_number') + if sernum_offset is None: + sernum_offset = self.field_offset('struct socinfo_v0_10', 'serial_number') + if sernum_offset is None: + print_out_str("No serial number information available") + return False + addr_of_sernum = hex(int(content_socinfo, 16) + sernum_offset) + addr_of_sernum = addr_of_sernum.strip('L') + serial_number = self.read_u32(int(addr_of_sernum, 16)) + if serial_number is not None: + print_out_str('Serial number %s' % hex(serial_number)) + return True + return False + def auto_parse(self, file_path): for cls in sorted(AutoDumpInfo.__subclasses__(), key=lambda x: x.priority, reverse=True): diff --git a/linux-ramdump-parser-v2/ramparse.py b/linux-ramdump-parser-v2/ramparse.py old mode 100755 new mode 100644 index 78c77cd3052cc426317e803ac9cffb36f021a4cd..7245e9bbb3a05809f892c1985ac666f1af0f249c --- a/linux-ramdump-parser-v2/ramparse.py +++ b/linux-ramdump-parser-v2/ramparse.py @@ -349,6 +349,9 @@ if __name__ == '__main__': print_out_str('!!! Exiting now...') sys.exit(1) + if not dump.print_socinfo(): + print_out_str('!!! No serial number information available.') + if options.qdss: print_out_str('!!! --parse-qdss is now deprecated') print_out_str(