1eb985b5dSKuan-Ying Lee# SPDX-License-Identifier: GPL-2.0 2e36903b0SDmitrii Bundin# 3eb985b5dSKuan-Ying Lee# Copyright (c) 2023 MediaTek Inc. 4e36903b0SDmitrii Bundin# 5e36903b0SDmitrii Bundin# Authors: 6eb985b5dSKuan-Ying Lee# Kuan-Ying Lee <[email protected]> 7e36903b0SDmitrii Bundin# 8e36903b0SDmitrii Bundin 9e36903b0SDmitrii Bundinimport gdb 10eb985b5dSKuan-Ying Leeimport math 11eb985b5dSKuan-Ying Leefrom linux import utils, constants 12e36903b0SDmitrii Bundin 13eb985b5dSKuan-Ying Leedef DIV_ROUND_UP(n,d): 14eb985b5dSKuan-Ying Lee return ((n) + (d) - 1) // (d) 15e36903b0SDmitrii Bundin 16eb985b5dSKuan-Ying Leedef test_bit(nr, addr): 17eb985b5dSKuan-Ying Lee if addr.dereference() & (0x1 << nr): 18eb985b5dSKuan-Ying Lee return True 19e36903b0SDmitrii Bundin else: 20eb985b5dSKuan-Ying Lee return False 21e36903b0SDmitrii Bundin 22eb985b5dSKuan-Ying Leeclass page_ops(): 23eb985b5dSKuan-Ying Lee ops = None 24eb985b5dSKuan-Ying Lee def __init__(self): 25eb985b5dSKuan-Ying Lee if not constants.LX_CONFIG_SPARSEMEM_VMEMMAP: 26eb985b5dSKuan-Ying Lee raise gdb.GdbError('Only support CONFIG_SPARSEMEM_VMEMMAP now') 27eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_ARM64 and utils.is_target_arch('aarch64'): 28eb985b5dSKuan-Ying Lee self.ops = aarch64_page_ops() 29e36903b0SDmitrii Bundin else: 30eb985b5dSKuan-Ying Lee raise gdb.GdbError('Only support aarch64 now') 31e36903b0SDmitrii Bundin 32eb985b5dSKuan-Ying Leeclass aarch64_page_ops(): 33eb985b5dSKuan-Ying Lee def __init__(self): 34eb985b5dSKuan-Ying Lee self.SUBSECTION_SHIFT = 21 35eb985b5dSKuan-Ying Lee self.SEBSECTION_SIZE = 1 << self.SUBSECTION_SHIFT 36f2eaed15SKuan-Ying Lee self.MODULES_VSIZE = 2 * 1024 * 1024 * 1024 37e36903b0SDmitrii Bundin 38eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_ARM64_64K_PAGES: 39eb985b5dSKuan-Ying Lee self.SECTION_SIZE_BITS = 29 40e36903b0SDmitrii Bundin else: 41eb985b5dSKuan-Ying Lee self.SECTION_SIZE_BITS = 27 42eb985b5dSKuan-Ying Lee self.MAX_PHYSMEM_BITS = constants.LX_CONFIG_ARM64_VA_BITS 43e36903b0SDmitrii Bundin 44d3e5bab9SArnd Bergmann self.PAGE_SHIFT = constants.LX_CONFIG_PAGE_SHIFT 45eb985b5dSKuan-Ying Lee self.PAGE_SIZE = 1 << self.PAGE_SHIFT 46eb985b5dSKuan-Ying Lee self.PAGE_MASK = (~(self.PAGE_SIZE - 1)) & ((1 << 64) - 1) 47e36903b0SDmitrii Bundin 48eb985b5dSKuan-Ying Lee self.VA_BITS = constants.LX_CONFIG_ARM64_VA_BITS 49eb985b5dSKuan-Ying Lee if self.VA_BITS > 48: 50*7d8742bfSKuan-Ying Lee if constants.LX_CONFIG_ARM64_16K_PAGES: 51*7d8742bfSKuan-Ying Lee self.VA_BITS_MIN = 47 52*7d8742bfSKuan-Ying Lee else: 53eb985b5dSKuan-Ying Lee self.VA_BITS_MIN = 48 5404a40baeSKuan-Ying Lee tcr_el1 = gdb.execute("info registers $TCR_EL1", to_string=True) 5504a40baeSKuan-Ying Lee tcr_el1 = int(tcr_el1.split()[1], 16) 5604a40baeSKuan-Ying Lee self.vabits_actual = 64 - ((tcr_el1 >> 16) & 63) 57e36903b0SDmitrii Bundin else: 58eb985b5dSKuan-Ying Lee self.VA_BITS_MIN = self.VA_BITS 59eb985b5dSKuan-Ying Lee self.vabits_actual = self.VA_BITS 60eb985b5dSKuan-Ying Lee self.kimage_voffset = gdb.parse_and_eval('kimage_voffset') & ((1 << 64) - 1) 61e36903b0SDmitrii Bundin 62eb985b5dSKuan-Ying Lee self.SECTIONS_SHIFT = self.MAX_PHYSMEM_BITS - self.SECTION_SIZE_BITS 63e36903b0SDmitrii Bundin 64eb985b5dSKuan-Ying Lee if str(constants.LX_CONFIG_ARCH_FORCE_MAX_ORDER).isdigit(): 65eb985b5dSKuan-Ying Lee self.MAX_ORDER = constants.LX_CONFIG_ARCH_FORCE_MAX_ORDER 66eb985b5dSKuan-Ying Lee else: 6763ce5947SKuan-Ying Lee self.MAX_ORDER = 10 68e36903b0SDmitrii Bundin 6963ce5947SKuan-Ying Lee self.MAX_ORDER_NR_PAGES = 1 << (self.MAX_ORDER) 70eb985b5dSKuan-Ying Lee self.PFN_SECTION_SHIFT = self.SECTION_SIZE_BITS - self.PAGE_SHIFT 71eb985b5dSKuan-Ying Lee self.NR_MEM_SECTIONS = 1 << self.SECTIONS_SHIFT 72eb985b5dSKuan-Ying Lee self.PAGES_PER_SECTION = 1 << self.PFN_SECTION_SHIFT 73eb985b5dSKuan-Ying Lee self.PAGE_SECTION_MASK = (~(self.PAGES_PER_SECTION - 1)) & ((1 << 64) - 1) 74eb985b5dSKuan-Ying Lee 75eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_SPARSEMEM_EXTREME: 76eb985b5dSKuan-Ying Lee self.SECTIONS_PER_ROOT = self.PAGE_SIZE // gdb.lookup_type("struct mem_section").sizeof 77eb985b5dSKuan-Ying Lee else: 78eb985b5dSKuan-Ying Lee self.SECTIONS_PER_ROOT = 1 79eb985b5dSKuan-Ying Lee 80eb985b5dSKuan-Ying Lee self.NR_SECTION_ROOTS = DIV_ROUND_UP(self.NR_MEM_SECTIONS, self.SECTIONS_PER_ROOT) 81eb985b5dSKuan-Ying Lee self.SECTION_ROOT_MASK = self.SECTIONS_PER_ROOT - 1 82eb985b5dSKuan-Ying Lee self.SUBSECTION_SHIFT = 21 83eb985b5dSKuan-Ying Lee self.SEBSECTION_SIZE = 1 << self.SUBSECTION_SHIFT 84eb985b5dSKuan-Ying Lee self.PFN_SUBSECTION_SHIFT = self.SUBSECTION_SHIFT - self.PAGE_SHIFT 85eb985b5dSKuan-Ying Lee self.PAGES_PER_SUBSECTION = 1 << self.PFN_SUBSECTION_SHIFT 86eb985b5dSKuan-Ying Lee 87eb985b5dSKuan-Ying Lee self.SECTION_HAS_MEM_MAP = 1 << int(gdb.parse_and_eval('SECTION_HAS_MEM_MAP_BIT')) 88eb985b5dSKuan-Ying Lee self.SECTION_IS_EARLY = 1 << int(gdb.parse_and_eval('SECTION_IS_EARLY_BIT')) 89eb985b5dSKuan-Ying Lee 90eb985b5dSKuan-Ying Lee self.struct_page_size = utils.get_page_type().sizeof 91eb985b5dSKuan-Ying Lee self.STRUCT_PAGE_MAX_SHIFT = (int)(math.log(self.struct_page_size, 2)) 92eb985b5dSKuan-Ying Lee 93eb985b5dSKuan-Ying Lee self.PAGE_OFFSET = self._PAGE_OFFSET(self.VA_BITS) 94eb985b5dSKuan-Ying Lee self.MODULES_VADDR = self._PAGE_END(self.VA_BITS_MIN) 95eb985b5dSKuan-Ying Lee self.MODULES_END = self.MODULES_VADDR + self.MODULES_VSIZE 96eb985b5dSKuan-Ying Lee 973c0e9a20SKuan-Ying Lee self.VMEMMAP_RANGE = self._PAGE_END(self.VA_BITS_MIN) - self.PAGE_OFFSET 983c0e9a20SKuan-Ying Lee self.VMEMMAP_SIZE = (self.VMEMMAP_RANGE >> self.PAGE_SHIFT) * self.struct_page_size 993c0e9a20SKuan-Ying Lee self.VMEMMAP_END = (-(1 * 1024 * 1024 * 1024)) & 0xffffffffffffffff 1003c0e9a20SKuan-Ying Lee self.VMEMMAP_START = self.VMEMMAP_END - self.VMEMMAP_SIZE 101eb985b5dSKuan-Ying Lee 102eb985b5dSKuan-Ying Lee self.VMALLOC_START = self.MODULES_END 103eb985b5dSKuan-Ying Lee self.VMALLOC_END = self.VMEMMAP_START - 256 * 1024 * 1024 104eb985b5dSKuan-Ying Lee 105eb985b5dSKuan-Ying Lee self.memstart_addr = gdb.parse_and_eval("memstart_addr") 106eb985b5dSKuan-Ying Lee self.PHYS_OFFSET = self.memstart_addr 107eb985b5dSKuan-Ying Lee self.vmemmap = gdb.Value(self.VMEMMAP_START).cast(utils.get_page_type().pointer()) - (self.memstart_addr >> self.PAGE_SHIFT) 108eb985b5dSKuan-Ying Lee 109eb985b5dSKuan-Ying Lee self.KERNEL_START = gdb.parse_and_eval("_text") 110eb985b5dSKuan-Ying Lee self.KERNEL_END = gdb.parse_and_eval("_end") 111eb985b5dSKuan-Ying Lee 112eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_KASAN_GENERIC or constants.LX_CONFIG_KASAN_SW_TAGS: 113eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_KASAN_GENERIC: 114eb985b5dSKuan-Ying Lee self.KASAN_SHADOW_SCALE_SHIFT = 3 115eb985b5dSKuan-Ying Lee else: 116eb985b5dSKuan-Ying Lee self.KASAN_SHADOW_SCALE_SHIFT = 4 117eb985b5dSKuan-Ying Lee self.KASAN_SHADOW_OFFSET = constants.LX_CONFIG_KASAN_SHADOW_OFFSET 118eb985b5dSKuan-Ying Lee self.KASAN_SHADOW_END = (1 << (64 - self.KASAN_SHADOW_SCALE_SHIFT)) + self.KASAN_SHADOW_OFFSET 119eb985b5dSKuan-Ying Lee self.PAGE_END = self.KASAN_SHADOW_END - (1 << (self.vabits_actual - self.KASAN_SHADOW_SCALE_SHIFT)) 120eb985b5dSKuan-Ying Lee else: 121eb985b5dSKuan-Ying Lee self.PAGE_END = self._PAGE_END(self.VA_BITS_MIN) 122eb985b5dSKuan-Ying Lee 123eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_NUMA and constants.LX_CONFIG_NODES_SHIFT: 124eb985b5dSKuan-Ying Lee self.NODE_SHIFT = constants.LX_CONFIG_NODES_SHIFT 125eb985b5dSKuan-Ying Lee else: 126eb985b5dSKuan-Ying Lee self.NODE_SHIFT = 0 127eb985b5dSKuan-Ying Lee 128eb985b5dSKuan-Ying Lee self.MAX_NUMNODES = 1 << self.NODE_SHIFT 129eb985b5dSKuan-Ying Lee 130eb985b5dSKuan-Ying Lee def SECTION_NR_TO_ROOT(self, sec): 131eb985b5dSKuan-Ying Lee return sec // self.SECTIONS_PER_ROOT 132eb985b5dSKuan-Ying Lee 133eb985b5dSKuan-Ying Lee def __nr_to_section(self, nr): 134eb985b5dSKuan-Ying Lee root = self.SECTION_NR_TO_ROOT(nr) 135eb985b5dSKuan-Ying Lee mem_section = gdb.parse_and_eval("mem_section") 136eb985b5dSKuan-Ying Lee return mem_section[root][nr & self.SECTION_ROOT_MASK] 137eb985b5dSKuan-Ying Lee 138eb985b5dSKuan-Ying Lee def pfn_to_section_nr(self, pfn): 139eb985b5dSKuan-Ying Lee return pfn >> self.PFN_SECTION_SHIFT 140eb985b5dSKuan-Ying Lee 141eb985b5dSKuan-Ying Lee def section_nr_to_pfn(self, sec): 142eb985b5dSKuan-Ying Lee return sec << self.PFN_SECTION_SHIFT 143eb985b5dSKuan-Ying Lee 144eb985b5dSKuan-Ying Lee def __pfn_to_section(self, pfn): 145eb985b5dSKuan-Ying Lee return self.__nr_to_section(self.pfn_to_section_nr(pfn)) 146eb985b5dSKuan-Ying Lee 147eb985b5dSKuan-Ying Lee def pfn_to_section(self, pfn): 148eb985b5dSKuan-Ying Lee return self.__pfn_to_section(pfn) 149eb985b5dSKuan-Ying Lee 150eb985b5dSKuan-Ying Lee def subsection_map_index(self, pfn): 151eb985b5dSKuan-Ying Lee return (pfn & ~(self.PAGE_SECTION_MASK)) // self.PAGES_PER_SUBSECTION 152eb985b5dSKuan-Ying Lee 153eb985b5dSKuan-Ying Lee def pfn_section_valid(self, ms, pfn): 154eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_SPARSEMEM_VMEMMAP: 155eb985b5dSKuan-Ying Lee idx = self.subsection_map_index(pfn) 156eb985b5dSKuan-Ying Lee return test_bit(idx, ms['usage']['subsection_map']) 157eb985b5dSKuan-Ying Lee else: 158eb985b5dSKuan-Ying Lee return True 159eb985b5dSKuan-Ying Lee 160eb985b5dSKuan-Ying Lee def valid_section(self, mem_section): 161eb985b5dSKuan-Ying Lee if mem_section != None and (mem_section['section_mem_map'] & self.SECTION_HAS_MEM_MAP): 162eb985b5dSKuan-Ying Lee return True 163eb985b5dSKuan-Ying Lee return False 164eb985b5dSKuan-Ying Lee 165eb985b5dSKuan-Ying Lee def early_section(self, mem_section): 166eb985b5dSKuan-Ying Lee if mem_section != None and (mem_section['section_mem_map'] & self.SECTION_IS_EARLY): 167eb985b5dSKuan-Ying Lee return True 168eb985b5dSKuan-Ying Lee return False 169eb985b5dSKuan-Ying Lee 170eb985b5dSKuan-Ying Lee def pfn_valid(self, pfn): 171eb985b5dSKuan-Ying Lee ms = None 172eb985b5dSKuan-Ying Lee if self.PHYS_PFN(self.PFN_PHYS(pfn)) != pfn: 173eb985b5dSKuan-Ying Lee return False 174eb985b5dSKuan-Ying Lee if self.pfn_to_section_nr(pfn) >= self.NR_MEM_SECTIONS: 175eb985b5dSKuan-Ying Lee return False 176eb985b5dSKuan-Ying Lee ms = self.__pfn_to_section(pfn) 177eb985b5dSKuan-Ying Lee 178eb985b5dSKuan-Ying Lee if not self.valid_section(ms): 179eb985b5dSKuan-Ying Lee return False 180eb985b5dSKuan-Ying Lee return self.early_section(ms) or self.pfn_section_valid(ms, pfn) 181eb985b5dSKuan-Ying Lee 182eb985b5dSKuan-Ying Lee def _PAGE_OFFSET(self, va): 183eb985b5dSKuan-Ying Lee return (-(1 << (va))) & 0xffffffffffffffff 184eb985b5dSKuan-Ying Lee 185eb985b5dSKuan-Ying Lee def _PAGE_END(self, va): 186eb985b5dSKuan-Ying Lee return (-(1 << (va - 1))) & 0xffffffffffffffff 187eb985b5dSKuan-Ying Lee 188eb985b5dSKuan-Ying Lee def kasan_reset_tag(self, addr): 189eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_KASAN_SW_TAGS or constants.LX_CONFIG_KASAN_HW_TAGS: 190eb985b5dSKuan-Ying Lee return int(addr) | (0xff << 56) 191eb985b5dSKuan-Ying Lee else: 192eb985b5dSKuan-Ying Lee return addr 193eb985b5dSKuan-Ying Lee 194eb985b5dSKuan-Ying Lee def __is_lm_address(self, addr): 195eb985b5dSKuan-Ying Lee if (addr - self.PAGE_OFFSET) < (self.PAGE_END - self.PAGE_OFFSET): 196eb985b5dSKuan-Ying Lee return True 197eb985b5dSKuan-Ying Lee else: 198eb985b5dSKuan-Ying Lee return False 199eb985b5dSKuan-Ying Lee def __lm_to_phys(self, addr): 200eb985b5dSKuan-Ying Lee return addr - self.PAGE_OFFSET + self.PHYS_OFFSET 201eb985b5dSKuan-Ying Lee 202eb985b5dSKuan-Ying Lee def __kimg_to_phys(self, addr): 203eb985b5dSKuan-Ying Lee return addr - self.kimage_voffset 204eb985b5dSKuan-Ying Lee 205eb985b5dSKuan-Ying Lee def __virt_to_phys_nodebug(self, va): 206eb985b5dSKuan-Ying Lee untagged_va = self.kasan_reset_tag(va) 207eb985b5dSKuan-Ying Lee if self.__is_lm_address(untagged_va): 208eb985b5dSKuan-Ying Lee return self.__lm_to_phys(untagged_va) 209eb985b5dSKuan-Ying Lee else: 210eb985b5dSKuan-Ying Lee return self.__kimg_to_phys(untagged_va) 211eb985b5dSKuan-Ying Lee 212eb985b5dSKuan-Ying Lee def __virt_to_phys(self, va): 213eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_DEBUG_VIRTUAL: 214eb985b5dSKuan-Ying Lee if not self.__is_lm_address(self.kasan_reset_tag(va)): 215eb985b5dSKuan-Ying Lee raise gdb.GdbError("Warning: virt_to_phys used for non-linear address: 0x%lx\n" % va) 216eb985b5dSKuan-Ying Lee return self.__virt_to_phys_nodebug(va) 217eb985b5dSKuan-Ying Lee 218eb985b5dSKuan-Ying Lee def virt_to_phys(self, va): 219eb985b5dSKuan-Ying Lee return self.__virt_to_phys(va) 220eb985b5dSKuan-Ying Lee 221eb985b5dSKuan-Ying Lee def PFN_PHYS(self, pfn): 222eb985b5dSKuan-Ying Lee return pfn << self.PAGE_SHIFT 223eb985b5dSKuan-Ying Lee 224eb985b5dSKuan-Ying Lee def PHYS_PFN(self, phys): 225eb985b5dSKuan-Ying Lee return phys >> self.PAGE_SHIFT 226eb985b5dSKuan-Ying Lee 227eb985b5dSKuan-Ying Lee def __phys_to_virt(self, pa): 228eb985b5dSKuan-Ying Lee return (pa - self.PHYS_OFFSET) | self.PAGE_OFFSET 229eb985b5dSKuan-Ying Lee 230eb985b5dSKuan-Ying Lee def __phys_to_pfn(self, pa): 231eb985b5dSKuan-Ying Lee return self.PHYS_PFN(pa) 232eb985b5dSKuan-Ying Lee 233eb985b5dSKuan-Ying Lee def __pfn_to_phys(self, pfn): 234eb985b5dSKuan-Ying Lee return self.PFN_PHYS(pfn) 235eb985b5dSKuan-Ying Lee 236eb985b5dSKuan-Ying Lee def __pa_symbol_nodebug(self, x): 237eb985b5dSKuan-Ying Lee return self.__kimg_to_phys(x) 238eb985b5dSKuan-Ying Lee 239eb985b5dSKuan-Ying Lee def __phys_addr_symbol(self, x): 240eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_DEBUG_VIRTUAL: 241eb985b5dSKuan-Ying Lee if x < self.KERNEL_START or x > self.KERNEL_END: 242eb985b5dSKuan-Ying Lee raise gdb.GdbError("0x%x exceed kernel range" % x) 243eb985b5dSKuan-Ying Lee return self.__pa_symbol_nodebug(x) 244eb985b5dSKuan-Ying Lee 245eb985b5dSKuan-Ying Lee def __pa_symbol(self, x): 246eb985b5dSKuan-Ying Lee return self.__phys_addr_symbol(x) 247eb985b5dSKuan-Ying Lee 248eb985b5dSKuan-Ying Lee def __va(self, pa): 249eb985b5dSKuan-Ying Lee return self.__phys_to_virt(pa) 250eb985b5dSKuan-Ying Lee 251eb985b5dSKuan-Ying Lee def pfn_to_kaddr(self, pfn): 252eb985b5dSKuan-Ying Lee return self.__va(pfn << self.PAGE_SHIFT) 253eb985b5dSKuan-Ying Lee 254eb985b5dSKuan-Ying Lee def virt_to_pfn(self, va): 255eb985b5dSKuan-Ying Lee return self.__phys_to_pfn(self.__virt_to_phys(va)) 256eb985b5dSKuan-Ying Lee 257eb985b5dSKuan-Ying Lee def sym_to_pfn(self, x): 258eb985b5dSKuan-Ying Lee return self.__phys_to_pfn(self.__pa_symbol(x)) 259eb985b5dSKuan-Ying Lee 260eb985b5dSKuan-Ying Lee def page_to_pfn(self, page): 261eb985b5dSKuan-Ying Lee return int(page.cast(utils.get_page_type().pointer()) - self.vmemmap.cast(utils.get_page_type().pointer())) 262eb985b5dSKuan-Ying Lee 263eb985b5dSKuan-Ying Lee def page_to_phys(self, page): 264eb985b5dSKuan-Ying Lee return self.__pfn_to_phys(self.page_to_pfn(page)) 265eb985b5dSKuan-Ying Lee 266eb985b5dSKuan-Ying Lee def pfn_to_page(self, pfn): 267eb985b5dSKuan-Ying Lee return (self.vmemmap + pfn).cast(utils.get_page_type().pointer()) 268eb985b5dSKuan-Ying Lee 269eb985b5dSKuan-Ying Lee def page_to_virt(self, page): 270eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_DEBUG_VIRTUAL: 271eb985b5dSKuan-Ying Lee return self.__va(self.page_to_phys(page)) 272eb985b5dSKuan-Ying Lee else: 273eb985b5dSKuan-Ying Lee __idx = int((page.cast(gdb.lookup_type("unsigned long")) - self.VMEMMAP_START).cast(utils.get_ulong_type())) // self.struct_page_size 274eb985b5dSKuan-Ying Lee return self.PAGE_OFFSET + (__idx * self.PAGE_SIZE) 275eb985b5dSKuan-Ying Lee 276eb985b5dSKuan-Ying Lee def virt_to_page(self, va): 277eb985b5dSKuan-Ying Lee if constants.LX_CONFIG_DEBUG_VIRTUAL: 278eb985b5dSKuan-Ying Lee return self.pfn_to_page(self.virt_to_pfn(va)) 279eb985b5dSKuan-Ying Lee else: 280eb985b5dSKuan-Ying Lee __idx = int(self.kasan_reset_tag(va) - self.PAGE_OFFSET) // self.PAGE_SIZE 281eb985b5dSKuan-Ying Lee addr = self.VMEMMAP_START + (__idx * self.struct_page_size) 282eb985b5dSKuan-Ying Lee return gdb.Value(addr).cast(utils.get_page_type().pointer()) 283eb985b5dSKuan-Ying Lee 284eb985b5dSKuan-Ying Lee def page_address(self, page): 285eb985b5dSKuan-Ying Lee return self.page_to_virt(page) 286eb985b5dSKuan-Ying Lee 287eb985b5dSKuan-Ying Lee def folio_address(self, folio): 288eb985b5dSKuan-Ying Lee return self.page_address(folio['page'].address) 289eb985b5dSKuan-Ying Lee 290eb985b5dSKuan-Ying Leeclass LxPFN2Page(gdb.Command): 291eb985b5dSKuan-Ying Lee """PFN to struct page""" 292e36903b0SDmitrii Bundin 293e36903b0SDmitrii Bundin def __init__(self): 294eb985b5dSKuan-Ying Lee super(LxPFN2Page, self).__init__("lx-pfn_to_page", gdb.COMMAND_USER) 295e36903b0SDmitrii Bundin 296e36903b0SDmitrii Bundin def invoke(self, arg, from_tty): 297eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 298eb985b5dSKuan-Ying Lee pfn = int(argv[0]) 299eb985b5dSKuan-Ying Lee page = page_ops().ops.pfn_to_page(pfn) 300eb985b5dSKuan-Ying Lee gdb.write("pfn_to_page(0x%x) = 0x%x\n" % (pfn, page)) 301e36903b0SDmitrii Bundin 302eb985b5dSKuan-Ying LeeLxPFN2Page() 303e36903b0SDmitrii Bundin 304eb985b5dSKuan-Ying Leeclass LxPage2PFN(gdb.Command): 305eb985b5dSKuan-Ying Lee """struct page to PFN""" 306eb985b5dSKuan-Ying Lee 307eb985b5dSKuan-Ying Lee def __init__(self): 308eb985b5dSKuan-Ying Lee super(LxPage2PFN, self).__init__("lx-page_to_pfn", gdb.COMMAND_USER) 309eb985b5dSKuan-Ying Lee 310eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 311eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 312eb985b5dSKuan-Ying Lee struct_page_addr = int(argv[0], 16) 313eb985b5dSKuan-Ying Lee page = gdb.Value(struct_page_addr).cast(utils.get_page_type().pointer()) 314eb985b5dSKuan-Ying Lee pfn = page_ops().ops.page_to_pfn(page) 315eb985b5dSKuan-Ying Lee gdb.write("page_to_pfn(0x%x) = 0x%x\n" % (page, pfn)) 316eb985b5dSKuan-Ying Lee 317eb985b5dSKuan-Ying LeeLxPage2PFN() 318eb985b5dSKuan-Ying Lee 319eb985b5dSKuan-Ying Leeclass LxPageAddress(gdb.Command): 320eb985b5dSKuan-Ying Lee """struct page to linear mapping address""" 321eb985b5dSKuan-Ying Lee 322eb985b5dSKuan-Ying Lee def __init__(self): 323eb985b5dSKuan-Ying Lee super(LxPageAddress, self).__init__("lx-page_address", gdb.COMMAND_USER) 324eb985b5dSKuan-Ying Lee 325eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 326eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 327eb985b5dSKuan-Ying Lee struct_page_addr = int(argv[0], 16) 328eb985b5dSKuan-Ying Lee page = gdb.Value(struct_page_addr).cast(utils.get_page_type().pointer()) 329eb985b5dSKuan-Ying Lee addr = page_ops().ops.page_address(page) 330eb985b5dSKuan-Ying Lee gdb.write("page_address(0x%x) = 0x%x\n" % (page, addr)) 331eb985b5dSKuan-Ying Lee 332eb985b5dSKuan-Ying LeeLxPageAddress() 333eb985b5dSKuan-Ying Lee 334eb985b5dSKuan-Ying Leeclass LxPage2Phys(gdb.Command): 335eb985b5dSKuan-Ying Lee """struct page to physical address""" 336eb985b5dSKuan-Ying Lee 337eb985b5dSKuan-Ying Lee def __init__(self): 338eb985b5dSKuan-Ying Lee super(LxPage2Phys, self).__init__("lx-page_to_phys", gdb.COMMAND_USER) 339eb985b5dSKuan-Ying Lee 340eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 341eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 342eb985b5dSKuan-Ying Lee struct_page_addr = int(argv[0], 16) 343eb985b5dSKuan-Ying Lee page = gdb.Value(struct_page_addr).cast(utils.get_page_type().pointer()) 344eb985b5dSKuan-Ying Lee phys_addr = page_ops().ops.page_to_phys(page) 345eb985b5dSKuan-Ying Lee gdb.write("page_to_phys(0x%x) = 0x%x\n" % (page, phys_addr)) 346eb985b5dSKuan-Ying Lee 347eb985b5dSKuan-Ying LeeLxPage2Phys() 348eb985b5dSKuan-Ying Lee 349eb985b5dSKuan-Ying Leeclass LxVirt2Phys(gdb.Command): 350eb985b5dSKuan-Ying Lee """virtual address to physical address""" 351eb985b5dSKuan-Ying Lee 352eb985b5dSKuan-Ying Lee def __init__(self): 353eb985b5dSKuan-Ying Lee super(LxVirt2Phys, self).__init__("lx-virt_to_phys", gdb.COMMAND_USER) 354eb985b5dSKuan-Ying Lee 355eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 356eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 357eb985b5dSKuan-Ying Lee linear_addr = int(argv[0], 16) 358eb985b5dSKuan-Ying Lee phys_addr = page_ops().ops.virt_to_phys(linear_addr) 359eb985b5dSKuan-Ying Lee gdb.write("virt_to_phys(0x%x) = 0x%x\n" % (linear_addr, phys_addr)) 360eb985b5dSKuan-Ying Lee 361eb985b5dSKuan-Ying LeeLxVirt2Phys() 362eb985b5dSKuan-Ying Lee 363eb985b5dSKuan-Ying Leeclass LxVirt2Page(gdb.Command): 364eb985b5dSKuan-Ying Lee """virtual address to struct page""" 365eb985b5dSKuan-Ying Lee 366eb985b5dSKuan-Ying Lee def __init__(self): 367eb985b5dSKuan-Ying Lee super(LxVirt2Page, self).__init__("lx-virt_to_page", gdb.COMMAND_USER) 368eb985b5dSKuan-Ying Lee 369eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 370eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 371eb985b5dSKuan-Ying Lee linear_addr = int(argv[0], 16) 372eb985b5dSKuan-Ying Lee page = page_ops().ops.virt_to_page(linear_addr) 373eb985b5dSKuan-Ying Lee gdb.write("virt_to_page(0x%x) = 0x%x\n" % (linear_addr, page)) 374eb985b5dSKuan-Ying Lee 375eb985b5dSKuan-Ying LeeLxVirt2Page() 376eb985b5dSKuan-Ying Lee 377eb985b5dSKuan-Ying Leeclass LxSym2PFN(gdb.Command): 378eb985b5dSKuan-Ying Lee """symbol address to PFN""" 379eb985b5dSKuan-Ying Lee 380eb985b5dSKuan-Ying Lee def __init__(self): 381eb985b5dSKuan-Ying Lee super(LxSym2PFN, self).__init__("lx-sym_to_pfn", gdb.COMMAND_USER) 382eb985b5dSKuan-Ying Lee 383eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 384eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 385eb985b5dSKuan-Ying Lee sym_addr = int(argv[0], 16) 386eb985b5dSKuan-Ying Lee pfn = page_ops().ops.sym_to_pfn(sym_addr) 387eb985b5dSKuan-Ying Lee gdb.write("sym_to_pfn(0x%x) = %d\n" % (sym_addr, pfn)) 388eb985b5dSKuan-Ying Lee 389eb985b5dSKuan-Ying LeeLxSym2PFN() 390eb985b5dSKuan-Ying Lee 391eb985b5dSKuan-Ying Leeclass LxPFN2Kaddr(gdb.Command): 392eb985b5dSKuan-Ying Lee """PFN to kernel address""" 393eb985b5dSKuan-Ying Lee 394eb985b5dSKuan-Ying Lee def __init__(self): 395eb985b5dSKuan-Ying Lee super(LxPFN2Kaddr, self).__init__("lx-pfn_to_kaddr", gdb.COMMAND_USER) 396eb985b5dSKuan-Ying Lee 397eb985b5dSKuan-Ying Lee def invoke(self, arg, from_tty): 398eb985b5dSKuan-Ying Lee argv = gdb.string_to_argv(arg) 399eb985b5dSKuan-Ying Lee pfn = int(argv[0]) 400eb985b5dSKuan-Ying Lee kaddr = page_ops().ops.pfn_to_kaddr(pfn) 401eb985b5dSKuan-Ying Lee gdb.write("pfn_to_kaddr(%d) = 0x%x\n" % (pfn, kaddr)) 402eb985b5dSKuan-Ying Lee 403eb985b5dSKuan-Ying LeeLxPFN2Kaddr() 404