aboutsummaryrefslogtreecommitdiffstats
path: root/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'bus.c')
-rw-r--r--bus.c50
1 files changed, 13 insertions, 37 deletions
diff --git a/bus.c b/bus.c
index 802b6df..951ac77 100644
--- a/bus.c
+++ b/bus.c
@@ -57,35 +57,25 @@ relocate:
57 window.base = (u32)(addr >> 16); // Safe, due to above range check 57 window.base = (u32)(addr >> 16); // Safe, due to above range check
58 window.target = target; 58 window.target = target;
59 nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, window.raw); 59 nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, window.raw);
60 // Wait for the window to move by re-reading (as done in nvgpu driver)
61 (void) nvdebug_readl(g, NV_PBUS_BAR0_WINDOW);
60 return (int)(addr & 0xffffull); 62 return (int)(addr & 0xffffull);
61} 63}
62 64
63 65/* Get a copy of the BAR2 page directory configuration (base and aperture)
64/* Get a persistent pointer to the page directory base 66 @param pd Pointer at which to store the configuration, including a pointer
65 @param pdb Dereferencable pointer to the zeroeth entry of top-level page 67 and aperture for the zeroth entry of the top-level page directory
66 directory (PD3) for the BAR2 register region. 68 (PD3 for V2 page tables). This pointer **may not** be directly
67 Note: The returned pointer will be into the PRAMIN space. If the PRAMIN 69 dereferencable, and the caller may need to shift the BAR2 window.
68 window is moved to a region that does not cover the BAR2 page table, 70 @return 0 on success, -errno on error.
69 this ***will move the window***. 71 Note: This may move the PRAMIN window.
70 Note: Even if the page table is located in SYS_MEM, we route reads/writes via
71 PRAMIN. This ensures that we always see what the GPU sees, and that
72 includes any passes through I/O MMUs or IOVA spaces.
73*/ 72*/
74int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) { 73int get_bar2_pdb(struct nvdebug_state *g, page_dir_config_t* pd) {
75 static void* cached_pdb = NULL;
76 static bool cached_is_v2_pdb = false;
77 static long pd_hash = 0;
78 int ret; 74 int ret;
79 bar_config_block_t bar2_block; 75 bar_config_block_t bar2_block;
80 page_dir_config_t pd_config;
81 uint64_t pdb_vram;
82 76
83 // Use cached base as long as it's still pointing to the same thing 77 if (!pd)
84 if (cached_pdb && readl(cached_pdb) == pd_hash) { 78 return -EINVAL;
85 *pdb = cached_pdb;
86 *is_v2_pdb = cached_is_v2_pdb;
87 return 0;
88 }
89 79
90 if (!g->bar2) 80 if (!g->bar2)
91 return -ENXIO; 81 return -ENXIO;
@@ -107,24 +97,10 @@ int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) {
107 } 97 }
108 printk(KERN_INFO "[nvdebug] BAR2 inst block at off %x in PRAMIN\n", ret); 98 printk(KERN_INFO "[nvdebug] BAR2 inst block at off %x in PRAMIN\n", ret);
109 // Pull the page directory base configuration from the instance block 99 // Pull the page directory base configuration from the instance block
110 if ((pd_config.raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) { 100 if ((pd->raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) {
111 printk(KERN_ERR "[nvdebug] Unable to read BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); 101 printk(KERN_ERR "[nvdebug] Unable to read BAR2/3 PDB configuration! BAR2/3 inaccessible.\n");
112 return -ENOTSUPP; 102 return -ENOTSUPP;
113 } 103 }
114 pdb_vram = pd_config.page_dir_hi;
115 pdb_vram <<= 20;
116 pdb_vram |= pd_config.page_dir_lo;
117 pdb_vram <<= 12;
118 printk(KERN_INFO "[nvdebug] BAR2 PDB @ %llx (config raw: %llx)\n", pdb_vram, pd_config.raw);
119 // Setup PRAMIN to point at the page directory
120 if ((ret = addr_to_pramin_mut(g, pdb_vram, pd_config.target)) < 0) {
121 printk(KERN_ERR "[nvdebug] Invalid BAR2/3 PDB configuration! BAR2/3 inaccessible.\n");
122 return ret;
123 }
124
125 *pdb = cached_pdb = g->regs + NV_PRAMIN + ret;
126 pd_hash = readl(cached_pdb);
127 *is_v2_pdb = cached_is_v2_pdb = pd_config.is_ver2;
128 104
129 return 0; 105 return 0;
130} 106}