diff options
author | Keith Packard <keithp@keithp.com> | 2008-05-05 14:22:42 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2008-05-05 14:22:42 -0700 |
commit | f0bc796a028dc7c6281d3d0cb2deef9df37e380a (patch) | |
tree | 8bdc369b71e7ad25e0cf0ea3c07febb0d114ec9c | |
parent | 4867780bd6900293880d1db963798d075ec9b01a (diff) |
Add object base to relocation store address.
The relocated value was being written to the wrong location, missing
the object base address.
-rw-r--r-- | linux-core/i915_gem.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index b66c7865..a1ce139b 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -99,6 +99,23 @@ i915_gem_object_unbind(struct drm_gem_object *obj) DRM_INFO ("done\n"); } +static void +i915_gem_dump_object (struct drm_gem_object *obj, int len, const char *where) +{ + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + uint32_t *mem = kmap_atomic (obj_priv->page_list[0], KM_USER0); + volatile uint32_t *gtt = ioremap(dev->agp->base + obj_priv->gtt_offset, + PAGE_SIZE); + int i; + + DRM_INFO ("%s: object at offset %08x\n", where, obj_priv->gtt_offset); + for (i = 0; i < len/4; i++) + DRM_INFO ("%3d: mem %08x gtt %08x\n", i, mem[i], readl(gtt + i)); + iounmap (gtt); + kunmap_atomic (mem, KM_USER0); +} + /** * Finds free space in the GTT aperture and binds the object there. */ @@ -176,20 +193,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return -ENOMEM; } - { - uint32_t *mem = kmap_atomic (obj_priv->page_list[0], KM_USER0); - volatile uint32_t *gtt = ioremap(dev->agp->base + obj_priv->gtt_offset, - PAGE_SIZE); - int i; - - DRM_INFO ("object at offset %08x agp base %08x gtt addr %p\n", - obj_priv->gtt_offset, (int) dev->agp->base, gtt); - for (i = 0; i < 16; i++) - DRM_INFO ("%3d: mem %08x gtt %08x\n", i, mem[i], gtt[i]); - iounmap (gtt); - kunmap_atomic (mem, KM_USER0); - } - return 0; } @@ -220,7 +223,7 @@ i915_gem_reloc_and_validate_object(struct drm_gem_object *obj, struct drm_gem_object *target_obj; struct drm_i915_gem_object *target_obj_priv; void *reloc_page; - uint32_t reloc_val, *reloc_entry; + uint32_t reloc_val, reloc_offset, *reloc_entry; int ret; ret = copy_from_user(&reloc, relocs + i, sizeof(reloc)); @@ -257,8 +260,9 @@ i915_gem_reloc_and_validate_object(struct drm_gem_object *obj, /* Map the page containing the relocation we're going to * perform. */ + reloc_offset = obj_priv->gtt_offset + reloc.offset; reloc_page = ioremap(dev->agp->base + - (reloc.offset & ~(PAGE_SIZE - 1)), + (reloc_offset & ~(PAGE_SIZE - 1)), PAGE_SIZE); if (reloc_page == NULL) { @@ -267,17 +271,19 @@ i915_gem_reloc_and_validate_object(struct drm_gem_object *obj, } reloc_entry = (uint32_t *)((char *)reloc_page + - (reloc.offset & (PAGE_SIZE - 1))); + (reloc_offset & (PAGE_SIZE - 1))); reloc_val = target_obj_priv->gtt_offset + reloc.delta; - DRM_DEBUG("Applied relocation: %p@0x%08x = 0x%08x\n", - obj, (unsigned int) reloc.offset, reloc_val); - *reloc_entry = reloc_val; + DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n", + obj, (unsigned int) reloc.offset, + readl (reloc_entry), reloc_val); + writel (reloc_val, reloc_entry); iounmap(reloc_page); drm_gem_object_unreference (target_obj); } + i915_gem_dump_object (obj, 128, __FUNCTION__); return 0; } |