aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runlist.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/runlist.c b/runlist.c
index f6a05ac..ed35c7e 100644
--- a/runlist.c
+++ b/runlist.c
@@ -2,6 +2,8 @@
2 2
3#include "nvdebug.h" 3#include "nvdebug.h"
4 4
5#define FALLBACK_TO_PRAMIN
6
5/* Get runlist head and info (incl. length) 7/* Get runlist head and info (incl. length)
6 @param rl_iter Location at which to store output 8 @param rl_iter Location at which to store output
7 @param rl_id Which runlist to obtain? 9 @param rl_id Which runlist to obtain?
@@ -61,7 +63,7 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
61 uint32_t bar_inst_pramin_offset = vram2PRAMIN(g, (uint64_t)bar2_block.ptr << 12); 63 uint32_t bar_inst_pramin_offset = vram2PRAMIN(g, (uint64_t)bar2_block.ptr << 12);
62 if (!bar_inst_pramin_offset) { 64 if (!bar_inst_pramin_offset) {
63 printk(KERN_WARNING "[nvdebug] Unable to find instance block for BAR2/3 in the current NV_PRAMIN window. VRAM inaccessible.\n"); 65 printk(KERN_WARNING "[nvdebug] Unable to find instance block for BAR2/3 in the current NV_PRAMIN window. VRAM inaccessible.\n");
64 return -EOPNOTSUPP; 66 goto attempt_pramin_access;
65 } 67 }
66 /* TODO: Support BAR1? 68 /* TODO: Support BAR1?
67 bar_inst_pramin_offset = vram2PRAMIN(g, bar1_block.ptr << 12); 69 bar_inst_pramin_offset = vram2PRAMIN(g, bar1_block.ptr << 12);
@@ -82,12 +84,12 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
82 // TODO: SYSMEM support for page table location 84 // TODO: SYSMEM support for page table location
83 if (pd_config.target != TARGET_VID_MEM) { 85 if (pd_config.target != TARGET_VID_MEM) {
84 printk(KERN_WARNING "[nvdebug] BAR2 PDB is in an unsupported location.\n"); 86 printk(KERN_WARNING "[nvdebug] BAR2 PDB is in an unsupported location.\n");
85 return -EOPNOTSUPP; 87 goto attempt_pramin_access;
86 } 88 }
87 uint32_t bar_pdb_pramin_offset = vram2PRAMIN(g, bar_pdb_vram_addr); 89 uint32_t bar_pdb_pramin_offset = vram2PRAMIN(g, bar_pdb_vram_addr);
88 if (!bar_pdb_pramin_offset) { 90 if (!bar_pdb_pramin_offset) {
89 printk(KERN_WARNING "[nvdebug] Unable to find page directory BAR2/3 in the current NV_PRAMIN window. VRAM inaccessible.\n"); 91 printk(KERN_WARNING "[nvdebug] Unable to find page directory BAR2/3 in the current NV_PRAMIN window. VRAM inaccessible.\n");
90 return -EOPNOTSUPP; 92 goto attempt_pramin_access;
91 } 93 }
92 uint64_t runlist_bar_vaddr; 94 uint64_t runlist_bar_vaddr;
93 if (pd_config.is_ver2) 95 if (pd_config.is_ver2)
@@ -96,7 +98,7 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
96 runlist_bar_vaddr = search_v1_page_directory(g, g->regs + NV_PRAMIN + bar_pdb_pramin_offset, phy2PRAMIN, runlist_iova); 98 runlist_bar_vaddr = search_v1_page_directory(g, g->regs + NV_PRAMIN + bar_pdb_pramin_offset, phy2PRAMIN, runlist_iova);
97 if (!runlist_bar_vaddr) { 99 if (!runlist_bar_vaddr) {
98 printk(KERN_WARNING "[nvdebug] Unable to find runlist mapping in BAR2/3 page tables.\n"); 100 printk(KERN_WARNING "[nvdebug] Unable to find runlist mapping in BAR2/3 page tables.\n");
99 return -EOPNOTSUPP; 101 goto attempt_pramin_access;
100 } 102 }
101 printk(KERN_INFO "[nvdebug] Runlist @ %llx in BAR2 virtual address space.\n", runlist_bar_vaddr); 103 printk(KERN_INFO "[nvdebug] Runlist @ %llx in BAR2 virtual address space.\n", runlist_bar_vaddr);
102 /* XXX: Old test code 104 /* XXX: Old test code
@@ -121,6 +123,28 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
121 } 123 }
122 rl_iter->rl_info = rl_info; 124 rl_iter->rl_info = rl_info;
123 return 0; 125 return 0;
126attempt_pramin_access:
127#ifdef FALLBACK_TO_PRAMIN
128 printk(KERN_INFO "[nvdebug] Attempting to move PRAMIN window to runlist as BAR2/3-based access failed [DANGEROUS SIDE EFFECTS]!\n");
129 bar0_window_t win;
130 win.base = (runlist_iova >> 16);
131 win.target = TARGET_VID_MEM;
132 // Shift PRAMIN window. This will cause problems if it races with driver code
133 // that tries to do the same, or expects the window not to move.
134 nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, win.raw);
135 uint32_t off = vram2PRAMIN(g, runlist_iova);
136 // Workaround bug for if `off` should be zero (vram2PRAMIN normally returns
137 // this on error)
138 if (!off && (runlist_iova & 0xffffull != runlist_iova)) {
139 printk(KERN_INFO "[nvdebug] Unable to shift PRAMIN to runlist. Aborting...\n");
140 return -EOPNOTSUPP;
141 }
142 rl_iter->curr_entry = g->regs + NV_PRAMIN + off;
143 rl_iter->rl_info = rl_info;
144 return 0;
145#else
146 return -EOPNOTSUPP;
147#endif // FALLBACK_TO_PRAMIN
124} 148}
125 149
126int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id) { 150int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id) {