summaryrefslogtreecommitdiff
path: root/tools/aubdump.c
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2016-11-18 11:51:26 -0800
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>2016-11-22 16:38:41 +0000
commita5788706852d0d02d6b9b7510daa1ffce083d4d5 (patch)
tree0ecade7c8296b11f4db33c33911dc3d3f4277051 /tools/aubdump.c
parent59cdcf1febdbeb1c00dccb30940089f6877d6c1d (diff)
aubdump: Handle 48-bit relocations properly
aubdump was only writing 32-bits regardless of platform. This is fine if the client being dumped leaves the top 32 bits zero since the aubdump GTT is fairly small. However, if the client does store something in the upper 32 bits, this results in an invalid relocation. Cc: Kristian Høgsberg <krh@bitplanet.net> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Diffstat (limited to 'tools/aubdump.c')
-rw-r--r--tools/aubdump.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/tools/aubdump.c b/tools/aubdump.c
index f7ef6995..433f01ab 100644
--- a/tools/aubdump.c
+++ b/tools/aubdump.c
@@ -273,6 +273,32 @@ aub_dump_ringbuffer(uint64_t batch_offset, uint64_t offset, int ring_flag)
data_out(ringbuffer, ring_count * 4);
}
+static void
+write_reloc(void *p, uint64_t v)
+{
+ if (gen >= 8) {
+ /* From the Broadwell PRM Vol. 2a,
+ * MI_LOAD_REGISTER_MEM::MemoryAddress:
+ *
+ * "This field specifies the address of the memory
+ * location where the register value specified in the
+ * DWord above will read from. The address specifies
+ * the DWord location of the data. Range =
+ * GraphicsVirtualAddress[63:2] for a DWord register
+ * GraphicsAddress [63:48] are ignored by the HW and
+ * assumed to be in correct canonical form [63:48] ==
+ * [47]."
+ *
+ * In practice, this will always mean the top bits are zero
+ * because of the GTT size limitation of the aubdump tool.
+ */
+ const int shift = 63 - 47;
+ *(uint64_t *)p = (((int64_t)v) << shift) >> shift;
+ } else {
+ *(uint32_t *)p = v;
+ }
+}
+
static void *
relocate_bo(struct bo *bo, const struct drm_i915_gem_execbuffer2 *execbuffer2,
const struct drm_i915_gem_exec_object2 *obj)
@@ -282,7 +308,6 @@ relocate_bo(struct bo *bo, const struct drm_i915_gem_execbuffer2 *execbuffer2,
const struct drm_i915_gem_relocation_entry *relocs =
(const struct drm_i915_gem_relocation_entry *) (uintptr_t) obj->relocs_ptr;
void *relocated;
- uint32_t *dw;
int handle;
relocated = malloc(bo->size);
@@ -296,8 +321,8 @@ relocate_bo(struct bo *bo, const struct drm_i915_gem_execbuffer2 *execbuffer2,
else
handle = relocs[i].target_handle;
- dw = (uint32_t*)(((char *) relocated) + relocs[i].offset);
- *dw = get_bo(handle)->offset + relocs[i].delta;
+ write_reloc(((char *)relocated) + relocs[i].offset,
+ get_bo(handle)->offset + relocs[i].delta);
}
return relocated;