diff options
Diffstat (limited to 'mmu.c')
-rw-r--r-- | mmu.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -64,21 +64,22 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g, | |||
64 | // Hack to workaround PDE0 being double-size and strangely formatted | 64 | // Hack to workaround PDE0 being double-size and strangely formatted |
65 | if (NV_MMU_PT_V2_ENTRY_SZ[level] == 16) | 65 | if (NV_MMU_PT_V2_ENTRY_SZ[level] == 16) |
66 | pde_offset += 8; | 66 | pde_offset += 8; |
67 | entry.raw = readl(pde_offset); | 67 | entry.raw_w = readq(pde_offset); |
68 | // If we reached an invalid (unpopulated) PDE, walk back up the tree | 68 | // If we reached an invalid (unpopulated) PDE, walk back up the tree |
69 | if (entry.target == PD_AND_TARGET_INVALID) | 69 | if (entry.target == PD_AND_TARGET_INVALID) |
70 | return 0; | 70 | return 0; |
71 | // Succeed when we reach a PTE with the address we want | 71 | // Succeed when we reach a PTE with the address we want |
72 | if (entry.is_pte) { | 72 | if (entry.is_pte) { |
73 | printk(KERN_INFO "[nvdebug] PTE for phy addr %llx (raw: %x)\n", ((u64)entry.addr) << 12, entry.raw); | 73 | // TODO: Handle huge pages here |
74 | printk(KERN_INFO "[nvdebug] PTE for phy addr %#018llx, ap '%s', vol '%d', priv '%d', ro '%d', no_atomics '%d' (raw: %#018llx)\n", ((u64)entry.addr_w) << 12, pd_target_to_text(entry.target), entry.is_volatile, entry.is_privileged, entry.is_readonly, entry.atomics_disabled, entry.raw_w); | ||
74 | return (uint64_t)entry.addr << 12 == addr_to_find; | 75 | return (uint64_t)entry.addr << 12 == addr_to_find; |
75 | } | 76 | } |
76 | printk(KERN_INFO "[nvdebug] Found PDE pointing to %llx in ap '%d' at lvl %d (raw: %x)\n", ((u64)entry.addr) << 12, entry.target, level, entry.raw); | 77 | printk(KERN_INFO "[nvdebug] Found PDE pointing to %#018llx in ap '%s' vol '%d' at lvl %d (raw: %#018llx)\n", ((u64)entry.addr_w) << 12, pd_target_to_text(entry.target), entry.is_volatile, level, entry.raw_w); |
77 | // Depth-first search of the page table | 78 | // Depth-first search of the page table |
78 | for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { | 79 | for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { |
79 | next = off2addr(g, ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i); | 80 | next = off2addr(g, ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i); |
80 | // off2addr can fail | 81 | // off2addr can fail |
81 | if (!next) { | 82 | if (!next || !entry.addr_w) { |
82 | printk(KERN_ERR "[nvdebug] %s: Unable to resolve GPU PA to CPU PA\n", __func__); | 83 | printk(KERN_ERR "[nvdebug] %s: Unable to resolve GPU PA to CPU PA\n", __func__); |
83 | return 0; | 84 | return 0; |
84 | } | 85 | } |
@@ -111,6 +112,7 @@ uint64_t search_page_directory(struct nvdebug_state *g, | |||
111 | printk(KERN_WARNING "[nvdebug] Attempting to search for unaligned address %llx in search_page_directory()!\n", addr_to_find); | 112 | printk(KERN_WARNING "[nvdebug] Attempting to search for unaligned address %llx in search_page_directory()!\n", addr_to_find); |
112 | return 0; | 113 | return 0; |
113 | } | 114 | } |
115 | printk(KERN_INFO "[nvdebug] Searching for addr %#018llx in page table with base %#018llx\n", (u64)addr_to_find, (u64)pde_offset); | ||
114 | // Search the top-level page directory (PDE3) | 116 | // Search the top-level page directory (PDE3) |
115 | for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) | 117 | for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) |
116 | if ((res = search_page_directory_subtree(g, pde_offset + NV_MMU_PT_V2_ENTRY_SZ[0] * i, off2addr, addr_to_find, 0))) | 118 | if ((res = search_page_directory_subtree(g, pde_offset + NV_MMU_PT_V2_ENTRY_SZ[0] * i, off2addr, addr_to_find, 0))) |