diff options
author | rnoland <rnoland@FreeBSD.org> | 2010-04-22 18:21:25 +0000 |
---|---|---|
committer | rnoland <rnoland@FreeBSD.org> | 2010-04-22 18:21:25 +0000 |
commit | b733ebaa1ccc608f662359519c4712cf384b1360 (patch) | |
tree | 4cbae1e0936ed160e9fca32b44038b3450bb6072 /sys/dev/drm/drmP.h | |
parent | c0d6a78ddcc9bdcf4f9ee2858efab1abf0db5bdf (diff) | |
download | FreeBSD-src-b733ebaa1ccc608f662359519c4712cf384b1360.zip FreeBSD-src-b733ebaa1ccc608f662359519c4712cf384b1360.tar.gz |
Rework how drm maps are handled.
* On 32 bit platforms we steal the upper 4 bits of the map handle
to store a unique map id.
* On 64 bit platforms we steal the upper 24 bits.
Resolves issues where the offsets that are handed to mmap may overlap the VRAM on some cards.
Tested on: radeon, intel, mga, and via.
This will break nouveau. I will spin new patches shortly.
Diffstat (limited to 'sys/dev/drm/drmP.h')
-rw-r--r-- | sys/dev/drm/drmP.h | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index f89e750..1204974 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -239,22 +239,22 @@ typedef u_int8_t u8; #define DRM_MEMORYBARRIER() mb() #define DRM_READ8(map, offset) \ - *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) #define DRM_READ16(map, offset) \ - *(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) #define DRM_READ32(map, offset) \ - *(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) #define DRM_WRITE8(map, offset, val) \ - *(volatile u_int8_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) = val #define DRM_WRITE16(map, offset, val) \ - *(volatile u_int16_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) = val #define DRM_WRITE32(map, offset, val) \ - *(volatile u_int32_t *)(((vm_offset_t)(map)->handle) + \ + *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) = val #define DRM_VERIFYAREA_READ( uaddr, size ) \ @@ -481,18 +481,21 @@ typedef struct drm_sg_mem { struct drm_dma_handle *dmah; /* Handle to PCI memory */ } drm_sg_mem_t; +#define DRM_MAP_HANDLE_BITS (sizeof(void *) == 4 ? 4 : 24) +#define DRM_MAP_HANDLE_SHIFT (sizeof(void *) * 8 - DRM_MAP_HANDLE_BITS) typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; typedef struct drm_local_map { - unsigned long offset; /* Physical address (0 for SAREA)*/ - unsigned long size; /* Physical size (bytes) */ - enum drm_map_type type; /* Type of memory mapped */ - enum drm_map_flags flags; /* Flags */ - void *handle; /* User-space: "Handle" to pass to mmap */ - /* Kernel-space: kernel-virtual address */ - int mtrr; /* Boolean: MTRR used */ - /* Private data */ - int rid; /* PCI resource ID for bus_space */ + unsigned long offset; /* Physical address (0 for SAREA) */ + unsigned long size; /* Physical size (bytes) */ + enum drm_map_type type; /* Type of memory mapped */ + enum drm_map_flags flags; /* Flags */ + void *handle; /* User-space: "Handle" to pass to mmap */ + /* Kernel-space: kernel-virtual address */ + int mtrr; /* Boolean: MTRR used */ + /* Private data */ + int rid; /* PCI resource ID for bus_space */ + void *virtual; /* Kernel-space: kernel-virtual address */ struct resource *bsr; bus_space_tag_t bst; bus_space_handle_t bsh; @@ -643,6 +646,7 @@ struct drm_device { /* Linked list of mappable regions. Protected by dev_lock */ drm_map_list_t maplist; + struct unrhdr *map_unrhdr; drm_local_map_t **context_sareas; int max_context; @@ -973,17 +977,17 @@ drm_free(void *pt, size_t size, struct malloc_type *area) static __inline__ void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) { - map->handle = drm_ioremap_wc(dev, map); + map->virtual = drm_ioremap_wc(dev, map); } static __inline__ void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) { - map->handle = drm_ioremap(dev, map); + map->virtual = drm_ioremap(dev, map); } static __inline__ void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev) { - if ( map->handle && map->size ) + if ( map->virtual && map->size ) drm_ioremapfree(map); } @@ -994,7 +998,7 @@ drm_core_findmap(struct drm_device *dev, unsigned long offset) DRM_SPINLOCK_ASSERT(&dev->dev_lock); TAILQ_FOREACH(map, &dev->maplist, link) { - if (map->offset == offset) + if (offset == (unsigned long)map->handle) return map; } return NULL; |