summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm/drmP.h
diff options
context:
space:
mode:
authorrnoland <rnoland@FreeBSD.org>2010-04-22 18:21:25 +0000
committerrnoland <rnoland@FreeBSD.org>2010-04-22 18:21:25 +0000
commitb733ebaa1ccc608f662359519c4712cf384b1360 (patch)
tree4cbae1e0936ed160e9fca32b44038b3450bb6072 /sys/dev/drm/drmP.h
parentc0d6a78ddcc9bdcf4f9ee2858efab1abf0db5bdf (diff)
downloadFreeBSD-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.h42
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;
OpenPOWER on IntegriCloud