aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mmu.c17
-rw-r--r--nvdebug.h1
2 files changed, 12 insertions, 6 deletions
diff --git a/mmu.c b/mmu.c
index 30e9362..e420864 100644
--- a/mmu.c
+++ b/mmu.c
@@ -15,11 +15,12 @@
15 15
16/* Convert a physical VRAM address to an offset in the PRAMIN window 16/* Convert a physical VRAM address to an offset in the PRAMIN window
17 @param addr VRAM address to convert 17 @param addr VRAM address to convert
18 @return 0 on error, PRAMIN offset on success 18 @return -errno on error, PRAMIN offset on success
19 19
20 Note: Use off2PRAMIN() instead if you want a dereferenceable address 20 Note: Use off2PRAMIN() instead if you want a dereferenceable address
21 Note: PRAMIN window is only 1MB, so returning an int is safe
21*/ 22*/
22uint32_t vram2PRAMIN(struct nvdebug_state *g, uint64_t addr) { 23static int vram2PRAMIN(struct nvdebug_state *g, uint64_t addr) {
23 uint64_t pramin_base_va; 24 uint64_t pramin_base_va;
24 bar0_window_t window; 25 bar0_window_t window;
25 window.raw = nvdebug_readl(g, NV_PBUS_BAR0_WINDOW); 26 window.raw = nvdebug_readl(g, NV_PBUS_BAR0_WINDOW);
@@ -27,20 +28,26 @@ uint32_t vram2PRAMIN(struct nvdebug_state *g, uint64_t addr) {
27 if (addr & ~0x0001ffffffffffff) { 28 if (addr & ~0x0001ffffffffffff) {
28 printk(KERN_ERR "[nvdebug] Invalid address %llx passed to %s!\n", 29 printk(KERN_ERR "[nvdebug] Invalid address %llx passed to %s!\n",
29 addr, __func__); 30 addr, __func__);
30 return 0; 31 return -EINVAL;
31 } 32 }
32 // For unclear (debugging?) reasons, PRAMIN can point to SYSMEM 33 // For unclear (debugging?) reasons, PRAMIN can point to SYSMEM
33 if (window.target != TARGET_VID_MEM) 34 if (window.target != TARGET_VID_MEM)
34 return 0; 35 return -EFAULT;
35 pramin_base_va = ((uint64_t)window.base) << 16; 36 pramin_base_va = ((uint64_t)window.base) << 16;
36 // Protect against out-of-bounds accesses 37 // Protect against out-of-bounds accesses
37 if (addr < pramin_base_va || addr > pramin_base_va + NV_PRAMIN_LEN) 38 if (addr < pramin_base_va || addr > pramin_base_va + NV_PRAMIN_LEN)
38 return 0; 39 return -ERANGE;
39 return addr - pramin_base_va; 40 return addr - pramin_base_va;
40} 41}
41 42
42// Convert a GPU physical address to CPU virtual address via the PRAMIN window 43// Convert a GPU physical address to CPU virtual address via the PRAMIN window
44// @return A dereferencable address, or 0 (an invalid physical address) on err
43void __iomem *phy2PRAMIN(struct nvdebug_state* g, uint64_t phy) { 45void __iomem *phy2PRAMIN(struct nvdebug_state* g, uint64_t phy) {
46 int off = vram2PRAMIN(g, phy);
47 if (off == -ERANGE)
48 printk(KERN_ERR "[nvdebug] Page table walk off end of PRAMIN!\n");
49 if (off < 0)
50 return 0;
44 return g->regs + NV_PRAMIN + vram2PRAMIN(g, phy); 51 return g->regs + NV_PRAMIN + vram2PRAMIN(g, phy);
45} 52}
46 53
diff --git a/nvdebug.h b/nvdebug.h
index 67f2111..567806d 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -1149,7 +1149,6 @@ int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id);
1149int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id); 1149int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id);
1150 1150
1151// Defined in mmu.c 1151// Defined in mmu.c
1152uint32_t vram2PRAMIN(struct nvdebug_state *g, uint64_t addr);
1153void __iomem *phy2PRAMIN(struct nvdebug_state* g, uint64_t phy); 1152void __iomem *phy2PRAMIN(struct nvdebug_state* g, uint64_t phy);
1154uint64_t search_page_directory( 1153uint64_t search_page_directory(
1155 struct nvdebug_state *g, 1154 struct nvdebug_state *g,