diff --git a/linux-ramdump-parser-v2/bitops.py b/linux-ramdump-parser-v2/bitops.py index 4f9da69254b587f587f3a94f642bb65c20a4dc50..ab1901af4e756bb1c1b287836fddf4671c29a947 100644 --- a/linux-ramdump-parser-v2/bitops.py +++ b/linux-ramdump-parser-v2/bitops.py @@ -9,6 +9,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. +import ctypes + def bm(msb, lsb): 'Creates a bitmask from msb to lsb' @@ -25,3 +27,10 @@ def is_set(val, bit): if (val >> bit) & 0x1: return True return False + + +def align(x, a): + """Round x up to the nearest multiple of a""" + # See include/uapi/linux/kernel.h + notmask = ctypes.c_uint64(~(a - 1)).value + return (x + a - 1) & notmask diff --git a/linux-ramdump-parser-v2/debug_image_v2.py b/linux-ramdump-parser-v2/debug_image_v2.py index 061f1fd3c4969bc159b5bfd84929d11b73b43182..f63d37b67ee35fe097c2c4e7bccac9883ed37862 100644 --- a/linux-ramdump-parser-v2/debug_image_v2.py +++ b/linux-ramdump-parser-v2/debug_image_v2.py @@ -169,8 +169,11 @@ class DebugImage_v2(): cache_type = lookup_cache_type(ramdump.hw_id, client_id, version) try: cache_type.parse(start, end, ramdump, outfile) + except NotImplementedError: + print_out_str('Cache dumping not supported for %s on this target' + % client_name) except: - print_out_str('!!! Exception while running {0}'.format(client_name)) + print_out_str('!!! Unhandled exception while running {0}'.format(client_name)) print_out_exception() outfile.close() diff --git a/linux-ramdump-parser-v2/mm.py b/linux-ramdump-parser-v2/mm.py index 72e611ffa1660a07f0382d06df6f4e9fcec3a7bb..09e648461dfbd000de1cab41e114d07df44f0b28 100755 --- a/linux-ramdump-parser-v2/mm.py +++ b/linux-ramdump-parser-v2/mm.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +# Copyright (c) 2013-2015, 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 @@ -9,6 +9,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. +import bitops + def page_buddy(ramdump, page): mapcount_offset = ramdump.field_offset('struct page', '_mapcount') @@ -127,21 +129,37 @@ def page_to_pfn_sparse(ramdump, page): # divide by struct page size for division fun return (page - addr) / sizeof_page -# Yes, we are hard coding the vmemmap. This isn't very likely to change unless -# the rest of the addresses start changing as well. When that happens, the -# entire parser will probably be broken in many other ways so a better solution -# can be derived then. + +def get_vmemmap(ramdump): + # See: include/asm-generic/pgtable-nopud.h, + # arch/arm64/include/asm/pgtable-hwdef.h, + # arch/arm64/include/asm/pgtable.h + nlevels = int(ramdump.get_config_val("CONFIG_ARM64_PGTABLE_LEVELS")) + if ramdump.is_config_defined("CONFIG_ARM64_64K_PAGES"): + page_shift = 16 + else: + page_shift = 12 + pgdir_shift = ((page_shift - 3) * nlevels) + 3 + pud_shift = pgdir_shift + pud_size = 1 << pud_shift + va_bits = int(ramdump.get_config_val("CONFIG_ARM64_VA_BITS")) + spsize = ramdump.sizeof('struct page') + vmemmap_size = bitops.align((1 << (va_bits - page_shift)) * spsize, + pud_size) + vmalloc_end = ramdump.page_offset - pud_size - vmemmap_size + return vmalloc_end + + def page_to_pfn_vmemmap(ramdump, page): - mem_map = 0xffffffbc00000000 + vmemmap = get_vmemmap(ramdump) page_size = ramdump.sizeof('struct page') - return ((page - mem_map) / page_size) + return ((page - vmemmap) / page_size) def pfn_to_page_vmemmap(ramdump, pfn): - mem_map = 0xffffffbc00000000 + vmemmap = get_vmemmap(ramdump) page_size = ramdump.sizeof('struct page') - pfn_offset = ramdump.phys_offset >> 12 - return mem_map + (pfn * page_size) + return vmemmap + (pfn * page_size) def page_to_pfn_flat(ramdump, page): diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py index feb9f6a890cf898a9533db8e10b3cb7330b76167..10af03725cd90aeea57c8eb22bce16d87ed8044e 100644 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -496,6 +496,7 @@ class RamDump(): self.phys_offset = options.phys_offset self.lookup_table = [] self.config = [] + self.config_dict = {} if self.arm64: self.page_offset = 0xffffffc000000000 self.thread_size = 16384 @@ -618,8 +619,14 @@ class RamDump(): os.remove(zconfig.name) for l in t: self.config.append(l.rstrip().decode('ascii', 'ignore')) + if not l.startswith('#') and l.strip() != '': + cfg, val = l.split('=') + self.config_dict[cfg] = val.strip() return True + def get_config_val(self, config): + return self.config_dict.get(config) + def is_config_defined(self, config): s = config + '=y' return s in self.config