summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_display_engine.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/kernel/gsp_display_engine.c b/kernel/gsp_display_engine.c
index 811def9..c2fab96 100644
--- a/kernel/gsp_display_engine.c
+++ b/kernel/gsp_display_engine.c
@@ -465,6 +465,51 @@ static int gsp_disp_ctxdma_pa(struct nv_vgpu_device *vgpu, u32 handle,
disp.im_logs++;
pr_info("inst mem pa=0x%llx space=%u handle=0x%x hash_nz=%u\n",
im_pa, im_space, handle, nz);
+
+ /*
+ * The announced block may not be where the RM's writes
+ * actually landed (BAR1 aperture shift). Scan the whole
+ * emulated FB shadow once for hash-entry-shaped words:
+ * word1 = {chn[31:25], instance[24:14], client[13:0]}.
+ * Bounded: stops after 6 candidate blocks.
+ */
+ if (fb) {
+ u64 blk;
+ u32 blocks = 0;
+
+ for (blk = 0;
+ blk + GSP_DISP_INST_OBJ_END <= fb_size &&
+ blocks < 6; blk += 0x10000) {
+ u32 ee, cand = 0;
+ u64 first = 0;
+
+ for (ee = 0;
+ ee < GSP_DISP_INST_HASH_END;
+ ee += 8) {
+ u32 w1 = *(u32 *)(fb + blk +
+ ee + 4);
+ u32 inst = (w1 >> 14) &
+ 0x7ff;
+ u32 chn = (w1 >> 25) &
+ 0x7f;
+
+ if (w1 && chn <= 80 &&
+ inst >= 0x100 && inst < 0x800) {
+ if (!cand)
+ first = blk + ee;
+ cand++;
+ }
+ }
+ if (cand) {
+ pr_info("im scan: blk=0x%llx cand=%u first=0x%llx\n",
+ blk, cand, first);
+ blocks++;
+ }
+ }
+ pr_info("im scan: done, %u candidate blocks; BAR1_BLOCK=0x%x\n",
+ blocks,
+ gsp_disp_bar0_read(vgpu, 0x1704));
+ }
}
for (e = 0; e < GSP_DISP_INST_HASH_END; e += 8) {