@@ -1839,9 +1839,8 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
}
if (dev_priv->gtt.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->gtt.aliasing_ppgtt;
-
seq_printf(m, "aliasing PPGTT:\n");
- seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
+ ppgtt->debug_dump(ppgtt, m);
}
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
mutex_unlock(&dev->struct_mutex);
@@ -537,6 +537,7 @@ struct i915_hw_ppgtt {
int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
struct intel_ring_buffer *ring);
void (*cleanup)(struct i915_hw_ppgtt *ppgtt);
+ void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m);
};
/* To make things as simple as possible (ie. no refcounting), a VMA's lifetime
@@ -100,6 +100,65 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
return pte;
}
+static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
+{
+ struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
+ struct i915_hw_context *ctx =
+ container_of(ppgtt, struct i915_hw_context, ppgtt);
+ gen6_gtt_pte_t __iomem *pd_addr;
+ gen6_gtt_pte_t scratch_pte;
+ uint32_t pd_entry;
+ bool found = false;
+ int pte, pde;
+
+ scratch_pte = ppgtt->base.pte_encode(ppgtt->base.scratch.addr,
+ I915_CACHE_LLC);
+
+
+ pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
+ ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
+
+ seq_printf(m, " Context %d (pd_offset %x-%x):\n", ctx->id,
+ ppgtt->pd_offset, ppgtt->pd_offset + ppgtt->num_pd_entries);
+ for (pde = 0; pde < ppgtt->num_pd_entries; pde++) {
+ u32 expected;
+ gen6_gtt_pte_t *pt_vaddr;
+ dma_addr_t pt_addr = ppgtt->pt_dma_addr[pde];
+ pd_entry = readl(pd_addr + pde);
+ expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
+
+ if (pd_entry != expected)
+ seq_printf(m, "\tPDE #%d mismatch: Actual PDE: %x Expected PDE: %x\n",
+ pde,
+ pd_entry,
+ expected);
+#if 0
+ seq_printf(m, "\tPDE: %x\n", pd_entry);
+#endif
+
+ pt_vaddr = kmap_atomic(ppgtt->pt_pages[pde]);
+ for (pte = 0; pte < I915_PPGTT_PT_ENTRIES; pte++) {
+ unsigned long va =
+ (pde * PAGE_SIZE * I915_PPGTT_PT_ENTRIES) +
+ (pte * PAGE_SIZE);
+ if (pt_vaddr[pte] != scratch_pte) {
+ seq_printf(m, "\t\t0x%lx [%03d,%04d]: = %08x %08x %08x %08x\n",
+ va,
+ pde, pte,
+ pt_vaddr[pte],
+ pt_vaddr[pte],
+ pt_vaddr[pte],
+ pt_vaddr[pte]);
+ found = true;
+ }
+ }
+ kunmap_atomic(pt_vaddr);
+ }
+
+ if (!found)
+ seq_puts(m, "\tempty\n");
+}
+
static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
{
struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
@@ -391,6 +450,7 @@ alloc:
ppgtt->enable = gen6_ppgtt_enable;
ppgtt->switch_mm = gen6_mm_switch;
ppgtt->cleanup = gen6_ppgtt_cleanup;
+ ppgtt->debug_dump = gen6_dump_ppgtt;
vm->clear_range = gen6_ppgtt_clear_range;
vm->insert_entries = gen6_ppgtt_insert_entries;
Dump the aliasing PPGTT with it. The aliasing PPGTT should actually always be empty. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem_gtt.c | 60 +++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-)