diff options
130 files changed, 4089 insertions, 3613 deletions
diff --git a/bsd-core/Makefile b/bsd-core/Makefile index ea44a7cd..6281b00c 100644 --- a/bsd-core/Makefile +++ b/bsd-core/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ # i810, i830 & sis are not complete -SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis +SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma .include <bsd.subdir.mk> diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index 28723f56..0cc63a3a 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -25,6 +25,8 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/ati_pcigart.h,v 1.1 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -42,25 +44,6 @@ # define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ # define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ -static unsigned long DRM(ati_alloc_pcigart_table)( void ) -{ - unsigned long address; - - DRM_DEBUG( "\n" ); - - address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK ); - - DRM_DEBUG( "returning 0x%08lx\n", address ); - return address; -} - -static void DRM(ati_free_pcigart_table)( unsigned long address ) -{ - DRM_DEBUG( "\n" ); - - free( (void *)address, DRM(M_DRM)); -} - int DRM(ati_pcigart_init)( drm_device_t *dev, unsigned long *addr, dma_addr_t *bus_addr) @@ -76,23 +59,15 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, goto done; } - address = DRM(ati_alloc_pcigart_table)(); + address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, + DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0); if ( !address ) { DRM_ERROR( "cannot allocate PCI GART page!\n" ); goto done; } - /* FIXME non-vtophys==bustophys-arches */ + /* XXX: we need to busdma this */ bus_address = vtophys( address ); - /*pci_map_single(dev->pdev, (void *)address, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE);*/ -/* if (bus_address == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_free_pcigart_table)( (unsigned long)address ); - address = 0; - goto done; - }*/ pci_gart = (u32 *)address; @@ -102,16 +77,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); for ( i = 0 ; i < pages ; i++ ) { - /* we need to support large memory configurations */ - /* FIXME non-vtophys==vtobus-arches */ entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) ); -/* if (entry->busaddr[i] == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_pcigart_cleanup)( dev, (unsigned long)address, bus_address ); - address = 0; - bus_address = 0; - goto done; - }*/ page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { @@ -122,8 +88,6 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, ret = 1; - DRM_READMEMORYBARRIER(); - done: *addr = address; *bus_addr = bus_address; @@ -142,9 +106,8 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, return 0; } - if ( addr ) { - DRM(ati_free_pcigart_table)( addr ); - } - +#if __FreeBSD_version > 500000 + contigfree( (void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM)); /* Not available on 4.x */ +#endif return 1; } diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 541bc2eb..96dd52d8 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drmP.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #ifndef _DRM_P_H_ @@ -95,21 +96,20 @@ typedef struct drm_file drm_file_t; #define DRM_MEM_MAGIC 3 #define DRM_MEM_IOCTLS 4 #define DRM_MEM_MAPS 5 -#define DRM_MEM_VMAS 6 -#define DRM_MEM_BUFS 7 -#define DRM_MEM_SEGS 8 -#define DRM_MEM_PAGES 9 -#define DRM_MEM_FILES 10 -#define DRM_MEM_QUEUES 11 -#define DRM_MEM_CMDS 12 -#define DRM_MEM_MAPPINGS 13 -#define DRM_MEM_BUFLISTS 14 -#define DRM_MEM_AGPLISTS 15 -#define DRM_MEM_TOTALAGP 16 -#define DRM_MEM_BOUNDAGP 17 -#define DRM_MEM_CTXBITMAP 18 -#define DRM_MEM_STUB 19 -#define DRM_MEM_SGLISTS 20 +#define DRM_MEM_BUFS 6 +#define DRM_MEM_SEGS 7 +#define DRM_MEM_PAGES 8 +#define DRM_MEM_FILES 9 +#define DRM_MEM_QUEUES 10 +#define DRM_MEM_CMDS 11 +#define DRM_MEM_MAPPINGS 12 +#define DRM_MEM_BUFLISTS 13 +#define DRM_MEM_AGPLISTS 14 +#define DRM_MEM_TOTALAGP 15 +#define DRM_MEM_BOUNDAGP 16 +#define DRM_MEM_CTXBITMAP 17 +#define DRM_MEM_STUB 18 +#define DRM_MEM_SGLISTS 19 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) @@ -121,15 +121,15 @@ typedef struct drm_file drm_file_t; /* Mapping helper macros */ #define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) + (map)->handle = DRM(ioremap)( dev, map ) #define DRM_IOREMAP_NOCACHE(map) \ - (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) + (map)->handle = DRM(ioremap_nocache)( dev, map ) #define DRM_IOREMAPFREE(map) \ do { \ if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ + DRM(ioremapfree)( map ); \ } while (0) /* Internal types and structures */ @@ -152,16 +152,11 @@ typedef struct drm_pci_list { } drm_pci_list_t; typedef struct drm_ioctl_desc { - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int auth_needed; int root_only; } drm_ioctl_desc_t; -typedef struct drm_devstate { - pid_t owner; /* X server pid holding x_lock */ - -} drm_devstate_t; - typedef struct drm_magic_entry { drm_magic_t magic; struct drm_file *priv; @@ -173,12 +168,6 @@ typedef struct drm_magic_head { struct drm_magic_entry *tail; } drm_magic_head_t; -typedef struct drm_vma_entry { - struct vm_area_struct *vma; - struct drm_vma_entry *next; - pid_t pid; -} drm_vma_entry_t; - typedef struct drm_buf { int idx; /* Index into master buflist */ int total; /* Buffer size */ @@ -191,7 +180,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + DRMFILE filp; /* Unique identifier of holding process */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -308,7 +297,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -377,7 +366,6 @@ typedef struct drm_sg_mem { unsigned long handle; void *virtual; int pages; - struct page **pagelist; dma_addr_t *busaddr; } drm_sg_mem_t; @@ -386,10 +374,23 @@ typedef struct drm_sigdata { drm_hw_lock_t *lock; } drm_sigdata_t; +typedef struct drm_local_map { + unsigned long offset; /* Physical address (0 for SAREA)*/ + unsigned long size; /* Physical size (bytes) */ + drm_map_type_t type; /* Type of memory mapped */ + drm_map_flags_t flags; /* Flags */ + void *handle; /* User-space: "Handle" to pass to mmap */ + /* Kernel-space: kernel-virtual address */ + int mtrr; /* MTRR slot used */ + /* Private data */ + bus_space_tag_t iot; + bus_space_handle_t ioh; +} drm_local_map_t; + typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t; typedef struct drm_map_list_entry { TAILQ_ENTRY(drm_map_list_entry) link; - drm_map_t *map; + drm_local_map_t *map; } drm_map_list_entry_t; TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig); @@ -423,7 +424,6 @@ struct drm_device { /* Usage Counters */ int open_count; /* Outstanding files open */ atomic_t ioctl_count; /* Outstanding IOCTLs pending */ - atomic_t vma_count; /* Outstanding vma areas open */ int buf_use; /* Buffers in use -- cannot alloc */ atomic_t buf_alloc; /* Buffer allocation in progress */ @@ -440,10 +440,9 @@ struct drm_device { drm_map_list_t *maplist; /* Linked list of regions */ int map_count; /* Number of mappable regions */ - drm_map_t **context_sareas; + drm_local_map_t **context_sareas; int max_context; - drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */ drm_lock_data_t lock; /* Information on hardware lock */ /* DMA queues (contexts) */ @@ -454,9 +453,9 @@ struct drm_device { drm_device_dma_t *dma; /* Optional pointer for DMA support */ /* Context support */ -#ifdef __FreeBSD__ int irq; /* Interrupt used by board */ int irqrid; /* Interrupt used by board */ +#ifdef __FreeBSD__ struct resource *irqr; /* Resource for interrupt used by board */ #elif defined(__NetBSD__) struct pci_attach_args pa; @@ -477,9 +476,11 @@ struct drm_device { #if __HAVE_VBL_IRQ wait_queue_head_t vbl_queue; /* vbl wait channel */ atomic_t vbl_received; +#if 0 /* vbl signals are untested, ntested */ struct drm_vbl_sig_list vbl_sig_list; DRM_SPINTYPE vbl_lock; #endif +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -530,15 +531,16 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s); /* Memory management support (drm_memory.h) */ extern void DRM(mem_init)(void); +extern void DRM(mem_uninit)(void); extern void *DRM(alloc)(size_t size, int area); extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area); extern char *DRM(strdup)(const char *s, int area); extern void DRM(strfree)(char *s, int area); extern void DRM(free)(void *pt, size_t size, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map); +extern void *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map); +extern void DRM(ioremapfree)(drm_local_map_t *map); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); @@ -580,7 +582,7 @@ extern int DRM(order)( unsigned long size ); extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ @@ -652,5 +654,82 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, dma_addr_t bus_addr); #endif +/* Locking IOCTL support (drm_drv.h) */ +extern int DRM(lock)(DRM_IOCTL_ARGS); +extern int DRM(unlock)(DRM_IOCTL_ARGS); + +/* Misc. IOCTL support (drm_ioctl.h) */ +extern int DRM(irq_busid)(DRM_IOCTL_ARGS); +extern int DRM(getunique)(DRM_IOCTL_ARGS); +extern int DRM(setunique)(DRM_IOCTL_ARGS); +extern int DRM(getmap)(DRM_IOCTL_ARGS); +extern int DRM(getclient)(DRM_IOCTL_ARGS); +extern int DRM(getstats)(DRM_IOCTL_ARGS); + +/* Context IOCTL support (drm_context.h) */ +extern int DRM(resctx)(DRM_IOCTL_ARGS); +extern int DRM(addctx)(DRM_IOCTL_ARGS); +extern int DRM(modctx)(DRM_IOCTL_ARGS); +extern int DRM(getctx)(DRM_IOCTL_ARGS); +extern int DRM(switchctx)(DRM_IOCTL_ARGS); +extern int DRM(newctx)(DRM_IOCTL_ARGS); +extern int DRM(rmctx)(DRM_IOCTL_ARGS); +extern int DRM(setsareactx)(DRM_IOCTL_ARGS); +extern int DRM(getsareactx)(DRM_IOCTL_ARGS); + +/* Drawable IOCTL support (drm_drawable.h) */ +extern int DRM(adddraw)(DRM_IOCTL_ARGS); +extern int DRM(rmdraw)(DRM_IOCTL_ARGS); + +/* Authentication IOCTL support (drm_auth.h) */ +extern int DRM(getmagic)(DRM_IOCTL_ARGS); +extern int DRM(authmagic)(DRM_IOCTL_ARGS); + +/* Locking IOCTL support (drm_lock.h) */ +extern int DRM(block)(DRM_IOCTL_ARGS); +extern int DRM(unblock)(DRM_IOCTL_ARGS); +extern int DRM(finish)(DRM_IOCTL_ARGS); + +/* Buffer management support (drm_bufs.h) */ +extern int DRM(addmap)(DRM_IOCTL_ARGS); +extern int DRM(rmmap)(DRM_IOCTL_ARGS); +#if __HAVE_DMA +extern int DRM(addbufs_agp)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_pci)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_sg)(DRM_IOCTL_ARGS); +extern int DRM(addbufs)(DRM_IOCTL_ARGS); +extern int DRM(infobufs)(DRM_IOCTL_ARGS); +extern int DRM(markbufs)(DRM_IOCTL_ARGS); +extern int DRM(freebufs)(DRM_IOCTL_ARGS); +extern int DRM(mapbufs)(DRM_IOCTL_ARGS); +#endif + +/* DMA support (drm_dma.h) */ +#if __HAVE_DMA +extern int DRM(control)(DRM_IOCTL_ARGS); +#endif +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(DRM_IOCTL_ARGS); +#endif + +/* AGP/GART support (drm_agpsupport.h) */ +#if __REALLY_HAVE_AGP +extern int DRM(agp_acquire)(DRM_IOCTL_ARGS); +extern int DRM(agp_release)(DRM_IOCTL_ARGS); +extern int DRM(agp_enable)(DRM_IOCTL_ARGS); +extern int DRM(agp_info)(DRM_IOCTL_ARGS); +extern int DRM(agp_alloc)(DRM_IOCTL_ARGS); +extern int DRM(agp_free)(DRM_IOCTL_ARGS); +extern int DRM(agp_unbind)(DRM_IOCTL_ARGS); +extern int DRM(agp_bind)(DRM_IOCTL_ARGS); +#endif + +/* Scatter Gather Support (drm_scatter.h) */ +#if __HAVE_SG +extern int DRM(sg_alloc)(DRM_IOCTL_ARGS); +extern int DRM(sg_free)(DRM_IOCTL_ARGS); +#endif + + #endif /* __KERNEL__ */ #endif /* _DRM_P_H_ */ diff --git a/bsd-core/drm_agpsupport.c b/bsd-core/drm_agpsupport.c index a940378e..ca7bea9e 100644 --- a/bsd-core/drm_agpsupport.c +++ b/bsd-core/drm_agpsupport.c @@ -27,6 +27,7 @@ * Author: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_agpsupport.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -37,7 +38,8 @@ int DRM(agp_info)(DRM_IOCTL_ARGS) struct agp_info *kern; drm_agp_info_t info; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; kern = &dev->agp->info; agp_get_info(dev->agp->agpdev, kern); @@ -60,9 +62,11 @@ int DRM(agp_acquire)(DRM_IOCTL_ARGS) DRM_DEVICE; int retcode; - if (!dev->agp || dev->agp->acquired) return EINVAL; + if (!dev->agp || dev->agp->acquired) + return EINVAL; retcode = agp_acquire(dev->agp->agpdev); - if (retcode) return retcode; + if (retcode) + return retcode; dev->agp->acquired = 1; return 0; } @@ -93,7 +97,8 @@ int DRM(agp_enable)(DRM_IOCTL_ARGS) DRM_DEVICE; drm_agp_mode_t mode; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; mode = *(drm_agp_mode_t *) data; @@ -114,7 +119,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS) u_int32_t type; struct agp_memory_info info; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_buffer_t *) data; @@ -136,7 +142,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS) entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; - if (dev->agp->memory) dev->agp->memory->prev = entry; + if (dev->agp->memory) + dev->agp->memory->prev = entry; dev->agp->memory = entry; agp_memory_info(dev->agp->agpdev, entry->handle, &info); @@ -166,7 +173,8 @@ int DRM(agp_unbind)(DRM_IOCTL_ARGS) drm_agp_mem_t *entry; int retcode; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_binding_t *) data; if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle))) return EINVAL; @@ -209,15 +217,20 @@ int DRM(agp_free)(DRM_IOCTL_ARGS) drm_agp_buffer_t request; drm_agp_mem_t *entry; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_buffer_t *) data; if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle))) return EINVAL; - if (entry->bound) DRM(unbind_agp)(entry->handle); + if (entry->bound) + DRM(unbind_agp)(entry->handle); - if (entry->prev) entry->prev->next = entry->next; - else dev->agp->memory = entry->next; - if (entry->next) entry->next->prev = entry->prev; + if (entry->prev) + entry->prev->next = entry->next; + else + dev->agp->memory = entry->next; + if (entry->next) + entry->next->prev = entry->prev; DRM(free_agp)(entry->handle, entry->pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; diff --git a/bsd-core/drm_auth.c b/bsd-core/drm_auth.c index 0b411d14..c506ee7e 100644 --- a/bsd-core/drm_auth.c +++ b/bsd-core/drm_auth.c @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_auth.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -116,25 +117,20 @@ int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; drm_auth_t auth; - static DRM_SPINTYPE lock; - static int first = 1; DRM_DEVICE; DRM_PRIV; - if (first) { - DRM_SPININIT(lock, "drm getmagic"); - first = 0; - } - /* Find unique magic */ if (priv->magic) { auth.magic = priv->magic; } else { do { - DRM_SPINLOCK(&lock); - if (!sequence) ++sequence; /* reserve 0 */ - auth.magic = sequence++; - DRM_SPINUNLOCK(&lock); + int old = sequence; + + auth.magic = old+1; + + if (!atomic_cmpset_int(&sequence, old, auth.magic)) + continue; } while (DRM(find_file)(dev, auth.magic)); priv->magic = auth.magic; DRM(add_magic)(dev, priv, auth.magic); diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 7d56d0a3..8e0534f2 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_bufs.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -69,18 +70,26 @@ int DRM(order)( unsigned long size ) int DRM(addmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; - drm_map_t *map; + drm_map_t request; + drm_local_map_t *map; drm_map_list_entry_t *list; if (!(dev->flags & (FREAD|FWRITE))) return DRM_ERR(EACCES); /* Require read/write */ - map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) ); + + map = (drm_local_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); if ( !map ) return DRM_ERR(ENOMEM); - *map = *(drm_map_t *)data; - + map->offset = request.offset; + map->size = request.size; + map->type = request.type; + map->flags = request.flags; + map->mtrr = -1; + map->handle = 0; + /* Only allow shared memory to be removable since we only keep enough * book keeping information about shared memory to allow for removal * when processes fork. @@ -95,22 +104,14 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return DRM_ERR(EINVAL); } - map->mtrr = -1; - map->handle = 0; switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) - if ( map->offset + map->size < map->offset - ) { + if ( map->offset + map->size < map->offset ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return DRM_ERR(EINVAL); } -#endif -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif #if __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { @@ -130,14 +131,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) mtrrmap.base = map->offset; mtrrmap.len = map->size; mtrrmap.type = MTRR_TYPE_WC; - mtrrmap.flags = MTRR_PRIVATE | MTRR_VALID; - mtrrmap.owner = p->p_pid; - /* USER? KERNEL? XXX */ - map->mtrr = mtrr_get( &mtrrmap, &one, p, MTRR_GETSET_KERNEL ); + mtrrmap.flags = MTRR_VALID; + map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL ); #endif } #endif /* __REALLY_HAVE_MTRR */ - map->handle = DRM(ioremap)( map->offset, map->size ); + DRM_IOREMAP(map); break; case _DRM_SHM: @@ -155,9 +154,6 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) break; #if __REALLY_HAVE_AGP case _DRM_AGP: -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif map->offset += dev->agp->base; map->mtrr = dev->agp->agp_mtrr; /* for getmap */ break; @@ -187,11 +183,19 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) TAILQ_INSERT_TAIL(dev->maplist, list, link); DRM_UNLOCK; - *(drm_map_t *)data = *map; + request.offset = map->offset; + request.size = map->size; + request.type = map->type; + request.flags = map->flags; + request.mtrr = map->mtrr; + request.handle = map->handle; - if ( map->type != _DRM_SHM ) { - ((drm_map_t *)data)->handle = (void *)map->offset; + if ( request.type != _DRM_SHM ) { + request.handle = (void *)request.offset; } + + DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, request, sizeof(drm_map_t) ); + return 0; } @@ -204,7 +208,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_map_list_entry_t *list; - drm_map_t *map; + drm_local_map_t *map; drm_map_t request; int found_maps = 0; @@ -257,7 +261,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) #endif } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)( map ); break; case _DRM_SHM: DRM(free)( map->handle, map->size, DRM_MEM_SAREA ); @@ -413,7 +417,7 @@ int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -621,7 +625,7 @@ int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -774,7 +778,7 @@ int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -858,16 +862,16 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) - return DRM(addbufs_agp)( kdev, cmd, data, flags, p ); + return DRM(addbufs_agp)( kdev, cmd, data, flags, p, filp ); else #endif #if __REALLY_HAVE_SG if ( request.flags & _DRM_SG_BUFFER ) - return DRM(addbufs_sg)( kdev, cmd, data, flags, p ); + return DRM(addbufs_sg)( kdev, cmd, data, flags, p, filp ); else #endif #if __HAVE_PCI_DMA - return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); + return DRM(addbufs_pci)( kdev, cmd, data, flags, p, filp ); #else return DRM_ERR(EINVAL); #endif @@ -991,9 +995,9 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR("Process %d freeing buffer not owned\n", + DRM_CURRENTPID); return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); @@ -1018,6 +1022,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) #endif /* __FreeBSD__ */ #ifdef __NetBSD__ struct vnode *vn; + struct vmspace *vms = p->p_vmspace; #endif /* __NetBSD__ */ drm_buf_map_t request; @@ -1043,7 +1048,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) if ( request.count >= dma->buf_count ) { if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) { - drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev ); + drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev ); if ( !map ) { retcode = EINVAL; diff --git a/bsd-core/drm_context.c b/bsd-core/drm_context.c index 0274a8b7..c3a20f6e 100644 --- a/bsd-core/drm_context.c +++ b/bsd-core/drm_context.c @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_context.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -69,7 +70,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) if((bit+1) > dev->max_context) { dev->max_context = (bit+1); if(dev->context_sareas) { - drm_map_t **ctx_sareas; + drm_local_map_t **ctx_sareas; ctx_sareas = DRM(realloc)(dev->context_sareas, (dev->max_context - 1) * @@ -149,7 +150,7 @@ int DRM(getsareactx)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_ctx_priv_map_t request; - drm_map_t *map; + drm_local_map_t *map; DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); @@ -174,7 +175,7 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_ctx_priv_map_t request; - drm_map_t *map = NULL; + drm_local_map_t *map = NULL; drm_map_list_entry_t *list; DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, @@ -183,24 +184,20 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS ) DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map=list->map; - if(map->handle == request.handle) - goto found; + if(map->handle == request.handle) { + if (dev->max_context < 0) + goto bad; + if (request.ctx_id >= (unsigned) dev->max_context) + goto bad; + dev->context_sareas[request.ctx_id] = map; + DRM_UNLOCK; + return 0; + } } bad: DRM_UNLOCK; return DRM_ERR(EINVAL); - -found: - map = list->map; - if (!map) goto bad; - if (dev->max_context < 0) - goto bad; - if (request.ctx_id >= (unsigned) dev->max_context) - goto bad; - dev->context_sareas[request.ctx_id] = map; - DRM_UNLOCK; - return 0; } /* ================================================================ diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c index 0f0dd4fd..fa0bd20d 100644 --- a/bsd-core/drm_dma.c +++ b/bsd-core/drm_dma.c @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_dma.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -180,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = NULL; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -203,14 +205,14 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) { drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); @@ -524,7 +526,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); #endif -#if __HAVE_VBL_IRQ +#if __HAVE_VBL_IRQ && 0 /* disabled */ DRM_SPININIT( dev->vbl_lock, "vblsig" ); TAILQ_INIT( &dev->vbl_sig_list ); #endif @@ -534,9 +536,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) /* Install handler */ dev->irqrid = 0; +#ifdef __FreeBSD__ dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, 0, ~0, 1, RF_SHAREABLE); if (!dev->irqr) { +#elif defined(__NetBSD__) + if (pci_intr_map(&dev->pa, &dev->ih) != 0) { +#endif DRM_LOCK; dev->irq = 0; dev->irqrid = 0; @@ -544,11 +550,24 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) return ENOENT; } +#ifdef __FreeBSD__ +#if __FreeBSD_version < 500000 retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, DRM(dma_service), dev, &dev->irqh); +#else + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, + DRM(dma_service), dev, &dev->irqh); +#endif if ( retcode ) { +#elif defined(__NetBSD__) + dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, + (int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev); + if ( !dev->irqh ) { +#endif DRM_LOCK; +#ifdef __FreeBSD__ bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); +#endif dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK; @@ -580,9 +599,13 @@ int DRM(irq_uninstall)( drm_device_t *dev ) DRM(driver_irq_uninstall)( dev ); +#ifdef __FreeBSD__ bus_teardown_intr(dev->device, dev->irqr, dev->irqh); bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); - +#elif defined(__NetBSD__) + pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); +#endif + return 0; } @@ -624,6 +647,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; if (flags & _DRM_VBLANK_SIGNAL) { +#if 0 /* disabled */ drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); if (vbl_sig == NULL) return ENOMEM; @@ -639,6 +663,8 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); DRM_SPINUNLOCK(&dev->vbl_lock); ret = 0; +#endif + ret = EINVAL; } else { ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); @@ -653,6 +679,11 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) return ret; } +void DRM(vbl_send_signals)(drm_device_t *dev) +{ +} + +#if 0 /* disabled */ void DRM(vbl_send_signals)( drm_device_t *dev ) { drm_vbl_sig_t *vbl_sig; @@ -671,13 +702,14 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) psignal(p, vbl_sig->signo); TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); - DRM_FREE(vbl_sig); + DRM_FREE(vbl_sig,sizeof(*vbl_sig)); } vbl_sig = next; } DRM_SPINUNLOCK(&dev->vbl_lock); } +#endif #endif /* __HAVE_VBL_IRQ */ diff --git a/bsd-core/drm_drawable.c b/bsd-core/drm_drawable.c index 30841067..25dfc6d9 100644 --- a/bsd-core/drm_drawable.c +++ b/bsd-core/drm_drawable.c @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_drawable.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index 4a6fc15f..d43a4666 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_drv.h,v 1.12 2003/03/09 02:08:28 anholt Exp $ */ /* @@ -125,16 +127,10 @@ #define DRIVER_NUM_CARDS 1 #endif -#ifdef __FreeBSD__ static int DRM(init)(device_t nbdev); static void DRM(cleanup)(device_t nbdev); -#elif defined(__NetBSD__) -static int DRM(init)(drm_device_t *); -static void DRM(cleanup)(drm_device_t *); -#endif #ifdef __FreeBSD__ -#define CDEV_MAJOR 145 #define DRIVER_SOFTC(unit) \ ((drm_device_t *) devclass_get_softc(DRM(devclass), unit)) @@ -147,9 +143,8 @@ MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); #endif /* __FreeBSD__ */ #ifdef __NetBSD__ -#define CDEV_MAJOR 90 #define DRIVER_SOFTC(unit) \ - ((drm_device_t *) device_lookup(&DRM(_cd), unit)) + ((drm_device_t *) device_lookup(&DRM(cd), unit)) #endif /* __NetBSD__ */ static drm_ioctl_desc_t DRM(ioctls)[] = { @@ -229,6 +224,22 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { const char *DRM(find_description)(int vendor, int device); #ifdef __FreeBSD__ +static struct cdevsw DRM(cdevsw) = { + .d_open = DRM( open ), + .d_close = DRM( close ), + .d_read = DRM( read ), + .d_write = DRM( write ), + .d_ioctl = DRM( ioctl ), + .d_poll = DRM( poll ), + .d_mmap = DRM( mmap ), + .d_name = DRIVER_NAME, + .d_maj = CDEV_MAJOR, + .d_flags = D_TTY | D_TRACKCLOSE, +#if __FreeBSD_version < 500000 + .d_bmaj = -1 +#endif +}; + static int DRM(probe)(device_t dev) { const char *s = NULL; @@ -271,57 +282,108 @@ static driver_t DRM(driver) = { sizeof(drm_device_t), }; -static devclass_t DRM( devclass); - -static struct cdevsw DRM( cdevsw) = { - /* open */ DRM( open ), - /* close */ DRM( close ), - /* read */ DRM( read ), - /* write */ DRM( write ), - /* ioctl */ DRM( ioctl ), - /* poll */ DRM( poll ), - /* mmap */ DRM( mmap ), - /* strategy */ nostrategy, - /* name */ DRIVER_NAME, - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ D_TTY | D_TRACKCLOSE, -#if __FreeBSD_version >= 500000 - /* kqfilter */ 0 +static devclass_t DRM(devclass); + +#elif defined(__NetBSD__) + +static struct cdevsw DRM(cdevsw) = { + DRM(open), + DRM(close), + DRM(read), + DRM(write), + DRM(ioctl), + nostop, + notty, + DRM(poll), + DRM(mmap), + nokqfilter, + D_TTY +}; + +int DRM(refcnt) = 0; +#if __NetBSD_Version__ >= 106080000 +MOD_DEV( DRIVER_NAME, DRIVER_NAME, NULL, -1, &DRM(cdevsw), CDEV_MAJOR); #else - /* bmaj */ -1 +MOD_DEV( DRIVER_NAME, LM_DT_CHAR, CDEV_MAJOR, &DRM(cdevsw) ); #endif -}; -#elif defined(__NetBSD__) -int DRM(probe)(struct device *parent, struct cfdata *match, void *aux); -void DRM(attach)(struct device *parent, struct device *self, void *aux); -int DRM(detach)(struct device *self, int flags); -int DRM(activate)(struct device *self, enum devact act); - -struct cfattach DRM(_ca) = { - sizeof(drm_device_t), DRM(probe), - DRM(attach), DRM(detach), DRM(activate) }; +int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver); +static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd); + +int DRM(modprobe)(); +int DRM(probe)(struct pci_attach_args *pa); +void DRM(attach)(struct pci_attach_args *pa, dev_t kdev); + +int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver) { + DISPATCH(lkmtp, cmd, ver, DRM(lkmhandle), DRM(lkmhandle), DRM(lkmhandle)); +} + +static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd) +{ + int j, error = 0; +#if defined(__NetBSD__) && (__NetBSD_Version__ > 106080000) + struct lkm_dev *args = lkmtp->private.lkm_dev; +#endif + + switch(cmd) { + case LKM_E_LOAD: + if (lkmexists(lkmtp)) + return EEXIST; + + if(DRM(modprobe)()) + return 0; + + return 1; + + case LKM_E_UNLOAD: + if (DRM(refcnt) > 0) + return (EBUSY); + break; + case LKM_E_STAT: + break; + + default: + error = EIO; + break; + } -int DRM(probe)(struct device *parent, struct cfdata *match, void *aux) + return error; +} + +int DRM(modprobe)() { + struct pci_attach_args pa; + int error = 0; + if((error = pci_find_device(&pa, DRM(probe))) != 0) + DRM(attach)(&pa, 0); + + return error; +} + +int DRM(probe)(struct pci_attach_args *pa) { - struct pci_attach_args *pa = aux;
const char *desc; desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); - if (desc != NULL) - return 10; + if (desc != NULL) { + return 1; + } + return 0; } -void DRM(attach)(struct device *parent, struct device *self, void *aux) +void DRM(attach)(struct pci_attach_args *pa, dev_t kdev) { - struct pci_attach_args *pa = aux; - drm_device_t *dev = (drm_device_t *)self; - - memcpy(&dev->pa, aux, sizeof(dev->pa)); -
+ int i; + drm_device_t *dev; + + config_makeroom(kdev, &DRM(cd)); + DRM(cd).cd_devs[(kdev)] = DRM(alloc)(sizeof(drm_device_t), + DRM_MEM_DRIVER); + dev = DRIVER_SOFTC(kdev); + + memset(dev, 0, sizeof(drm_device_t)); + memcpy(&dev->pa, pa, sizeof(dev->pa)); + DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id))); DRM(init)(dev); } @@ -345,8 +407,7 @@ int DRM(activate)(struct device *self, enum devact act) } return (0); } - -#endif +#endif /* __NetBSD__ */ const char *DRM(find_description)(int vendor, int device) { const char *s = NULL; @@ -372,7 +433,6 @@ static int DRM(setup)( drm_device_t *dev ) DRIVER_PRESETUP(); atomic_set( &dev->ioctl_count, 0 ); - atomic_set( &dev->vma_count, 0 ); dev->buf_use = 0; atomic_set( &dev->buf_alloc, 0 ); @@ -435,7 +495,6 @@ static int DRM(setup)( drm_device_t *dev ) TAILQ_INIT(dev->maplist); dev->map_count = 0; - dev->vmalist = NULL; dev->lock.hw_lock = NULL; dev->lock.lock_queue = 0; dev->queue_count = 0; @@ -487,9 +546,8 @@ static int DRM(setup)( drm_device_t *dev ) static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; - drm_map_t *map; + drm_local_map_t *map; drm_map_list_entry_t *list; - drm_vma_entry_t *vma, *vma_next; int i; DRM_DEBUG( "\n" ); @@ -546,15 +604,6 @@ static int DRM(takedown)( drm_device_t *dev ) } #endif - /* Clear vma list (only built for debugging) */ - if ( dev->vmalist ) { - for ( vma = dev->vmalist ; vma ; vma = vma_next ) { - vma_next = vma->next; - DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS ); - } - dev->vmalist = NULL; - } - if( dev->maplist ) { while ((list=TAILQ_FIRST(dev->maplist))) { map = list->map; @@ -581,15 +630,13 @@ static int DRM(takedown)( drm_device_t *dev ) mtrrmap.len = map->size; mtrrmap.type = MTRR_TYPE_WC; mtrrmap.flags = 0; - /*mtrrmap.owner = p->p_pid;*/ - /* XXX: Use curproc here? */ retcode = mtrr_set( &mtrrmap, &one, DRM_CURPROC, MTRR_GETSET_KERNEL); #endif DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map ); break; case _DRM_SHM: DRM(free)(map->handle, @@ -646,7 +693,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } DRM_UNLOCK; @@ -658,15 +705,13 @@ static int DRM(takedown)( drm_device_t *dev ) * linux/init/main.c (this is not currently supported). * bsd: drm_init is called via the attach function per device. */ -#ifdef __FreeBSD__ static int DRM(init)( device_t nbdev ) -#elif defined(__NetBSD__) -static int DRM(init)( drm_device_t *dev ) -#endif { int unit; #ifdef __FreeBSD__ drm_device_t *dev; +#elif defined(__NetBSD__) + drm_device_t *dev = nbdev; #endif #if __HAVE_CTX_BITMAP int retcode; @@ -724,7 +769,6 @@ static int DRM(init)( drm_device_t *dev ) struct mtrr mtrrmap; int one = 1; mtrrmap.base = dev->agp->info.ai_aperture_base; - /* Might need a multiplier here XXX */ mtrrmap.len = dev->agp->info.ai_aperture_size; mtrrmap.type = MTRR_TYPE_WC; mtrrmap.flags = MTRR_VALID; @@ -763,21 +807,16 @@ static int DRM(init)( drm_device_t *dev ) * bsd: drm_cleanup is called per device at module unload time. * FIXME: NetBSD */ -#ifdef __FreeBSD__ static void DRM(cleanup)(device_t nbdev) -#elif defined(__NetBSD__) -static void DRM(cleanup)(drm_device_t *dev) -#endif { -#ifdef __FreeBSD__ drm_device_t *dev; -#endif -#if __REALLY_HAVE_MTRR #ifdef __NetBSD__ +#if __REALLY_HAVE_MTRR struct mtrr mtrrmap; int one = 1; -#endif /* __NetBSD__ */ #endif /* __REALLY_HAVE_MTRR */ + dev = nbdev; +#endif /* __NetBSD__ */ DRM_DEBUG( "\n" ); @@ -799,7 +838,7 @@ static void DRM(cleanup)(drm_device_t *dev) mtrrmap.len = dev->agp->info.ai_aperture_size; mtrrmap.type = 0; mtrrmap.flags = 0; - retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); + mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); #endif } #endif @@ -814,6 +853,8 @@ static void DRM(cleanup)(drm_device_t *dev) } #endif DRIVER_POSTCLEANUP(); + DRM(mem_uninit)(); + DRM_SPINUNINIT(dev->count_lock); } @@ -876,7 +917,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) drm_file_t *priv; DRM_DEVICE; int retcode = 0; - + DRMFILE __unused filp = (void *)(DRM_CURRENTPID); + DRM_DEBUG( "open_count = %d\n", dev->open_count ); priv = DRM(find_file_by_proc)(dev, p); if (!priv) { @@ -899,7 +941,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_CURRENTPID) { + && dev->lock.filp == (void *)DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -926,7 +968,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ) ) { - dev->lock.pid = p->p_pid; + dev->lock.pid = DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -935,7 +977,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #if 0 atomic_inc( &dev->total_sleeps ); #endif - retcode = tsleep(&dev->lock.lock_queue, + retcode = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, "drmlk2", 0); @@ -949,7 +991,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( dev, (void *)priv->pid ); #endif #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) @@ -999,12 +1041,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_IOCTL_ARGS ) +int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, + DRM_STRUCTPROC *p) { DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); DRM_PRIV; @@ -1043,7 +1086,6 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) *(int *) data = fgetown(dev->buf_sigio); #endif return 0; - } #endif /* __FreeBSD__ */ #ifdef __NetBSD__ case TIOCSPGRP: @@ -1056,6 +1098,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) *(int *)data = dev->buf_pgid; return 0; #endif /* __NetBSD__ */ + } if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = EINVAL; @@ -1070,7 +1113,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { - retcode = func( kdev, cmd, data, flags, p ); + retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); } } @@ -1125,7 +1168,7 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_CURRENTPID; + dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ diff --git a/bsd-core/drm_fops.c b/bsd-core/drm_fops.c index ed85a8de..75baa5f2 100644 --- a/bsd-core/drm_fops.c +++ b/bsd-core/drm_fops.c @@ -28,6 +28,8 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_fops.h,v 1.5 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -100,7 +102,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, the circular buffer), is based on Alessandro Rubini's LINUX DEVICE DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */ -ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag) +int DRM(read)(dev_t kdev, struct uio *uio, int ioflag) { DRM_DEVICE; int left; @@ -182,8 +184,8 @@ int DRM(write_string)(drm_device_t *dev, const char *s) selwakeup(&dev->buf_sel); } - DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); #ifdef __FreeBSD__ + DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); if (dev->buf_sigio) { DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid); #if __FreeBSD_version >= 500000 @@ -200,6 +202,7 @@ int DRM(write_string)(drm_device_t *dev, const char *s) gsignal(dev->buf_pgid, SIGIO); else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL) psignal(p, SIGIO); + } #endif /* __NetBSD__ */ DRM_DEBUG("waking\n"); wakeup(&dev->buf_rp); diff --git a/bsd-core/drm_ioctl.c b/bsd-core/drm_ioctl.c index 63562fef..270b2bb5 100644 --- a/bsd-core/drm_ioctl.c +++ b/bsd-core/drm_ioctl.c @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_ioctl.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -136,7 +138,7 @@ int DRM(getmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_map_t map; - drm_map_t *mapinlist; + drm_local_map_t *mapinlist; drm_map_list_entry_t *list; int idx; int i = 0; diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 5e9294bc..3bab78ef 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_lock.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -47,14 +49,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - do { old = *lock; if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; else new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -77,14 +77,13 @@ int DRM(lock_transfer)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + return 1; } @@ -92,20 +91,16 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - pid_t pid = dev->lock.pid; - char failed; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = 0; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", - context, - _DRM_LOCKING_CONTEXT(old), - pid); + DRM_ERROR("%d freed heavyweight lock held by %d\n", + context, _DRM_LOCKING_CONTEXT(old)); return 1; } DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); @@ -224,8 +219,6 @@ int DRM(notifier)(void *priv) { drm_sigdata_t *s = (drm_sigdata_t *)priv; unsigned int old, new; - char failed; - /* Allow signal delivery if lock isn't held */ if (!_DRM_LOCK_IS_HELD(s->lock->lock) @@ -236,8 +229,8 @@ int DRM(notifier)(void *priv) do { old = s->lock->lock; new = old | _DRM_LOCK_CONT; - _DRM_CAS(&s->lock->lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(&s->lock->lock, old, new)); + return 0; } diff --git a/bsd-core/drm_memory.c b/bsd-core/drm_memory.c index f7dc547a..0df7ee72 100644 --- a/bsd-core/drm_memory.c +++ b/bsd-core/drm_memory.c @@ -27,13 +27,15 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_memory.h,v 1.7 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) #define malloctype DRM(M_DRM) -/* The macros confliced in the MALLOC_DEFINE */ +/* The macros conflicted in the MALLOC_DEFINE */ MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures"); @@ -59,7 +61,6 @@ static drm_mem_stats_t DRM(mem_stats)[] = { [DRM_MEM_MAGIC] = { "magic" }, [DRM_MEM_IOCTLS] = { "ioctltab" }, [DRM_MEM_MAPS] = { "maplist" }, - [DRM_MEM_VMAS] = { "vmalist" }, [DRM_MEM_BUFS] = { "buflist" }, [DRM_MEM_SEGS] = { "seglist" }, [DRM_MEM_PAGES] = { "pagelist" }, @@ -81,6 +82,10 @@ void DRM(mem_init)(void) { drm_mem_stats_t *mem; +#ifdef __NetBSD__ + malloc_type_attach(DRM(M_DRM)); +#endif + DRM_SPININIT(DRM(mem_lock), "drm memory"); for (mem = DRM(mem_stats); mem->name; ++mem) { @@ -95,9 +100,16 @@ void DRM(mem_init)(void) DRM(ram_used) = 0; } +void DRM(mem_uninit)(void) +{ + DRM_SPINUNINIT(DRM(mem_lock)); +} + #ifdef __FreeBSD__ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ -static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS +static int +DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1, + int arg2, struct sysctl_req *req) { drm_mem_stats_t *pt; char buf[128]; @@ -112,7 +124,7 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n", "locked", 0, 0, 0, DRM(ram_used)); DRM_SYSCTL_PRINT("\n"); - for (pt = DRM(mem_stats); pt->name; pt++) { + for (pt = stats; pt->name; pt++) { DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", pt->name, pt->succeed_count, @@ -132,13 +144,22 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS { int ret; - + drm_mem_stats_t *stats; + + stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT); + if (stats == NULL) + return ENOMEM; + DRM_SPINLOCK(&DRM(mem_lock)); - ret = DRM(_mem_info)(oidp, arg1, arg2, req); + bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats))); DRM_SPINUNLOCK(&DRM(mem_lock)); + + ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req); + + free(stats, DRM(M_DRM)); return ret; } -#endif +#endif /* __FreeBSD__ */ void *DRM(alloc)(size_t size, int area) { @@ -149,11 +170,7 @@ void *DRM(alloc)(size_t size, int area) return NULL; } -#ifdef __FreeBSD__ if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) { -#elif defined(__NetBSD__) - if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) { -#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].fail_count; DRM_SPINUNLOCK(&DRM(mem_lock)); @@ -203,13 +220,10 @@ void DRM(free)(void *pt, size_t size, int area) int alloc_count; int free_count; - if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); + if (!pt) + DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); else -#ifdef __FreeBSD__ - free(pt, DRM(M_DRM)); -#elif defined(__NetBSD__) - free(pt, M_DEVBUF); -#endif + free(pt, DRM(M_DRM)); DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[area].bytes_freed += size; free_count = ++DRM(mem_stats)[area].free_count; @@ -221,25 +235,36 @@ void DRM(free)(void *pt, size_t size, int area) } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map ) { void *pt; - if (!size) { + if (!map->size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, - "Mapping 0 bytes at 0x%08lx\n", offset); + "Mapping 0 bytes at 0x%08lx\n", map->offset); return NULL; } +#ifdef __NetBSD__ + map->iot = dev->pa.pa_memt; +#endif - if (!(pt = pmap_mapdev(offset, size))) { +#ifdef __FreeBSD__ + if (!(pt = pmap_mapdev(map->offset, map->size))) { +#elif defined(__NetBSD__) + if (bus_space_map(map->iot, map->offset, map->size, + BUS_SPACE_MAP_LINEAR, &map->ioh)) { +#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } +#ifdef __NetBSD__ + pt = bus_space_vaddr(map->iot, map->ioh); +#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; - DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size; DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } @@ -271,19 +296,23 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) } #endif -void DRM(ioremapfree)(void *pt, unsigned long size) +void DRM(ioremapfree)(drm_local_map_t *map) { int alloc_count; int free_count; - if (!pt) + if (map->handle == NULL) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); else - pmap_unmapdev((vm_offset_t) pt, size); +#ifdef __FreeBSD__ + pmap_unmapdev((vm_offset_t) map->handle, map->size); +#elif defined(__NetBSD__) + bus_space_unmap(map->iot, map->ioh, map->size); +#endif DRM_SPINLOCK(&DRM(mem_lock)); - DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size; free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM_SPINUNLOCK(&DRM(mem_lock)); diff --git a/bsd-core/drm_os_freebsd.h b/bsd-core/drm_os_freebsd.h index 1a3feb6e..30a6e362 100644 --- a/bsd-core/drm_os_freebsd.h +++ b/bsd-core/drm_os_freebsd.h @@ -1,3 +1,6 @@ +/* + * $FreeBSD: src/sys/dev/drm/drm_os_freebsd.h,v 1.8 2003/03/09 02:08:28 anholt Exp $ + */ #include <sys/param.h> #include <sys/queue.h> #include <sys/malloc.h> @@ -45,7 +48,11 @@ #define __REALLY_HAVE_AGP __HAVE_AGP #endif +#ifdef __i386__ #define __REALLY_HAVE_MTRR (__HAVE_MTRR) +#else +#define __REALLY_HAVE_MTRR 0 +#endif #define __REALLY_HAVE_SG (__HAVE_SG) #if __REALLY_HAVE_AGP @@ -79,6 +86,7 @@ #define DRM_STRUCTPROC struct thread #define DRM_SPINTYPE struct mtx #define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF) +#define DRM_SPINUNINIT(l) mtx_destroy(&l) #define DRM_SPINLOCK(l) mtx_lock(l) #define DRM_SPINUNLOCK(u) mtx_unlock(u); #define DRM_CURRENTPID curthread->td_proc->p_pid @@ -87,12 +95,17 @@ #define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock #define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPINUNINIT(l) #define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, DRM_CURPROC) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, DRM_CURPROC) #define DRM_SUSER(p) suser(p) @@ -100,12 +113,20 @@ #define DRM_IRQ_ARGS void *arg #define DRM_DEVICE drm_device_t *dev = kdev->si_drv1 #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) + +/* Read/write from bus space, with byteswapping to le if necessary */ +#define DRM_READ8(map, offset) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) +#define DRM_READ32(map, offset) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE8(map, offset, val) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val +#define DRM_WRITE32(map, offset, val) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val +/* +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) +*/ #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_ERR(v) v @@ -116,6 +137,16 @@ return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -130,7 +161,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -166,7 +197,7 @@ while (!condition) { \ copyin(user, kern, size) /* Macros for userspace access with checking readability once */ /* FIXME: can't find equivalent functionality for nocheck yet. - * It's be slower than linux, but should be correct. + * It'll be slower than linux, but should be correct. */ #define DRM_VERIFYAREA_READ( uaddr, size ) \ (!useracc((caddr_t)uaddr, size, VM_PROT_READ)) @@ -175,20 +206,13 @@ while (!condition) { \ #define DRM_GET_USER_UNCHECKED(val, uaddr) \ ((val) = fuword(uaddr), 0) -/* From machine/bus_at386.h on i386 */ -#define DRM_READMEMORYBARRIER() \ -do { \ - __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \ -} while (0) - -#define DRM_WRITEMEMORYBARRIER() \ -do { \ - __asm __volatile("" : : : "memory"); \ -} while (0) - +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); #define PAGE_ALIGN(addr) round_page(addr) - + #ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */ #define M_WAITOK 0 #endif @@ -206,12 +230,11 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; -#define cpu_to_le32(x) (x) +#define cpu_to_le32(x) (x) /* FIXME */ -typedef u_int32_t dma_addr_t; +typedef unsigned long dma_addr_t; typedef u_int32_t atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; @@ -223,6 +246,23 @@ typedef u_int8_t u8; #define atomic_sub(n, p) atomic_subtract_int(p, n) /* Fake this */ + +#if __FreeBSD_version < 500000 +/* The extra atomic functions from 5.0 haven't been merged to 4.x */ +static __inline int +atomic_cmpset_int(volatile int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} +#endif + static __inline atomic_t test_and_set_bit(int b, volatile void *p) { @@ -284,20 +324,6 @@ find_first_zero_bit(volatile void *p, int max) #endif -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -356,8 +382,6 @@ find_first_zero_bit(volatile void *p, int max) /* drm_drv.h */ extern d_ioctl_t DRM(ioctl); -extern d_ioctl_t DRM(lock); -extern d_ioctl_t DRM(unlock); extern d_open_t DRM(open); extern d_close_t DRM(close); extern d_read_t DRM(read); @@ -369,81 +393,9 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern d_ioctl_t DRM(irq_busid); -extern d_ioctl_t DRM(getunique); -extern d_ioctl_t DRM(setunique); -extern d_ioctl_t DRM(getmap); -extern d_ioctl_t DRM(getclient); -extern d_ioctl_t DRM(getstats); - -/* Context IOCTL support (drm_context.h) */ -extern d_ioctl_t DRM(resctx); -extern d_ioctl_t DRM(addctx); -extern d_ioctl_t DRM(modctx); -extern d_ioctl_t DRM(getctx); -extern d_ioctl_t DRM(switchctx); -extern d_ioctl_t DRM(newctx); -extern d_ioctl_t DRM(rmctx); -extern d_ioctl_t DRM(setsareactx); -extern d_ioctl_t DRM(getsareactx); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern d_ioctl_t DRM(adddraw); -extern d_ioctl_t DRM(rmdraw); - -/* Authentication IOCTL support (drm_auth.h) */ -extern d_ioctl_t DRM(getmagic); -extern d_ioctl_t DRM(authmagic); - -/* Locking IOCTL support (drm_lock.h) */ -extern d_ioctl_t DRM(block); -extern d_ioctl_t DRM(unblock); -extern d_ioctl_t DRM(finish); - -/* Buffer management support (drm_bufs.h) */ -extern d_ioctl_t DRM(addmap); -extern d_ioctl_t DRM(rmmap); -#if __HAVE_DMA -extern d_ioctl_t DRM(addbufs_agp); -extern d_ioctl_t DRM(addbufs_pci); -extern d_ioctl_t DRM(addbufs_sg); -extern d_ioctl_t DRM(addbufs); -extern d_ioctl_t DRM(infobufs); -extern d_ioctl_t DRM(markbufs); -extern d_ioctl_t DRM(freebufs); -extern d_ioctl_t DRM(mapbufs); -#endif - -/* Memory management support (drm_memory.h) */ -extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern d_ioctl_t DRM(control); -#endif -#if __HAVE_VBL_IRQ -extern d_ioctl_t DRM(wait_vblank); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern d_ioctl_t DRM(agp_acquire); -extern d_ioctl_t DRM(agp_release); -extern d_ioctl_t DRM(agp_enable); -extern d_ioctl_t DRM(agp_info); -extern d_ioctl_t DRM(agp_alloc); -extern d_ioctl_t DRM(agp_free); -extern d_ioctl_t DRM(agp_unbind); -extern d_ioctl_t DRM(agp_bind); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern d_ioctl_t DRM(sg_alloc); -extern d_ioctl_t DRM(sg_free); -#endif - -/* SysCtl Support (drm_sysctl.h) */ +/* sysctl support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); + +/* Memory info sysctl (drm_memory.h) */ +extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h index 2082c047..fa158254 100644 --- a/bsd-core/drm_os_netbsd.h +++ b/bsd-core/drm_os_netbsd.h @@ -17,6 +17,7 @@ #include <uvm/uvm.h> #include <sys/vnode.h> #include <sys/poll.h> +#include <sys/lkm.h> /* For TIOCSPGRP/TIOCGPGRP */ #include <sys/ttycom.h> @@ -31,11 +32,9 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#include "drmvar.h" - #define __REALLY_HAVE_AGP __HAVE_AGP -#define __REALLY_HAVE_MTRR 0 +#define __REALLY_HAVE_MTRR 1 #define __REALLY_HAVE_SG 0 #if __REALLY_HAVE_AGP @@ -43,8 +42,7 @@ #include <sys/agpio.h> #endif -#define device_t struct device * -extern struct cfdriver DRM(_cd); +#include <opt_drm.h> #if DRM_DEBUG #undef DRM_DEBUG_CODE @@ -52,36 +50,58 @@ extern struct cfdriver DRM(_cd); #endif #undef DRM_DEBUG +#if DRM_LINUX +#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */ +#endif + +typedef drm_device_t *device_t; + +extern struct cfdriver DRM(cd); + #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) #define DRM_DEV_UID 0 #define DRM_DEV_GID 0 -#define CDEV_MAJOR 90 +#define CDEV_MAJOR 34 #define DRM_CURPROC curproc -#define DRM_STRUCTPROC struct proc +#define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock #define DRM_SPININIT(l,name) simple_lock_init(&l) -#define DRM_SPINLOCK(l) simple_lock(l) +#define DRM_SPINUNINIT(l) +#define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINUNLOCK(u) simple_unlock(u); -#define DRM_CURRENTPID curproc->p_pid +#define DRM_CURRENTPID curproc->p_pid -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL) #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending -#define DRM_IRQ_ARGS void *device -#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev)) +#define DRM_IRQ_ARGS void *arg +#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev)) +/* XXX Not sure if this is the 'right' version.. */ +#if __NetBSD_Version__ >= 106140000 +MALLOC_DECLARE(DRM(M_DRM)); +#else +/* XXX Make sure this works */ +extern const int DRM(M_DRM) = M_DEVBUF; +#endif /* __NetBSD_Version__ */ #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) -#define DRM_AGP_FIND_DEVICE() + +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) + +#define DRM_AGP_FIND_DEVICE() agp_find_device(0) #define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ @@ -90,6 +110,16 @@ extern struct cfdriver DRM(_cd); return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -104,7 +134,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -113,7 +143,15 @@ do { \ } \ } while (0) -#define return DRM_ERR(v) return v; +#define DRM_HZ hz + +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +while (!condition) { \ + ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ + if ( ret ) \ + return ret; \ +} + #define DRM_ERR(v) v #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ @@ -124,21 +162,25 @@ do { \ copyout(arg2, arg1, arg3) #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ copyin(arg2, arg1, arg3) +/* Macros for userspace access with checking readability once */ +/* FIXME: can't find equivalent functionality for nocheck yet. + * It'll be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ)) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + ((val) = fuword(uaddr), 0) -#define DRM_READMEMORYBARRIER \ -{ \ - int xchangeDummy; \ - DRM_DEBUG("%s\n", __FUNCTION__); \ - __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \ - __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \ - " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \ - " pop %%eax" : /* no outputs */ : /* no inputs */ ); \ -} while (0); - -#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); -#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup((void *)w) #define DRM_WAKEUP_INT(w) wakeup(w) +#define DRM_INIT_WAITQUEUE( queue ) do {} while (0) #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) @@ -150,30 +192,46 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; +#define cpu_to_le32(x) (x) /* FIXME */ + typedef u_int32_t dma_addr_t; -typedef volatile u_int32_t atomic_t; +typedef volatile long atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; typedef dev_type_ioctl(d_ioctl_t); typedef vaddr_t vm_offset_t; +/* FIXME */ #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_int(p, 1) -#define atomic_dec(p) atomic_subtract_int(p, 1) -#define atomic_add(n, p) atomic_add_int(p, n) -#define atomic_sub(n, p) atomic_subtract_int(p, n) +#define atomic_inc(p) (*(p) += 1) +#define atomic_dec(p) (*(p) -= 1) +#define atomic_add(n, p) (*(p) += (n)) +#define atomic_sub(n, p) (*(p) -= (n)) -/* FIXME: Is NetBSD's kernel non-reentrant? */ +/* FIXME */ #define atomic_add_int(p, v) *(p) += v #define atomic_subtract_int(p, v) *(p) -= v #define atomic_set_int(p, bits) *(p) |= (bits) #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(__volatile__ int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -223,20 +281,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -257,7 +301,7 @@ do { \ #define DRM_DEBUG(fmt, arg...) \ do { \ if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -291,8 +335,6 @@ do { \ /* drm_drv.h */ extern dev_type_ioctl(DRM(ioctl)); -extern dev_type_ioctl(DRM(lock)); -extern dev_type_ioctl(DRM(unlock)); extern dev_type_open(DRM(open)); extern dev_type_close(DRM(close)); extern dev_type_read(DRM(read)); @@ -304,75 +346,5 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern dev_type_ioctl(DRM(irq_busid)); -extern dev_type_ioctl(DRM(getunique)); -extern dev_type_ioctl(DRM(setunique)); -extern dev_type_ioctl(DRM(getmap)); -extern dev_type_ioctl(DRM(getclient)); -extern dev_type_ioctl(DRM(getstats)); - -/* Context IOCTL support (drm_context.h) */ -extern dev_type_ioctl(DRM(resctx)); -extern dev_type_ioctl(DRM(addctx)); -extern dev_type_ioctl(DRM(modctx)); -extern dev_type_ioctl(DRM(getctx)); -extern dev_type_ioctl(DRM(switchctx)); -extern dev_type_ioctl(DRM(newctx)); -extern dev_type_ioctl(DRM(rmctx)); -extern dev_type_ioctl(DRM(setsareactx)); -extern dev_type_ioctl(DRM(getsareactx)); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern dev_type_ioctl(DRM(adddraw)); -extern dev_type_ioctl(DRM(rmdraw)); - -/* Authentication IOCTL support (drm_auth.h) */ -extern dev_type_ioctl(DRM(getmagic)); -extern dev_type_ioctl(DRM(authmagic)); - -/* Locking IOCTL support (drm_lock.h) */ -extern dev_type_ioctl(DRM(block)); -extern dev_type_ioctl(DRM(unblock)); -extern dev_type_ioctl(DRM(finish)); - -/* Buffer management support (drm_bufs.h) */ -extern dev_type_ioctl(DRM(addmap)); -extern dev_type_ioctl(DRM(rmmap)); -#if __HAVE_DMA -extern dev_type_ioctl(DRM(addbufs_agp)); -extern dev_type_ioctl(DRM(addbufs_pci)); -extern dev_type_ioctl(DRM(addbufs_sg)); -extern dev_type_ioctl(DRM(addbufs)); -extern dev_type_ioctl(DRM(infobufs)); -extern dev_type_ioctl(DRM(markbufs)); -extern dev_type_ioctl(DRM(freebufs)); -extern dev_type_ioctl(DRM(mapbufs)); -#endif - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern dev_type_ioctl(DRM(control)); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern dev_type_ioctl(DRM(agp_acquire)); -extern dev_type_ioctl(DRM(agp_release)); -extern dev_type_ioctl(DRM(agp_enable)); -extern dev_type_ioctl(DRM(agp_info)); -extern dev_type_ioctl(DRM(agp_alloc)); -extern dev_type_ioctl(DRM(agp_free)); -extern dev_type_ioctl(DRM(agp_unbind)); -extern dev_type_ioctl(DRM(agp_bind)); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern dev_type_ioctl(DRM(sg_alloc)); -extern dev_type_ioctl(DRM(sg_free)); -#endif - -/* SysCtl Support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); diff --git a/bsd-core/drm_scatter.c b/bsd-core/drm_scatter.c index c16b7c05..e57e5e5b 100644 --- a/bsd-core/drm_scatter.c +++ b/bsd-core/drm_scatter.c @@ -25,6 +25,8 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_scatter.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -40,9 +42,6 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry ) DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -73,21 +72,10 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages ); entry->pages = pages; - entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - if ( !entry->pagelist ) { - DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return ENOMEM; - } - - bzero(entry->pagelist, pages * sizeof(*entry->pagelist)); entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); if ( !entry->busaddr ) { - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -100,9 +88,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -124,46 +109,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) dev->sg = entry; -#if DEBUG_SCATTER - /* Verify that each page points to its virtual address, and vice - * versa. - */ - { - int error = 0; - - for ( i = 0 ; i < pages ; i++ ) { - unsigned long *tmp; - - tmp = page_address( entry->pagelist[i] ); - for ( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - *tmp = 0xcafebabe; - } - tmp = (unsigned long *)((u8 *)entry->virtual + - (PAGE_SIZE * i)); - for( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - if ( *tmp != 0xcafebabe && error == 0 ) { - error = 1; - DRM_ERROR( "Scatter allocation error, " - "pagelist does not match " - "virtual mapping\n" ); - } - } - tmp = page_address( entry->pagelist[i] ); - for(j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++) { - *tmp = 0; - } - } - if (error == 0) - DRM_ERROR( "Scatter allocation matches pagelist\n" ); - } -#endif - return 0; DRM(sg_cleanup)( entry ); diff --git a/bsd-core/drm_sysctl.c b/bsd-core/drm_sysctl.c index 2ec7ff95..2ca187d8 100644 --- a/bsd-core/drm_sysctl.c +++ b/bsd-core/drm_sysctl.c @@ -1,5 +1,5 @@ /* - * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ + * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #ifdef __FreeBSD__ @@ -11,9 +11,6 @@ static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(queues_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS; -#if DRM_DEBUG_CODExx -static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS; -#endif #if DRM_DMA_HISTOGRAM static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS; #endif @@ -28,9 +25,6 @@ struct DRM(sysctl_list) { { "clients", DRM(clients_info) }, { "queues", DRM(queues_info) }, { "bufs", DRM(bufs_info) }, -#if DRM_DEBUG_CODExx - { "vma", DRM(vma_info) }, -#endif #if DRM_DMA_HISTOGRAM { "histo", drm_histo_info) }, #endif @@ -125,7 +119,7 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; - drm_map_t *map; + drm_local_map_t *map; drm_map_list_entry_t *listentry; const char *types[] = { "FB", "REG", "SHM" }; const char *type; @@ -203,7 +197,7 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS q->read_queue ? 'r':'-', q->write_queue ? 'w':'-', q->flush_queue ? 'f':'-', - DRM_BUFCOUNT(&q->waitlist), + (int)DRM_BUFCOUNT(&q->waitlist), atomic_read(&q->total_flushed), atomic_read(&q->total_queued), atomic_read(&q->total_locks)); @@ -309,92 +303,6 @@ static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS return ret; } -#if DRM_DEBUG_CODExx - -static int DRM(_vma_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - drm_vma_entry_t *pt; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - unsigned long i; - struct vm_area_struct *vma; - unsigned long address; -#if defined(__i386__) - unsigned int pgprot; -#endif - char buf[128]; - int error; - - DRM_SYSCTL_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", - atomic_read(&dev->vma_count), - high_memory, virt_to_phys(high_memory)); - for (pt = dev->vmalist; pt; pt = pt->next) { - if (!(vma = pt->vma)) continue; - DRM_SYSCTL_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", - pt->pid, - vma->vm_start, - vma->vm_end, - vma->vm_flags & VM_READ ? 'r' : '-', - vma->vm_flags & VM_WRITE ? 'w' : '-', - vma->vm_flags & VM_EXEC ? 'x' : '-', - vma->vm_flags & VM_MAYSHARE ? 's' : 'p', - vma->vm_flags & VM_LOCKED ? 'l' : '-', - vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_offset ); -#if defined(__i386__) - pgprot = pgprot_val(vma->vm_page_prot); - DRM_SYSCTL_PRINT(" %c%c%c%c%c%c%c%c%c", - pgprot & _PAGE_PRESENT ? 'p' : '-', - pgprot & _PAGE_RW ? 'w' : 'r', - pgprot & _PAGE_USER ? 'u' : 's', - pgprot & _PAGE_PWT ? 't' : 'b', - pgprot & _PAGE_PCD ? 'u' : 'c', - pgprot & _PAGE_ACCESSED ? 'a' : '-', - pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_4M ? 'm' : 'k', - pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); -#endif - DRM_SYSCTL_PRINT("\n"); - for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) { - pgd = pgd_offset(vma->vm_mm, i); - pmd = pmd_offset(pgd, i); - pte = pte_offset(pmd, i); - if (pte_present(*pte)) { - address = __pa(pte_page(*pte)) - + (i & (PAGE_SIZE-1)); - DRM_SYSCTL_PRINT(" 0x%08lx -> 0x%08lx" - " %c%c%c%c%c\n", - i, - address, - pte_read(*pte) ? 'r' : '-', - pte_write(*pte) ? 'w' : '-', - pte_exec(*pte) ? 'x' : '-', - pte_dirty(*pte) ? 'd' : '-', - pte_young(*pte) ? 'a' : '-' ); - } else { - DRM_SYSCTL_PRINT(" 0x%08lx\n", i); - } - } - } - - SYSCTL_OUT(req, "", 1); - return 0; -} - -static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - int ret; - - DRM_LOCK; - ret = DRM(_vma_info)(oidp, arg1, arg2, req); - DRM_UNLOCK; - return ret; -} -#endif - #if DRM_DMA_HISTOGRAM static int DRM(_histo_info)DRM_SYSCTL_HANDLER_ARGS diff --git a/bsd-core/drm_vm.c b/bsd-core/drm_vm.c index 70a5b0e6..1ce0efab 100644 --- a/bsd-core/drm_vm.c +++ b/bsd-core/drm_vm.c @@ -1,5 +1,11 @@ +/* + * $FreeBSD: src/sys/dev/drm/drm_vm.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ + */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 +static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr, + int prot) +#elif defined(__FreeBSD__) static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) #elif defined(__NetBSD__) static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) @@ -17,17 +23,25 @@ static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) physical = dma->pagelist[page]; DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = physical; + return 0; +#else return atop(physical); +#endif } -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 +int DRM(mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr, + int prot) +#elif defined(__FreeBSD__) int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) #elif defined(__NetBSD__) paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) #endif { DRM_DEVICE; - drm_map_t *map = NULL; + drm_local_map_t *map = NULL; drm_map_list_entry_t *listentry=NULL; drm_file_t *priv; @@ -44,7 +58,11 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + return DRM(dma_mmap)(kdev, offset, paddr, prot); +#else return DRM(dma_mmap)(kdev, offset, prot); +#endif /* A sequential search of a linked list is fine here because: 1) there will only be @@ -73,10 +91,20 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: case _DRM_AGP: +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = offset; + return 0; +#else return atop(offset); +#endif case _DRM_SCATTER_GATHER: case _DRM_SHM: +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = vtophys(offset); + return 0; +#else return atop(vtophys(offset)); +#endif default: return -1; /* This should never happen. */ } diff --git a/bsd-core/mga_drv.c b/bsd-core/mga_drv.c index 8b69b41b..de0387f7 100644 --- a/bsd-core/mga_drv.c +++ b/bsd-core/mga_drv.c @@ -27,10 +27,10 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ -#include <sys/types.h> - #include "mga.h" #include "drmP.h" #include "drm.h" @@ -63,4 +63,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_vm.h" #include "drm_sysctl.h" +#ifdef __FreeBSD__ DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(mga, DV_TTY, NULL); +#endif diff --git a/bsd-core/r128_drv.c b/bsd-core/r128_drv.c index 1a8046fb..28a2c85e 100644 --- a/bsd-core/r128_drv.c +++ b/bsd-core/r128_drv.c @@ -27,11 +27,10 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ - -#include <sys/types.h> - #include "r128.h" #include "drmP.h" #include "drm.h" @@ -83,4 +82,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_scatter.h" #endif +#ifdef __FreeBSD__ DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(r128, DV_TTY, NULL); +#endif /* __FreeBSD__ */ diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index d02ab959..2e7c5d66 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -25,10 +25,10 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $ */ -#include <sys/types.h> - #include "radeon.h" #include "drmP.h" #include "drm.h" @@ -38,21 +38,42 @@ #include "ati_pcigart.h" #endif -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to eta@lclark.edu inaccuracies or if a chip you have works that is marked unsupported here. - */ drm_chipinfo_t DRM(devicelist)[] = { - {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"}, - {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"}, - {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"}, - {0x1002, 0x5144, 1, "ATI Radeon QD (AGP)"}, - {0x1002, 0x5145, 1, "ATI Radeon QE (AGP)"}, - {0x1002, 0x5146, 1, "ATI Radeon QF (AGP)"}, - {0x1002, 0x5147, 1, "ATI Radeon QG (AGP)"}, - {0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"}, - {0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"}, - {0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"}, - {0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"}, + {0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"}, + {0x1002, 0x4336, 1, "ATI Radeon Mobility U1"}, + {0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"}, + {0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"}, + {0x1002, 0x4966, 1, "ATI Radeon If R250 9000"}, + {0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"}, + {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"}, + {0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"}, + {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"}, + {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"}, + {0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"}, + {0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"}, + {0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"}, + {0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"}, + {0x1002, 0x5144, 1, "ATI Radeon QD R100"}, + {0x1002, 0x5145, 1, "ATI Radeon QE R100"}, + {0x1002, 0x5146, 1, "ATI Radeon QF R100"}, + {0x1002, 0x5147, 1, "ATI Radeon QG R100"}, + {0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"}, + {0x1002, 0x5149, 1, "ATI Radeon QI R200"}, + {0x1002, 0x514A, 1, "ATI Radeon QJ R200"}, + {0x1002, 0x514B, 1, "ATI Radeon QK R200"}, + {0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"}, + {0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"}, + {0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"}, + {0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"}, + {0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"}, + {0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"}, + {0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"}, + {0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"}, + {0x1002, 0x5168, 1, "ATI Radeon Qh R200"}, + {0x1002, 0x5169, 1, "ATI Radeon Qi R200"}, + {0x1002, 0x516A, 1, "ATI Radeon Qj R200"}, + {0x1002, 0x516B, 1, "ATI Radeon Qk R200"}, + {0x1002, 0x516C, 1, "ATI Radeon Ql R200"}, {0, 0, 0, NULL} }; @@ -74,4 +95,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_scatter.h" #endif +#ifdef __FreeBSD__ DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(radeon, DV_TTY, NULL); +#endif /* __FreeBSD__ */ diff --git a/bsd-core/tdfx_drv.c b/bsd-core/tdfx_drv.c index 8bc8c57d..e10542f1 100644 --- a/bsd-core/tdfx_drv.c +++ b/bsd-core/tdfx_drv.c @@ -28,11 +28,10 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ - -#include <sys/types.h> - #include "tdfx.h" #include "drmP.h" @@ -96,4 +95,6 @@ drm_chipinfo_t DRM(devicelist)[] = { #ifdef __FreeBSD__ DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(tdfx, DV_TTY, NULL); #endif /* __FreeBSD__ */ diff --git a/bsd/Makefile b/bsd/Makefile index ea44a7cd..6281b00c 100644 --- a/bsd/Makefile +++ b/bsd/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ # i810, i830 & sis are not complete -SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis +SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma .include <bsd.subdir.mk> diff --git a/bsd/Makefile.bsd b/bsd/Makefile.bsd index ea44a7cd..6281b00c 100644 --- a/bsd/Makefile.bsd +++ b/bsd/Makefile.bsd @@ -1,6 +1,6 @@ # $FreeBSD$ # i810, i830 & sis are not complete -SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis +SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma .include <bsd.subdir.mk> diff --git a/bsd/ati_pcigart.h b/bsd/ati_pcigart.h index 28723f56..0cc63a3a 100644 --- a/bsd/ati_pcigart.h +++ b/bsd/ati_pcigart.h @@ -25,6 +25,8 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/ati_pcigart.h,v 1.1 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -42,25 +44,6 @@ # define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ # define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ -static unsigned long DRM(ati_alloc_pcigart_table)( void ) -{ - unsigned long address; - - DRM_DEBUG( "\n" ); - - address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK ); - - DRM_DEBUG( "returning 0x%08lx\n", address ); - return address; -} - -static void DRM(ati_free_pcigart_table)( unsigned long address ) -{ - DRM_DEBUG( "\n" ); - - free( (void *)address, DRM(M_DRM)); -} - int DRM(ati_pcigart_init)( drm_device_t *dev, unsigned long *addr, dma_addr_t *bus_addr) @@ -76,23 +59,15 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, goto done; } - address = DRM(ati_alloc_pcigart_table)(); + address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, + DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0); if ( !address ) { DRM_ERROR( "cannot allocate PCI GART page!\n" ); goto done; } - /* FIXME non-vtophys==bustophys-arches */ + /* XXX: we need to busdma this */ bus_address = vtophys( address ); - /*pci_map_single(dev->pdev, (void *)address, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE);*/ -/* if (bus_address == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_free_pcigart_table)( (unsigned long)address ); - address = 0; - goto done; - }*/ pci_gart = (u32 *)address; @@ -102,16 +77,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); for ( i = 0 ; i < pages ; i++ ) { - /* we need to support large memory configurations */ - /* FIXME non-vtophys==vtobus-arches */ entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) ); -/* if (entry->busaddr[i] == 0) { - DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_pcigart_cleanup)( dev, (unsigned long)address, bus_address ); - address = 0; - bus_address = 0; - goto done; - }*/ page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { @@ -122,8 +88,6 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, ret = 1; - DRM_READMEMORYBARRIER(); - done: *addr = address; *bus_addr = bus_address; @@ -142,9 +106,8 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, return 0; } - if ( addr ) { - DRM(ati_free_pcigart_table)( addr ); - } - +#if __FreeBSD_version > 500000 + contigfree( (void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM)); /* Not available on 4.x */ +#endif return 1; } @@ -30,6 +30,7 @@ * Acknowledgements: * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg. * + * $FreeBSD: src/sys/dev/drm/drm.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #ifndef _DRM_H_ @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drmP.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #ifndef _DRM_P_H_ @@ -95,21 +96,20 @@ typedef struct drm_file drm_file_t; #define DRM_MEM_MAGIC 3 #define DRM_MEM_IOCTLS 4 #define DRM_MEM_MAPS 5 -#define DRM_MEM_VMAS 6 -#define DRM_MEM_BUFS 7 -#define DRM_MEM_SEGS 8 -#define DRM_MEM_PAGES 9 -#define DRM_MEM_FILES 10 -#define DRM_MEM_QUEUES 11 -#define DRM_MEM_CMDS 12 -#define DRM_MEM_MAPPINGS 13 -#define DRM_MEM_BUFLISTS 14 -#define DRM_MEM_AGPLISTS 15 -#define DRM_MEM_TOTALAGP 16 -#define DRM_MEM_BOUNDAGP 17 -#define DRM_MEM_CTXBITMAP 18 -#define DRM_MEM_STUB 19 -#define DRM_MEM_SGLISTS 20 +#define DRM_MEM_BUFS 6 +#define DRM_MEM_SEGS 7 +#define DRM_MEM_PAGES 8 +#define DRM_MEM_FILES 9 +#define DRM_MEM_QUEUES 10 +#define DRM_MEM_CMDS 11 +#define DRM_MEM_MAPPINGS 12 +#define DRM_MEM_BUFLISTS 13 +#define DRM_MEM_AGPLISTS 14 +#define DRM_MEM_TOTALAGP 15 +#define DRM_MEM_BOUNDAGP 16 +#define DRM_MEM_CTXBITMAP 17 +#define DRM_MEM_STUB 18 +#define DRM_MEM_SGLISTS 19 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) @@ -121,15 +121,15 @@ typedef struct drm_file drm_file_t; /* Mapping helper macros */ #define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) + (map)->handle = DRM(ioremap)( dev, map ) #define DRM_IOREMAP_NOCACHE(map) \ - (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) + (map)->handle = DRM(ioremap_nocache)( dev, map ) #define DRM_IOREMAPFREE(map) \ do { \ if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ + DRM(ioremapfree)( map ); \ } while (0) /* Internal types and structures */ @@ -152,16 +152,11 @@ typedef struct drm_pci_list { } drm_pci_list_t; typedef struct drm_ioctl_desc { - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int auth_needed; int root_only; } drm_ioctl_desc_t; -typedef struct drm_devstate { - pid_t owner; /* X server pid holding x_lock */ - -} drm_devstate_t; - typedef struct drm_magic_entry { drm_magic_t magic; struct drm_file *priv; @@ -173,12 +168,6 @@ typedef struct drm_magic_head { struct drm_magic_entry *tail; } drm_magic_head_t; -typedef struct drm_vma_entry { - struct vm_area_struct *vma; - struct drm_vma_entry *next; - pid_t pid; -} drm_vma_entry_t; - typedef struct drm_buf { int idx; /* Index into master buflist */ int total; /* Buffer size */ @@ -191,7 +180,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + DRMFILE filp; /* Unique identifier of holding process */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -308,7 +297,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -377,7 +366,6 @@ typedef struct drm_sg_mem { unsigned long handle; void *virtual; int pages; - struct page **pagelist; dma_addr_t *busaddr; } drm_sg_mem_t; @@ -386,10 +374,23 @@ typedef struct drm_sigdata { drm_hw_lock_t *lock; } drm_sigdata_t; +typedef struct drm_local_map { + unsigned long offset; /* Physical address (0 for SAREA)*/ + unsigned long size; /* Physical size (bytes) */ + drm_map_type_t type; /* Type of memory mapped */ + drm_map_flags_t flags; /* Flags */ + void *handle; /* User-space: "Handle" to pass to mmap */ + /* Kernel-space: kernel-virtual address */ + int mtrr; /* MTRR slot used */ + /* Private data */ + bus_space_tag_t iot; + bus_space_handle_t ioh; +} drm_local_map_t; + typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t; typedef struct drm_map_list_entry { TAILQ_ENTRY(drm_map_list_entry) link; - drm_map_t *map; + drm_local_map_t *map; } drm_map_list_entry_t; TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig); @@ -423,7 +424,6 @@ struct drm_device { /* Usage Counters */ int open_count; /* Outstanding files open */ atomic_t ioctl_count; /* Outstanding IOCTLs pending */ - atomic_t vma_count; /* Outstanding vma areas open */ int buf_use; /* Buffers in use -- cannot alloc */ atomic_t buf_alloc; /* Buffer allocation in progress */ @@ -440,10 +440,9 @@ struct drm_device { drm_map_list_t *maplist; /* Linked list of regions */ int map_count; /* Number of mappable regions */ - drm_map_t **context_sareas; + drm_local_map_t **context_sareas; int max_context; - drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */ drm_lock_data_t lock; /* Information on hardware lock */ /* DMA queues (contexts) */ @@ -454,9 +453,9 @@ struct drm_device { drm_device_dma_t *dma; /* Optional pointer for DMA support */ /* Context support */ -#ifdef __FreeBSD__ int irq; /* Interrupt used by board */ int irqrid; /* Interrupt used by board */ +#ifdef __FreeBSD__ struct resource *irqr; /* Resource for interrupt used by board */ #elif defined(__NetBSD__) struct pci_attach_args pa; @@ -477,9 +476,11 @@ struct drm_device { #if __HAVE_VBL_IRQ wait_queue_head_t vbl_queue; /* vbl wait channel */ atomic_t vbl_received; +#if 0 /* vbl signals are untested, ntested */ struct drm_vbl_sig_list vbl_sig_list; DRM_SPINTYPE vbl_lock; #endif +#endif cycles_t ctx_start; cycles_t lck_start; #if __HAVE_DMA_HISTOGRAM @@ -530,15 +531,16 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s); /* Memory management support (drm_memory.h) */ extern void DRM(mem_init)(void); +extern void DRM(mem_uninit)(void); extern void *DRM(alloc)(size_t size, int area); extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area); extern char *DRM(strdup)(const char *s, int area); extern void DRM(strfree)(char *s, int area); extern void DRM(free)(void *pt, size_t size, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map); +extern void *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map); +extern void DRM(ioremapfree)(drm_local_map_t *map); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); @@ -580,7 +582,7 @@ extern int DRM(order)( unsigned long size ); extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ @@ -652,5 +654,82 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, dma_addr_t bus_addr); #endif +/* Locking IOCTL support (drm_drv.h) */ +extern int DRM(lock)(DRM_IOCTL_ARGS); +extern int DRM(unlock)(DRM_IOCTL_ARGS); + +/* Misc. IOCTL support (drm_ioctl.h) */ +extern int DRM(irq_busid)(DRM_IOCTL_ARGS); +extern int DRM(getunique)(DRM_IOCTL_ARGS); +extern int DRM(setunique)(DRM_IOCTL_ARGS); +extern int DRM(getmap)(DRM_IOCTL_ARGS); +extern int DRM(getclient)(DRM_IOCTL_ARGS); +extern int DRM(getstats)(DRM_IOCTL_ARGS); + +/* Context IOCTL support (drm_context.h) */ +extern int DRM(resctx)(DRM_IOCTL_ARGS); +extern int DRM(addctx)(DRM_IOCTL_ARGS); +extern int DRM(modctx)(DRM_IOCTL_ARGS); +extern int DRM(getctx)(DRM_IOCTL_ARGS); +extern int DRM(switchctx)(DRM_IOCTL_ARGS); +extern int DRM(newctx)(DRM_IOCTL_ARGS); +extern int DRM(rmctx)(DRM_IOCTL_ARGS); +extern int DRM(setsareactx)(DRM_IOCTL_ARGS); +extern int DRM(getsareactx)(DRM_IOCTL_ARGS); + +/* Drawable IOCTL support (drm_drawable.h) */ +extern int DRM(adddraw)(DRM_IOCTL_ARGS); +extern int DRM(rmdraw)(DRM_IOCTL_ARGS); + +/* Authentication IOCTL support (drm_auth.h) */ +extern int DRM(getmagic)(DRM_IOCTL_ARGS); +extern int DRM(authmagic)(DRM_IOCTL_ARGS); + +/* Locking IOCTL support (drm_lock.h) */ +extern int DRM(block)(DRM_IOCTL_ARGS); +extern int DRM(unblock)(DRM_IOCTL_ARGS); +extern int DRM(finish)(DRM_IOCTL_ARGS); + +/* Buffer management support (drm_bufs.h) */ +extern int DRM(addmap)(DRM_IOCTL_ARGS); +extern int DRM(rmmap)(DRM_IOCTL_ARGS); +#if __HAVE_DMA +extern int DRM(addbufs_agp)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_pci)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_sg)(DRM_IOCTL_ARGS); +extern int DRM(addbufs)(DRM_IOCTL_ARGS); +extern int DRM(infobufs)(DRM_IOCTL_ARGS); +extern int DRM(markbufs)(DRM_IOCTL_ARGS); +extern int DRM(freebufs)(DRM_IOCTL_ARGS); +extern int DRM(mapbufs)(DRM_IOCTL_ARGS); +#endif + +/* DMA support (drm_dma.h) */ +#if __HAVE_DMA +extern int DRM(control)(DRM_IOCTL_ARGS); +#endif +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(DRM_IOCTL_ARGS); +#endif + +/* AGP/GART support (drm_agpsupport.h) */ +#if __REALLY_HAVE_AGP +extern int DRM(agp_acquire)(DRM_IOCTL_ARGS); +extern int DRM(agp_release)(DRM_IOCTL_ARGS); +extern int DRM(agp_enable)(DRM_IOCTL_ARGS); +extern int DRM(agp_info)(DRM_IOCTL_ARGS); +extern int DRM(agp_alloc)(DRM_IOCTL_ARGS); +extern int DRM(agp_free)(DRM_IOCTL_ARGS); +extern int DRM(agp_unbind)(DRM_IOCTL_ARGS); +extern int DRM(agp_bind)(DRM_IOCTL_ARGS); +#endif + +/* Scatter Gather Support (drm_scatter.h) */ +#if __HAVE_SG +extern int DRM(sg_alloc)(DRM_IOCTL_ARGS); +extern int DRM(sg_free)(DRM_IOCTL_ARGS); +#endif + + #endif /* __KERNEL__ */ #endif /* _DRM_P_H_ */ diff --git a/bsd/drm_agpsupport.h b/bsd/drm_agpsupport.h index a940378e..ca7bea9e 100644 --- a/bsd/drm_agpsupport.h +++ b/bsd/drm_agpsupport.h @@ -27,6 +27,7 @@ * Author: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_agpsupport.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -37,7 +38,8 @@ int DRM(agp_info)(DRM_IOCTL_ARGS) struct agp_info *kern; drm_agp_info_t info; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; kern = &dev->agp->info; agp_get_info(dev->agp->agpdev, kern); @@ -60,9 +62,11 @@ int DRM(agp_acquire)(DRM_IOCTL_ARGS) DRM_DEVICE; int retcode; - if (!dev->agp || dev->agp->acquired) return EINVAL; + if (!dev->agp || dev->agp->acquired) + return EINVAL; retcode = agp_acquire(dev->agp->agpdev); - if (retcode) return retcode; + if (retcode) + return retcode; dev->agp->acquired = 1; return 0; } @@ -93,7 +97,8 @@ int DRM(agp_enable)(DRM_IOCTL_ARGS) DRM_DEVICE; drm_agp_mode_t mode; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; mode = *(drm_agp_mode_t *) data; @@ -114,7 +119,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS) u_int32_t type; struct agp_memory_info info; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_buffer_t *) data; @@ -136,7 +142,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS) entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; - if (dev->agp->memory) dev->agp->memory->prev = entry; + if (dev->agp->memory) + dev->agp->memory->prev = entry; dev->agp->memory = entry; agp_memory_info(dev->agp->agpdev, entry->handle, &info); @@ -166,7 +173,8 @@ int DRM(agp_unbind)(DRM_IOCTL_ARGS) drm_agp_mem_t *entry; int retcode; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_binding_t *) data; if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle))) return EINVAL; @@ -209,15 +217,20 @@ int DRM(agp_free)(DRM_IOCTL_ARGS) drm_agp_buffer_t request; drm_agp_mem_t *entry; - if (!dev->agp || !dev->agp->acquired) return EINVAL; + if (!dev->agp || !dev->agp->acquired) + return EINVAL; request = *(drm_agp_buffer_t *) data; if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle))) return EINVAL; - if (entry->bound) DRM(unbind_agp)(entry->handle); + if (entry->bound) + DRM(unbind_agp)(entry->handle); - if (entry->prev) entry->prev->next = entry->next; - else dev->agp->memory = entry->next; - if (entry->next) entry->next->prev = entry->prev; + if (entry->prev) + entry->prev->next = entry->next; + else + dev->agp->memory = entry->next; + if (entry->next) + entry->next->prev = entry->prev; DRM(free_agp)(entry->handle, entry->pages); DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; diff --git a/bsd/drm_auth.h b/bsd/drm_auth.h index 0b411d14..c506ee7e 100644 --- a/bsd/drm_auth.h +++ b/bsd/drm_auth.h @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_auth.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -116,25 +117,20 @@ int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; drm_auth_t auth; - static DRM_SPINTYPE lock; - static int first = 1; DRM_DEVICE; DRM_PRIV; - if (first) { - DRM_SPININIT(lock, "drm getmagic"); - first = 0; - } - /* Find unique magic */ if (priv->magic) { auth.magic = priv->magic; } else { do { - DRM_SPINLOCK(&lock); - if (!sequence) ++sequence; /* reserve 0 */ - auth.magic = sequence++; - DRM_SPINUNLOCK(&lock); + int old = sequence; + + auth.magic = old+1; + + if (!atomic_cmpset_int(&sequence, old, auth.magic)) + continue; } while (DRM(find_file)(dev, auth.magic)); priv->magic = auth.magic; DRM(add_magic)(dev, priv, auth.magic); diff --git a/bsd/drm_bufs.h b/bsd/drm_bufs.h index 7d56d0a3..8e0534f2 100644 --- a/bsd/drm_bufs.h +++ b/bsd/drm_bufs.h @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_bufs.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -69,18 +70,26 @@ int DRM(order)( unsigned long size ) int DRM(addmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; - drm_map_t *map; + drm_map_t request; + drm_local_map_t *map; drm_map_list_entry_t *list; if (!(dev->flags & (FREAD|FWRITE))) return DRM_ERR(EACCES); /* Require read/write */ - map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) ); + + map = (drm_local_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); if ( !map ) return DRM_ERR(ENOMEM); - *map = *(drm_map_t *)data; - + map->offset = request.offset; + map->size = request.size; + map->type = request.type; + map->flags = request.flags; + map->mtrr = -1; + map->handle = 0; + /* Only allow shared memory to be removable since we only keep enough * book keeping information about shared memory to allow for removal * when processes fork. @@ -95,22 +104,14 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return DRM_ERR(EINVAL); } - map->mtrr = -1; - map->handle = 0; switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) - if ( map->offset + map->size < map->offset - ) { + if ( map->offset + map->size < map->offset ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); return DRM_ERR(EINVAL); } -#endif -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif #if __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { @@ -130,14 +131,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) mtrrmap.base = map->offset; mtrrmap.len = map->size; mtrrmap.type = MTRR_TYPE_WC; - mtrrmap.flags = MTRR_PRIVATE | MTRR_VALID; - mtrrmap.owner = p->p_pid; - /* USER? KERNEL? XXX */ - map->mtrr = mtrr_get( &mtrrmap, &one, p, MTRR_GETSET_KERNEL ); + mtrrmap.flags = MTRR_VALID; + map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL ); #endif } #endif /* __REALLY_HAVE_MTRR */ - map->handle = DRM(ioremap)( map->offset, map->size ); + DRM_IOREMAP(map); break; case _DRM_SHM: @@ -155,9 +154,6 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) break; #if __REALLY_HAVE_AGP case _DRM_AGP: -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif map->offset += dev->agp->base; map->mtrr = dev->agp->agp_mtrr; /* for getmap */ break; @@ -187,11 +183,19 @@ int DRM(addmap)( DRM_IOCTL_ARGS ) TAILQ_INSERT_TAIL(dev->maplist, list, link); DRM_UNLOCK; - *(drm_map_t *)data = *map; + request.offset = map->offset; + request.size = map->size; + request.type = map->type; + request.flags = map->flags; + request.mtrr = map->mtrr; + request.handle = map->handle; - if ( map->type != _DRM_SHM ) { - ((drm_map_t *)data)->handle = (void *)map->offset; + if ( request.type != _DRM_SHM ) { + request.handle = (void *)request.offset; } + + DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, request, sizeof(drm_map_t) ); + return 0; } @@ -204,7 +208,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_map_list_entry_t *list; - drm_map_t *map; + drm_local_map_t *map; drm_map_t request; int found_maps = 0; @@ -257,7 +261,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) #endif } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)( map ); break; case _DRM_SHM: DRM(free)( map->handle, map->size, DRM_MEM_SAREA ); @@ -413,7 +417,7 @@ int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -621,7 +625,7 @@ int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -774,7 +778,7 @@ int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -858,16 +862,16 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) - return DRM(addbufs_agp)( kdev, cmd, data, flags, p ); + return DRM(addbufs_agp)( kdev, cmd, data, flags, p, filp ); else #endif #if __REALLY_HAVE_SG if ( request.flags & _DRM_SG_BUFFER ) - return DRM(addbufs_sg)( kdev, cmd, data, flags, p ); + return DRM(addbufs_sg)( kdev, cmd, data, flags, p, filp ); else #endif #if __HAVE_PCI_DMA - return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); + return DRM(addbufs_pci)( kdev, cmd, data, flags, p, filp ); #else return DRM_ERR(EINVAL); #endif @@ -991,9 +995,9 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR("Process %d freeing buffer not owned\n", + DRM_CURRENTPID); return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); @@ -1018,6 +1022,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) #endif /* __FreeBSD__ */ #ifdef __NetBSD__ struct vnode *vn; + struct vmspace *vms = p->p_vmspace; #endif /* __NetBSD__ */ drm_buf_map_t request; @@ -1043,7 +1048,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) if ( request.count >= dma->buf_count ) { if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) { - drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev ); + drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev ); if ( !map ) { retcode = EINVAL; diff --git a/bsd/drm_context.h b/bsd/drm_context.h index 0274a8b7..c3a20f6e 100644 --- a/bsd/drm_context.h +++ b/bsd/drm_context.h @@ -27,6 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * $FreeBSD: src/sys/dev/drm/drm_context.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -69,7 +70,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) if((bit+1) > dev->max_context) { dev->max_context = (bit+1); if(dev->context_sareas) { - drm_map_t **ctx_sareas; + drm_local_map_t **ctx_sareas; ctx_sareas = DRM(realloc)(dev->context_sareas, (dev->max_context - 1) * @@ -149,7 +150,7 @@ int DRM(getsareactx)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_ctx_priv_map_t request; - drm_map_t *map; + drm_local_map_t *map; DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); @@ -174,7 +175,7 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_ctx_priv_map_t request; - drm_map_t *map = NULL; + drm_local_map_t *map = NULL; drm_map_list_entry_t *list; DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, @@ -183,24 +184,20 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS ) DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map=list->map; - if(map->handle == request.handle) - goto found; + if(map->handle == request.handle) { + if (dev->max_context < 0) + goto bad; + if (request.ctx_id >= (unsigned) dev->max_context) + goto bad; + dev->context_sareas[request.ctx_id] = map; + DRM_UNLOCK; + return 0; + } } bad: DRM_UNLOCK; return DRM_ERR(EINVAL); - -found: - map = list->map; - if (!map) goto bad; - if (dev->max_context < 0) - goto bad; - if (request.ctx_id >= (unsigned) dev->max_context) - goto bad; - dev->context_sareas[request.ctx_id] = map; - DRM_UNLOCK; - return 0; } /* ================================================================ diff --git a/bsd/drm_dma.h b/bsd/drm_dma.h index 0f0dd4fd..fa0bd20d 100644 --- a/bsd/drm_dma.h +++ b/bsd/drm_dma.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_dma.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -180,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = NULL; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -203,14 +205,14 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) { drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); @@ -524,7 +526,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); #endif -#if __HAVE_VBL_IRQ +#if __HAVE_VBL_IRQ && 0 /* disabled */ DRM_SPININIT( dev->vbl_lock, "vblsig" ); TAILQ_INIT( &dev->vbl_sig_list ); #endif @@ -534,9 +536,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) /* Install handler */ dev->irqrid = 0; +#ifdef __FreeBSD__ dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, 0, ~0, 1, RF_SHAREABLE); if (!dev->irqr) { +#elif defined(__NetBSD__) + if (pci_intr_map(&dev->pa, &dev->ih) != 0) { +#endif DRM_LOCK; dev->irq = 0; dev->irqrid = 0; @@ -544,11 +550,24 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) return ENOENT; } +#ifdef __FreeBSD__ +#if __FreeBSD_version < 500000 retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, DRM(dma_service), dev, &dev->irqh); +#else + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, + DRM(dma_service), dev, &dev->irqh); +#endif if ( retcode ) { +#elif defined(__NetBSD__) + dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, + (int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev); + if ( !dev->irqh ) { +#endif DRM_LOCK; +#ifdef __FreeBSD__ bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); +#endif dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK; @@ -580,9 +599,13 @@ int DRM(irq_uninstall)( drm_device_t *dev ) DRM(driver_irq_uninstall)( dev ); +#ifdef __FreeBSD__ bus_teardown_intr(dev->device, dev->irqr, dev->irqh); bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); - +#elif defined(__NetBSD__) + pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); +#endif + return 0; } @@ -624,6 +647,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; if (flags & _DRM_VBLANK_SIGNAL) { +#if 0 /* disabled */ drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); if (vbl_sig == NULL) return ENOMEM; @@ -639,6 +663,8 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); DRM_SPINUNLOCK(&dev->vbl_lock); ret = 0; +#endif + ret = EINVAL; } else { ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); @@ -653,6 +679,11 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) return ret; } +void DRM(vbl_send_signals)(drm_device_t *dev) +{ +} + +#if 0 /* disabled */ void DRM(vbl_send_signals)( drm_device_t *dev ) { drm_vbl_sig_t *vbl_sig; @@ -671,13 +702,14 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) psignal(p, vbl_sig->signo); TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); - DRM_FREE(vbl_sig); + DRM_FREE(vbl_sig,sizeof(*vbl_sig)); } vbl_sig = next; } DRM_SPINUNLOCK(&dev->vbl_lock); } +#endif #endif /* __HAVE_VBL_IRQ */ diff --git a/bsd/drm_drawable.h b/bsd/drm_drawable.h index 30841067..25dfc6d9 100644 --- a/bsd/drm_drawable.h +++ b/bsd/drm_drawable.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_drawable.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" diff --git a/bsd/drm_drv.h b/bsd/drm_drv.h index 4a6fc15f..d43a4666 100644 --- a/bsd/drm_drv.h +++ b/bsd/drm_drv.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_drv.h,v 1.12 2003/03/09 02:08:28 anholt Exp $ */ /* @@ -125,16 +127,10 @@ #define DRIVER_NUM_CARDS 1 #endif -#ifdef __FreeBSD__ static int DRM(init)(device_t nbdev); static void DRM(cleanup)(device_t nbdev); -#elif defined(__NetBSD__) -static int DRM(init)(drm_device_t *); -static void DRM(cleanup)(drm_device_t *); -#endif #ifdef __FreeBSD__ -#define CDEV_MAJOR 145 #define DRIVER_SOFTC(unit) \ ((drm_device_t *) devclass_get_softc(DRM(devclass), unit)) @@ -147,9 +143,8 @@ MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); #endif /* __FreeBSD__ */ #ifdef __NetBSD__ -#define CDEV_MAJOR 90 #define DRIVER_SOFTC(unit) \ - ((drm_device_t *) device_lookup(&DRM(_cd), unit)) + ((drm_device_t *) device_lookup(&DRM(cd), unit)) #endif /* __NetBSD__ */ static drm_ioctl_desc_t DRM(ioctls)[] = { @@ -229,6 +224,22 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { const char *DRM(find_description)(int vendor, int device); #ifdef __FreeBSD__ +static struct cdevsw DRM(cdevsw) = { + .d_open = DRM( open ), + .d_close = DRM( close ), + .d_read = DRM( read ), + .d_write = DRM( write ), + .d_ioctl = DRM( ioctl ), + .d_poll = DRM( poll ), + .d_mmap = DRM( mmap ), + .d_name = DRIVER_NAME, + .d_maj = CDEV_MAJOR, + .d_flags = D_TTY | D_TRACKCLOSE, +#if __FreeBSD_version < 500000 + .d_bmaj = -1 +#endif +}; + static int DRM(probe)(device_t dev) { const char *s = NULL; @@ -271,57 +282,108 @@ static driver_t DRM(driver) = { sizeof(drm_device_t), }; -static devclass_t DRM( devclass); - -static struct cdevsw DRM( cdevsw) = { - /* open */ DRM( open ), - /* close */ DRM( close ), - /* read */ DRM( read ), - /* write */ DRM( write ), - /* ioctl */ DRM( ioctl ), - /* poll */ DRM( poll ), - /* mmap */ DRM( mmap ), - /* strategy */ nostrategy, - /* name */ DRIVER_NAME, - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ D_TTY | D_TRACKCLOSE, -#if __FreeBSD_version >= 500000 - /* kqfilter */ 0 +static devclass_t DRM(devclass); + +#elif defined(__NetBSD__) + +static struct cdevsw DRM(cdevsw) = { + DRM(open), + DRM(close), + DRM(read), + DRM(write), + DRM(ioctl), + nostop, + notty, + DRM(poll), + DRM(mmap), + nokqfilter, + D_TTY +}; + +int DRM(refcnt) = 0; +#if __NetBSD_Version__ >= 106080000 +MOD_DEV( DRIVER_NAME, DRIVER_NAME, NULL, -1, &DRM(cdevsw), CDEV_MAJOR); #else - /* bmaj */ -1 +MOD_DEV( DRIVER_NAME, LM_DT_CHAR, CDEV_MAJOR, &DRM(cdevsw) ); #endif -}; -#elif defined(__NetBSD__) -int DRM(probe)(struct device *parent, struct cfdata *match, void *aux); -void DRM(attach)(struct device *parent, struct device *self, void *aux); -int DRM(detach)(struct device *self, int flags); -int DRM(activate)(struct device *self, enum devact act); - -struct cfattach DRM(_ca) = { - sizeof(drm_device_t), DRM(probe), - DRM(attach), DRM(detach), DRM(activate) }; +int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver); +static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd); + +int DRM(modprobe)(); +int DRM(probe)(struct pci_attach_args *pa); +void DRM(attach)(struct pci_attach_args *pa, dev_t kdev); + +int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver) { + DISPATCH(lkmtp, cmd, ver, DRM(lkmhandle), DRM(lkmhandle), DRM(lkmhandle)); +} + +static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd) +{ + int j, error = 0; +#if defined(__NetBSD__) && (__NetBSD_Version__ > 106080000) + struct lkm_dev *args = lkmtp->private.lkm_dev; +#endif + + switch(cmd) { + case LKM_E_LOAD: + if (lkmexists(lkmtp)) + return EEXIST; + + if(DRM(modprobe)()) + return 0; + + return 1; + + case LKM_E_UNLOAD: + if (DRM(refcnt) > 0) + return (EBUSY); + break; + case LKM_E_STAT: + break; + + default: + error = EIO; + break; + } -int DRM(probe)(struct device *parent, struct cfdata *match, void *aux) + return error; +} + +int DRM(modprobe)() { + struct pci_attach_args pa; + int error = 0; + if((error = pci_find_device(&pa, DRM(probe))) != 0) + DRM(attach)(&pa, 0); + + return error; +} + +int DRM(probe)(struct pci_attach_args *pa) { - struct pci_attach_args *pa = aux;
const char *desc; desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); - if (desc != NULL) - return 10; + if (desc != NULL) { + return 1; + } + return 0; } -void DRM(attach)(struct device *parent, struct device *self, void *aux) +void DRM(attach)(struct pci_attach_args *pa, dev_t kdev) { - struct pci_attach_args *pa = aux; - drm_device_t *dev = (drm_device_t *)self; - - memcpy(&dev->pa, aux, sizeof(dev->pa)); -
+ int i; + drm_device_t *dev; + + config_makeroom(kdev, &DRM(cd)); + DRM(cd).cd_devs[(kdev)] = DRM(alloc)(sizeof(drm_device_t), + DRM_MEM_DRIVER); + dev = DRIVER_SOFTC(kdev); + + memset(dev, 0, sizeof(drm_device_t)); + memcpy(&dev->pa, pa, sizeof(dev->pa)); + DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id))); DRM(init)(dev); } @@ -345,8 +407,7 @@ int DRM(activate)(struct device *self, enum devact act) } return (0); } - -#endif +#endif /* __NetBSD__ */ const char *DRM(find_description)(int vendor, int device) { const char *s = NULL; @@ -372,7 +433,6 @@ static int DRM(setup)( drm_device_t *dev ) DRIVER_PRESETUP(); atomic_set( &dev->ioctl_count, 0 ); - atomic_set( &dev->vma_count, 0 ); dev->buf_use = 0; atomic_set( &dev->buf_alloc, 0 ); @@ -435,7 +495,6 @@ static int DRM(setup)( drm_device_t *dev ) TAILQ_INIT(dev->maplist); dev->map_count = 0; - dev->vmalist = NULL; dev->lock.hw_lock = NULL; dev->lock.lock_queue = 0; dev->queue_count = 0; @@ -487,9 +546,8 @@ static int DRM(setup)( drm_device_t *dev ) static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; - drm_map_t *map; + drm_local_map_t *map; drm_map_list_entry_t *list; - drm_vma_entry_t *vma, *vma_next; int i; DRM_DEBUG( "\n" ); @@ -546,15 +604,6 @@ static int DRM(takedown)( drm_device_t *dev ) } #endif - /* Clear vma list (only built for debugging) */ - if ( dev->vmalist ) { - for ( vma = dev->vmalist ; vma ; vma = vma_next ) { - vma_next = vma->next; - DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS ); - } - dev->vmalist = NULL; - } - if( dev->maplist ) { while ((list=TAILQ_FIRST(dev->maplist))) { map = list->map; @@ -581,15 +630,13 @@ static int DRM(takedown)( drm_device_t *dev ) mtrrmap.len = map->size; mtrrmap.type = MTRR_TYPE_WC; mtrrmap.flags = 0; - /*mtrrmap.owner = p->p_pid;*/ - /* XXX: Use curproc here? */ retcode = mtrr_set( &mtrrmap, &one, DRM_CURPROC, MTRR_GETSET_KERNEL); #endif DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map ); break; case _DRM_SHM: DRM(free)(map->handle, @@ -646,7 +693,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } DRM_UNLOCK; @@ -658,15 +705,13 @@ static int DRM(takedown)( drm_device_t *dev ) * linux/init/main.c (this is not currently supported). * bsd: drm_init is called via the attach function per device. */ -#ifdef __FreeBSD__ static int DRM(init)( device_t nbdev ) -#elif defined(__NetBSD__) -static int DRM(init)( drm_device_t *dev ) -#endif { int unit; #ifdef __FreeBSD__ drm_device_t *dev; +#elif defined(__NetBSD__) + drm_device_t *dev = nbdev; #endif #if __HAVE_CTX_BITMAP int retcode; @@ -724,7 +769,6 @@ static int DRM(init)( drm_device_t *dev ) struct mtrr mtrrmap; int one = 1; mtrrmap.base = dev->agp->info.ai_aperture_base; - /* Might need a multiplier here XXX */ mtrrmap.len = dev->agp->info.ai_aperture_size; mtrrmap.type = MTRR_TYPE_WC; mtrrmap.flags = MTRR_VALID; @@ -763,21 +807,16 @@ static int DRM(init)( drm_device_t *dev ) * bsd: drm_cleanup is called per device at module unload time. * FIXME: NetBSD */ -#ifdef __FreeBSD__ static void DRM(cleanup)(device_t nbdev) -#elif defined(__NetBSD__) -static void DRM(cleanup)(drm_device_t *dev) -#endif { -#ifdef __FreeBSD__ drm_device_t *dev; -#endif -#if __REALLY_HAVE_MTRR #ifdef __NetBSD__ +#if __REALLY_HAVE_MTRR struct mtrr mtrrmap; int one = 1; -#endif /* __NetBSD__ */ #endif /* __REALLY_HAVE_MTRR */ + dev = nbdev; +#endif /* __NetBSD__ */ DRM_DEBUG( "\n" ); @@ -799,7 +838,7 @@ static void DRM(cleanup)(drm_device_t *dev) mtrrmap.len = dev->agp->info.ai_aperture_size; mtrrmap.type = 0; mtrrmap.flags = 0; - retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); + mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); #endif } #endif @@ -814,6 +853,8 @@ static void DRM(cleanup)(drm_device_t *dev) } #endif DRIVER_POSTCLEANUP(); + DRM(mem_uninit)(); + DRM_SPINUNINIT(dev->count_lock); } @@ -876,7 +917,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) drm_file_t *priv; DRM_DEVICE; int retcode = 0; - + DRMFILE __unused filp = (void *)(DRM_CURRENTPID); + DRM_DEBUG( "open_count = %d\n", dev->open_count ); priv = DRM(find_file_by_proc)(dev, p); if (!priv) { @@ -899,7 +941,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_CURRENTPID) { + && dev->lock.filp == (void *)DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -926,7 +968,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ) ) { - dev->lock.pid = p->p_pid; + dev->lock.pid = DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -935,7 +977,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #if 0 atomic_inc( &dev->total_sleeps ); #endif - retcode = tsleep(&dev->lock.lock_queue, + retcode = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, "drmlk2", 0); @@ -949,7 +991,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( dev, (void *)priv->pid ); #endif #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) @@ -999,12 +1041,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_IOCTL_ARGS ) +int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, + DRM_STRUCTPROC *p) { DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); DRM_PRIV; @@ -1043,7 +1086,6 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) *(int *) data = fgetown(dev->buf_sigio); #endif return 0; - } #endif /* __FreeBSD__ */ #ifdef __NetBSD__ case TIOCSPGRP: @@ -1056,6 +1098,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) *(int *)data = dev->buf_pgid; return 0; #endif /* __NetBSD__ */ + } if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = EINVAL; @@ -1070,7 +1113,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { - retcode = func( kdev, cmd, data, flags, p ); + retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); } } @@ -1125,7 +1168,7 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_CURRENTPID; + dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ diff --git a/bsd/drm_fops.h b/bsd/drm_fops.h index ed85a8de..75baa5f2 100644 --- a/bsd/drm_fops.h +++ b/bsd/drm_fops.h @@ -28,6 +28,8 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_fops.h,v 1.5 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -100,7 +102,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, the circular buffer), is based on Alessandro Rubini's LINUX DEVICE DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */ -ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag) +int DRM(read)(dev_t kdev, struct uio *uio, int ioflag) { DRM_DEVICE; int left; @@ -182,8 +184,8 @@ int DRM(write_string)(drm_device_t *dev, const char *s) selwakeup(&dev->buf_sel); } - DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); #ifdef __FreeBSD__ + DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); if (dev->buf_sigio) { DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid); #if __FreeBSD_version >= 500000 @@ -200,6 +202,7 @@ int DRM(write_string)(drm_device_t *dev, const char *s) gsignal(dev->buf_pgid, SIGIO); else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL) psignal(p, SIGIO); + } #endif /* __NetBSD__ */ DRM_DEBUG("waking\n"); wakeup(&dev->buf_rp); diff --git a/bsd/drm_init.h b/bsd/drm_init.h index adf421a4..ec9ea1d7 100644 --- a/bsd/drm_init.h +++ b/bsd/drm_init.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_init.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" diff --git a/bsd/drm_ioctl.h b/bsd/drm_ioctl.h index 63562fef..270b2bb5 100644 --- a/bsd/drm_ioctl.h +++ b/bsd/drm_ioctl.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_ioctl.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -136,7 +138,7 @@ int DRM(getmap)( DRM_IOCTL_ARGS ) { DRM_DEVICE; drm_map_t map; - drm_map_t *mapinlist; + drm_local_map_t *mapinlist; drm_map_list_entry_t *list; int idx; int i = 0; diff --git a/bsd/drm_lists.h b/bsd/drm_lists.h index 1ab55f90..8c34e117 100644 --- a/bsd/drm_lists.h +++ b/bsd/drm_lists.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_lists.h,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -43,7 +45,7 @@ int DRM(waitlist_create)(drm_waitlist_t *bl, int count) if(!bl->bufs) return DRM_ERR(ENOMEM); - memset(bl->bufs, 0, sizeof(*bl->bufs)); + bzero(bl->bufs, sizeof(*bl->bufs)); bl->count = count; bl->rp = bl->bufs; @@ -66,6 +68,8 @@ int DRM(waitlist_destroy)(drm_waitlist_t *bl) bl->rp = NULL; bl->wp = NULL; bl->end = NULL; + DRM_SPINUNINIT( bl->write_lock ); + DRM_SPINUNINIT( bl->read_lock ); return 0; } @@ -137,6 +141,7 @@ int DRM(freelist_destroy)(drm_freelist_t *bl) { atomic_set(&bl->count, 0); bl->next = NULL; + DRM_SPINUNINIT( bl->lock ); return 0; } @@ -175,7 +180,7 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) /* Check for high water mark */ if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) { atomic_set(&bl->wfh, 0); - DRM_WAKEUP_INT(&bl->waiting); + DRM_WAKEUP_INT((void *)&bl->waiting); } return 0; } @@ -222,7 +227,7 @@ drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block) for (;;) { if (!atomic_read(&bl->wfh) && (buf = DRM(freelist_try(bl)))) break; - error = tsleep(&bl->waiting, PZERO|PCATCH, + error = tsleep((void *)&bl->waiting, PZERO|PCATCH, "drmfg", 0); if (error) break; diff --git a/bsd/drm_lock.h b/bsd/drm_lock.h index 5e9294bc..3bab78ef 100644 --- a/bsd/drm_lock.h +++ b/bsd/drm_lock.h @@ -27,6 +27,8 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_lock.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -47,14 +49,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - do { old = *lock; if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; else new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -77,14 +77,13 @@ int DRM(lock_transfer)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + return 1; } @@ -92,20 +91,16 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - pid_t pid = dev->lock.pid; - char failed; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = 0; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", - context, - _DRM_LOCKING_CONTEXT(old), - pid); + DRM_ERROR("%d freed heavyweight lock held by %d\n", + context, _DRM_LOCKING_CONTEXT(old)); return 1; } DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); @@ -224,8 +219,6 @@ int DRM(notifier)(void *priv) { drm_sigdata_t *s = (drm_sigdata_t *)priv; unsigned int old, new; - char failed; - /* Allow signal delivery if lock isn't held */ if (!_DRM_LOCK_IS_HELD(s->lock->lock) @@ -236,8 +229,8 @@ int DRM(notifier)(void *priv) do { old = s->lock->lock; new = old | _DRM_LOCK_CONT; - _DRM_CAS(&s->lock->lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(&s->lock->lock, old, new)); + return 0; } diff --git a/bsd/drm_memory.h b/bsd/drm_memory.h index f7dc547a..0df7ee72 100644 --- a/bsd/drm_memory.h +++ b/bsd/drm_memory.h @@ -27,13 +27,15 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_memory.h,v 1.7 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) #define malloctype DRM(M_DRM) -/* The macros confliced in the MALLOC_DEFINE */ +/* The macros conflicted in the MALLOC_DEFINE */ MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures"); @@ -59,7 +61,6 @@ static drm_mem_stats_t DRM(mem_stats)[] = { [DRM_MEM_MAGIC] = { "magic" }, [DRM_MEM_IOCTLS] = { "ioctltab" }, [DRM_MEM_MAPS] = { "maplist" }, - [DRM_MEM_VMAS] = { "vmalist" }, [DRM_MEM_BUFS] = { "buflist" }, [DRM_MEM_SEGS] = { "seglist" }, [DRM_MEM_PAGES] = { "pagelist" }, @@ -81,6 +82,10 @@ void DRM(mem_init)(void) { drm_mem_stats_t *mem; +#ifdef __NetBSD__ + malloc_type_attach(DRM(M_DRM)); +#endif + DRM_SPININIT(DRM(mem_lock), "drm memory"); for (mem = DRM(mem_stats); mem->name; ++mem) { @@ -95,9 +100,16 @@ void DRM(mem_init)(void) DRM(ram_used) = 0; } +void DRM(mem_uninit)(void) +{ + DRM_SPINUNINIT(DRM(mem_lock)); +} + #ifdef __FreeBSD__ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ -static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS +static int +DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1, + int arg2, struct sysctl_req *req) { drm_mem_stats_t *pt; char buf[128]; @@ -112,7 +124,7 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n", "locked", 0, 0, 0, DRM(ram_used)); DRM_SYSCTL_PRINT("\n"); - for (pt = DRM(mem_stats); pt->name; pt++) { + for (pt = stats; pt->name; pt++) { DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", pt->name, pt->succeed_count, @@ -132,13 +144,22 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS { int ret; - + drm_mem_stats_t *stats; + + stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT); + if (stats == NULL) + return ENOMEM; + DRM_SPINLOCK(&DRM(mem_lock)); - ret = DRM(_mem_info)(oidp, arg1, arg2, req); + bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats))); DRM_SPINUNLOCK(&DRM(mem_lock)); + + ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req); + + free(stats, DRM(M_DRM)); return ret; } -#endif +#endif /* __FreeBSD__ */ void *DRM(alloc)(size_t size, int area) { @@ -149,11 +170,7 @@ void *DRM(alloc)(size_t size, int area) return NULL; } -#ifdef __FreeBSD__ if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) { -#elif defined(__NetBSD__) - if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) { -#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].fail_count; DRM_SPINUNLOCK(&DRM(mem_lock)); @@ -203,13 +220,10 @@ void DRM(free)(void *pt, size_t size, int area) int alloc_count; int free_count; - if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); + if (!pt) + DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); else -#ifdef __FreeBSD__ - free(pt, DRM(M_DRM)); -#elif defined(__NetBSD__) - free(pt, M_DEVBUF); -#endif + free(pt, DRM(M_DRM)); DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[area].bytes_freed += size; free_count = ++DRM(mem_stats)[area].free_count; @@ -221,25 +235,36 @@ void DRM(free)(void *pt, size_t size, int area) } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map ) { void *pt; - if (!size) { + if (!map->size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, - "Mapping 0 bytes at 0x%08lx\n", offset); + "Mapping 0 bytes at 0x%08lx\n", map->offset); return NULL; } +#ifdef __NetBSD__ + map->iot = dev->pa.pa_memt; +#endif - if (!(pt = pmap_mapdev(offset, size))) { +#ifdef __FreeBSD__ + if (!(pt = pmap_mapdev(map->offset, map->size))) { +#elif defined(__NetBSD__) + if (bus_space_map(map->iot, map->offset, map->size, + BUS_SPACE_MAP_LINEAR, &map->ioh)) { +#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } +#ifdef __NetBSD__ + pt = bus_space_vaddr(map->iot, map->ioh); +#endif DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; - DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size; DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } @@ -271,19 +296,23 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) } #endif -void DRM(ioremapfree)(void *pt, unsigned long size) +void DRM(ioremapfree)(drm_local_map_t *map) { int alloc_count; int free_count; - if (!pt) + if (map->handle == NULL) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); else - pmap_unmapdev((vm_offset_t) pt, size); +#ifdef __FreeBSD__ + pmap_unmapdev((vm_offset_t) map->handle, map->size); +#elif defined(__NetBSD__) + bus_space_unmap(map->iot, map->ioh, map->size); +#endif DRM_SPINLOCK(&DRM(mem_lock)); - DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; + DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size; free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM_SPINUNLOCK(&DRM(mem_lock)); diff --git a/bsd/drm_os_freebsd.h b/bsd/drm_os_freebsd.h index 1a3feb6e..30a6e362 100644 --- a/bsd/drm_os_freebsd.h +++ b/bsd/drm_os_freebsd.h @@ -1,3 +1,6 @@ +/* + * $FreeBSD: src/sys/dev/drm/drm_os_freebsd.h,v 1.8 2003/03/09 02:08:28 anholt Exp $ + */ #include <sys/param.h> #include <sys/queue.h> #include <sys/malloc.h> @@ -45,7 +48,11 @@ #define __REALLY_HAVE_AGP __HAVE_AGP #endif +#ifdef __i386__ #define __REALLY_HAVE_MTRR (__HAVE_MTRR) +#else +#define __REALLY_HAVE_MTRR 0 +#endif #define __REALLY_HAVE_SG (__HAVE_SG) #if __REALLY_HAVE_AGP @@ -79,6 +86,7 @@ #define DRM_STRUCTPROC struct thread #define DRM_SPINTYPE struct mtx #define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF) +#define DRM_SPINUNINIT(l) mtx_destroy(&l) #define DRM_SPINLOCK(l) mtx_lock(l) #define DRM_SPINUNLOCK(u) mtx_unlock(u); #define DRM_CURRENTPID curthread->td_proc->p_pid @@ -87,12 +95,17 @@ #define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock #define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPINUNINIT(l) #define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, DRM_CURPROC) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, DRM_CURPROC) #define DRM_SUSER(p) suser(p) @@ -100,12 +113,20 @@ #define DRM_IRQ_ARGS void *arg #define DRM_DEVICE drm_device_t *dev = kdev->si_drv1 #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) + +/* Read/write from bus space, with byteswapping to le if necessary */ +#define DRM_READ8(map, offset) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) +#define DRM_READ32(map, offset) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE8(map, offset, val) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val +#define DRM_WRITE32(map, offset, val) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val +/* +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) +*/ #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_ERR(v) v @@ -116,6 +137,16 @@ return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -130,7 +161,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -166,7 +197,7 @@ while (!condition) { \ copyin(user, kern, size) /* Macros for userspace access with checking readability once */ /* FIXME: can't find equivalent functionality for nocheck yet. - * It's be slower than linux, but should be correct. + * It'll be slower than linux, but should be correct. */ #define DRM_VERIFYAREA_READ( uaddr, size ) \ (!useracc((caddr_t)uaddr, size, VM_PROT_READ)) @@ -175,20 +206,13 @@ while (!condition) { \ #define DRM_GET_USER_UNCHECKED(val, uaddr) \ ((val) = fuword(uaddr), 0) -/* From machine/bus_at386.h on i386 */ -#define DRM_READMEMORYBARRIER() \ -do { \ - __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \ -} while (0) - -#define DRM_WRITEMEMORYBARRIER() \ -do { \ - __asm __volatile("" : : : "memory"); \ -} while (0) - +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); #define PAGE_ALIGN(addr) round_page(addr) - + #ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */ #define M_WAITOK 0 #endif @@ -206,12 +230,11 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; -#define cpu_to_le32(x) (x) +#define cpu_to_le32(x) (x) /* FIXME */ -typedef u_int32_t dma_addr_t; +typedef unsigned long dma_addr_t; typedef u_int32_t atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; @@ -223,6 +246,23 @@ typedef u_int8_t u8; #define atomic_sub(n, p) atomic_subtract_int(p, n) /* Fake this */ + +#if __FreeBSD_version < 500000 +/* The extra atomic functions from 5.0 haven't been merged to 4.x */ +static __inline int +atomic_cmpset_int(volatile int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} +#endif + static __inline atomic_t test_and_set_bit(int b, volatile void *p) { @@ -284,20 +324,6 @@ find_first_zero_bit(volatile void *p, int max) #endif -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -356,8 +382,6 @@ find_first_zero_bit(volatile void *p, int max) /* drm_drv.h */ extern d_ioctl_t DRM(ioctl); -extern d_ioctl_t DRM(lock); -extern d_ioctl_t DRM(unlock); extern d_open_t DRM(open); extern d_close_t DRM(close); extern d_read_t DRM(read); @@ -369,81 +393,9 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern d_ioctl_t DRM(irq_busid); -extern d_ioctl_t DRM(getunique); -extern d_ioctl_t DRM(setunique); -extern d_ioctl_t DRM(getmap); -extern d_ioctl_t DRM(getclient); -extern d_ioctl_t DRM(getstats); - -/* Context IOCTL support (drm_context.h) */ -extern d_ioctl_t DRM(resctx); -extern d_ioctl_t DRM(addctx); -extern d_ioctl_t DRM(modctx); -extern d_ioctl_t DRM(getctx); -extern d_ioctl_t DRM(switchctx); -extern d_ioctl_t DRM(newctx); -extern d_ioctl_t DRM(rmctx); -extern d_ioctl_t DRM(setsareactx); -extern d_ioctl_t DRM(getsareactx); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern d_ioctl_t DRM(adddraw); -extern d_ioctl_t DRM(rmdraw); - -/* Authentication IOCTL support (drm_auth.h) */ -extern d_ioctl_t DRM(getmagic); -extern d_ioctl_t DRM(authmagic); - -/* Locking IOCTL support (drm_lock.h) */ -extern d_ioctl_t DRM(block); -extern d_ioctl_t DRM(unblock); -extern d_ioctl_t DRM(finish); - -/* Buffer management support (drm_bufs.h) */ -extern d_ioctl_t DRM(addmap); -extern d_ioctl_t DRM(rmmap); -#if __HAVE_DMA -extern d_ioctl_t DRM(addbufs_agp); -extern d_ioctl_t DRM(addbufs_pci); -extern d_ioctl_t DRM(addbufs_sg); -extern d_ioctl_t DRM(addbufs); -extern d_ioctl_t DRM(infobufs); -extern d_ioctl_t DRM(markbufs); -extern d_ioctl_t DRM(freebufs); -extern d_ioctl_t DRM(mapbufs); -#endif - -/* Memory management support (drm_memory.h) */ -extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern d_ioctl_t DRM(control); -#endif -#if __HAVE_VBL_IRQ -extern d_ioctl_t DRM(wait_vblank); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern d_ioctl_t DRM(agp_acquire); -extern d_ioctl_t DRM(agp_release); -extern d_ioctl_t DRM(agp_enable); -extern d_ioctl_t DRM(agp_info); -extern d_ioctl_t DRM(agp_alloc); -extern d_ioctl_t DRM(agp_free); -extern d_ioctl_t DRM(agp_unbind); -extern d_ioctl_t DRM(agp_bind); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern d_ioctl_t DRM(sg_alloc); -extern d_ioctl_t DRM(sg_free); -#endif - -/* SysCtl Support (drm_sysctl.h) */ +/* sysctl support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); + +/* Memory info sysctl (drm_memory.h) */ +extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h index 2082c047..fa158254 100644 --- a/bsd/drm_os_netbsd.h +++ b/bsd/drm_os_netbsd.h @@ -17,6 +17,7 @@ #include <uvm/uvm.h> #include <sys/vnode.h> #include <sys/poll.h> +#include <sys/lkm.h> /* For TIOCSPGRP/TIOCGPGRP */ #include <sys/ttycom.h> @@ -31,11 +32,9 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#include "drmvar.h" - #define __REALLY_HAVE_AGP __HAVE_AGP -#define __REALLY_HAVE_MTRR 0 +#define __REALLY_HAVE_MTRR 1 #define __REALLY_HAVE_SG 0 #if __REALLY_HAVE_AGP @@ -43,8 +42,7 @@ #include <sys/agpio.h> #endif -#define device_t struct device * -extern struct cfdriver DRM(_cd); +#include <opt_drm.h> #if DRM_DEBUG #undef DRM_DEBUG_CODE @@ -52,36 +50,58 @@ extern struct cfdriver DRM(_cd); #endif #undef DRM_DEBUG +#if DRM_LINUX +#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */ +#endif + +typedef drm_device_t *device_t; + +extern struct cfdriver DRM(cd); + #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) #define DRM_DEV_UID 0 #define DRM_DEV_GID 0 -#define CDEV_MAJOR 90 +#define CDEV_MAJOR 34 #define DRM_CURPROC curproc -#define DRM_STRUCTPROC struct proc +#define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock #define DRM_SPININIT(l,name) simple_lock_init(&l) -#define DRM_SPINLOCK(l) simple_lock(l) +#define DRM_SPINUNINIT(l) +#define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINUNLOCK(u) simple_unlock(u); -#define DRM_CURRENTPID curproc->p_pid +#define DRM_CURRENTPID curproc->p_pid -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL) #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending -#define DRM_IRQ_ARGS void *device -#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev)) +#define DRM_IRQ_ARGS void *arg +#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev)) +/* XXX Not sure if this is the 'right' version.. */ +#if __NetBSD_Version__ >= 106140000 +MALLOC_DECLARE(DRM(M_DRM)); +#else +/* XXX Make sure this works */ +extern const int DRM(M_DRM) = M_DEVBUF; +#endif /* __NetBSD_Version__ */ #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) -#define DRM_AGP_FIND_DEVICE() + +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) + +#define DRM_AGP_FIND_DEVICE() agp_find_device(0) #define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ @@ -90,6 +110,16 @@ extern struct cfdriver DRM(_cd); return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -104,7 +134,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -113,7 +143,15 @@ do { \ } \ } while (0) -#define return DRM_ERR(v) return v; +#define DRM_HZ hz + +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +while (!condition) { \ + ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ + if ( ret ) \ + return ret; \ +} + #define DRM_ERR(v) v #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ @@ -124,21 +162,25 @@ do { \ copyout(arg2, arg1, arg3) #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ copyin(arg2, arg1, arg3) +/* Macros for userspace access with checking readability once */ +/* FIXME: can't find equivalent functionality for nocheck yet. + * It'll be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ)) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + ((val) = fuword(uaddr), 0) -#define DRM_READMEMORYBARRIER \ -{ \ - int xchangeDummy; \ - DRM_DEBUG("%s\n", __FUNCTION__); \ - __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \ - __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \ - " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \ - " pop %%eax" : /* no outputs */ : /* no inputs */ ); \ -} while (0); - -#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); -#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup((void *)w) #define DRM_WAKEUP_INT(w) wakeup(w) +#define DRM_INIT_WAITQUEUE( queue ) do {} while (0) #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) @@ -150,30 +192,46 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; +#define cpu_to_le32(x) (x) /* FIXME */ + typedef u_int32_t dma_addr_t; -typedef volatile u_int32_t atomic_t; +typedef volatile long atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; typedef dev_type_ioctl(d_ioctl_t); typedef vaddr_t vm_offset_t; +/* FIXME */ #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_int(p, 1) -#define atomic_dec(p) atomic_subtract_int(p, 1) -#define atomic_add(n, p) atomic_add_int(p, n) -#define atomic_sub(n, p) atomic_subtract_int(p, n) +#define atomic_inc(p) (*(p) += 1) +#define atomic_dec(p) (*(p) -= 1) +#define atomic_add(n, p) (*(p) += (n)) +#define atomic_sub(n, p) (*(p) -= (n)) -/* FIXME: Is NetBSD's kernel non-reentrant? */ +/* FIXME */ #define atomic_add_int(p, v) *(p) += v #define atomic_subtract_int(p, v) *(p) -= v #define atomic_set_int(p, bits) *(p) |= (bits) #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(__volatile__ int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -223,20 +281,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -257,7 +301,7 @@ do { \ #define DRM_DEBUG(fmt, arg...) \ do { \ if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -291,8 +335,6 @@ do { \ /* drm_drv.h */ extern dev_type_ioctl(DRM(ioctl)); -extern dev_type_ioctl(DRM(lock)); -extern dev_type_ioctl(DRM(unlock)); extern dev_type_open(DRM(open)); extern dev_type_close(DRM(close)); extern dev_type_read(DRM(read)); @@ -304,75 +346,5 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern dev_type_ioctl(DRM(irq_busid)); -extern dev_type_ioctl(DRM(getunique)); -extern dev_type_ioctl(DRM(setunique)); -extern dev_type_ioctl(DRM(getmap)); -extern dev_type_ioctl(DRM(getclient)); -extern dev_type_ioctl(DRM(getstats)); - -/* Context IOCTL support (drm_context.h) */ -extern dev_type_ioctl(DRM(resctx)); -extern dev_type_ioctl(DRM(addctx)); -extern dev_type_ioctl(DRM(modctx)); -extern dev_type_ioctl(DRM(getctx)); -extern dev_type_ioctl(DRM(switchctx)); -extern dev_type_ioctl(DRM(newctx)); -extern dev_type_ioctl(DRM(rmctx)); -extern dev_type_ioctl(DRM(setsareactx)); -extern dev_type_ioctl(DRM(getsareactx)); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern dev_type_ioctl(DRM(adddraw)); -extern dev_type_ioctl(DRM(rmdraw)); - -/* Authentication IOCTL support (drm_auth.h) */ -extern dev_type_ioctl(DRM(getmagic)); -extern dev_type_ioctl(DRM(authmagic)); - -/* Locking IOCTL support (drm_lock.h) */ -extern dev_type_ioctl(DRM(block)); -extern dev_type_ioctl(DRM(unblock)); -extern dev_type_ioctl(DRM(finish)); - -/* Buffer management support (drm_bufs.h) */ -extern dev_type_ioctl(DRM(addmap)); -extern dev_type_ioctl(DRM(rmmap)); -#if __HAVE_DMA -extern dev_type_ioctl(DRM(addbufs_agp)); -extern dev_type_ioctl(DRM(addbufs_pci)); -extern dev_type_ioctl(DRM(addbufs_sg)); -extern dev_type_ioctl(DRM(addbufs)); -extern dev_type_ioctl(DRM(infobufs)); -extern dev_type_ioctl(DRM(markbufs)); -extern dev_type_ioctl(DRM(freebufs)); -extern dev_type_ioctl(DRM(mapbufs)); -#endif - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern dev_type_ioctl(DRM(control)); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern dev_type_ioctl(DRM(agp_acquire)); -extern dev_type_ioctl(DRM(agp_release)); -extern dev_type_ioctl(DRM(agp_enable)); -extern dev_type_ioctl(DRM(agp_info)); -extern dev_type_ioctl(DRM(agp_alloc)); -extern dev_type_ioctl(DRM(agp_free)); -extern dev_type_ioctl(DRM(agp_unbind)); -extern dev_type_ioctl(DRM(agp_bind)); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern dev_type_ioctl(DRM(sg_alloc)); -extern dev_type_ioctl(DRM(sg_free)); -#endif - -/* SysCtl Support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); diff --git a/bsd/drm_scatter.h b/bsd/drm_scatter.h index c16b7c05..e57e5e5b 100644 --- a/bsd/drm_scatter.h +++ b/bsd/drm_scatter.h @@ -25,6 +25,8 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/drm_scatter.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ #include "drmP.h" @@ -40,9 +42,6 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry ) DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -73,21 +72,10 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages ); entry->pages = pages; - entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); - if ( !entry->pagelist ) { - DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return ENOMEM; - } - - bzero(entry->pagelist, pages * sizeof(*entry->pagelist)); entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); if ( !entry->busaddr ) { - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -100,9 +88,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); - DRM(free)( entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES ); DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); @@ -124,46 +109,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS ) dev->sg = entry; -#if DEBUG_SCATTER - /* Verify that each page points to its virtual address, and vice - * versa. - */ - { - int error = 0; - - for ( i = 0 ; i < pages ; i++ ) { - unsigned long *tmp; - - tmp = page_address( entry->pagelist[i] ); - for ( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - *tmp = 0xcafebabe; - } - tmp = (unsigned long *)((u8 *)entry->virtual + - (PAGE_SIZE * i)); - for( j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++ ) { - if ( *tmp != 0xcafebabe && error == 0 ) { - error = 1; - DRM_ERROR( "Scatter allocation error, " - "pagelist does not match " - "virtual mapping\n" ); - } - } - tmp = page_address( entry->pagelist[i] ); - for(j = 0 ; - j < PAGE_SIZE / sizeof(unsigned long) ; - j++, tmp++) { - *tmp = 0; - } - } - if (error == 0) - DRM_ERROR( "Scatter allocation matches pagelist\n" ); - } -#endif - return 0; DRM(sg_cleanup)( entry ); diff --git a/bsd/drm_sysctl.h b/bsd/drm_sysctl.h index 2ec7ff95..2ca187d8 100644 --- a/bsd/drm_sysctl.h +++ b/bsd/drm_sysctl.h @@ -1,5 +1,5 @@ /* - * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ + * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.2 2003/03/09 02:08:28 anholt Exp $ */ #ifdef __FreeBSD__ @@ -11,9 +11,6 @@ static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(queues_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS; -#if DRM_DEBUG_CODExx -static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS; -#endif #if DRM_DMA_HISTOGRAM static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS; #endif @@ -28,9 +25,6 @@ struct DRM(sysctl_list) { { "clients", DRM(clients_info) }, { "queues", DRM(queues_info) }, { "bufs", DRM(bufs_info) }, -#if DRM_DEBUG_CODExx - { "vma", DRM(vma_info) }, -#endif #if DRM_DMA_HISTOGRAM { "histo", drm_histo_info) }, #endif @@ -125,7 +119,7 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS { drm_device_t *dev = arg1; - drm_map_t *map; + drm_local_map_t *map; drm_map_list_entry_t *listentry; const char *types[] = { "FB", "REG", "SHM" }; const char *type; @@ -203,7 +197,7 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS q->read_queue ? 'r':'-', q->write_queue ? 'w':'-', q->flush_queue ? 'f':'-', - DRM_BUFCOUNT(&q->waitlist), + (int)DRM_BUFCOUNT(&q->waitlist), atomic_read(&q->total_flushed), atomic_read(&q->total_queued), atomic_read(&q->total_locks)); @@ -309,92 +303,6 @@ static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS return ret; } -#if DRM_DEBUG_CODExx - -static int DRM(_vma_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - drm_vma_entry_t *pt; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - unsigned long i; - struct vm_area_struct *vma; - unsigned long address; -#if defined(__i386__) - unsigned int pgprot; -#endif - char buf[128]; - int error; - - DRM_SYSCTL_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", - atomic_read(&dev->vma_count), - high_memory, virt_to_phys(high_memory)); - for (pt = dev->vmalist; pt; pt = pt->next) { - if (!(vma = pt->vma)) continue; - DRM_SYSCTL_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", - pt->pid, - vma->vm_start, - vma->vm_end, - vma->vm_flags & VM_READ ? 'r' : '-', - vma->vm_flags & VM_WRITE ? 'w' : '-', - vma->vm_flags & VM_EXEC ? 'x' : '-', - vma->vm_flags & VM_MAYSHARE ? 's' : 'p', - vma->vm_flags & VM_LOCKED ? 'l' : '-', - vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_offset ); -#if defined(__i386__) - pgprot = pgprot_val(vma->vm_page_prot); - DRM_SYSCTL_PRINT(" %c%c%c%c%c%c%c%c%c", - pgprot & _PAGE_PRESENT ? 'p' : '-', - pgprot & _PAGE_RW ? 'w' : 'r', - pgprot & _PAGE_USER ? 'u' : 's', - pgprot & _PAGE_PWT ? 't' : 'b', - pgprot & _PAGE_PCD ? 'u' : 'c', - pgprot & _PAGE_ACCESSED ? 'a' : '-', - pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_4M ? 'm' : 'k', - pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); -#endif - DRM_SYSCTL_PRINT("\n"); - for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) { - pgd = pgd_offset(vma->vm_mm, i); - pmd = pmd_offset(pgd, i); - pte = pte_offset(pmd, i); - if (pte_present(*pte)) { - address = __pa(pte_page(*pte)) - + (i & (PAGE_SIZE-1)); - DRM_SYSCTL_PRINT(" 0x%08lx -> 0x%08lx" - " %c%c%c%c%c\n", - i, - address, - pte_read(*pte) ? 'r' : '-', - pte_write(*pte) ? 'w' : '-', - pte_exec(*pte) ? 'x' : '-', - pte_dirty(*pte) ? 'd' : '-', - pte_young(*pte) ? 'a' : '-' ); - } else { - DRM_SYSCTL_PRINT(" 0x%08lx\n", i); - } - } - } - - SYSCTL_OUT(req, "", 1); - return 0; -} - -static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS -{ - drm_device_t *dev = arg1; - int ret; - - DRM_LOCK; - ret = DRM(_vma_info)(oidp, arg1, arg2, req); - DRM_UNLOCK; - return ret; -} -#endif - #if DRM_DMA_HISTOGRAM static int DRM(_histo_info)DRM_SYSCTL_HANDLER_ARGS diff --git a/bsd/drm_vm.h b/bsd/drm_vm.h index 70a5b0e6..1ce0efab 100644 --- a/bsd/drm_vm.h +++ b/bsd/drm_vm.h @@ -1,5 +1,11 @@ +/* + * $FreeBSD: src/sys/dev/drm/drm_vm.h,v 1.4 2003/03/09 02:08:28 anholt Exp $ + */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 +static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr, + int prot) +#elif defined(__FreeBSD__) static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) #elif defined(__NetBSD__) static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) @@ -17,17 +23,25 @@ static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) physical = dma->pagelist[page]; DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = physical; + return 0; +#else return atop(physical); +#endif } -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 +int DRM(mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr, + int prot) +#elif defined(__FreeBSD__) int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) #elif defined(__NetBSD__) paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) #endif { DRM_DEVICE; - drm_map_t *map = NULL; + drm_local_map_t *map = NULL; drm_map_list_entry_t *listentry=NULL; drm_file_t *priv; @@ -44,7 +58,11 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + return DRM(dma_mmap)(kdev, offset, paddr, prot); +#else return DRM(dma_mmap)(kdev, offset, prot); +#endif /* A sequential search of a linked list is fine here because: 1) there will only be @@ -73,10 +91,20 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: case _DRM_AGP: +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = offset; + return 0; +#else return atop(offset); +#endif case _DRM_SCATTER_GATHER: case _DRM_SHM: +#if defined(__FreeBSD__) && __FreeBSD_version >= 500102 + *paddr = vtophys(offset); + return 0; +#else return atop(vtophys(offset)); +#endif default: return -1; /* This should never happen. */ } diff --git a/bsd/gamma.h b/bsd/gamma.h deleted file mode 100644 index 161dc048..00000000 --- a/bsd/gamma.h +++ /dev/null @@ -1,71 +0,0 @@ -/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- - * Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - */ - -#ifndef __GAMMA_H__ -#define __GAMMA_H__ - -/* This remains constant for all DRM template files. - */ -#define DRM(x) gamma_##x - -/* General customization: - */ -#define __HAVE_MTRR 1 - -/* DMA customization: - */ -#define __HAVE_DMA 1 -#define __HAVE_OLD_DMA 1 -#define __HAVE_PCI_DMA 1 - -#define __HAVE_MULTIPLE_DMA_QUEUES 1 -#define __HAVE_DMA_WAITQUEUE 1 - -#define __HAVE_DMA_WAITLIST 1 -#define __HAVE_DMA_FREELIST 1 - -#define __HAVE_DMA_FLUSH 1 -#define __HAVE_DMA_SCHEDULE 1 - -#define __HAVE_DMA_READY 1 -#define DRIVER_DMA_READY() do { \ - gamma_dma_ready(dev); \ -} while (0) - -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - /* FIXME ! */ \ - gamma_dma_quiescent_dual(dev); \ - return 0; \ -} while (0) - -#define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 - -#endif /* __GAMMA_H__ */ diff --git a/bsd/gamma/Makefile b/bsd/gamma/Makefile deleted file mode 100644 index d416e463..00000000 --- a/bsd/gamma/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/.. -KMOD = gamma -NOMAN= YES -SRCS = gamma_drv.c gamma_dma.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm.h -CFLAGS += ${DEBUG_FLAGS} -I. -I.. - -.if defined(DRM_DEBUG) -DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" -.endif - -.if !defined(DRM_NOLINUX) -DRM_LINUX_OPT= "\#define DRM_LINUX 1" -.endif - -opt_drm.h: - touch opt_drm.h - echo $(DRM_DEBUG_OPT) >> opt_drm.h - echo $(DRM_LINUX_OPT) >> opt_drm.h - -.include <bsd.kmod.mk> diff --git a/bsd/gamma_dma.c b/bsd/gamma_dma.c deleted file mode 100644 index 714554d2..00000000 --- a/bsd/gamma_dma.c +++ /dev/null @@ -1,611 +0,0 @@ -/* gamma_dma.c -- DMA support for GMX 2000 -*- linux-c -*- - * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * - */ - - - -#include "gamma.h" -#include "drmP.h" -#include "drm.h" -#include "gamma_drm.h" -#include "gamma_drv.h" - - -static __inline__ void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, - unsigned long length) -{ - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - GAMMA_WRITE(GAMMA_DMAADDRESS, DRM_VTOPHYS((void *)address)); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) - ; - GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); -} - -void gamma_dma_quiescent_single(drm_device_t *dev) -{ - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; - - GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); - GAMMA_WRITE(GAMMA_SYNC, 0); - - do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; - } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); -} - -void gamma_dma_quiescent_dual(drm_device_t *dev) -{ - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; - - GAMMA_WRITE(GAMMA_BROADCASTMASK, 3); - - GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); - GAMMA_WRITE(GAMMA_SYNC, 0); - - /* Read from first MX */ - do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; - } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - - /* Read from second MX */ - do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) - ; - } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG); -} - -void gamma_dma_ready(drm_device_t *dev) -{ - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; -} - -static __inline__ int gamma_dma_is_ready(drm_device_t *dev) -{ - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - return !GAMMA_READ(GAMMA_DMACOUNT); -} - -void gamma_dma_service( DRM_IRQ_ARGS) -{ - drm_device_t *dev = (drm_device_t *)arg; - drm_device_dma_t *dma = dev->dma; - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - - atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ - GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); - GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); - if (gamma_dma_is_ready(dev)) { - /* Free previous buffer */ - if (test_and_set_bit(0, &dev->dma_flag)) return; - if (dma->this_buffer) { - gamma_free_buffer(dev, dma->this_buffer); - dma->this_buffer = NULL; - } - clear_bit(0, &dev->dma_flag); - - taskqueue_enqueue(taskqueue_swi, &dev->task); - } -} - -/* Only called by gamma_dma_schedule. */ -static int gamma_do_dma(drm_device_t *dev, int locked) -{ - unsigned long address; - unsigned long length; - drm_buf_t *buf; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t dma_start, dma_stop; -#endif - - if (test_and_set_bit(0, &dev->dma_flag)) return DRM_ERR( EBUSY ); - -#if DRM_DMA_HISTOGRAM - dma_start = get_cycles(); -#endif - - if (!dma->next_buffer) { - DRM_ERROR("No next_buffer\n"); - clear_bit(0, &dev->dma_flag); - return DRM_ERR( EINVAL ); - } - - buf = dma->next_buffer; - address = (unsigned long)buf->address; - length = buf->used; - - DRM_DEBUG("context %d, buffer %d (%ld bytes)\n", - buf->context, buf->idx, length); - - if (buf->list == DRM_LIST_RECLAIM) { - gamma_clear_next_buffer(dev); - gamma_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return DRM_ERR( EINVAL ); - } - - if (!length) { - DRM_ERROR("0 length buffer\n"); - gamma_clear_next_buffer(dev); - gamma_free_buffer(dev, buf); - clear_bit(0, &dev->dma_flag); - return 0; - } - - if (!gamma_dma_is_ready(dev)) { - clear_bit(0, &dev->dma_flag); - return DRM_ERR( EBUSY ); - } - - if (buf->while_locked) { - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Dispatching buffer %d from pid %d" - " \"while locked\", but no lock held\n", - buf->idx, buf->pid); - } - } else { - if (!locked && !gamma_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - clear_bit(0, &dev->dma_flag); - return DRM_ERR( EBUSY ); - } - } - - if (dev->last_context != buf->context - && !(dev->queuelist[buf->context]->flags - & _DRM_CONTEXT_PRESERVED)) { - /* PRE: dev->last_context != buf->context */ - if (DRM(context_switch)(dev, dev->last_context, - buf->context)) { - DRM(clear_next_buffer)(dev); - DRM(free_buffer)(dev, buf); - } - retcode = EBUSY; - goto cleanup; - - /* POST: we will wait for the context - switch and will dispatch on a later call - when dev->last_context == buf->context. - NOTE WE HOLD THE LOCK THROUGHOUT THIS - TIME! */ - } - - gamma_clear_next_buffer(dev); - buf->pending = 1; - buf->waiting = 0; - buf->list = DRM_LIST_PEND; -#if DRM_DMA_HISTOGRAM - buf->time_dispatched = get_cycles(); -#endif - - gamma_dma_dispatch(dev, address, length); - gamma_free_buffer(dev, dma->this_buffer); - dma->this_buffer = buf; - - atomic_inc(&dev->counts[7]); /* _DRM_STAT_DMA */ - atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */ - - if (!buf->while_locked && !dev->context_flag && !locked) { - if (gamma_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } - } -cleanup: - - clear_bit(0, &dev->dma_flag); - -#if DRM_DMA_HISTOGRAM - dma_stop = get_cycles(); - atomic_inc(&dev->histo.dma[gamma_histogram_slot(dma_stop - dma_start)]); -#endif - - return DRM_ERR( retcode ); -} - -static void gamma_dma_timer_bh(unsigned long dev) -{ - gamma_dma_schedule((drm_device_t *)dev, 0); -} - -void gamma_dma_immediate_bh(DRM_TASKQUEUE_ARGS) -{ - gamma_dma_schedule(arg, 0); -} - -int gamma_dma_schedule(drm_device_t *dev, int locked) -{ - int next; - drm_queue_t *q; - drm_buf_t *buf; - int retcode = 0; - int processed = 0; - int missed; - int expire = 20; - drm_device_dma_t *dma = dev->dma; -#if DRM_DMA_HISTOGRAM - cycles_t schedule_start; -#endif - - if (test_and_set_bit(0, &dev->interrupt_flag)) { - /* Not reentrant */ - atomic_inc(&dev->counts[10]); /* _DRM_STAT_MISSED */ - return DRM_ERR( EBUSY ); - } - missed = atomic_read(&dev->counts[10]); - -#if DRM_DMA_HISTOGRAM - schedule_start = get_cycles(); -#endif - -again: - if (dev->context_flag) { - clear_bit(0, &dev->interrupt_flag); - return DRM_ERR( EBUSY ); - } - if (dma->next_buffer) { - /* Unsent buffer that was previously - selected, but that couldn't be sent - because the lock could not be obtained - or the DMA engine wasn't ready. Try - again. */ - if (!(retcode = gamma_do_dma(dev, locked))) ++processed; - } else { - do { - next = gamma_select_queue(dev, gamma_dma_timer_bh); - if (next >= 0) { - q = dev->queuelist[next]; - buf = gamma_waitlist_get(&q->waitlist); - dma->next_buffer = buf; - dma->next_queue = q; - if (buf && buf->list == DRM_LIST_RECLAIM) { - gamma_clear_next_buffer(dev); - gamma_free_buffer(dev, buf); - } - } - } while (next >= 0 && !dma->next_buffer); - if (dma->next_buffer) { - if (!(retcode = gamma_do_dma(dev, locked))) { - ++processed; - } - } - } - - if (--expire) { - if (missed != atomic_read(&dev->counts[10])) { - if (gamma_dma_is_ready(dev)) goto again; - } - if (processed && gamma_dma_is_ready(dev)) { - processed = 0; - goto again; - } - } - - clear_bit(0, &dev->interrupt_flag); - -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles() - - schedule_start)]); -#endif - return retcode; -} - -static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) -{ - unsigned long address; - unsigned long length; - int must_free = 0; - int retcode = 0; - int i; - int idx; - drm_buf_t *buf; - drm_buf_t *last_buf = NULL; - drm_device_dma_t *dma = dev->dma; - static int never; - - /* Turn off interrupt handling */ - while (test_and_set_bit(0, &dev->interrupt_flag)) { - retcode = tsleep(&never, PZERO|PCATCH, "gamp1", 1); - if (retcode) - return retcode; - } - if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) { - while (!gamma_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - retcode = tsleep(&never, PZERO|PCATCH, "gamp2", 1); - if (retcode) - return retcode; - } - ++must_free; - } - - for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); - continue; - } - buf = dma->buflist[ idx ]; - if (buf->pid != DRM_CURRENTPID) { - DRM_ERROR("Process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid); - retcode = EINVAL; - goto cleanup; - } - if (buf->list != DRM_LIST_NONE) { - DRM_ERROR("Process %d using %d's buffer on list %d\n", - DRM_CURRENTPID, buf->pid, buf->list); - retcode = EINVAL; - goto cleanup; - } - /* This isn't a race condition on - buf->list, since our concern is the - buffer reclaim during the time the - process closes the /dev/drm? handle, so - it can't also be doing DMA. */ - buf->list = DRM_LIST_PRIO; - buf->used = d->send_sizes[i]; - buf->context = d->context; - buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED; - address = (unsigned long)buf->address; - length = buf->used; - if (!length) { - DRM_ERROR("0 length buffer\n"); - } - if (buf->pending) { - DRM_ERROR("Sending pending buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - retcode = EINVAL; - goto cleanup; - } - if (buf->waiting) { - DRM_ERROR("Sending waiting buffer:" - " buffer %d, offset %d\n", - d->send_indices[i], i); - retcode = EINVAL; - goto cleanup; - } - buf->pending = 1; - - if (dev->last_context != buf->context - && !(dev->queuelist[buf->context]->flags - & _DRM_CONTEXT_PRESERVED)) { - /* PRE: dev->last_context != buf->context */ - DRM(context_switch)(dev, dev->last_context, - buf->context); - /* POST: we will wait for the context - switch and will dispatch on a later call - when dev->last_context == buf->context. - NOTE WE HOLD THE LOCK THROUGHOUT THIS - TIME! */ - retcode = tsleep(&dev->context_wait, PZERO|PCATCH, - "gamctx", 0); - if (retcode) - goto cleanup; - if (dev->last_context != buf->context) { - DRM_ERROR("Context mismatch: %d %d\n", - dev->last_context, - buf->context); - } - } - -#if DRM_DMA_HISTOGRAM - buf->time_queued = get_cycles(); - buf->time_dispatched = buf->time_queued; -#endif - gamma_dma_dispatch(dev, address, length); - atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */ - atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */ - - if (last_buf) { - gamma_free_buffer(dev, last_buf); - } - last_buf = buf; - } - - -cleanup: - if (last_buf) { - gamma_dma_ready(dev); - gamma_free_buffer(dev, last_buf); - } - - if (must_free && !dev->context_flag) { - if (gamma_lock_free(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("\n"); - } - } - clear_bit(0, &dev->interrupt_flag); - return DRM_ERR( retcode ); -} - -static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) -{ - drm_buf_t *last_buf = NULL; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; - - if (d->flags & _DRM_DMA_BLOCK) { - last_buf = dma->buflist[d->send_indices[d->send_count-1]]; - atomic_inc(&last_buf->dma_wait); - } - - if ((retcode = gamma_dma_enqueue(dev, d))) { - if (d->flags & _DRM_DMA_BLOCK) - atomic_dec(&last_buf->dma_wait); - return retcode; - } - - gamma_dma_schedule(dev, 0); - - if (d->flags & _DRM_DMA_BLOCK) { - DRM_DEBUG("%d waiting\n", DRM_CURRENTPID); - for (;;) { - retcode = tsleep(&last_buf->dma_wait, PZERO|PCATCH, - "gamdw", 0); - if (!last_buf->waiting - && !last_buf->pending) - break; /* finished */ - if (retcode) - break; - } - atomic_dec(&last_buf->dma_wait); - DRM_DEBUG("%d running\n", DRM_CURRENTPID); - if (!retcode - || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) { - if (!last_buf->dma_wait) { - gamma_free_buffer(dev, last_buf); - } - } - if (retcode) { - DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n", - d->context, - last_buf->waiting, - last_buf->pending, - DRM_WAITCOUNT(dev, d->context), - last_buf->idx, - last_buf->list, - last_buf->pid, - DRM_CURRENTPID); - } - } - return DRM_ERR( retcode ); -} - -int gamma_dma( DRM_IOCTL_ARGS ) -{ - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_dma_t d; - - DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t *) data, sizeof(d)); - - if (d.send_count < 0 || d.send_count > dma->buf_count) { - DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n", - DRM_CURRENTPID, d.send_count, dma->buf_count); - return DRM_ERR( EINVAL ); - } - - if (d.request_count < 0 || d.request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - return DRM_ERR( EINVAL ); - } - - if (d.send_count) { - if (d.flags & _DRM_DMA_PRIORITY) - retcode = gamma_dma_priority(dev, &d); - else - retcode = gamma_dma_send_buffers(dev, &d); - } - - d.granted_count = 0; - - if (!retcode && d.request_count) { - retcode = gamma_dma_get_buffers(dev, &d); - } - - DRM_DEBUG("%d returning, granted = %d\n", - DRM_CURRENTPID, d.granted_count); - DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d)); - - return retcode; -} - -void DRM(driver_irq_preinstall)(drm_device_t *dev) { - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; -#if 1 - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); -#else - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE ); - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); -#endif -} - -void DRM(driver_irq_postinstall)(drm_device_t *dev) { - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; -#if 1 - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); -#else - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); -#endif -} - -void DRM(driver_irq_uninstall)( drm_device_t *dev ) { - drm_gamma_private_t *dev_priv = - (drm_gamma_private_t *)dev->dev_private; - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); -} diff --git a/bsd/gamma_drm.h b/bsd/gamma_drm.h deleted file mode 100644 index 0d58b07b..00000000 --- a/bsd/gamma_drm.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _GAMMA_DRM_H_ -#define _GAMMA_DRM_H_ - -typedef struct _drm_gamma_tex_region { - unsigned char next, prev; /* indices to form a circular LRU */ - unsigned char in_use; /* owned by a client, or free? */ - int age; /* tracked by clients to update local LRU's */ -} drm_gamma_tex_region_t; - -typedef struct { - unsigned int GDeltaMode; - unsigned int GDepthMode; - unsigned int GGeometryMode; - unsigned int GTransformMode; -} drm_gamma_context_regs_t; - -typedef struct _drm_gamma_sarea { - drm_gamma_context_regs_t context_state; - - unsigned int dirty; - - - /* Maintain an LRU of contiguous regions of texture space. If - * you think you own a region of texture memory, and it has an - * age different to the one you set, then you are mistaken and - * it has been stolen by another client. If global texAge - * hasn't changed, there is no need to walk the list. - * - * These regions can be used as a proxy for the fine-grained - * texture information of other clients - by maintaining them - * in the same lru which is used to age their own textures, - * clients have an approximate lru for the whole of global - * texture space, and can make informed decisions as to which - * areas to kick out. There is no need to choose whether to - * kick out your own texture or someone else's - simply eject - * them all in LRU order. - */ - -#define GAMMA_NR_TEX_REGIONS 64 - drm_gamma_tex_region_t texList[GAMMA_NR_TEX_REGIONS+1]; - /* Last elt is sentinal */ - int texAge; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int last_quiescent; /* */ - int ctxOwner; /* last context to upload state */ - - int vertex_prim; -} drm_gamma_sarea_t; - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (xf86drmGamma.h) - */ - -/* Gamma specific ioctls - * The device specific ioctl range is 0x40 to 0x79. - */ -#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) -#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t) - -typedef struct drm_gamma_copy { - unsigned int DMAOutputAddress; - unsigned int DMAOutputCount; - unsigned int DMAReadGLINTSource; - unsigned int DMARectangleWriteAddress; - unsigned int DMARectangleWriteLinePitch; - unsigned int DMARectangleWrite; - unsigned int DMARectangleReadAddress; - unsigned int DMARectangleReadLinePitch; - unsigned int DMARectangleRead; - unsigned int DMARectangleReadTarget; -} drm_gamma_copy_t; - -typedef struct drm_gamma_init { - enum { - GAMMA_INIT_DMA = 0x01, - GAMMA_CLEANUP_DMA = 0x02 - } func; - - int sarea_priv_offset; - int pcimode; - unsigned int mmio0; - unsigned int mmio1; - unsigned int mmio2; - unsigned int mmio3; - unsigned int buffers_offset; -} drm_gamma_init_t; - -#endif /* _GAMMA_DRM_H_ */ diff --git a/bsd/gamma_drv.c b/bsd/gamma_drv.c deleted file mode 100644 index 153420fb..00000000 --- a/bsd/gamma_drv.c +++ /dev/null @@ -1,86 +0,0 @@ -/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- - * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * Gareth Hughes <gareth@valinux.com> - */ - -#include <sys/types.h> -#include "gamma.h" -#include "drmP.h" -#include "drm.h" -#include "gamma_drm.h" -#include "gamma_drv.h" - -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "gamma" -#define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010216" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } - -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to anholt@teleport.com inaccuracies or if a chip you have works that is marked unsupported here. - */ -drm_chipinfo_t DRM(devicelist)[] = { - {0x3d3d, 0x0008, 1, "3DLabs Gamma"}, - {0, 0, 0, NULL} -}; - - -#define __HAVE_COUNTERS 5 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_DMA -#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL -#define __HAVE_COUNTER10 _DRM_STAT_MISSED - - -#include "drm_auth.h" -#include "drm_bufs.h" -#include "drm_context.h" -#include "drm_dma.h" -#include "drm_drawable.h" -#include "drm_drv.h" - - -#include "drm_fops.h" -#include "drm_init.h" -#include "drm_ioctl.h" -#include "drm_lists.h" -#include "drm_lock.h" -#include "drm_memory.h" -#include "drm_vm.h" -#include "drm_sysctl.h" - -DRIVER_MODULE(gamma, pci, gamma_driver, gamma_devclass, 0, 0); diff --git a/bsd/gamma_drv.h b/bsd/gamma_drv.h deleted file mode 100644 index 69250b9e..00000000 --- a/bsd/gamma_drv.h +++ /dev/null @@ -1,104 +0,0 @@ -/* gamma_drv.h -- Private header for 3dlabs GMX 2000 driver -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * - */ - -#ifndef _GAMMA_DRV_H_ -#define _GAMMA_DRV_H_ - - -typedef struct drm_gamma_private { - drm_map_t *buffers; - drm_map_t *mmio0; - drm_map_t *mmio1; - drm_map_t *mmio2; - drm_map_t *mmio3; -} drm_gamma_private_t; - -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return DRM_ERR( EINVAL ); \ - } \ -} while (0) - - -extern void gamma_dma_ready(drm_device_t *dev); -extern void gamma_dma_quiescent_single(drm_device_t *dev); -extern void gamma_dma_quiescent_dual(drm_device_t *dev); - - /* gamma_dma.c */ -extern int gamma_dma_schedule(drm_device_t *dev, int locked); -extern int gamma_dma( DRM_IOCTL_ARGS ); -extern int gamma_find_devices(void); -extern int gamma_found(void); - - -#define GAMMA_OFF(reg) \ - ((reg < 0x1000) \ - ? reg \ - : ((reg < 0x10000) \ - ? (reg - 0x1000) \ - : ((reg < 0x11000) \ - ? (reg - 0x10000) \ - : (reg - 0x11000)))) - -#define GAMMA_BASE(reg) ((unsigned long) \ - ((reg < 0x1000) ? dev_priv->mmio0->handle : \ - ((reg < 0x10000) ? dev_priv->mmio1->handle : \ - ((reg < 0x11000) ? dev_priv->mmio2->handle : \ - dev_priv->mmio3->handle)))) - -#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) -#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) -#define GAMMA_READ(reg) GAMMA_DEREF(reg) -#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0) - -#define GAMMA_BROADCASTMASK 0x9378 -#define GAMMA_COMMANDINTENABLE 0x0c48 -#define GAMMA_DMAADDRESS 0x0028 -#define GAMMA_DMACOUNT 0x0030 -#define GAMMA_FILTERMODE 0x8c00 -#define GAMMA_GCOMMANDINTFLAGS 0x0c50 -#define GAMMA_GCOMMANDMODE 0x0c40 -#define GAMMA_GCOMMANDSTATUS 0x0c60 -#define GAMMA_GDELAYTIMER 0x0c38 -#define GAMMA_GDMACONTROL 0x0060 -#define GAMMA_GINTENABLE 0x0808 -#define GAMMA_GINTFLAGS 0x0810 -#define GAMMA_INFIFOSPACE 0x0018 -#define GAMMA_OUTFIFOWORDS 0x0020 -#define GAMMA_OUTPUTFIFO 0x2000 -#define GAMMA_SYNC 0x8c40 -#define GAMMA_SYNC_TAG 0x0188 - -#endif diff --git a/bsd/mga_drv.c b/bsd/mga_drv.c index 8b69b41b..de0387f7 100644 --- a/bsd/mga_drv.c +++ b/bsd/mga_drv.c @@ -27,10 +27,10 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ -#include <sys/types.h> - #include "mga.h" #include "drmP.h" #include "drm.h" @@ -63,4 +63,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_vm.h" #include "drm_sysctl.h" +#ifdef __FreeBSD__ DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(mga, DV_TTY, NULL); +#endif diff --git a/bsd/r128_drv.c b/bsd/r128_drv.c index 1a8046fb..28a2c85e 100644 --- a/bsd/r128_drv.c +++ b/bsd/r128_drv.c @@ -27,11 +27,10 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $ */ - -#include <sys/types.h> - #include "r128.h" #include "drmP.h" #include "drm.h" @@ -83,4 +82,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_scatter.h" #endif +#ifdef __FreeBSD__ DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(r128, DV_TTY, NULL); +#endif /* __FreeBSD__ */ diff --git a/bsd/radeon_drv.c b/bsd/radeon_drv.c index d02ab959..2e7c5d66 100644 --- a/bsd/radeon_drv.c +++ b/bsd/radeon_drv.c @@ -25,10 +25,10 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $ */ -#include <sys/types.h> - #include "radeon.h" #include "drmP.h" #include "drm.h" @@ -38,21 +38,42 @@ #include "ati_pcigart.h" #endif -/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h - * Please report to eta@lclark.edu inaccuracies or if a chip you have works that is marked unsupported here. - */ drm_chipinfo_t DRM(devicelist)[] = { - {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"}, - {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"}, - {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"}, - {0x1002, 0x5144, 1, "ATI Radeon QD (AGP)"}, - {0x1002, 0x5145, 1, "ATI Radeon QE (AGP)"}, - {0x1002, 0x5146, 1, "ATI Radeon QF (AGP)"}, - {0x1002, 0x5147, 1, "ATI Radeon QG (AGP)"}, - {0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"}, - {0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"}, - {0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"}, - {0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"}, + {0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"}, + {0x1002, 0x4336, 1, "ATI Radeon Mobility U1"}, + {0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"}, + {0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"}, + {0x1002, 0x4966, 1, "ATI Radeon If R250 9000"}, + {0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"}, + {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"}, + {0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"}, + {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"}, + {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"}, + {0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"}, + {0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"}, + {0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"}, + {0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"}, + {0x1002, 0x5144, 1, "ATI Radeon QD R100"}, + {0x1002, 0x5145, 1, "ATI Radeon QE R100"}, + {0x1002, 0x5146, 1, "ATI Radeon QF R100"}, + {0x1002, 0x5147, 1, "ATI Radeon QG R100"}, + {0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"}, + {0x1002, 0x5149, 1, "ATI Radeon QI R200"}, + {0x1002, 0x514A, 1, "ATI Radeon QJ R200"}, + {0x1002, 0x514B, 1, "ATI Radeon QK R200"}, + {0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"}, + {0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"}, + {0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"}, + {0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"}, + {0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"}, + {0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"}, + {0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"}, + {0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"}, + {0x1002, 0x5168, 1, "ATI Radeon Qh R200"}, + {0x1002, 0x5169, 1, "ATI Radeon Qi R200"}, + {0x1002, 0x516A, 1, "ATI Radeon Qj R200"}, + {0x1002, 0x516B, 1, "ATI Radeon Qk R200"}, + {0x1002, 0x516C, 1, "ATI Radeon Ql R200"}, {0, 0, 0, NULL} }; @@ -74,4 +95,8 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_scatter.h" #endif +#ifdef __FreeBSD__ DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(radeon, DV_TTY, NULL); +#endif /* __FreeBSD__ */ diff --git a/bsd/tdfx_drv.c b/bsd/tdfx_drv.c index 8bc8c57d..e10542f1 100644 --- a/bsd/tdfx_drv.c +++ b/bsd/tdfx_drv.c @@ -28,11 +28,10 @@ * Rickard E. (Rik) Faith <faith@valinux.com> * Daryll Strauss <daryll@valinux.com> * Gareth Hughes <gareth@valinux.com> + * + * $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $ */ - -#include <sys/types.h> - #include "tdfx.h" #include "drmP.h" @@ -96,4 +95,6 @@ drm_chipinfo_t DRM(devicelist)[] = { #ifdef __FreeBSD__ DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0); +#elif defined(__NetBSD__) +CFDRIVER_DECL(tdfx, DV_TTY, NULL); #endif /* __FreeBSD__ */ diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index d250365e..e1280921 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -27,7 +27,7 @@ * Authors: Rickard E. (Rik) Faith <faith@valinux.com> * Kevin E. Martin <martin@valinux.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.28 2002/10/16 01:26:49 dawes Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.31 2003/02/04 03:01:59 dawes Exp $ * */ @@ -84,13 +84,16 @@ extern unsigned long _bus_base(void); #include "xf86drm.h" -#ifndef DRM_MAJOR -#define DRM_MAJOR 226 /* Linux */ +#ifdef __FreeBSD__ +#define DRM_MAJOR 145 +#endif + +#ifdef __NetBSD__ +#define DRM_MAJOR 34 #endif -#ifndef __linux__ -#undef DRM_MAJOR -#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */ +#ifndef DRM_MAJOR +#define DRM_MAJOR 226 /* Linux */ #endif #ifndef DRM_MAX_MINOR diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index c738173d..233b6309 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o mach64.o +list-multi := gamma.o tdfx.o mach64.o r128.o mga.o i810.o i830.o radeon.o ffb.o gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o @@ -11,8 +11,8 @@ mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o i810-objs := i810_drv.o i810_dma.o -i830-objs := i830_drv.o i830_dma.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_state.o +i830-objs := i830_drv.o i830_dma.o i830_irq.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o ffb-objs := ffb_drv.o ffb_context.o obj-$(CONFIG_DRM_GAMMA) += gamma.o diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 17262609..a6b32285 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -261,6 +261,7 @@ do { \ } \ } \ } while(0) +#define DRM_DROP_MAP(_map) /* Internal types and structures */ #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) @@ -275,6 +276,17 @@ do { \ (_map) = (_dev)->context_sareas[_ctx]; \ } while(0) +#define LOCK_TEST_WITH_RETURN( dev, filp ) \ +do { \ + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ + dev->lock.filp != filp ) { \ + DRM_ERROR( "%s called without lock held\n", \ + __FUNCTION__ ); \ + return -EINVAL; \ + } \ +} while (0) + + typedef int drm_ioctl_t( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -323,7 +335,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + struct file *filp; /* Pointer to holding file descr */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -441,7 +453,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + struct file *filp; /* File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -523,6 +535,8 @@ typedef struct drm_map_list { drm_map_t *map; } drm_map_list_t; +typedef drm_map_t drm_local_map_t; + #if __HAVE_VBL_IRQ typedef struct drm_vbl_sig { @@ -815,15 +829,15 @@ extern int DRM(mapbufs)( struct inode *inode, struct file *filp, extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)( struct file *filp ); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ extern void DRM(clear_next_buffer)(drm_device_t *dev); extern int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)); -extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma); -extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); +extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); +extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); #endif #if __HAVE_DMA_IRQ extern int DRM(control)( struct inode *inode, struct file *filp, diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 6d6b5911..35dd866f 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -267,12 +267,12 @@ drm_agp_head_t *DRM(agp_init)(void) head->cant_use_aperture = head->agp_info.cant_use_aperture; head->page_mask = head->agp_info.page_mask; #endif - - DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", - head->agp_info.version.major, - head->agp_info.version.minor, - head->agp_info.aper_base, - head->agp_info.aper_size); + + DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); } return head; } diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 9ce7cfff..b4e73699 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -404,7 +404,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -617,7 +617,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -774,7 +774,7 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -1012,9 +1012,9 @@ int DRM(freebufs)( struct inode *inode, struct file *filp, return -EINVAL; } buf = dma->buflist[idx]; - if ( buf->pid != current->pid ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - current->pid, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "Process %d freeing buffer not owned\n", + current->pid ); return -EINVAL; } DRM(free_buffer)( dev, buf ); diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c index df4ed809..d21c8b9d 100644 --- a/linux-core/drm_dma.c +++ b/linux-core/drm_dma.c @@ -189,7 +189,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = 0; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -211,14 +211,16 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); @@ -319,8 +321,10 @@ int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)) } -int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) +int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_queue_t *q; drm_buf_t *buf; @@ -382,10 +386,10 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return -EINVAL; } buf = dma->buflist[ idx ]; - if (buf->pid != current->pid) { + if (buf->filp != filp) { atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); + DRM_ERROR("Process %d using buffer not owned\n", + current->pid); return -EINVAL; } if (buf->list != DRM_LIST_NONE) { @@ -427,9 +431,11 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return 0; } -static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, +static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, int order) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_buf_t *buf; drm_device_dma_t *dma = dev->dma; @@ -439,13 +445,13 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, d->flags & _DRM_DMA_WAIT); if (!buf) break; if (buf->pending || buf->waiting) { - DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n", + DRM_ERROR("Free buffer %d in use by %x (w%d, p%d)\n", buf->idx, - buf->pid, + buf->filp, buf->waiting, buf->pending); } - buf->pid = current->pid; + buf->filp = filp; if (copy_to_user(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) @@ -462,7 +468,7 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, } -int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) +int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma) { int order; int retcode = 0; @@ -471,7 +477,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) order = DRM(order)(dma->request_size); dma->granted_count = 0; - retcode = DRM(dma_get_buffers_of_order)(dev, dma, order); + retcode = DRM(dma_get_buffers_of_order)(filp, dma, order); if (dma->granted_count < dma->request_count && (dma->flags & _DRM_DMA_SMALLER_OK)) { @@ -481,7 +487,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order >= DRM_MIN_ORDER; --tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } @@ -494,7 +500,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order <= DRM_MAX_ORDER; ++tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } @@ -714,7 +720,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) list_del( (struct list_head *) vbl_sig ); - DRM_FREE( vbl_sig ); + DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); dev->vbl_pending--; } diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 3ebe7811..0a4f3aeb 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -496,7 +496,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = 0; wake_up_interruptible( &dev->lock.lock_queue ); } up( &dev->struct_sem ); @@ -732,8 +732,6 @@ int DRM(open)( struct inode *inode, struct file *filp ) return -ENODEV; } - DRM_DEBUG( "open_count = %d\n", dev->open_count ); - retcode = DRM(open_helper)( inode, filp, dev ); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); @@ -765,15 +763,15 @@ int DRM(release)( struct inode *inode, struct file *filp ) * Begin inline drm_release */ - DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count ); + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count ); if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.pid == current->pid ) { - DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); + dev->lock.filp == filp ) { + DRM_DEBUG( "File %p released, freeing lock for context %d\n", + filp, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); #if __HAVE_RELEASE DRIVER_RELEASE(); #endif @@ -789,6 +787,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) else if ( dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); + add_wait_queue( &dev->lock.lock_queue, &entry ); for (;;) { current->state = TASK_INTERRUPTIBLE; @@ -799,7 +798,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ) ) { - dev->lock.pid = priv->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -823,7 +822,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( filp ); #endif DRM(fasync)( -1, filp, 0 ); @@ -847,7 +846,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) dev->file_last = priv->prev; } up( &dev->struct_sem ); - + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); /* ======================================================== @@ -872,6 +871,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) spin_unlock( &dev->count_lock ); unlock_kernel(); + return retcode; } @@ -891,8 +891,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp, atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; - DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", - current->pid, cmd, nr, dev->device, priv->authenticated ); + DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + current->pid, cmd, nr, (long)dev->device, + priv->authenticated ); if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = -EINVAL; @@ -968,7 +969,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = current->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -1050,7 +1051,7 @@ int DRM(unlock)( struct inode *inode, struct file *filp, * agent to request it then we should just be able to * take it immediately and not eat the ioctl. */ - dev->lock.pid = 0; + dev->lock.filp = 0; { __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; unsigned int old, new, prev, ctx; diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 3d4bffa5..10d1aed1 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -95,8 +95,8 @@ int DRM(flush)(struct file *filp) drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count); return 0; } @@ -106,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on) drm_device_t *dev = priv->dev; int retcode; - DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; return 0; diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 01604e75..d753cce0 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp, if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) return -EFAULT; +#ifdef __alpha__ + { + int domain = p.busnum >> 8; + p.busnum &= 0xff; + + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + dev; + dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) { + struct pci_controller *hose = dev->sysdata; + + if (hose->index == domain) { + p.busnum += hose->bus->number; + break; + } + } + } +#endif dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); if (!dev) { DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", @@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp, do { struct pci_dev *pci_dev; - int b, d, f; + int domain, b, d, f; char *p; for(p = dev->unique; p && *p && *p != ':'; p++); @@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp, f = (int)simple_strtoul(p+1, &p, 10); if (*p) break; + domain = b >> 8; + b &= 0xff; + +#ifdef __alpha__ + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + pci_dev; + pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { + struct pci_controller *hose = pci_dev->sysdata; + + if (hose->index == domain) { + b += hose->bus->number; + break; + } + } +#endif + pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); if (pci_dev) { dev->pdev = pci_dev; diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index c887d1f6..e9b17cc4 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -79,7 +79,7 @@ int DRM(lock_transfer)(drm_device_t *dev, { unsigned int old, new, prev; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -92,19 +92,17 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - pid_t pid = dev->lock.pid; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = 0; prev = cmpxchg(lock, old, new); } while (prev != old); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", + DRM_ERROR("%d freed heavyweight lock held by %d\n", context, - _DRM_LOCKING_CONTEXT(old), - pid); + _DRM_LOCKING_CONTEXT(old)); return 1; } wake_up_interruptible(&dev->lock.lock_queue); diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index a9ad02af..585c67d4 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -3,16 +3,17 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> +#define DRMFILE struct file * #define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data #define DRM_ERR(d) -(d) #define DRM_CURRENTPID current->pid #define DRM_UDELAY(d) udelay(d) -#define DRM_READ8(addr) readb(addr) -#define DRM_READ32(addr) readl(addr) -#define DRM_WRITE8(addr, val) writeb(val, addr) -#define DRM_WRITE32(addr, val) writel(val, addr) -#define DRM_READMEMORYBARRIER() mb() -#define DRM_WRITEMEMORYBARRIER() wmb() +#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset)) +#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_READMEMORYBARRIER(map) mb() +#define DRM_WRITEMEMORYBARRIER(map) wmb() #define DRM_DEVICE drm_file_t *priv = filp->private_data; \ drm_device_t *dev = priv->dev @@ -42,7 +43,7 @@ /* malloc/free without the overhead of DRM(alloc) */ #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) -#define DRM_FREE(x) kfree(x) +#define DRM_FREE(x,size) kfree(x) #define DRM_GETSAREA() \ do { \ diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c index d29db7b7..510df672 100644 --- a/linux-core/drm_proc.c +++ b/linux-core/drm_proc.c @@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request, *eof = 0; if (dev->unique) { - DRM_PROC_PRINT("%s 0x%x %s\n", - dev->name, dev->device, dev->unique); + DRM_PROC_PRINT("%s 0x%lx %s\n", + dev->name, (long)dev->device, dev->unique); } else { - DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); + DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device); } if (len > request + offset) return request; diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index ffb7c708..de9345e3 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -53,30 +53,10 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) +#define down_write down +#define up_write up +#endif static inline void i810_print_status_page(drm_device_t *dev) { @@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; -#if LINUX_VERSION_CODE <= 0x020402 - down( ¤t->mm->mmap_sem ); -#else down_write( ¤t->mm->mmap_sem ); -#endif old_fops = filp->f_op; filp->f_op = &i810_buffer_fops; dev_priv->mmap_buffer = buf; @@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) filp->f_op = old_fops; if ((unsigned long)buf_priv->virtual > -1024UL) { /* Real error */ - DRM_DEBUG("mmap error\n"); + DRM_ERROR("mmap error\n"); retcode = (signed int)buf_priv->virtual; buf_priv->virtual = 0; } -#if LINUX_VERSION_CODE <= 0x020402 - up( ¤t->mm->mmap_sem ); -#else up_write( ¤t->mm->mmap_sem ); -#endif + return retcode; } @@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf) if(buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; -#if LINUX_VERSION_CODE <= 0x020402 - down( ¤t->mm->mmap_sem ); -#else - down_write( ¤t->mm->mmap_sem ); -#endif + + down_write(¤t->mm->mmap_sem); retcode = DO_MUNMAP(current->mm, (unsigned long)buf_priv->virtual, (size_t) buf->total); -#if LINUX_VERSION_CODE <= 0x020402 - up( ¤t->mm->mmap_sem ); -#else - up_write( ¤t->mm->mmap_sem ); -#endif + up_write(¤t->mm->mmap_sem); + buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -242,7 +209,6 @@ static int i810_unmap_buffer(drm_buf_t *buf) static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; int retcode = 0; @@ -257,10 +223,10 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -321,7 +287,7 @@ static int i810_wait_ring(drm_device_t *dev, int n) end = jiffies + (HZ*3); iters++; - if((signed)(end - jiffies) <= 0) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; @@ -889,8 +855,10 @@ static int i810_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i810_reclaim_buffers(struct file *filp) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -904,7 +872,7 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index 106abf56..bbb570bc 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -88,7 +88,7 @@ extern int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i810_reclaim_buffers(struct file *filp); extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); @@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, #define I810_READ16(reg) I810_DEREF16(reg) #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) +#define I810_VERBOSE 0 +#define RING_LOCALS unsigned int outring, ringmask; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +#define OUT_RING(n) do { \ + if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) +#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c index d29e21cb..d2555c92 100644 --- a/linux-core/i830_dma.c +++ b/linux-core/i830_dma.c @@ -38,6 +38,7 @@ #include "i830_drm.h" #include "i830_drv.h" #include <linux/interrupt.h> /* For task queue support */ +#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */ #include <linux/delay.h> #ifdef DO_MUNMAP_4_ARGS @@ -53,8 +54,6 @@ #define I830_BUF_UNMAPPED 0 #define I830_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; - #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) #define down_write down #define up_write up @@ -67,32 +66,6 @@ #define UnlockPage(page) unlock_page(page) #endif -#define I830_VERBOSE 0 - -#define BEGIN_LP_RING(n) do { \ - if (I830_VERBOSE) \ - printk("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ - dev_priv->ring.tail = outring; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) static inline void i830_print_status_page(drm_device_t *dev) { @@ -244,7 +217,6 @@ static int i830_unmap_buffer(drm_buf_t *buf) static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i830_buf_priv_t *buf_priv; int retcode = 0; @@ -252,7 +224,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, buf = i830_freelist_get(dev); if (!buf) { retcode = -ENOMEM; - DRM_ERROR("retcode=%d\n", retcode); + DRM_DEBUG("retcode=%d\n", retcode); return retcode; } @@ -262,7 +234,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -286,12 +258,21 @@ static int i830_dma_cleanup(drm_device_t *dev) dev_priv->ring.Size); } if(dev_priv->hw_status_page != 0UL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, + pci_free_consistent(dev->pdev, PAGE_SIZE, (void *)dev_priv->hw_status_page, dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I830_WRITE(0x02080, 0x1ffff000); } + + /* Disable interrupts here because after dev_private + * is freed, it's too late. + */ + if (dev->irq) { + I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -305,7 +286,7 @@ static int i830_dma_cleanup(drm_device_t *dev) return 0; } -static int i830_wait_ring(drm_device_t *dev, int n) +int i830_wait_ring(drm_device_t *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -331,6 +312,7 @@ static int i830_wait_ring(drm_device_t *dev, int n) goto out_wait_ring; } udelay(1); + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } out_wait_ring: @@ -346,6 +328,9 @@ static void i830_kernel_lost_context(drm_device_t *dev) ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; + + if (ring->head == ring->tail) + dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) @@ -460,6 +445,8 @@ static int i830_dma_initialize(drm_device_t *dev, dev_priv->back_pitch = init->back_pitch; dev_priv->depth_pitch = init->depth_pitch; + dev_priv->do_boxes = 0; + dev_priv->use_mi_batchbuffer_start = 0; /* Program Hardware Status Page */ dev_priv->hw_status_page = @@ -474,7 +461,7 @@ static int i830_dma_initialize(drm_device_t *dev, memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I830_WRITE(0x02080, dev_priv->dma_status_page); + I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -535,11 +522,7 @@ static void i830EmitContextVerified( drm_device_t *dev, unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 ); - - OUT_RING( GFX_OP_STIPPLE ); - OUT_RING( 0 ); - + BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 ); for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { tmp = code[i]; @@ -577,38 +560,44 @@ static void i830EmitContextVerified( drm_device_t *dev, ADVANCE_LP_RING(); } -static void i830EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || + (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == + (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { - OUT_RING( GFX_OP_MAP_INFO ); - OUT_RING( code[I830_TEXREG_MI1] ); - OUT_RING( code[I830_TEXREG_MI2] ); - OUT_RING( code[I830_TEXREG_MI3] ); - OUT_RING( code[I830_TEXREG_MI4] ); - OUT_RING( code[I830_TEXREG_MI5] ); + BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); - for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - OUT_RING( tmp ); - j++; - } + OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ + OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ + OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ + OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ + OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ + OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); - ADVANCE_LP_RING(); + ADVANCE_LP_RING(); + } + else + printk("rejected packet %x\n", code[0]); } static void i830EmitTexBlendVerified( drm_device_t *dev, - volatile unsigned int *code, - volatile unsigned int num) + unsigned int *code, + unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -618,7 +607,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev, if (!num) return; - BEGIN_LP_RING( num ); + BEGIN_LP_RING( num + 1 ); for ( i = 0 ; i < num ; i++ ) { tmp = code[i]; @@ -641,6 +630,8 @@ static void i830EmitTexPalette( drm_device_t *dev, int i; RING_LOCALS; + return; + BEGIN_LP_RING( 258 ); if(is_shared == 1) { @@ -654,42 +645,41 @@ static void i830EmitTexPalette( drm_device_t *dev, OUT_RING(palette[i]); } OUT_RING(0); + /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! + */ } /* Need to do some additional checking when setting the dest buffer. */ static void i830EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); + BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); + tmp = code[I830_DESTREG_CBUFADDR]; - if (tmp == dev_priv->front_di1) { - /* Don't use fence when front buffer rendering */ - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); - OUT_RING( tmp ); + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + if (((int)outring) & 8) { + OUT_RING(0); + OUT_RING(0); + } OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_DEPTH | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING( dev_priv->zi1 ); - } else if(tmp == dev_priv->back_di1) { - OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_USE_FENCE); OUT_RING( tmp ); + OUT_RING( 0 ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); + OUT_RING( 0 ); } else { DRM_ERROR("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); @@ -717,21 +707,35 @@ static void i830EmitDestVerified( drm_device_t *dev, OUT_RING( 0 ); } - OUT_RING( code[I830_DESTREG_SENABLE] ); - OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); + OUT_RING( 0 ); ADVANCE_LP_RING(); } +static void i830EmitStippleVerified( drm_device_t *dev, + unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + BEGIN_LP_RING( 2 ); + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[1] ); + ADVANCE_LP_RING(); +} + + static void i830EmitState( drm_device_t *dev ) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; + DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); + if (dirty & I830_UPLOAD_BUFFERS) { i830EmitDestVerified( dev, sarea_priv->BufferState ); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; @@ -765,17 +769,154 @@ static void i830EmitState( drm_device_t *dev ) } if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); } else { - if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); - } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); + } + + /* 1.3: + */ +#if 0 + if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } +#endif + } + + /* 1.3: + */ + if (dirty & I830_UPLOAD_STIPPLE) { + i830EmitStippleVerified( dev, + sarea_priv->StippleState); + sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; } + + if (dirty & I830_UPLOAD_TEX2) { + i830EmitTexVerified( dev, sarea_priv->TexState2 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX2; + } + + if (dirty & I830_UPLOAD_TEX3) { + i830EmitTexVerified( dev, sarea_priv->TexState3 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX3; + } + + + if (dirty & I830_UPLOAD_TEXBLEND2) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState2, + sarea_priv->TexBlendStateWordsUsed2); + + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; + } + + if (dirty & I830_UPLOAD_TEXBLEND3) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState3, + sarea_priv->TexBlendStateWordsUsed3); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; + } +} + +/* ================================================================ + * Performance monitoring functions + */ + +static void i830_fill_box( drm_device_t *dev, + int x, int y, int w, int h, + int r, int g, int b ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + u32 color; + unsigned int BR13, CMD; + RING_LOCALS; + + BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + + if (dev_priv->cpp == 4) { + BR13 |= (1<<25); + CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + } else { + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + } + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (y << 16) | x ); + OUT_RING( ((y+h) << 16) | (x+w) ); + + if ( dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_offset ); + } else { + OUT_RING( dev_priv->back_offset ); + } + + OUT_RING( color ); + ADVANCE_LP_RING(); +} + +static void i830_cp_performance_boxes( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + /* Purple box for page flipping + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) + i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); + + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) + i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); + + /* Blue box: lost context? + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) + i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); + + /* Yellow box for texture swaps + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) + i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) + i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->dma_used) { + int bar = dev_priv->dma_used / 10240; + if (bar > 100) bar = 100; + if (bar < 1) bar = 1; + i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); + dev_priv->dma_used = 0; + } + + dev_priv->sarea_priv->perf_boxes = 0; } static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, @@ -793,6 +934,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int BR13, CMD, D_CMD; RING_LOCALS; + + if ( dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(I830_FRONT | I830_BACK); + if ( tmp & I830_FRONT ) flags |= I830_BACK; + if ( tmp & I830_BACK ) flags |= I830_FRONT; + } + i830_kernel_lost_context(dev); switch(cpp) { @@ -872,13 +1022,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; int cpp = dev_priv->cpp; - int ofs = dev_priv->back_offset; int i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) + i830_cp_performance_boxes( dev ); + switch(cpp) { case 2: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); @@ -895,7 +1049,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) break; } - i830_kernel_lost_context(dev); if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; @@ -915,23 +1068,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) BEGIN_LP_RING( 8 ); OUT_RING( CMD ); OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | - pbox->x2 ); - - OUT_RING( dev_priv->front_offset ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->front_offset ); + else + OUT_RING( dev_priv->back_offset ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( BR13 & 0xffff ); - OUT_RING( ofs ); + + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->back_offset ); + else + OUT_RING( dev_priv->front_offset ); ADVANCE_LP_RING(); } } +static void i830_dma_dispatch_flip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); + + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) { + dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; + i830_cp_performance_boxes( dev ); + } + + + BEGIN_LP_RING( 2 ); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP ); + OUT_RING( 0 ); + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + OUT_RING(0); + ADVANCE_LP_RING(); + + + BEGIN_LP_RING( 2 ); + OUT_RING( MI_WAIT_FOR_EVENT | + MI_WAIT_FOR_PLANE_A_FLIP ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} static void i830_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, @@ -984,8 +1186,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev, sarea_priv->vertex_prim | ((used/4)-2)); - vp[used/4] = MI_BATCH_BUFFER_END; - used += 4; + if (dev_priv->use_mi_batchbuffer_start) { + vp[used/4] = MI_BATCH_BUFFER_END; + used += 4; + } if (used & 4) { vp[used/4] = 0; @@ -1008,11 +1212,21 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev, ADVANCE_LP_RING(); } - BEGIN_LP_RING(2); - OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); - OUT_RING( start | MI_BATCH_NON_SECURE ); - ADVANCE_LP_RING(); - + if (dev_priv->use_mi_batchbuffer_start) { + BEGIN_LP_RING(2); + OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + ADVANCE_LP_RING(); + } + else { + BEGIN_LP_RING(4); + OUT_RING( MI_BATCH_BUFFER ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + } while (++i < nbox); } @@ -1050,7 +1264,7 @@ void i830_dma_quiescent(drm_device_t *dev) OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); } static int i830_flush_queue(drm_device_t *dev) @@ -1067,7 +1281,7 @@ static int i830_flush_queue(drm_device_t *dev) OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1086,8 +1300,10 @@ static int i830_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i830_reclaim_buffers( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -1101,7 +1317,7 @@ void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); @@ -1207,6 +1423,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp, return 0; } + + +/* Not sure why this isn't set all the time: + */ +static void i830_do_init_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} + +int i830_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + if (dev_priv->current_page != 0) + i830_dma_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flip_buf called without lock held\n"); + return -EINVAL; + } + + if (!dev_priv->page_flipping) + i830_do_init_pageflip( dev ); + + i830_dma_dispatch_flip( dev ); + return 0; +} + int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1270,3 +1533,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, { return 0; } + + + +int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_PARAM_IRQ_ACTIVE: + value = dev->irq ? 1 : 0; + break; + default: + return -EINVAL; + } + + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_setparam_t param; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_SETPARAM_USE_MI_BATCHBUFFER_START: + dev_priv->use_mi_batchbuffer_start = param.value; + break; + default: + return -EINVAL; + } + + return 0; +} diff --git a/linux-core/i830_drm.h b/linux-core/i830_drm.h index 725ad369..664ab0ed 100644 --- a/linux-core/i830_drm.h +++ b/linux-core/i830_drm.h @@ -3,6 +3,9 @@ /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. + * + * KW: Actually, you can't ever change them because doing so would + * break backwards compatibility. */ #ifndef _I830_DEFINES_ @@ -18,14 +21,12 @@ #define I830_NR_TEX_REGIONS 64 #define I830_LOG_MIN_TEX_REGION_SIZE 16 -/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ -#if !defined(I830_ENABLE_4_TEXTURES) +/* KW: These aren't correct but someone set them to two and then + * released the module. Now we can't change them as doing so would + * break backwards compatibility. + */ #define I830_TEXTURE_COUNT 2 -#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ -#else /* defined(I830_ENABLE_4_TEXTURES) */ -#define I830_TEXTURE_COUNT 4 -#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ -#endif /* I830_ENABLE_4_TEXTURES */ +#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ @@ -57,6 +58,7 @@ #define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -73,7 +75,6 @@ */ #define I830_DESTREG_CBUFADDR 0 -/* Invarient */ #define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DV0 2 #define I830_DESTREG_DV1 3 @@ -109,6 +110,13 @@ #define I830_CTXREG_MCSB1 16 #define I830_CTX_SETUP_SIZE 17 +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + + /* Texture state (per tex unit) */ @@ -124,6 +132,18 @@ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 @@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea { int ctxOwner; /* last context to upload state */ int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; } drm_i830_sarea_t; +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + /* I830 specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ @@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea { #define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) #define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) #define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49) +#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t) +#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t) +#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t) +#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t) typedef struct _drm_i830_clear { int clear_color; @@ -248,4 +300,36 @@ typedef struct drm_i830_dma { int granted; } drm_i830_dma_t; + +/* 1.3: Userspace can request & wait on irq's: + */ +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drm_i830_irq_emit_t; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drm_i830_irq_wait_t; + + +/* 1.3: New ioctl to query kernel params: + */ +#define I830_PARAM_IRQ_ACTIVE 1 + +typedef struct drm_i830_getparam { + int param; + int *value; +} drm_i830_getparam_t; + + +/* 1.3: New ioctl to set kernel params: + */ +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + +typedef struct drm_i830_setparam { + int param; + int value; +} drm_i830_setparam_t; + + #endif /* _I830_DRM_H_ */ diff --git a/linux-core/i830_drv.h b/linux-core/i830_drv.h index eec640ca..37313afd 100644 --- a/linux-core/i830_drv.h +++ b/linux-core/i830_drv.h @@ -78,6 +78,19 @@ typedef struct drm_i830_private { int back_pitch; int depth_pitch; unsigned int cpp; + + int do_boxes; + int dma_used; + + int current_page; + int page_flipping; + + wait_queue_head_t irq_queue; + atomic_t irq_received; + atomic_t irq_emitted; + + int use_mi_batchbuffer_start; + } drm_i830_private_t; /* i830_dma.c */ @@ -88,7 +101,7 @@ extern int i830_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i830_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i830_reclaim_buffers(struct file *filp); extern int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma); @@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp, extern int i830_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_getparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int i830_setparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +/* i830_irq.c */ +extern int i830_irq_emit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_irq_wait( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_wait_irq(drm_device_t *dev, int irq_nr); +extern int i830_emit_irq(drm_device_t *dev); + #define I830_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) @@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define I830_READ16(reg) I830_DEREF16(reg) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) + + +#define I830_VERBOSE 0 + +#define RING_LOCALS unsigned int outring, ringmask, outcount; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + printk("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i830_wait_ring(dev, n*4, __FUNCTION__); \ + outcount = 0; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outcount++; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ + dev_priv->ring.tail = outring; \ + dev_priv->ring.space -= outcount * 4; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + #define INST_PARSER_CLIENT 0x00000000 #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 @@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_ENABLE_R 0x020a0 +#define I830_IRQ_RESERVED ((1<<13)|(3<<2)) + + #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 @@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) + #define CMD_3D (0x3<<29) #define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) #define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) @@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) + +#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) #endif diff --git a/linux-core/i830_irq.c b/linux-core/i830_irq.c new file mode 100644 index 00000000..cedafc0d --- /dev/null +++ b/linux-core/i830_irq.c @@ -0,0 +1,178 @@ +/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- + * + * Copyright 2002 Tungsten Graphics, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#define __NO_VERSION__ +#include "i830.h" +#include "drmP.h" +#include "drm.h" +#include "i830_drm.h" +#include "i830_drv.h" +#include <linux/interrupt.h> /* For task queue support */ +#include <linux/delay.h> + + +void DRM(dma_service)(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u16 temp; + + temp = I830_READ16(I830REG_INT_IDENTITY_R); + printk("%s: %x\n", __FUNCTION__, temp); + + if(temp == 0) + return; + + I830_WRITE16(I830REG_INT_IDENTITY_R, temp); + + if (temp & 2) { + atomic_inc(&dev_priv->irq_received); + wake_up_interruptible(&dev_priv->irq_queue); + } +} + + +int i830_emit_irq(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG("%s\n", __FUNCTION__); + + atomic_inc(&dev_priv->irq_emitted); + + BEGIN_LP_RING(2); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + return atomic_read(&dev_priv->irq_emitted); +} + + +int i830_wait_irq(drm_device_t *dev, int irq_nr) +{ + drm_i830_private_t *dev_priv = + (drm_i830_private_t *)dev->dev_private; + DECLARE_WAITQUEUE(entry, current); + unsigned long end = jiffies + HZ*3; + int ret = 0; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + return 0; + + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; + + add_wait_queue(&dev_priv->irq_queue, &entry); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", + I830_READ16( I830REG_INT_IDENTITY_R ), + I830_READ16( I830REG_INT_MASK_R ), + I830_READ16( I830REG_INT_ENABLE_R ), + I830_READ16( I830REG_HWSTAM )); + + ret = -EBUSY; /* Lockup? Missed irq? */ + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->irq_queue, &entry); + return ret; +} + + +/* Needs the lock as it touches the ring. + */ +int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_emit_t emit; + int result; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_irq_emit called without lock held\n"); + return -EINVAL; + } + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) )) + return -EFAULT; + + result = i830_emit_irq( dev ); + + if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +/* Doesn't need the hardware lock. + */ +int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_wait_t irqwait; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg, + sizeof(irqwait) )) + return -EFAULT; + + return i830_wait_irq( dev, irqwait.irq_seq ); +} + diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel index c738173d..233b6309 100644 --- a/linux/Makefile.kernel +++ b/linux/Makefile.kernel @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. O_TARGET := drm.o -list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o mach64.o +list-multi := gamma.o tdfx.o mach64.o r128.o mga.o i810.o i830.o radeon.o ffb.o gamma-objs := gamma_drv.o gamma_dma.o tdfx-objs := tdfx_drv.o @@ -11,8 +11,8 @@ mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o i810-objs := i810_drv.o i810_dma.o -i830-objs := i830_drv.o i830_dma.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_state.o +i830-objs := i830_drv.o i830_dma.o i830_irq.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o ffb-objs := ffb_drv.o ffb_context.o obj-$(CONFIG_DRM_GAMMA) += gamma.o diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 2447af0c..492b0e61 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -32,6 +32,8 @@ # make TREE=/usr/my-kernel-tree/include # +SHELL=/bin/sh + .SUFFIXES: # *** Setup @@ -44,7 +46,8 @@ LIBS = DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \ drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h -DRMHEADERS = drm.h drmP.h drm_sarea.h +DRMSHARED = drm_sarea.h +DRMHEADERS = drm.h drmP.h $(DRMSHARED) GAMMAOBJS = gamma_drv.o gamma_dma.o GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) @@ -54,12 +57,20 @@ TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES) R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +R128SHARED = r128.h r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c + +MACH64OBJS = mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o +MACH64HEADERS = mach64.h mach64_drv.h mach64_drm.h $(DRMHEADERS) \ + $(DRMTEMPLATES) +MACH64SHARED = mach64.h mach64_drv.h mach64_drm.h mach64_dma.c mach64_irq.c \ + mach64_state.c -RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o +RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ + radeon_irq.o RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ $(DRMTEMPLATES) -MACH64OBJS= mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o -MACH64HEADERS= mach64.h mach64_drv.h mach64_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +RADEONSHARED = radeon.h radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \ + radeon_mem.c radeon_state.c INC = /usr/include @@ -162,11 +173,13 @@ endif MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +MGASHARED = mga.h mga_dma.c mga_drm.h mga_drv.h mga_state.c \ + mga_ucode.h mga_warp.c I810OBJS = i810_drv.o i810_dma.o I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -I830OBJS = i830_drv.o i830_dma.o +I830OBJS = i830_drv.o i830_dma.o i830_irq.o I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES) endif @@ -174,6 +187,10 @@ endif ifeq ($(MACHINE),alpha) MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6 endif +ifeq ($(MACHINE),x86_64) +MODCFLAGS+= -mcmodel=kernel +endif + MODS += sis.o @@ -210,6 +227,15 @@ endif # **** End of configuration +# Link in shared headers if needed + +SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED) $(MACH64SHARED) +SHAREDDIR = ../../../shared/drm/kernel + +$(SHAREDSRC): + @if [ ! -r $@ ]; then (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ .); fi + + dristat: dristat.c $(CC) $(PRGCFLAGS) $< -o $@ @@ -288,3 +314,7 @@ endif clean cleandir:: rm -f *.o *.a *~ core + @for i in $(SHAREDSRC); do \ + if [ -L $$i ]; then (set -x; rm -f $$i); fi; \ + done + diff --git a/linux/drmP.h b/linux/drmP.h index 17262609..a6b32285 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -261,6 +261,7 @@ do { \ } \ } \ } while(0) +#define DRM_DROP_MAP(_map) /* Internal types and structures */ #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) @@ -275,6 +276,17 @@ do { \ (_map) = (_dev)->context_sareas[_ctx]; \ } while(0) +#define LOCK_TEST_WITH_RETURN( dev, filp ) \ +do { \ + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ + dev->lock.filp != filp ) { \ + DRM_ERROR( "%s called without lock held\n", \ + __FUNCTION__ ); \ + return -EINVAL; \ + } \ +} while (0) + + typedef int drm_ioctl_t( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -323,7 +335,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + struct file *filp; /* Pointer to holding file descr */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -441,7 +453,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + struct file *filp; /* File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -523,6 +535,8 @@ typedef struct drm_map_list { drm_map_t *map; } drm_map_list_t; +typedef drm_map_t drm_local_map_t; + #if __HAVE_VBL_IRQ typedef struct drm_vbl_sig { @@ -815,15 +829,15 @@ extern int DRM(mapbufs)( struct inode *inode, struct file *filp, extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)( struct file *filp ); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ extern void DRM(clear_next_buffer)(drm_device_t *dev); extern int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)); -extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma); -extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); +extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); +extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); #endif #if __HAVE_DMA_IRQ extern int DRM(control)( struct inode *inode, struct file *filp, diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h index 6d6b5911..35dd866f 100644 --- a/linux/drm_agpsupport.h +++ b/linux/drm_agpsupport.h @@ -267,12 +267,12 @@ drm_agp_head_t *DRM(agp_init)(void) head->cant_use_aperture = head->agp_info.cant_use_aperture; head->page_mask = head->agp_info.page_mask; #endif - - DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", - head->agp_info.version.major, - head->agp_info.version.minor, - head->agp_info.aper_base, - head->agp_info.aper_size); + + DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n", + head->agp_info.version.major, + head->agp_info.version.minor, + head->agp_info.aper_base, + head->agp_info.aper_size); } return head; } diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h index 9ce7cfff..b4e73699 100644 --- a/linux/drm_bufs.h +++ b/linux/drm_bufs.h @@ -404,7 +404,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -617,7 +617,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -774,7 +774,7 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -1012,9 +1012,9 @@ int DRM(freebufs)( struct inode *inode, struct file *filp, return -EINVAL; } buf = dma->buflist[idx]; - if ( buf->pid != current->pid ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - current->pid, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "Process %d freeing buffer not owned\n", + current->pid ); return -EINVAL; } DRM(free_buffer)( dev, buf ); diff --git a/linux/drm_dma.h b/linux/drm_dma.h index df4ed809..d21c8b9d 100644 --- a/linux/drm_dma.h +++ b/linux/drm_dma.h @@ -189,7 +189,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = 0; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -211,14 +211,16 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); @@ -319,8 +321,10 @@ int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)) } -int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) +int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_queue_t *q; drm_buf_t *buf; @@ -382,10 +386,10 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return -EINVAL; } buf = dma->buflist[ idx ]; - if (buf->pid != current->pid) { + if (buf->filp != filp) { atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); + DRM_ERROR("Process %d using buffer not owned\n", + current->pid); return -EINVAL; } if (buf->list != DRM_LIST_NONE) { @@ -427,9 +431,11 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return 0; } -static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, +static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, int order) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_buf_t *buf; drm_device_dma_t *dma = dev->dma; @@ -439,13 +445,13 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, d->flags & _DRM_DMA_WAIT); if (!buf) break; if (buf->pending || buf->waiting) { - DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n", + DRM_ERROR("Free buffer %d in use by %x (w%d, p%d)\n", buf->idx, - buf->pid, + buf->filp, buf->waiting, buf->pending); } - buf->pid = current->pid; + buf->filp = filp; if (copy_to_user(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) @@ -462,7 +468,7 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, } -int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) +int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma) { int order; int retcode = 0; @@ -471,7 +477,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) order = DRM(order)(dma->request_size); dma->granted_count = 0; - retcode = DRM(dma_get_buffers_of_order)(dev, dma, order); + retcode = DRM(dma_get_buffers_of_order)(filp, dma, order); if (dma->granted_count < dma->request_count && (dma->flags & _DRM_DMA_SMALLER_OK)) { @@ -481,7 +487,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order >= DRM_MIN_ORDER; --tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } @@ -494,7 +500,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order <= DRM_MAX_ORDER; ++tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } @@ -714,7 +720,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) list_del( (struct list_head *) vbl_sig ); - DRM_FREE( vbl_sig ); + DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); dev->vbl_pending--; } diff --git a/linux/drm_drv.h b/linux/drm_drv.h index 3ebe7811..0a4f3aeb 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -496,7 +496,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = 0; wake_up_interruptible( &dev->lock.lock_queue ); } up( &dev->struct_sem ); @@ -732,8 +732,6 @@ int DRM(open)( struct inode *inode, struct file *filp ) return -ENODEV; } - DRM_DEBUG( "open_count = %d\n", dev->open_count ); - retcode = DRM(open_helper)( inode, filp, dev ); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); @@ -765,15 +763,15 @@ int DRM(release)( struct inode *inode, struct file *filp ) * Begin inline drm_release */ - DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count ); + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count ); if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.pid == current->pid ) { - DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); + dev->lock.filp == filp ) { + DRM_DEBUG( "File %p released, freeing lock for context %d\n", + filp, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); #if __HAVE_RELEASE DRIVER_RELEASE(); #endif @@ -789,6 +787,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) else if ( dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); + add_wait_queue( &dev->lock.lock_queue, &entry ); for (;;) { current->state = TASK_INTERRUPTIBLE; @@ -799,7 +798,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ) ) { - dev->lock.pid = priv->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -823,7 +822,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( filp ); #endif DRM(fasync)( -1, filp, 0 ); @@ -847,7 +846,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) dev->file_last = priv->prev; } up( &dev->struct_sem ); - + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); /* ======================================================== @@ -872,6 +871,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) spin_unlock( &dev->count_lock ); unlock_kernel(); + return retcode; } @@ -891,8 +891,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp, atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; - DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", - current->pid, cmd, nr, dev->device, priv->authenticated ); + DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + current->pid, cmd, nr, (long)dev->device, + priv->authenticated ); if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = -EINVAL; @@ -968,7 +969,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = current->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -1050,7 +1051,7 @@ int DRM(unlock)( struct inode *inode, struct file *filp, * agent to request it then we should just be able to * take it immediately and not eat the ioctl. */ - dev->lock.pid = 0; + dev->lock.filp = 0; { __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; unsigned int old, new, prev, ctx; diff --git a/linux/drm_fops.h b/linux/drm_fops.h index 3d4bffa5..10d1aed1 100644 --- a/linux/drm_fops.h +++ b/linux/drm_fops.h @@ -95,8 +95,8 @@ int DRM(flush)(struct file *filp) drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + current->pid, (long)dev->device, dev->open_count); return 0; } @@ -106,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on) drm_device_t *dev = priv->dev; int retcode; - DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); + DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device); retcode = fasync_helper(fd, filp, on, &dev->buf_async); if (retcode < 0) return retcode; return 0; diff --git a/linux/drm_ioctl.h b/linux/drm_ioctl.h index 01604e75..d753cce0 100644 --- a/linux/drm_ioctl.h +++ b/linux/drm_ioctl.h @@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp, if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) return -EFAULT; +#ifdef __alpha__ + { + int domain = p.busnum >> 8; + p.busnum &= 0xff; + + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + dev; + dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) { + struct pci_controller *hose = dev->sysdata; + + if (hose->index == domain) { + p.busnum += hose->bus->number; + break; + } + } + } +#endif dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); if (!dev) { DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", @@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp, do { struct pci_dev *pci_dev; - int b, d, f; + int domain, b, d, f; char *p; for(p = dev->unique; p && *p && *p != ':'; p++); @@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp, f = (int)simple_strtoul(p+1, &p, 10); if (*p) break; + domain = b >> 8; + b &= 0xff; + +#ifdef __alpha__ + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + pci_dev; + pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { + struct pci_controller *hose = pci_dev->sysdata; + + if (hose->index == domain) { + b += hose->bus->number; + break; + } + } +#endif + pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); if (pci_dev) { dev->pdev = pci_dev; diff --git a/linux/drm_lists.h b/linux/drm_lists.h index 5cd8cd47..4a64df71 100644 --- a/linux/drm_lists.h +++ b/linux/drm_lists.h @@ -73,8 +73,8 @@ int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf) left = DRM_LEFTCOUNT(bl); if (!left) { - DRM_ERROR("Overflow while adding buffer %d from pid %d\n", - buf->idx, buf->pid); + DRM_ERROR("Overflow while adding buffer %d from filp %p\n", + buf->idx, buf->filp); return -EINVAL; } #if __HAVE_DMA_HISTOGRAM diff --git a/linux/drm_lock.h b/linux/drm_lock.h index c887d1f6..e9b17cc4 100644 --- a/linux/drm_lock.h +++ b/linux/drm_lock.h @@ -79,7 +79,7 @@ int DRM(lock_transfer)(drm_device_t *dev, { unsigned int old, new, prev; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -92,19 +92,17 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - pid_t pid = dev->lock.pid; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = 0; prev = cmpxchg(lock, old, new); } while (prev != old); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", + DRM_ERROR("%d freed heavyweight lock held by %d\n", context, - _DRM_LOCKING_CONTEXT(old), - pid); + _DRM_LOCKING_CONTEXT(old)); return 1; } wake_up_interruptible(&dev->lock.lock_queue); diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h index a9ad02af..585c67d4 100644 --- a/linux/drm_os_linux.h +++ b/linux/drm_os_linux.h @@ -3,16 +3,17 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> +#define DRMFILE struct file * #define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data #define DRM_ERR(d) -(d) #define DRM_CURRENTPID current->pid #define DRM_UDELAY(d) udelay(d) -#define DRM_READ8(addr) readb(addr) -#define DRM_READ32(addr) readl(addr) -#define DRM_WRITE8(addr, val) writeb(val, addr) -#define DRM_WRITE32(addr, val) writel(val, addr) -#define DRM_READMEMORYBARRIER() mb() -#define DRM_WRITEMEMORYBARRIER() wmb() +#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset)) +#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_READMEMORYBARRIER(map) mb() +#define DRM_WRITEMEMORYBARRIER(map) wmb() #define DRM_DEVICE drm_file_t *priv = filp->private_data; \ drm_device_t *dev = priv->dev @@ -42,7 +43,7 @@ /* malloc/free without the overhead of DRM(alloc) */ #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) -#define DRM_FREE(x) kfree(x) +#define DRM_FREE(x,size) kfree(x) #define DRM_GETSAREA() \ do { \ diff --git a/linux/drm_proc.h b/linux/drm_proc.h index d29db7b7..510df672 100644 --- a/linux/drm_proc.h +++ b/linux/drm_proc.h @@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request, *eof = 0; if (dev->unique) { - DRM_PROC_PRINT("%s 0x%x %s\n", - dev->name, dev->device, dev->unique); + DRM_PROC_PRINT("%s 0x%lx %s\n", + dev->name, (long)dev->device, dev->unique); } else { - DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); + DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device); } if (len > request + offset) return request; diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index e18a577c..a3c21d11 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -190,7 +190,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("Dispatching buffer %d from pid %d" " \"while locked\", but no lock held\n", - buf->idx, buf->pid); + buf->idx, current->pid); } } else { if (!locked && !gamma_lock_take(&dev->lock.hw_lock->lock, @@ -342,7 +342,8 @@ again: return retcode; } -static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) +static int gamma_dma_priority(struct file *filp, + drm_device_t *dev, drm_dma_t *d) { unsigned long address; unsigned long length; @@ -380,15 +381,15 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) continue; } buf = dma->buflist[ idx ]; - if (buf->pid != current->pid) { - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); + if (buf->filp != filp) { + DRM_ERROR("Process %d using buffer not owned\n", + current->pid); retcode = -EINVAL; goto cleanup; } if (buf->list != DRM_LIST_NONE) { - DRM_ERROR("Process %d using %d's buffer on list %d\n", - current->pid, buf->pid, buf->list); + DRM_ERROR("Process %d using buffer on list %d\n", + current->pid, buf->list); retcode = -EINVAL; goto cleanup; } @@ -480,7 +481,8 @@ cleanup: return retcode; } -static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) +static int gamma_dma_send_buffers(struct file *filp, + drm_device_t *dev, drm_dma_t *d) { DECLARE_WAITQUEUE(entry, current); drm_buf_t *last_buf = NULL; @@ -492,7 +494,7 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) add_wait_queue(&last_buf->dma_wait, &entry); } - if ((retcode = gamma_dma_enqueue(dev, d))) { + if ((retcode = gamma_dma_enqueue(filp, d))) { if (d->flags & _DRM_DMA_BLOCK) remove_wait_queue(&last_buf->dma_wait, &entry); return retcode; @@ -522,14 +524,13 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) } } if (retcode) { - DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n", + DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d pid:%d\n", d->context, last_buf->waiting, last_buf->pending, - DRM_WAITCOUNT(dev, d->context), + (long)DRM_WAITCOUNT(dev, d->context), last_buf->idx, last_buf->list, - last_buf->pid, current->pid); } } @@ -562,15 +563,15 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, if (d.send_count) { if (d.flags & _DRM_DMA_PRIORITY) - retcode = gamma_dma_priority(dev, &d); + retcode = gamma_dma_priority(filp, dev, &d); else - retcode = gamma_dma_send_buffers(dev, &d); + retcode = gamma_dma_send_buffers(filp, dev, &d); } d.granted_count = 0; if (!retcode && d.request_count) { - retcode = gamma_dma_get_buffers(dev, &d); + retcode = gamma_dma_get_buffers(filp, &d); } DRM_DEBUG("%d returning, granted = %d\n", @@ -592,7 +593,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) drm_buf_t *buf; int i; struct list_head *list; - unsigned int *pgt; + unsigned long *pgt; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -645,7 +646,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { buf = dma->buflist[i]; - *pgt = (unsigned int)buf->address + 0x07; + *pgt = (unsigned long)buf->address + 0x07; pgt++; } diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index e7d0c896..2f7d3588 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -42,16 +42,6 @@ typedef struct drm_gamma_private { drm_map_t *mmio3; } drm_gamma_private_t; -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != current->pid ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return -EINVAL; \ - } \ -} while (0) - /* gamma_dma.c */ extern int gamma_dma_init( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); diff --git a/linux/i810.h b/linux/i810.h index ea1e7fe5..f37cb2e8 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -86,7 +86,7 @@ */ #define __HAVE_RELEASE 1 #define DRIVER_RELEASE() do { \ - i810_reclaim_buffers( dev, priv->pid ); \ + i810_reclaim_buffers( filp ); \ } while (0) /* DMA customization: diff --git a/linux/i810_dma.c b/linux/i810_dma.c index ffb7c708..de9345e3 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -53,30 +53,10 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) +#define down_write down +#define up_write up +#endif static inline void i810_print_status_page(drm_device_t *dev) { @@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; -#if LINUX_VERSION_CODE <= 0x020402 - down( ¤t->mm->mmap_sem ); -#else down_write( ¤t->mm->mmap_sem ); -#endif old_fops = filp->f_op; filp->f_op = &i810_buffer_fops; dev_priv->mmap_buffer = buf; @@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp) filp->f_op = old_fops; if ((unsigned long)buf_priv->virtual > -1024UL) { /* Real error */ - DRM_DEBUG("mmap error\n"); + DRM_ERROR("mmap error\n"); retcode = (signed int)buf_priv->virtual; buf_priv->virtual = 0; } -#if LINUX_VERSION_CODE <= 0x020402 - up( ¤t->mm->mmap_sem ); -#else up_write( ¤t->mm->mmap_sem ); -#endif + return retcode; } @@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf) if(buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; -#if LINUX_VERSION_CODE <= 0x020402 - down( ¤t->mm->mmap_sem ); -#else - down_write( ¤t->mm->mmap_sem ); -#endif + + down_write(¤t->mm->mmap_sem); retcode = DO_MUNMAP(current->mm, (unsigned long)buf_priv->virtual, (size_t) buf->total); -#if LINUX_VERSION_CODE <= 0x020402 - up( ¤t->mm->mmap_sem ); -#else - up_write( ¤t->mm->mmap_sem ); -#endif + up_write(¤t->mm->mmap_sem); + buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = 0; @@ -242,7 +209,6 @@ static int i810_unmap_buffer(drm_buf_t *buf) static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; int retcode = 0; @@ -257,10 +223,10 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -321,7 +287,7 @@ static int i810_wait_ring(drm_device_t *dev, int n) end = jiffies + (HZ*3); iters++; - if((signed)(end - jiffies) <= 0) { + if(time_before(end, jiffies)) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; @@ -889,8 +855,10 @@ static int i810_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i810_reclaim_buffers(struct file *filp) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -904,7 +872,7 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); diff --git a/linux/i810_drv.h b/linux/i810_drv.h index 106abf56..bbb570bc 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -88,7 +88,7 @@ extern int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i810_reclaim_buffers(struct file *filp); extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); @@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, #define I810_READ16(reg) I810_DEREF16(reg) #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) +#define I810_VERBOSE 0 +#define RING_LOCALS unsigned int outring, ringmask; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +#define OUT_RING(n) do { \ + if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) +#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 diff --git a/linux/i830.h b/linux/i830.h index b9752188..a351a4cf 100644 --- a/linux/i830.h +++ b/linux/i830.h @@ -45,22 +45,37 @@ #define DRIVER_NAME "i830" #define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20020828" +#define DRIVER_DATE "20021108" +/* Interface history: + * + * 1.1: Original. + * 1.2: ? + * 1.3: New irq emit/wait ioctls. + * New pageflip ioctl. + * New getparam ioctl. + * State for texunits 3&4 in sarea. + * New (alternative) layout for texture state. + */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_MINOR 3 +#define DRIVER_PATCHLEVEL 2 #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)] = { i830_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)] = { i830_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 } #define __HAVE_COUNTERS 4 #define __HAVE_COUNTER6 _DRM_STAT_IRQ @@ -72,7 +87,7 @@ */ #define __HAVE_RELEASE 1 #define DRIVER_RELEASE() do { \ - i830_reclaim_buffers( dev, priv->pid ); \ + i830_reclaim_buffers( filp ); \ } while (0) /* DMA customization: @@ -87,10 +102,49 @@ i830_dma_quiescent( dev ); \ } while (0) -/* Don't need an irq any more. The template code will make sure that - * a noop stub is generated for compatibility. + +/* Driver will work either way: IRQ's save cpu time when waiting for + * the card, but are subject to subtle interactions between bios, + * hardware and the driver. + */ +#define USE_IRQS 0 + + +#if USE_IRQS +#define __HAVE_DMA_IRQ 1 +#define __HAVE_SHARED_IRQ 1 + +#define DRIVER_PREINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + \ + I830_WRITE16( I830REG_HWSTAM, 0xffff ); \ + I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); \ +} while (0) + + +#define DRIVER_POSTINSTALL() do { \ + drm_i830_private_t *dev_priv = \ + (drm_i830_private_t *)dev->dev_private; \ + I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); \ + atomic_set(&dev_priv->irq_received, 0); \ + atomic_set(&dev_priv->irq_emitted, 0); \ + init_waitqueue_head(&dev_priv->irq_queue); \ +} while (0) + + +/* This gets called too late to be useful: dev_priv has already been + * freed. */ -#define __HAVE_DMA_IRQ 0 +#define DRIVER_UNINSTALL() do { \ +} while (0) + +#else +#define __HAVE_DMA_IRQ 0 +#endif + + /* Buffer customization: */ diff --git a/linux/i830_dma.c b/linux/i830_dma.c index d29e21cb..d2555c92 100644 --- a/linux/i830_dma.c +++ b/linux/i830_dma.c @@ -38,6 +38,7 @@ #include "i830_drm.h" #include "i830_drv.h" #include <linux/interrupt.h> /* For task queue support */ +#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */ #include <linux/delay.h> #ifdef DO_MUNMAP_4_ARGS @@ -53,8 +54,6 @@ #define I830_BUF_UNMAPPED 0 #define I830_BUF_MAPPED 1 -#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; - #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) #define down_write down #define up_write up @@ -67,32 +66,6 @@ #define UnlockPage(page) unlock_page(page) #endif -#define I830_VERBOSE 0 - -#define BEGIN_LP_RING(n) do { \ - if (I830_VERBOSE) \ - printk("BEGIN_LP_RING(%d) in %s\n", \ - n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ - dev_priv->ring.tail = outring; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) static inline void i830_print_status_page(drm_device_t *dev) { @@ -244,7 +217,6 @@ static int i830_unmap_buffer(drm_buf_t *buf) static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i830_buf_priv_t *buf_priv; int retcode = 0; @@ -252,7 +224,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, buf = i830_freelist_get(dev); if (!buf) { retcode = -ENOMEM; - DRM_ERROR("retcode=%d\n", retcode); + DRM_DEBUG("retcode=%d\n", retcode); return retcode; } @@ -262,7 +234,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -286,12 +258,21 @@ static int i830_dma_cleanup(drm_device_t *dev) dev_priv->ring.Size); } if(dev_priv->hw_status_page != 0UL) { - pci_free_consistent(dev->pdev, PAGE_SIZE, + pci_free_consistent(dev->pdev, PAGE_SIZE, (void *)dev_priv->hw_status_page, dev_priv->dma_status_page); /* Need to rewrite hardware status page */ I830_WRITE(0x02080, 0x1ffff000); } + + /* Disable interrupts here because after dev_private + * is freed, it's too late. + */ + if (dev->irq) { + I830_WRITE16( I830REG_INT_MASK_R, 0xffff ); + I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -305,7 +286,7 @@ static int i830_dma_cleanup(drm_device_t *dev) return 0; } -static int i830_wait_ring(drm_device_t *dev, int n) +int i830_wait_ring(drm_device_t *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -331,6 +312,7 @@ static int i830_wait_ring(drm_device_t *dev, int n) goto out_wait_ring; } udelay(1); + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } out_wait_ring: @@ -346,6 +328,9 @@ static void i830_kernel_lost_context(drm_device_t *dev) ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; + + if (ring->head == ring->tail) + dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) @@ -460,6 +445,8 @@ static int i830_dma_initialize(drm_device_t *dev, dev_priv->back_pitch = init->back_pitch; dev_priv->depth_pitch = init->depth_pitch; + dev_priv->do_boxes = 0; + dev_priv->use_mi_batchbuffer_start = 0; /* Program Hardware Status Page */ dev_priv->hw_status_page = @@ -474,7 +461,7 @@ static int i830_dma_initialize(drm_device_t *dev, memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); - I830_WRITE(0x02080, dev_priv->dma_status_page); + I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ @@ -535,11 +522,7 @@ static void i830EmitContextVerified( drm_device_t *dev, unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 ); - - OUT_RING( GFX_OP_STIPPLE ); - OUT_RING( 0 ); - + BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 ); for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { tmp = code[i]; @@ -577,38 +560,44 @@ static void i830EmitContextVerified( drm_device_t *dev, ADVANCE_LP_RING(); } -static void i830EmitTexVerified( drm_device_t *dev, - volatile unsigned int *code ) +static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); + if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || + (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == + (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { - OUT_RING( GFX_OP_MAP_INFO ); - OUT_RING( code[I830_TEXREG_MI1] ); - OUT_RING( code[I830_TEXREG_MI2] ); - OUT_RING( code[I830_TEXREG_MI3] ); - OUT_RING( code[I830_TEXREG_MI4] ); - OUT_RING( code[I830_TEXREG_MI5] ); + BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); - for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { - tmp = code[i]; - OUT_RING( tmp ); - j++; - } + OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ + OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ + OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ + OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ + OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ + OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } - if (j & 1) - OUT_RING( 0 ); + if (j & 1) + OUT_RING( 0 ); - ADVANCE_LP_RING(); + ADVANCE_LP_RING(); + } + else + printk("rejected packet %x\n", code[0]); } static void i830EmitTexBlendVerified( drm_device_t *dev, - volatile unsigned int *code, - volatile unsigned int num) + unsigned int *code, + unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -618,7 +607,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev, if (!num) return; - BEGIN_LP_RING( num ); + BEGIN_LP_RING( num + 1 ); for ( i = 0 ; i < num ; i++ ) { tmp = code[i]; @@ -641,6 +630,8 @@ static void i830EmitTexPalette( drm_device_t *dev, int i; RING_LOCALS; + return; + BEGIN_LP_RING( 258 ); if(is_shared == 1) { @@ -654,42 +645,41 @@ static void i830EmitTexPalette( drm_device_t *dev, OUT_RING(palette[i]); } OUT_RING(0); + /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! + */ } /* Need to do some additional checking when setting the dest buffer. */ static void i830EmitDestVerified( drm_device_t *dev, - volatile unsigned int *code ) + unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; - BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); + BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); + tmp = code[I830_DESTREG_CBUFADDR]; - if (tmp == dev_priv->front_di1) { - /* Don't use fence when front buffer rendering */ - OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); - OUT_RING( tmp ); + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + if (((int)outring) & 8) { + OUT_RING(0); + OUT_RING(0); + } OUT_RING( CMD_OP_DESTBUFFER_INFO ); - OUT_RING( BUF_3D_ID_DEPTH | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING( dev_priv->zi1 ); - } else if(tmp == dev_priv->back_di1) { - OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_USE_FENCE); OUT_RING( tmp ); + OUT_RING( 0 ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); + OUT_RING( 0 ); } else { DRM_ERROR("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); @@ -717,21 +707,35 @@ static void i830EmitDestVerified( drm_device_t *dev, OUT_RING( 0 ); } - OUT_RING( code[I830_DESTREG_SENABLE] ); - OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); + OUT_RING( 0 ); ADVANCE_LP_RING(); } +static void i830EmitStippleVerified( drm_device_t *dev, + unsigned int *code ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + BEGIN_LP_RING( 2 ); + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[1] ); + ADVANCE_LP_RING(); +} + + static void i830EmitState( drm_device_t *dev ) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; + DRM_DEBUG("%s %x\n", __FUNCTION__, dirty); + if (dirty & I830_UPLOAD_BUFFERS) { i830EmitDestVerified( dev, sarea_priv->BufferState ); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; @@ -765,17 +769,154 @@ static void i830EmitState( drm_device_t *dev ) } if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); } else { - if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); - } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); + } + + /* 1.3: + */ +#if 0 + if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } + if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { + i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); + sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); + } +#endif + } + + /* 1.3: + */ + if (dirty & I830_UPLOAD_STIPPLE) { + i830EmitStippleVerified( dev, + sarea_priv->StippleState); + sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; } + + if (dirty & I830_UPLOAD_TEX2) { + i830EmitTexVerified( dev, sarea_priv->TexState2 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX2; + } + + if (dirty & I830_UPLOAD_TEX3) { + i830EmitTexVerified( dev, sarea_priv->TexState3 ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX3; + } + + + if (dirty & I830_UPLOAD_TEXBLEND2) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState2, + sarea_priv->TexBlendStateWordsUsed2); + + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; + } + + if (dirty & I830_UPLOAD_TEXBLEND3) { + i830EmitTexBlendVerified( + dev, + sarea_priv->TexBlendState3, + sarea_priv->TexBlendStateWordsUsed3); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; + } +} + +/* ================================================================ + * Performance monitoring functions + */ + +static void i830_fill_box( drm_device_t *dev, + int x, int y, int w, int h, + int r, int g, int b ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + u32 color; + unsigned int BR13, CMD; + RING_LOCALS; + + BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + x += dev_priv->sarea_priv->boxes[0].x1; + y += dev_priv->sarea_priv->boxes[0].y1; + + if (dev_priv->cpp == 4) { + BR13 |= (1<<25); + CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + } else { + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + } + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (y << 16) | x ); + OUT_RING( ((y+h) << 16) | (x+w) ); + + if ( dev_priv->current_page == 1 ) { + OUT_RING( dev_priv->front_offset ); + } else { + OUT_RING( dev_priv->back_offset ); + } + + OUT_RING( color ); + ADVANCE_LP_RING(); +} + +static void i830_cp_performance_boxes( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + /* Purple box for page flipping + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) + i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); + + /* Red box if we have to wait for idle at any point + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) + i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); + + /* Blue box: lost context? + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) + i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); + + /* Yellow box for texture swaps + */ + if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) + i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); + + /* Green box if hardware never idles (as far as we can tell) + */ + if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) + i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); + + + /* Draw bars indicating number of buffers allocated + * (not a great measure, easily confused) + */ + if (dev_priv->dma_used) { + int bar = dev_priv->dma_used / 10240; + if (bar > 100) bar = 100; + if (bar < 1) bar = 1; + i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); + dev_priv->dma_used = 0; + } + + dev_priv->sarea_priv->perf_boxes = 0; } static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, @@ -793,6 +934,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int BR13, CMD, D_CMD; RING_LOCALS; + + if ( dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(I830_FRONT | I830_BACK); + if ( tmp & I830_FRONT ) flags |= I830_BACK; + if ( tmp & I830_BACK ) flags |= I830_FRONT; + } + i830_kernel_lost_context(dev); switch(cpp) { @@ -872,13 +1022,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int pitch = dev_priv->pitch; int cpp = dev_priv->cpp; - int ofs = dev_priv->back_offset; int i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) + i830_cp_performance_boxes( dev ); + switch(cpp) { case 2: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); @@ -895,7 +1049,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) break; } - i830_kernel_lost_context(dev); if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; @@ -915,23 +1068,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev ) BEGIN_LP_RING( 8 ); OUT_RING( CMD ); OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); - OUT_RING( (pbox->y2 << 16) | - pbox->x2 ); - - OUT_RING( dev_priv->front_offset ); - OUT_RING( (pbox->y1 << 16) | - pbox->x1 ); + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->front_offset ); + else + OUT_RING( dev_priv->back_offset ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( BR13 & 0xffff ); - OUT_RING( ofs ); + + if (dev_priv->current_page == 0) + OUT_RING( dev_priv->back_offset ); + else + OUT_RING( dev_priv->front_offset ); ADVANCE_LP_RING(); } } +static void i830_dma_dispatch_flip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pf_current_page); + + i830_kernel_lost_context(dev); + + if (dev_priv->do_boxes) { + dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; + i830_cp_performance_boxes( dev ); + } + + + BEGIN_LP_RING( 2 ); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP ); + OUT_RING( 0 ); + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + OUT_RING(0); + ADVANCE_LP_RING(); + + + BEGIN_LP_RING( 2 ); + OUT_RING( MI_WAIT_FOR_EVENT | + MI_WAIT_FOR_PLANE_A_FLIP ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} static void i830_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, @@ -984,8 +1186,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev, sarea_priv->vertex_prim | ((used/4)-2)); - vp[used/4] = MI_BATCH_BUFFER_END; - used += 4; + if (dev_priv->use_mi_batchbuffer_start) { + vp[used/4] = MI_BATCH_BUFFER_END; + used += 4; + } if (used & 4) { vp[used/4] = 0; @@ -1008,11 +1212,21 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev, ADVANCE_LP_RING(); } - BEGIN_LP_RING(2); - OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); - OUT_RING( start | MI_BATCH_NON_SECURE ); - ADVANCE_LP_RING(); - + if (dev_priv->use_mi_batchbuffer_start) { + BEGIN_LP_RING(2); + OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + ADVANCE_LP_RING(); + } + else { + BEGIN_LP_RING(4); + OUT_RING( MI_BATCH_BUFFER ); + OUT_RING( start | MI_BATCH_NON_SECURE ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + } while (++i < nbox); } @@ -1050,7 +1264,7 @@ void i830_dma_quiescent(drm_device_t *dev) OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); } static int i830_flush_queue(drm_device_t *dev) @@ -1067,7 +1281,7 @@ static int i830_flush_queue(drm_device_t *dev) OUT_RING( 0 ); ADVANCE_LP_RING(); - i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ ); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; @@ -1086,8 +1300,10 @@ static int i830_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i830_reclaim_buffers( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -1101,7 +1317,7 @@ void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); @@ -1207,6 +1423,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp, return 0; } + + +/* Not sure why this isn't set all the time: + */ +static void i830_do_init_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; +} + +int i830_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + if (dev_priv->current_page != 0) + i830_dma_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flip_buf called without lock held\n"); + return -EINVAL; + } + + if (!dev_priv->page_flipping) + i830_do_init_pageflip( dev ); + + i830_dma_dispatch_flip( dev ); + return 0; +} + int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1270,3 +1533,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, { return 0; } + + + +int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_getparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_PARAM_IRQ_ACTIVE: + value = dev->irq ? 1 : 0; + break; + default: + return -EINVAL; + } + + if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_setparam_t param; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user(¶m, (drm_i830_setparam_t *)arg, sizeof(param) )) + return -EFAULT; + + switch( param.param ) { + case I830_SETPARAM_USE_MI_BATCHBUFFER_START: + dev_priv->use_mi_batchbuffer_start = param.value; + break; + default: + return -EINVAL; + } + + return 0; +} diff --git a/linux/i830_drm.h b/linux/i830_drm.h index 725ad369..664ab0ed 100644 --- a/linux/i830_drm.h +++ b/linux/i830_drm.h @@ -3,6 +3,9 @@ /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. + * + * KW: Actually, you can't ever change them because doing so would + * break backwards compatibility. */ #ifndef _I830_DEFINES_ @@ -18,14 +21,12 @@ #define I830_NR_TEX_REGIONS 64 #define I830_LOG_MIN_TEX_REGION_SIZE 16 -/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ -#if !defined(I830_ENABLE_4_TEXTURES) +/* KW: These aren't correct but someone set them to two and then + * released the module. Now we can't change them as doing so would + * break backwards compatibility. + */ #define I830_TEXTURE_COUNT 2 -#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ -#else /* defined(I830_ENABLE_4_TEXTURES) */ -#define I830_TEXTURE_COUNT 4 -#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ -#endif /* I830_ENABLE_4_TEXTURES */ +#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ @@ -57,6 +58,7 @@ #define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 /* Indices into buf.Setup where various bits of state are mirrored per * context and per buffer. These can be fired at the card as a unit, @@ -73,7 +75,6 @@ */ #define I830_DESTREG_CBUFADDR 0 -/* Invarient */ #define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DV0 2 #define I830_DESTREG_DV1 3 @@ -109,6 +110,13 @@ #define I830_CTXREG_MCSB1 16 #define I830_CTX_SETUP_SIZE 17 +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + + /* Texture state (per tex unit) */ @@ -124,6 +132,18 @@ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEX_SETUP_SIZE 10 +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + #define I830_FRONT 0x1 #define I830_BACK 0x2 #define I830_DEPTH 0x4 @@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea { int ctxOwner; /* last context to upload state */ int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; } drm_i830_sarea_t; +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + /* I830 specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ @@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea { #define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) #define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) #define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49) +#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t) +#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t) +#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t) +#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t) typedef struct _drm_i830_clear { int clear_color; @@ -248,4 +300,36 @@ typedef struct drm_i830_dma { int granted; } drm_i830_dma_t; + +/* 1.3: Userspace can request & wait on irq's: + */ +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drm_i830_irq_emit_t; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drm_i830_irq_wait_t; + + +/* 1.3: New ioctl to query kernel params: + */ +#define I830_PARAM_IRQ_ACTIVE 1 + +typedef struct drm_i830_getparam { + int param; + int *value; +} drm_i830_getparam_t; + + +/* 1.3: New ioctl to set kernel params: + */ +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + +typedef struct drm_i830_setparam { + int param; + int value; +} drm_i830_setparam_t; + + #endif /* _I830_DRM_H_ */ diff --git a/linux/i830_drv.h b/linux/i830_drv.h index eec640ca..37313afd 100644 --- a/linux/i830_drv.h +++ b/linux/i830_drv.h @@ -78,6 +78,19 @@ typedef struct drm_i830_private { int back_pitch; int depth_pitch; unsigned int cpp; + + int do_boxes; + int dma_used; + + int current_page; + int page_flipping; + + wait_queue_head_t irq_queue; + atomic_t irq_received; + atomic_t irq_emitted; + + int use_mi_batchbuffer_start; + } drm_i830_private_t; /* i830_dma.c */ @@ -88,7 +101,7 @@ extern int i830_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i830_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i830_reclaim_buffers(struct file *filp); extern int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma); @@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp, extern int i830_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int i830_flip_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int i830_getparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int i830_setparam( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +/* i830_irq.c */ +extern int i830_irq_emit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_irq_wait( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int i830_wait_irq(drm_device_t *dev, int irq_nr); +extern int i830_emit_irq(drm_device_t *dev); + #define I830_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) @@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define I830_READ16(reg) I830_DEREF16(reg) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) + + +#define I830_VERBOSE 0 + +#define RING_LOCALS unsigned int outring, ringmask, outcount; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + printk("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i830_wait_ring(dev, n*4, __FUNCTION__); \ + outcount = 0; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ +} while (0) + + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outcount++; \ + outring += 4; \ + outring &= ringmask; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ + dev_priv->ring.tail = outring; \ + dev_priv->ring.space -= outcount * 4; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller); + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + #define INST_PARSER_CLIENT 0x00000000 #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 @@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_ENABLE_R 0x020a0 +#define I830_IRQ_RESERVED ((1<<13)|(3<<2)) + + #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 @@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) +#define ASYNC_FLIP (1<<22) + #define CMD_3D (0x3<<29) #define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) #define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) @@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp, #define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) +#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) + +#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) #endif diff --git a/linux/i830_irq.c b/linux/i830_irq.c new file mode 100644 index 00000000..cedafc0d --- /dev/null +++ b/linux/i830_irq.c @@ -0,0 +1,178 @@ +/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- + * + * Copyright 2002 Tungsten Graphics, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Keith Whitwell <keith@tungstengraphics.com> + * + */ + +#define __NO_VERSION__ +#include "i830.h" +#include "drmP.h" +#include "drm.h" +#include "i830_drm.h" +#include "i830_drv.h" +#include <linux/interrupt.h> /* For task queue support */ +#include <linux/delay.h> + + +void DRM(dma_service)(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u16 temp; + + temp = I830_READ16(I830REG_INT_IDENTITY_R); + printk("%s: %x\n", __FUNCTION__, temp); + + if(temp == 0) + return; + + I830_WRITE16(I830REG_INT_IDENTITY_R, temp); + + if (temp & 2) { + atomic_inc(&dev_priv->irq_received); + wake_up_interruptible(&dev_priv->irq_queue); + } +} + + +int i830_emit_irq(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG("%s\n", __FUNCTION__); + + atomic_inc(&dev_priv->irq_emitted); + + BEGIN_LP_RING(2); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + return atomic_read(&dev_priv->irq_emitted); +} + + +int i830_wait_irq(drm_device_t *dev, int irq_nr) +{ + drm_i830_private_t *dev_priv = + (drm_i830_private_t *)dev->dev_private; + DECLARE_WAITQUEUE(entry, current); + unsigned long end = jiffies + HZ*3; + int ret = 0; + + DRM_DEBUG("%s\n", __FUNCTION__); + + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + return 0; + + dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; + + add_wait_queue(&dev_priv->irq_queue, &entry); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + if (atomic_read(&dev_priv->irq_received) >= irq_nr) + break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", + I830_READ16( I830REG_INT_IDENTITY_R ), + I830_READ16( I830REG_INT_MASK_R ), + I830_READ16( I830REG_INT_ENABLE_R ), + I830_READ16( I830REG_HWSTAM )); + + ret = -EBUSY; /* Lockup? Missed irq? */ + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->irq_queue, &entry); + return ret; +} + + +/* Needs the lock as it touches the ring. + */ +int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_emit_t emit; + int result; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_irq_emit called without lock held\n"); + return -EINVAL; + } + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) )) + return -EFAULT; + + result = i830_emit_irq( dev ); + + if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return -EFAULT; + } + + return 0; +} + + +/* Doesn't need the hardware lock. + */ +int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_irq_wait_t irqwait; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return -EINVAL; + } + + if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg, + sizeof(irqwait) )) + return -EFAULT; + + return i830_wait_irq( dev, irqwait.irq_seq ); +} + diff --git a/linux/sis.h b/linux/sis.h index 0bf3dfa9..bc66f4dc 100644 --- a/linux/sis.h +++ b/linux/sis.h @@ -24,7 +24,7 @@ * DEALINGS IN THE SOFTWARE. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.2 2001/12/19 21:25:59 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.3 2002/10/30 12:52:38 alanh Exp $ */ #ifndef __SIS_H__ #define __SIS_H__ diff --git a/linux/sis_mm.c b/linux/sis_mm.c index 81832769..b2aa22d4 100644 --- a/linux/sis_mm.c +++ b/linux/sis_mm.c @@ -183,10 +183,10 @@ int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, if(block){ /* TODO */ agp.offset = block->ofs; - agp.free = (unsigned int)block; + agp.free = (unsigned long)block; if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){ DRM_DEBUG("adding to allocation set fails\n"); - mmFreeMem((PMemBlock)agp.free); + mmFreeMem((PMemBlock)(unsigned long)agp.free); retval = -1; } } @@ -219,7 +219,7 @@ int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, return -1; } - mmFreeMem((PMemBlock)agp.free); + mmFreeMem((PMemBlock)(unsigned long)agp.free); if(!del_alloc_set(agp.context, AGP_TYPE, agp.free)) retval = -1; @@ -289,7 +289,7 @@ int sis_final_context(int context) retval = setFirst(set, &item); while(retval){ DRM_DEBUG("free agp memory 0x%x\n", item); - mmFreeMem((PMemBlock)item); + mmFreeMem((PMemBlock)(unsigned long)item); retval = setNext(set, &item); } setDestroy(set); diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 65274f1d..bfb869e4 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -1013,7 +1013,7 @@ int mach64_dma_idle( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_dma_idle( dev_priv ); } @@ -1025,7 +1025,7 @@ int mach64_dma_flush( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_dma_flush( dev_priv ); } @@ -1037,7 +1037,7 @@ int mach64_engine_reset( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_engine_reset( dev_priv ); } @@ -1228,7 +1228,7 @@ _freelist_entry_found: * DMA buffer request and submission IOCTL handler */ -static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int mach64_dma_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -1242,7 +1242,7 @@ static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) if ( !buf ) return DRM_ERR(EAGAIN); #endif - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -1263,7 +1263,7 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) drm_dma_t d; int ret = 0; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -1289,7 +1289,7 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.request_count ) { - ret = mach64_dma_get_buffers( dev, &d ); + ret = mach64_dma_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index 74880250..8cfc97e9 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -728,16 +728,6 @@ mach64_update_ring_snapshot( drm_mach64_private_t *dev_priv ) } } -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - /* FIXME: right now this is needed to ensure free buffers for state emits */ /* CHECKME: I've disabled this as it isn't necessary - we already wait for free buffers */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) @@ -867,7 +857,7 @@ do { \ } while(0) /* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */ -#define DMAGETPTR( dev_priv, n ) \ +#define DMAGETPTR( filp, dev_priv, n ) \ do { \ if ( MACH64_VERBOSE ) { \ DRM_INFO( "DMAGETPTR( %d ) in %s\n", \ @@ -884,7 +874,7 @@ do { \ __FUNCTION__ ); \ return DRM_ERR(EFAULT); \ } \ - _buf->pid = DRM_CURRENTPID; \ + _buf->filp = filp; \ _outcount = 0; \ \ _buf_wptr = GETBUFPTR( _buf ); \ diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c index a2269701..3716102b 100644 --- a/shared-core/mach64_state.c +++ b/shared-core/mach64_state.c @@ -66,8 +66,8 @@ static void mach64_print_dirty( const char *msg, unsigned int flags ) /* This function returns 0 on success, 1 for no intersection, and * negative for an error */ -static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, - drm_clip_rect_t *box ) +static int mach64_emit_cliprect( DRMFILE filp, drm_mach64_private_t *dev_priv, + drm_clip_rect_t *box ) { u32 sc_left_right, sc_top_bottom; drm_clip_rect_t scissor; @@ -95,7 +95,7 @@ static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, if ( scissor.x1 >= scissor.x2 ) return 1; if ( scissor.y1 >= scissor.y2 ) return 1; - DMAGETPTR( dev_priv, 2 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 2 ); /* returns on failure to get buffer */ sc_left_right = ( (scissor.x1 << 0) | (scissor.x2 << 16) ); sc_top_bottom = ( (scissor.y1 << 0) | (scissor.y2 << 16) ); @@ -108,7 +108,7 @@ static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, return 0; } -static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) +static inline int mach64_emit_state( DRMFILE filp, drm_mach64_private_t *dev_priv ) { drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *regs = &sarea_priv->context_state; @@ -122,7 +122,7 @@ static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); } - DMAGETPTR( dev_priv, 17 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 17 ); /* returns on failure to get buffer */ if ( dirty & MACH64_UPLOAD_MISC ) { DMAOUTREG( MACH64_DP_MIX, regs->dp_mix ); @@ -187,11 +187,11 @@ static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) * DMA command dispatch functions */ -static int mach64_dma_dispatch_clear( drm_device_t *dev, - unsigned int flags, - int cx, int cy, int cw, int ch, - unsigned int clear_color, - unsigned int clear_depth ) +static int mach64_dma_dispatch_clear( DRMFILE filp, drm_device_t *dev, + unsigned int flags, + int cx, int cy, int cw, int ch, + unsigned int clear_color, + unsigned int clear_depth ) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -229,7 +229,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, if ( !nbox ) return 0; - DMAGETPTR( dev_priv, nbox * 31 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, nbox * 31 ); /* returns on failure to get buffer */ for ( i = 0 ; i < nbox ; i++ ) { int x = pbox[i].x1; @@ -337,7 +337,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, return 0; } -static int mach64_dma_dispatch_swap( drm_device_t *dev ) +static int mach64_dma_dispatch_swap( DRMFILE filp, drm_device_t *dev ) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -362,7 +362,7 @@ static int mach64_dma_dispatch_swap( drm_device_t *dev ) if ( !nbox ) return 0; - DMAGETPTR( dev_priv, 13 + nbox * 4 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 13 + nbox * 4 ); /* returns on failure to get buffer */ DMAOUTREG( MACH64_Z_CNTL, 0 ); DMAOUTREG( MACH64_SCALE_3D_CNTL, 0 ); @@ -524,7 +524,7 @@ static inline int copy_and_verify_from_user( u32 *to, const u32 *from, unsigned } } -static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, +static int mach64_dma_dispatch_vertex( DRMFILE filp, drm_device_t *dev, int prim, void *buf, unsigned long used, int discard ) { drm_mach64_private_t *dev_priv = dev->dev_private; @@ -548,21 +548,23 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, return DRM_ERR(EAGAIN); } - if ( (verify_ret = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { + if ( (verify_ret = + copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { copy_buf->used = used; DMASETPTR( copy_buf ); if ( sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS ) { - ret = mach64_emit_state( dev_priv ); + ret = mach64_emit_state( filp, dev_priv ); if (ret < 0) return ret; } do { /* Emit the next cliprect */ if ( i < sarea_priv->nbox ) { - ret = mach64_emit_cliprect(dev_priv, &sarea_priv->boxes[i]); + ret = mach64_emit_cliprect(filp, dev_priv, + &sarea_priv->boxes[i]); if ( ret < 0 ) { /* failed to get buffer */ return ret; @@ -616,7 +618,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, } -static int mach64_dma_dispatch_blit( drm_device_t *dev, +static int mach64_dma_dispatch_blit( DRMFILE filp, drm_device_t *dev, drm_mach64_blit_t *blit ) { drm_mach64_private_t *dev_priv = dev->dev_private; @@ -651,9 +653,9 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, */ buf = dma->buflist[blit->idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d (filp %p) using buffer with filp %p\n", + DRM_CURRENTPID, filp, buf->filp ); return DRM_ERR(EINVAL); } @@ -739,7 +741,7 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_mach64_clear_t *)data, sizeof(clear) ); @@ -749,9 +751,9 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_clear( dev, clear.flags, - clear.x, clear.y, clear.w, clear.h, - clear.clear_color, clear.clear_depth ); + ret = mach64_dma_dispatch_clear( filp, dev, clear.flags, + clear.x, clear.y, clear.w, clear.h, + clear.clear_color, clear.clear_depth ); /* Make sure we restore the 3D state next time. */ @@ -769,14 +771,14 @@ int mach64_dma_swap( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_swap( dev ); + ret = mach64_dma_dispatch_swap( filp, dev ); /* Make sure we restore the 3D state next time. */ @@ -792,7 +794,7 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -822,7 +824,7 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - return mach64_dma_dispatch_vertex( dev, vertex.prim, vertex.buf, + return mach64_dma_dispatch_vertex( filp, dev, vertex.prim, vertex.buf, vertex.used, vertex.discard ); } @@ -835,7 +837,7 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) drm_mach64_blit_t blit; int ret; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_mach64_blit_t *)data, sizeof(blit) ); @@ -851,7 +853,7 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); - ret = mach64_dma_dispatch_blit( dev, &blit ); + ret = mach64_dma_dispatch_blit( filp, dev, &blit ); /* Make sure we restore the 3D state next time. */ @@ -882,7 +884,7 @@ int mach64_get_param( DRM_IOCTL_ARGS ) switch ( param.param ) { case MACH64_PARAM_FRAMES_QUEUED: /* Needs lock since it calls mach64_ring_tick() */ - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); value = mach64_do_get_frames_queued( dev_priv ); break; case MACH64_PARAM_IRQ_NR: diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index 22bd61f0..5e95c9f9 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -686,7 +686,7 @@ int mga_dma_flush( DRM_IOCTL_ARGS ) drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_lock_t lock; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); @@ -720,7 +720,7 @@ int mga_dma_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mga_do_dma_reset( dev_priv ); } @@ -730,7 +730,8 @@ int mga_dma_reset( DRM_IOCTL_ARGS ) * DMA buffer management */ -static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int mga_dma_get_buffers( DRMFILE filp, + drm_device_t *dev, drm_dma_t *d ) { drm_buf_t *buf; int i; @@ -739,7 +740,7 @@ static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = mga_freelist_get( dev ); if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -761,7 +762,7 @@ int mga_dma_buffers( DRM_IOCTL_ARGS ) drm_dma_t d; int ret = 0; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -786,7 +787,7 @@ int mga_dma_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = mga_dma_get_buffers( dev, &d ); + ret = mga_dma_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h index a5085b06..7efc89bc 100644 --- a/shared-core/mga_drv.h +++ b/shared-core/mga_drv.h @@ -90,14 +90,14 @@ typedef struct drm_mga_private { unsigned int texture_offset; unsigned int texture_size; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *status; - drm_map_t *warp; - drm_map_t *primary; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *status; + drm_local_map_t *warp; + drm_local_map_t *primary; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; } drm_mga_private_t; /* mga_dma.c */ @@ -131,32 +131,30 @@ extern int mga_getparam( DRM_IOCTL_ARGS ); extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv ); extern int mga_warp_init( drm_mga_private_t *dev_priv ); -#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() - +#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->primary) +#if defined(__linux__) && defined(__alpha__) #define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) #define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) #define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg ) #define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg ) -#ifdef __alpha__ #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) #define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) +#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0) +#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0) static inline u32 _MGA_READ(u32 *addr) { - DRM_READMEMORYBARRIER(); + DRM_READMEMORYBARRIER(dev_priv->mmio); return *(volatile u32 *)addr; } - #else -#define MGA_READ( reg ) MGA_DEREF( reg ) -#define MGA_READ8( reg ) MGA_DEREF8( reg ) -#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0) +#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg)) +#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg)) +#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val)) +#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val)) #endif #define DWGREG0 0x1c00 @@ -186,16 +184,6 @@ do { \ } \ } while (0) -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - #define WRAP_TEST_WITH_RETURN( dev_priv ) \ do { \ if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ diff --git a/shared-core/mga_state.c b/shared-core/mga_state.c index 61077220..256dd47d 100644 --- a/shared-core/mga_state.c +++ b/shared-core/mga_state.c @@ -887,7 +887,7 @@ int mga_dma_clear( DRM_IOCTL_ARGS ) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t *)data, sizeof(clear) ); @@ -911,7 +911,7 @@ int mga_dma_swap( DRM_IOCTL_ARGS ) drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -936,7 +936,7 @@ int mga_dma_vertex( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( vertex, (drm_mga_vertex_t *)data, @@ -975,7 +975,7 @@ int mga_dma_indices( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_indices_t indices; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( indices, (drm_mga_indices_t *)data, @@ -1015,7 +1015,7 @@ int mga_dma_iload( DRM_IOCTL_ARGS ) drm_mga_iload_t iload; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t *)data, sizeof(iload) ); @@ -1055,7 +1055,7 @@ int mga_dma_blit( DRM_IOCTL_ARGS ) drm_mga_blit_t blit; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t *)data, sizeof(blit) ); diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c index 5175885e..7f0f4325 100644 --- a/shared-core/r128_cce.c +++ b/shared-core/r128_cce.c @@ -579,6 +579,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = 128; + dev_priv->ring.ring_rptr = dev_priv->ring_rptr; dev_priv->sarea_priv->last_frame = 0; R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); @@ -663,7 +664,7 @@ int r128_cce_start( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); @@ -686,7 +687,7 @@ int r128_cce_stop( DRM_IOCTL_ARGS ) int ret; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) ); @@ -725,7 +726,7 @@ int r128_cce_reset( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); @@ -746,7 +747,7 @@ int r128_cce_idle( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cce_running ) { r128_do_cce_flush( dev_priv ); @@ -760,7 +761,7 @@ int r128_engine_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return r128_do_engine_reset( dev ); } @@ -807,7 +808,7 @@ int r128_fullscreen( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_r128_fullscreen_t fs; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); @@ -889,7 +890,7 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev ) for ( i = 0 ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 ) + if ( buf->filp == 0 ) return buf; } @@ -948,7 +949,7 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) return DRM_ERR(EBUSY); } -static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -957,7 +958,7 @@ static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = r128_freelist_get( dev ); if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -978,7 +979,7 @@ int r128_cce_buffers( DRM_IOCTL_ARGS ) int ret = 0; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *) data, sizeof(d) ); @@ -1001,7 +1002,7 @@ int r128_cce_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = r128_cce_get_buffers( dev, &d ); + ret = r128_cce_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d) ); diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h index 763fcb3a..bd913878 100644 --- a/shared-core/r128_drv.h +++ b/shared-core/r128_drv.h @@ -34,8 +34,8 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) ) +#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ typedef struct drm_r128_freelist { unsigned int age; @@ -56,6 +56,7 @@ typedef struct drm_r128_ring_buffer { int space; int high_mark; + drm_local_map_t *ring_rptr; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { @@ -98,13 +99,13 @@ typedef struct drm_r128_private { u32 depth_pitch_offset_c; u32 span_pitch_offset_c; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *cce_ring; - drm_map_t *ring_rptr; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *cce_ring; + drm_local_map_t *ring_rptr; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; } drm_r128_private_t; typedef struct drm_r128_buf_priv { @@ -370,15 +371,10 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS ); #define R128_PERFORMANCE_BOXES 0 - -#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) -#define R128_ADDR(reg) (R128_BASE( reg ) + reg) - -#define R128_READ(reg) DRM_READ32( (volatile u32 *) R128_ADDR(reg) ) -#define R128_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) ) - -#define R128_READ8(reg) DRM_READ8( (volatile u8 *) R128_ADDR(reg) ) -#define R128_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) ) +#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) +#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) #define R128_WRITE_PLL(addr,val) \ do { \ @@ -403,15 +399,6 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); * Misc helper macros */ -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ @@ -453,7 +440,7 @@ do { \ #if defined(__powerpc__) #define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) #else -#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() +#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr) #endif diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c index 68f73061..8b9e97cf 100644 --- a/shared-core/r128_state.c +++ b/shared-core/r128_state.c @@ -778,7 +778,8 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, sarea_priv->nbox = 0; } -static int r128_cce_dispatch_blit( drm_device_t *dev, +static int r128_cce_dispatch_blit( DRMFILE filp, + drm_device_t *dev, drm_r128_blit_t *blit ) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -829,9 +830,9 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, buf = dma->buflist[blit->idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -896,7 +897,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, int count, x, y; u32 *buffer; u8 *mask; - int i; + int i, buffer_size, mask_size; RING_LOCALS; DRM_DEBUG( "\n" ); @@ -908,25 +909,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, return DRM_ERR(EFAULT); } - buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + buffer_size = depth->n * sizeof(u32); + buffer = DRM_MALLOC( buffer_size ); if ( buffer == NULL ) return DRM_ERR(ENOMEM); - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, - depth->n * sizeof(u32) ) ) { - DRM_FREE( buffer ); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { + DRM_FREE( buffer, buffer_size); return DRM_ERR(EFAULT); } + mask_size = depth->n * sizeof(u8); if ( depth->mask ) { - mask = DRM_MALLOC( depth->n * sizeof(u8) ); + mask = DRM_MALLOC( mask_size ); if ( mask == NULL ) { - DRM_FREE( buffer ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, - depth->n * sizeof(u8) ) ) { - DRM_FREE( buffer ); - DRM_FREE( mask ); + if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { + DRM_FREE( buffer, buffer_size ); + DRM_FREE( mask, mask_size ); return DRM_ERR(EFAULT); } @@ -953,7 +954,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - DRM_FREE( mask ); + DRM_FREE( mask, mask_size ); } else { for ( i = 0 ; i < count ; i++, x++ ) { BEGIN_RING( 6 ); @@ -977,7 +978,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - DRM_FREE( buffer ); + DRM_FREE( buffer, buffer_size ); return 0; } @@ -989,60 +990,62 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, int count, *x, *y; u32 *buffer; u8 *mask; - int i; + int i, xbuf_size, ybuf_size, buffer_size, mask_size; RING_LOCALS; DRM_DEBUG( "\n" ); count = depth->n; - x = DRM_MALLOC( count * sizeof(*x) ); + xbuf_size = count * sizeof(*x); + ybuf_size = count * sizeof(*y); + x = DRM_MALLOC( xbuf_size ); if ( x == NULL ) { return DRM_ERR(ENOMEM); } - y = DRM_MALLOC( count * sizeof(*y) ); + y = DRM_MALLOC( ybuf_size ); if ( y == NULL ) { - DRM_FREE( x ); + DRM_FREE( x, xbuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + buffer_size = depth->n * sizeof(u32); + buffer = DRM_MALLOC( buffer_size ); if ( buffer == NULL ) { - DRM_FREE( x ); - DRM_FREE( y ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, - depth->n * sizeof(u32) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(EFAULT); } if ( depth->mask ) { - mask = DRM_MALLOC( depth->n * sizeof(u8) ); + mask_size = depth->n * sizeof(u8); + mask = DRM_MALLOC( mask_size ); if ( mask == NULL ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, - depth->n * sizeof(u8) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); - DRM_FREE( mask ); + if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); + DRM_FREE( mask, mask_size ); return DRM_ERR(EFAULT); } @@ -1069,7 +1072,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - DRM_FREE( mask ); + DRM_FREE( mask, mask_size ); } else { for ( i = 0 ; i < count ; i++ ) { BEGIN_RING( 6 ); @@ -1093,9 +1096,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return 0; } @@ -1146,7 +1149,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; - int i; + int i, xbuf_size, ybuf_size; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -1155,23 +1158,25 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, count = dev_priv->depth_pitch; } - x = DRM_MALLOC( count * sizeof(*x) ); + xbuf_size = count * sizeof(*x); + ybuf_size = count * sizeof(*y); + x = DRM_MALLOC( xbuf_size ); if ( x == NULL ) { return DRM_ERR(ENOMEM); } - y = DRM_MALLOC( count * sizeof(*y) ); + y = DRM_MALLOC( ybuf_size ); if ( y == NULL ) { - DRM_FREE( x ); + DRM_FREE( x, xbuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } @@ -1199,8 +1204,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, ADVANCE_RING(); } - DRM_FREE( x ); - DRM_FREE( y ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return 0; } @@ -1240,7 +1245,7 @@ int r128_cce_clear( DRM_IOCTL_ARGS ) drm_r128_clear_t clear; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data, sizeof(clear) ); @@ -1266,7 +1271,7 @@ int r128_cce_swap( DRM_IOCTL_ARGS ) drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1293,7 +1298,7 @@ int r128_cce_vertex( DRM_IOCTL_ARGS ) drm_r128_buf_priv_t *buf_priv; drm_r128_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1324,9 +1329,9 @@ int r128_cce_vertex( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1353,7 +1358,7 @@ int r128_cce_indices( DRM_IOCTL_ARGS ) drm_r128_indices_t elts; int count; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1383,9 +1388,9 @@ int r128_cce_indices( DRM_IOCTL_ARGS ) buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1421,7 +1426,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data, sizeof(blit) ); @@ -1437,7 +1442,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return r128_cce_dispatch_blit( dev, &blit ); + return r128_cce_dispatch_blit( filp, dev, &blit ); } int r128_cce_depth( DRM_IOCTL_ARGS ) @@ -1446,7 +1451,7 @@ int r128_cce_depth( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data, sizeof(depth) ); @@ -1474,7 +1479,7 @@ int r128_cce_stipple( DRM_IOCTL_ARGS ) drm_r128_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data, sizeof(stipple) ); @@ -1502,7 +1507,7 @@ int r128_cce_indirect( DRM_IOCTL_ARGS ) RING_LOCALS; #endif - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1525,9 +1530,9 @@ int r128_cce_indirect( DRM_IOCTL_ARGS ) buf = dma->buflist[indirect.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6994fe9e..3ec8dfd1 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -926,11 +926,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); /* Writeback doesn't seem to work everywhere, test it first */ - DRM_WRITE32( &dev_priv->scratch[1], 0 ); + DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { - if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef ) + if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) break; DRM_UDELAY( 1 ); } @@ -1217,6 +1217,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + dev_priv->ring.ring_rptr = dev_priv->ring_rptr; #if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { @@ -1322,7 +1323,7 @@ int radeon_cp_start( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cp_running ) { DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); @@ -1350,7 +1351,7 @@ int radeon_cp_stop( DRM_IOCTL_ARGS ) int ret; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); @@ -1425,7 +1426,7 @@ int radeon_cp_reset( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); @@ -1446,7 +1447,7 @@ int radeon_cp_idle( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return radeon_do_cp_idle( dev_priv ); } @@ -1456,7 +1457,7 @@ int radeon_engine_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return radeon_do_engine_reset( dev ); } @@ -1515,7 +1516,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) for ( i = start ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 || (buf->pending && + if ( buf->filp == 0 || (buf->pending && buf_priv->age <= done_age) ) { dev_priv->stats.requested_bufs++; buf->pending = 0; @@ -1542,7 +1543,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) drm_buf_t *buf; int i, t; int start; - u32 done_age = DRM_READ32(&dev_priv->scratch[1]); + u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); if ( ++dev_priv->last_buf >= dma->buf_count ) dev_priv->last_buf = 0; @@ -1554,7 +1555,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) for ( i = start ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 || (buf->pending && + if ( buf->filp == 0 || (buf->pending && buf_priv->age <= done_age) ) { dev_priv->stats.requested_bufs++; buf->pending = 0; @@ -1619,7 +1620,7 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) return DRM_ERR(EBUSY); } -static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -1628,7 +1629,7 @@ static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = radeon_freelist_get( dev ); if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -1649,7 +1650,7 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) int ret = 0; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -1672,7 +1673,7 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = radeon_cp_get_buffers( dev, &d ); + ret = radeon_cp_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 512d36b9..3ab57309 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -396,7 +396,7 @@ typedef struct drm_radeon_init { enum { RADEON_INIT_CP = 0x01, RADEON_CLEANUP_CP = 0x02, - RADEON_INIT_R200_CP = 0x03, + RADEON_INIT_R200_CP = 0x03 } func; unsigned long sarea_priv_offset; int is_pci; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index fb8fbafe..7faffa7a 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -31,8 +31,8 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head , (val)) +#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ typedef struct drm_radeon_freelist { unsigned int age; @@ -53,6 +53,7 @@ typedef struct drm_radeon_ring_buffer { int space; int high_mark; + drm_local_map_t *ring_rptr; } drm_radeon_ring_buffer_t; typedef struct drm_radeon_depth_clear_t { @@ -67,7 +68,7 @@ struct mem_block { struct mem_block *prev; int start; int size; - int pid; /* 0: free, -1: heap, other: real pids */ + DRMFILE filp; /* 0: free, -1: heap, other: real files */ }; typedef struct drm_radeon_private { @@ -126,13 +127,13 @@ typedef struct drm_radeon_private { drm_radeon_depth_clear_t depth_clear; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *cp_ring; - drm_map_t *ring_rptr; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *cp_ring; + drm_local_map_t *ring_rptr; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; struct mem_block *agp_heap; struct mem_block *fb_heap; @@ -183,7 +184,7 @@ extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); extern int radeon_mem_free( DRM_IOCTL_ARGS ); extern int radeon_mem_init_heap( DRM_IOCTL_ARGS ); extern void radeon_mem_takedown( struct mem_block **heap ); -extern void radeon_mem_release( struct mem_block *heap ); +extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap ); /* radeon_irq.c */ extern int radeon_irq_emit( DRM_IOCTL_ARGS ); @@ -267,8 +268,10 @@ extern void radeon_do_release(drm_device_t *dev); #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 +#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) + #define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( &dev_priv->scratch[(x)] ) \ + ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) @@ -687,15 +690,10 @@ extern void radeon_do_release(drm_device_t *dev); #define RADEON_RING_HIGH_MARK 128 - -#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) -#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) - -#define RADEON_READ(reg) DRM_READ32( (volatile u32 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) ) - -#define RADEON_READ8(reg) DRM_READ8( (volatile u8 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) ) +#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) +#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) #define RADEON_WRITE_PLL( addr, val ) \ do { \ @@ -772,16 +770,6 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); * Misc helper macros */ -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - - /* Perfbox functionality only. */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ @@ -859,7 +847,7 @@ do { \ #define COMMIT_RING() do { \ /* Flush writes to ring */ \ - DRM_READMEMORYBARRIER(); \ + DRM_READMEMORYBARRIER(dev_priv->mmio); \ GET_RING_HEAD( &dev_priv->ring ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ /* read from PCI bus to ensure correct posting */ \ diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 596706bf..9199fbbf 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -179,7 +179,7 @@ int radeon_irq_emit( DRM_IOCTL_ARGS ) drm_radeon_irq_emit_t emit; int result; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c index 7ca10753..c3cbd3a9 100644 --- a/shared-core/radeon_mem.c +++ b/shared-core/radeon_mem.c @@ -40,7 +40,7 @@ */ static struct mem_block *split_block(struct mem_block *p, int start, int size, - int pid ) + DRMFILE filp ) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -49,7 +49,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->pid = 0; + newblock->filp = 0; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -65,7 +65,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->pid = 0; + newblock->filp = 0; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -75,20 +75,20 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, out: /* Our block is in the middle */ - p->pid = pid; + p->filp = filp; return p; } static struct mem_block *alloc_block( struct mem_block *heap, int size, - int align2, int pid ) + int align2, DRMFILE filp ) { struct mem_block *p; int mask = (1 << align2)-1; for (p = heap->next ; p != heap ; p = p->next) { int start = (p->start + mask) & ~mask; - if (p->pid == 0 && start + size <= p->start + p->size) - return split_block( p, start, size, pid ); + if (p->filp == 0 && start + size <= p->start + p->size) + return split_block( p, start, size, filp ); } return NULL; @@ -108,25 +108,25 @@ static struct mem_block *find_block( struct mem_block *heap, int start ) static void free_block( struct mem_block *p ) { - p->pid = 0; + p->filp = 0; - /* Assumes a single contiguous range. Needs a special pid in + /* Assumes a single contiguous range. Needs a special filp in * 'heap' to stop it being subsumed. */ - if (p->next->pid == 0) { + if (p->next->filp == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; p->next->prev = p; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } - if (p->prev->pid == 0) { + if (p->prev->filp == 0) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; q->next->prev = q; - DRM_FREE(p); + DRM_FREE(p, sizeof(*q)); } } @@ -141,47 +141,46 @@ static int init_heap(struct mem_block **heap, int start, int size) *heap = DRM_MALLOC(sizeof(**heap)); if (!*heap) { - DRM_FREE( blocks ); + DRM_FREE( blocks, sizeof(*blocks) ); return -ENOMEM; } blocks->start = start; blocks->size = size; - blocks->pid = 0; + blocks->filp = 0; blocks->next = blocks->prev = *heap; memset( *heap, 0, sizeof(**heap) ); - (*heap)->pid = -1; + (*heap)->filp = (DRMFILE) -1; (*heap)->next = (*heap)->prev = blocks; return 0; } -/* Free all blocks associated with the releasing pid. +/* Free all blocks associated with the releasing file. */ -void radeon_mem_release( struct mem_block *heap ) +void radeon_mem_release( DRMFILE filp, struct mem_block *heap ) { - int pid = DRM_CURRENTPID; struct mem_block *p; if (!heap || !heap->next) return; for (p = heap->next ; p != heap ; p = p->next) { - if (p->pid == pid) - p->pid = 0; + if (p->filp == filp) + p->filp = 0; } - /* Assumes a single contiguous range. Needs a special pid in + /* Assumes a single contiguous range. Needs a special filp in * 'heap' to stop it being subsumed. */ for (p = heap->next ; p != heap ; p = p->next) { - while (p->pid == 0 && p->next->pid == 0) { + while (p->filp == 0 && p->next->filp == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; p->next->prev = p; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } } } @@ -198,10 +197,10 @@ void radeon_mem_takedown( struct mem_block **heap ) for (p = (*heap)->next ; p != *heap ; ) { struct mem_block *q = p; p = p->next; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } - DRM_FREE( *heap ); + DRM_FREE( *heap, sizeof(**heap) ); *heap = 0; } @@ -248,7 +247,7 @@ int radeon_mem_alloc( DRM_IOCTL_ARGS ) alloc.alignment = 12; block = alloc_block( *heap, alloc.size, alloc.alignment, - DRM_CURRENTPID ); + filp ); if (!block) return DRM_ERR(ENOMEM); @@ -287,7 +286,7 @@ int radeon_mem_free( DRM_IOCTL_ARGS ) if (!block) return DRM_ERR(EFAULT); - if (block->pid != DRM_CURRENTPID) + if (block->filp != filp) return DRM_ERR(EPERM); free_block( block ); diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index d9bc948c..86cbead5 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -1063,7 +1063,8 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) -static int radeon_cp_dispatch_texture( drm_device_t *dev, +static int radeon_cp_dispatch_texture( DRMFILE filp, + drm_device_t *dev, drm_radeon_texture_t *tex, drm_radeon_tex_image_t *image ) { @@ -1216,7 +1217,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, } } - buf->pid = DRM_CURRENTPID; + buf->filp = filp; buf->used = (dwords + 8) * sizeof(u32); radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); radeon_cp_discard_buffer( dev, buf ); @@ -1273,7 +1274,7 @@ int radeon_cp_clear( DRM_IOCTL_ARGS ) drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, sizeof(clear) ); @@ -1342,7 +1343,7 @@ int radeon_cp_flip( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1362,7 +1363,7 @@ int radeon_cp_swap( DRM_IOCTL_ARGS ) drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1386,7 +1387,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS ) drm_radeon_vertex_t vertex; drm_radeon_tcl_prim_t prim; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1416,9 +1417,9 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1473,7 +1474,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS ) drm_radeon_tcl_prim_t prim; int count; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1503,9 +1504,9 @@ int radeon_cp_indices( DRM_IOCTL_ARGS ) buf = dma->buflist[elts.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1568,7 +1569,7 @@ int radeon_cp_texture( DRM_IOCTL_ARGS ) drm_radeon_tex_image_t image; int ret; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); @@ -1585,7 +1586,7 @@ int radeon_cp_texture( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - ret = radeon_cp_dispatch_texture( dev, &tex, &image ); + ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image ); COMMIT_RING(); return ret; @@ -1598,7 +1599,7 @@ int radeon_cp_stipple( DRM_IOCTL_ARGS ) drm_radeon_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, sizeof(stipple) ); @@ -1623,7 +1624,7 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS ) drm_radeon_indirect_t indirect; RING_LOCALS; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1645,9 +1646,9 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS ) buf = dma->buflist[indirect.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1700,7 +1701,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS ) int i; unsigned char laststate; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1725,9 +1726,9 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } @@ -2027,7 +2028,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) drm_radeon_cmd_header_t header; int orig_nbox; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -2096,8 +2097,9 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID || buf->pending ) { - DRM_ERROR( "bad buffer\n" ); + if ( buf->filp != filp || buf->pending ) { + DRM_ERROR( "bad buffer %p %p %d\n", + buf->filp, filp, buf->pending); return DRM_ERR(EINVAL); } diff --git a/shared/mach64_dma.c b/shared/mach64_dma.c index 65274f1d..bfb869e4 100644 --- a/shared/mach64_dma.c +++ b/shared/mach64_dma.c @@ -1013,7 +1013,7 @@ int mach64_dma_idle( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_dma_idle( dev_priv ); } @@ -1025,7 +1025,7 @@ int mach64_dma_flush( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_dma_flush( dev_priv ); } @@ -1037,7 +1037,7 @@ int mach64_engine_reset( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mach64_do_engine_reset( dev_priv ); } @@ -1228,7 +1228,7 @@ _freelist_entry_found: * DMA buffer request and submission IOCTL handler */ -static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int mach64_dma_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -1242,7 +1242,7 @@ static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) if ( !buf ) return DRM_ERR(EAGAIN); #endif - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -1263,7 +1263,7 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) drm_dma_t d; int ret = 0; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -1289,7 +1289,7 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.request_count ) { - ret = mach64_dma_get_buffers( dev, &d ); + ret = mach64_dma_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared/mach64_drv.h b/shared/mach64_drv.h index 74880250..8cfc97e9 100644 --- a/shared/mach64_drv.h +++ b/shared/mach64_drv.h @@ -728,16 +728,6 @@ mach64_update_ring_snapshot( drm_mach64_private_t *dev_priv ) } } -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - /* FIXME: right now this is needed to ensure free buffers for state emits */ /* CHECKME: I've disabled this as it isn't necessary - we already wait for free buffers */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) @@ -867,7 +857,7 @@ do { \ } while(0) /* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */ -#define DMAGETPTR( dev_priv, n ) \ +#define DMAGETPTR( filp, dev_priv, n ) \ do { \ if ( MACH64_VERBOSE ) { \ DRM_INFO( "DMAGETPTR( %d ) in %s\n", \ @@ -884,7 +874,7 @@ do { \ __FUNCTION__ ); \ return DRM_ERR(EFAULT); \ } \ - _buf->pid = DRM_CURRENTPID; \ + _buf->filp = filp; \ _outcount = 0; \ \ _buf_wptr = GETBUFPTR( _buf ); \ diff --git a/shared/mach64_state.c b/shared/mach64_state.c index a2269701..3716102b 100644 --- a/shared/mach64_state.c +++ b/shared/mach64_state.c @@ -66,8 +66,8 @@ static void mach64_print_dirty( const char *msg, unsigned int flags ) /* This function returns 0 on success, 1 for no intersection, and * negative for an error */ -static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, - drm_clip_rect_t *box ) +static int mach64_emit_cliprect( DRMFILE filp, drm_mach64_private_t *dev_priv, + drm_clip_rect_t *box ) { u32 sc_left_right, sc_top_bottom; drm_clip_rect_t scissor; @@ -95,7 +95,7 @@ static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, if ( scissor.x1 >= scissor.x2 ) return 1; if ( scissor.y1 >= scissor.y2 ) return 1; - DMAGETPTR( dev_priv, 2 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 2 ); /* returns on failure to get buffer */ sc_left_right = ( (scissor.x1 << 0) | (scissor.x2 << 16) ); sc_top_bottom = ( (scissor.y1 << 0) | (scissor.y2 << 16) ); @@ -108,7 +108,7 @@ static int mach64_emit_cliprect( drm_mach64_private_t *dev_priv, return 0; } -static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) +static inline int mach64_emit_state( DRMFILE filp, drm_mach64_private_t *dev_priv ) { drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *regs = &sarea_priv->context_state; @@ -122,7 +122,7 @@ static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); } - DMAGETPTR( dev_priv, 17 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 17 ); /* returns on failure to get buffer */ if ( dirty & MACH64_UPLOAD_MISC ) { DMAOUTREG( MACH64_DP_MIX, regs->dp_mix ); @@ -187,11 +187,11 @@ static inline int mach64_emit_state( drm_mach64_private_t *dev_priv ) * DMA command dispatch functions */ -static int mach64_dma_dispatch_clear( drm_device_t *dev, - unsigned int flags, - int cx, int cy, int cw, int ch, - unsigned int clear_color, - unsigned int clear_depth ) +static int mach64_dma_dispatch_clear( DRMFILE filp, drm_device_t *dev, + unsigned int flags, + int cx, int cy, int cw, int ch, + unsigned int clear_color, + unsigned int clear_depth ) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -229,7 +229,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, if ( !nbox ) return 0; - DMAGETPTR( dev_priv, nbox * 31 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, nbox * 31 ); /* returns on failure to get buffer */ for ( i = 0 ; i < nbox ; i++ ) { int x = pbox[i].x1; @@ -337,7 +337,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, return 0; } -static int mach64_dma_dispatch_swap( drm_device_t *dev ) +static int mach64_dma_dispatch_swap( DRMFILE filp, drm_device_t *dev ) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -362,7 +362,7 @@ static int mach64_dma_dispatch_swap( drm_device_t *dev ) if ( !nbox ) return 0; - DMAGETPTR( dev_priv, 13 + nbox * 4 ); /* returns on failure to get buffer */ + DMAGETPTR( filp, dev_priv, 13 + nbox * 4 ); /* returns on failure to get buffer */ DMAOUTREG( MACH64_Z_CNTL, 0 ); DMAOUTREG( MACH64_SCALE_3D_CNTL, 0 ); @@ -524,7 +524,7 @@ static inline int copy_and_verify_from_user( u32 *to, const u32 *from, unsigned } } -static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, +static int mach64_dma_dispatch_vertex( DRMFILE filp, drm_device_t *dev, int prim, void *buf, unsigned long used, int discard ) { drm_mach64_private_t *dev_priv = dev->dev_private; @@ -548,21 +548,23 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, return DRM_ERR(EAGAIN); } - if ( (verify_ret = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { + if ( (verify_ret = + copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { copy_buf->used = used; DMASETPTR( copy_buf ); if ( sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS ) { - ret = mach64_emit_state( dev_priv ); + ret = mach64_emit_state( filp, dev_priv ); if (ret < 0) return ret; } do { /* Emit the next cliprect */ if ( i < sarea_priv->nbox ) { - ret = mach64_emit_cliprect(dev_priv, &sarea_priv->boxes[i]); + ret = mach64_emit_cliprect(filp, dev_priv, + &sarea_priv->boxes[i]); if ( ret < 0 ) { /* failed to get buffer */ return ret; @@ -616,7 +618,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, } -static int mach64_dma_dispatch_blit( drm_device_t *dev, +static int mach64_dma_dispatch_blit( DRMFILE filp, drm_device_t *dev, drm_mach64_blit_t *blit ) { drm_mach64_private_t *dev_priv = dev->dev_private; @@ -651,9 +653,9 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, */ buf = dma->buflist[blit->idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d (filp %p) using buffer with filp %p\n", + DRM_CURRENTPID, filp, buf->filp ); return DRM_ERR(EINVAL); } @@ -739,7 +741,7 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_mach64_clear_t *)data, sizeof(clear) ); @@ -749,9 +751,9 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_clear( dev, clear.flags, - clear.x, clear.y, clear.w, clear.h, - clear.clear_color, clear.clear_depth ); + ret = mach64_dma_dispatch_clear( filp, dev, clear.flags, + clear.x, clear.y, clear.w, clear.h, + clear.clear_color, clear.clear_depth ); /* Make sure we restore the 3D state next time. */ @@ -769,14 +771,14 @@ int mach64_dma_swap( DRM_IOCTL_ARGS ) DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_swap( dev ); + ret = mach64_dma_dispatch_swap( filp, dev ); /* Make sure we restore the 3D state next time. */ @@ -792,7 +794,7 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -822,7 +824,7 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) if ( sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - return mach64_dma_dispatch_vertex( dev, vertex.prim, vertex.buf, + return mach64_dma_dispatch_vertex( filp, dev, vertex.prim, vertex.buf, vertex.used, vertex.discard ); } @@ -835,7 +837,7 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) drm_mach64_blit_t blit; int ret; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_mach64_blit_t *)data, sizeof(blit) ); @@ -851,7 +853,7 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); - ret = mach64_dma_dispatch_blit( dev, &blit ); + ret = mach64_dma_dispatch_blit( filp, dev, &blit ); /* Make sure we restore the 3D state next time. */ @@ -882,7 +884,7 @@ int mach64_get_param( DRM_IOCTL_ARGS ) switch ( param.param ) { case MACH64_PARAM_FRAMES_QUEUED: /* Needs lock since it calls mach64_ring_tick() */ - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); value = mach64_do_get_frames_queued( dev_priv ); break; case MACH64_PARAM_IRQ_NR: diff --git a/shared/mga_dma.c b/shared/mga_dma.c index 22bd61f0..5e95c9f9 100644 --- a/shared/mga_dma.c +++ b/shared/mga_dma.c @@ -686,7 +686,7 @@ int mga_dma_flush( DRM_IOCTL_ARGS ) drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_lock_t lock; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); @@ -720,7 +720,7 @@ int mga_dma_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return mga_do_dma_reset( dev_priv ); } @@ -730,7 +730,8 @@ int mga_dma_reset( DRM_IOCTL_ARGS ) * DMA buffer management */ -static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int mga_dma_get_buffers( DRMFILE filp, + drm_device_t *dev, drm_dma_t *d ) { drm_buf_t *buf; int i; @@ -739,7 +740,7 @@ static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = mga_freelist_get( dev ); if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -761,7 +762,7 @@ int mga_dma_buffers( DRM_IOCTL_ARGS ) drm_dma_t d; int ret = 0; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -786,7 +787,7 @@ int mga_dma_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = mga_dma_get_buffers( dev, &d ); + ret = mga_dma_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared/mga_drv.h b/shared/mga_drv.h index a5085b06..7efc89bc 100644 --- a/shared/mga_drv.h +++ b/shared/mga_drv.h @@ -90,14 +90,14 @@ typedef struct drm_mga_private { unsigned int texture_offset; unsigned int texture_size; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *status; - drm_map_t *warp; - drm_map_t *primary; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *status; + drm_local_map_t *warp; + drm_local_map_t *primary; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; } drm_mga_private_t; /* mga_dma.c */ @@ -131,32 +131,30 @@ extern int mga_getparam( DRM_IOCTL_ARGS ); extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv ); extern int mga_warp_init( drm_mga_private_t *dev_priv ); -#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() - +#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->primary) +#if defined(__linux__) && defined(__alpha__) #define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) #define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) #define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg ) #define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg ) -#ifdef __alpha__ #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) #define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) +#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0) +#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0) static inline u32 _MGA_READ(u32 *addr) { - DRM_READMEMORYBARRIER(); + DRM_READMEMORYBARRIER(dev_priv->mmio); return *(volatile u32 *)addr; } - #else -#define MGA_READ( reg ) MGA_DEREF( reg ) -#define MGA_READ8( reg ) MGA_DEREF8( reg ) -#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0) +#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg)) +#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg)) +#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val)) +#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val)) #endif #define DWGREG0 0x1c00 @@ -186,16 +184,6 @@ do { \ } \ } while (0) -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - #define WRAP_TEST_WITH_RETURN( dev_priv ) \ do { \ if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ diff --git a/shared/mga_state.c b/shared/mga_state.c index 61077220..256dd47d 100644 --- a/shared/mga_state.c +++ b/shared/mga_state.c @@ -887,7 +887,7 @@ int mga_dma_clear( DRM_IOCTL_ARGS ) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t *)data, sizeof(clear) ); @@ -911,7 +911,7 @@ int mga_dma_swap( DRM_IOCTL_ARGS ) drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -936,7 +936,7 @@ int mga_dma_vertex( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( vertex, (drm_mga_vertex_t *)data, @@ -975,7 +975,7 @@ int mga_dma_indices( DRM_IOCTL_ARGS ) drm_mga_buf_priv_t *buf_priv; drm_mga_indices_t indices; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( indices, (drm_mga_indices_t *)data, @@ -1015,7 +1015,7 @@ int mga_dma_iload( DRM_IOCTL_ARGS ) drm_mga_iload_t iload; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t *)data, sizeof(iload) ); @@ -1055,7 +1055,7 @@ int mga_dma_blit( DRM_IOCTL_ARGS ) drm_mga_blit_t blit; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t *)data, sizeof(blit) ); diff --git a/shared/r128_cce.c b/shared/r128_cce.c index 5175885e..7f0f4325 100644 --- a/shared/r128_cce.c +++ b/shared/r128_cce.c @@ -579,6 +579,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = 128; + dev_priv->ring.ring_rptr = dev_priv->ring_rptr; dev_priv->sarea_priv->last_frame = 0; R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); @@ -663,7 +664,7 @@ int r128_cce_start( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); @@ -686,7 +687,7 @@ int r128_cce_stop( DRM_IOCTL_ARGS ) int ret; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) ); @@ -725,7 +726,7 @@ int r128_cce_reset( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); @@ -746,7 +747,7 @@ int r128_cce_idle( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cce_running ) { r128_do_cce_flush( dev_priv ); @@ -760,7 +761,7 @@ int r128_engine_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return r128_do_engine_reset( dev ); } @@ -807,7 +808,7 @@ int r128_fullscreen( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_r128_fullscreen_t fs; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); @@ -889,7 +890,7 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev ) for ( i = 0 ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 ) + if ( buf->filp == 0 ) return buf; } @@ -948,7 +949,7 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) return DRM_ERR(EBUSY); } -static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -957,7 +958,7 @@ static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = r128_freelist_get( dev ); if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -978,7 +979,7 @@ int r128_cce_buffers( DRM_IOCTL_ARGS ) int ret = 0; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *) data, sizeof(d) ); @@ -1001,7 +1002,7 @@ int r128_cce_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = r128_cce_get_buffers( dev, &d ); + ret = r128_cce_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d) ); diff --git a/shared/r128_drv.h b/shared/r128_drv.h index 763fcb3a..bd913878 100644 --- a/shared/r128_drv.h +++ b/shared/r128_drv.h @@ -34,8 +34,8 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) ) +#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ typedef struct drm_r128_freelist { unsigned int age; @@ -56,6 +56,7 @@ typedef struct drm_r128_ring_buffer { int space; int high_mark; + drm_local_map_t *ring_rptr; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { @@ -98,13 +99,13 @@ typedef struct drm_r128_private { u32 depth_pitch_offset_c; u32 span_pitch_offset_c; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *cce_ring; - drm_map_t *ring_rptr; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *cce_ring; + drm_local_map_t *ring_rptr; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; } drm_r128_private_t; typedef struct drm_r128_buf_priv { @@ -370,15 +371,10 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS ); #define R128_PERFORMANCE_BOXES 0 - -#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) -#define R128_ADDR(reg) (R128_BASE( reg ) + reg) - -#define R128_READ(reg) DRM_READ32( (volatile u32 *) R128_ADDR(reg) ) -#define R128_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) ) - -#define R128_READ8(reg) DRM_READ8( (volatile u8 *) R128_ADDR(reg) ) -#define R128_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) ) +#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) +#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) #define R128_WRITE_PLL(addr,val) \ do { \ @@ -403,15 +399,6 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); * Misc helper macros */ -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ @@ -453,7 +440,7 @@ do { \ #if defined(__powerpc__) #define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) #else -#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() +#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr) #endif diff --git a/shared/r128_state.c b/shared/r128_state.c index 68f73061..8b9e97cf 100644 --- a/shared/r128_state.c +++ b/shared/r128_state.c @@ -778,7 +778,8 @@ static void r128_cce_dispatch_indices( drm_device_t *dev, sarea_priv->nbox = 0; } -static int r128_cce_dispatch_blit( drm_device_t *dev, +static int r128_cce_dispatch_blit( DRMFILE filp, + drm_device_t *dev, drm_r128_blit_t *blit ) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -829,9 +830,9 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, buf = dma->buflist[blit->idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -896,7 +897,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, int count, x, y; u32 *buffer; u8 *mask; - int i; + int i, buffer_size, mask_size; RING_LOCALS; DRM_DEBUG( "\n" ); @@ -908,25 +909,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, return DRM_ERR(EFAULT); } - buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + buffer_size = depth->n * sizeof(u32); + buffer = DRM_MALLOC( buffer_size ); if ( buffer == NULL ) return DRM_ERR(ENOMEM); - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, - depth->n * sizeof(u32) ) ) { - DRM_FREE( buffer ); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { + DRM_FREE( buffer, buffer_size); return DRM_ERR(EFAULT); } + mask_size = depth->n * sizeof(u8); if ( depth->mask ) { - mask = DRM_MALLOC( depth->n * sizeof(u8) ); + mask = DRM_MALLOC( mask_size ); if ( mask == NULL ) { - DRM_FREE( buffer ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, - depth->n * sizeof(u8) ) ) { - DRM_FREE( buffer ); - DRM_FREE( mask ); + if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { + DRM_FREE( buffer, buffer_size ); + DRM_FREE( mask, mask_size ); return DRM_ERR(EFAULT); } @@ -953,7 +954,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - DRM_FREE( mask ); + DRM_FREE( mask, mask_size ); } else { for ( i = 0 ; i < count ; i++, x++ ) { BEGIN_RING( 6 ); @@ -977,7 +978,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - DRM_FREE( buffer ); + DRM_FREE( buffer, buffer_size ); return 0; } @@ -989,60 +990,62 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, int count, *x, *y; u32 *buffer; u8 *mask; - int i; + int i, xbuf_size, ybuf_size, buffer_size, mask_size; RING_LOCALS; DRM_DEBUG( "\n" ); count = depth->n; - x = DRM_MALLOC( count * sizeof(*x) ); + xbuf_size = count * sizeof(*x); + ybuf_size = count * sizeof(*y); + x = DRM_MALLOC( xbuf_size ); if ( x == NULL ) { return DRM_ERR(ENOMEM); } - y = DRM_MALLOC( count * sizeof(*y) ); + y = DRM_MALLOC( ybuf_size ); if ( y == NULL ) { - DRM_FREE( x ); + DRM_FREE( x, xbuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + buffer_size = depth->n * sizeof(u32); + buffer = DRM_MALLOC( buffer_size ); if ( buffer == NULL ) { - DRM_FREE( x ); - DRM_FREE( y ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( buffer, depth->buffer, - depth->n * sizeof(u32) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(EFAULT); } if ( depth->mask ) { - mask = DRM_MALLOC( depth->n * sizeof(u8) ); + mask_size = depth->n * sizeof(u8); + mask = DRM_MALLOC( mask_size ); if ( mask == NULL ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( mask, depth->mask, - depth->n * sizeof(u8) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); - DRM_FREE( mask ); + if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); + DRM_FREE( mask, mask_size ); return DRM_ERR(EFAULT); } @@ -1069,7 +1072,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - DRM_FREE( mask ); + DRM_FREE( mask, mask_size ); } else { for ( i = 0 ; i < count ; i++ ) { BEGIN_RING( 6 ); @@ -1093,9 +1096,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - DRM_FREE( x ); - DRM_FREE( y ); - DRM_FREE( buffer ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); + DRM_FREE( buffer, buffer_size ); return 0; } @@ -1146,7 +1149,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; - int i; + int i, xbuf_size, ybuf_size; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -1155,23 +1158,25 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, count = dev_priv->depth_pitch; } - x = DRM_MALLOC( count * sizeof(*x) ); + xbuf_size = count * sizeof(*x); + ybuf_size = count * sizeof(*y); + x = DRM_MALLOC( xbuf_size ); if ( x == NULL ) { return DRM_ERR(ENOMEM); } - y = DRM_MALLOC( count * sizeof(*y) ); + y = DRM_MALLOC( ybuf_size ); if ( y == NULL ) { - DRM_FREE( x ); + DRM_FREE( x, xbuf_size ); return DRM_ERR(ENOMEM); } - if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } - if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { - DRM_FREE( x ); - DRM_FREE( y ); + if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) { + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return DRM_ERR(EFAULT); } @@ -1199,8 +1204,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, ADVANCE_RING(); } - DRM_FREE( x ); - DRM_FREE( y ); + DRM_FREE( x, xbuf_size ); + DRM_FREE( y, ybuf_size ); return 0; } @@ -1240,7 +1245,7 @@ int r128_cce_clear( DRM_IOCTL_ARGS ) drm_r128_clear_t clear; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data, sizeof(clear) ); @@ -1266,7 +1271,7 @@ int r128_cce_swap( DRM_IOCTL_ARGS ) drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "%s\n", __FUNCTION__ ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1293,7 +1298,7 @@ int r128_cce_vertex( DRM_IOCTL_ARGS ) drm_r128_buf_priv_t *buf_priv; drm_r128_vertex_t vertex; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1324,9 +1329,9 @@ int r128_cce_vertex( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1353,7 +1358,7 @@ int r128_cce_indices( DRM_IOCTL_ARGS ) drm_r128_indices_t elts; int count; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1383,9 +1388,9 @@ int r128_cce_indices( DRM_IOCTL_ARGS ) buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1421,7 +1426,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data, sizeof(blit) ); @@ -1437,7 +1442,7 @@ int r128_cce_blit( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return r128_cce_dispatch_blit( dev, &blit ); + return r128_cce_dispatch_blit( filp, dev, &blit ); } int r128_cce_depth( DRM_IOCTL_ARGS ) @@ -1446,7 +1451,7 @@ int r128_cce_depth( DRM_IOCTL_ARGS ) drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data, sizeof(depth) ); @@ -1474,7 +1479,7 @@ int r128_cce_stipple( DRM_IOCTL_ARGS ) drm_r128_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data, sizeof(stipple) ); @@ -1502,7 +1507,7 @@ int r128_cce_indirect( DRM_IOCTL_ARGS ) RING_LOCALS; #endif - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1525,9 +1530,9 @@ int r128_cce_indirect( DRM_IOCTL_ARGS ) buf = dma->buflist[indirect.idx]; buf_priv = buf->dev_private; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { diff --git a/shared/radeon.h b/shared/radeon.h index c36accb4..d465773e 100644 --- a/shared/radeon.h +++ b/shared/radeon.h @@ -120,19 +120,17 @@ do { \ if ( dev_priv->page_flipping ) { \ radeon_do_cleanup_pageflip( dev ); \ } \ - radeon_mem_release( dev_priv->agp_heap ); \ - radeon_mem_release( dev_priv->fb_heap ); \ + radeon_mem_release( filp, dev_priv->agp_heap ); \ + radeon_mem_release( filp, dev_priv->fb_heap ); \ } \ } while (0) /* When the last client dies, shut down the CP and free dev->dev_priv. */ -#define __HAVE_RELEASE 1 -#define DRIVER_RELEASE() \ +/* #define __HAVE_RELEASE 1 */ +#define DRIVER_PRETAKEDOWN() \ do { \ - DRM(reclaim_buffers)( dev, priv->pid ); \ - if ( dev->open_count == 1) \ - radeon_do_release( dev ); \ + radeon_do_release( dev ); \ } while (0) diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c index 6994fe9e..3ec8dfd1 100644 --- a/shared/radeon_cp.c +++ b/shared/radeon_cp.c @@ -926,11 +926,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); /* Writeback doesn't seem to work everywhere, test it first */ - DRM_WRITE32( &dev_priv->scratch[1], 0 ); + DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { - if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef ) + if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) break; DRM_UDELAY( 1 ); } @@ -1217,6 +1217,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + dev_priv->ring.ring_rptr = dev_priv->ring_rptr; #if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { @@ -1322,7 +1323,7 @@ int radeon_cp_start( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( dev_priv->cp_running ) { DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); @@ -1350,7 +1351,7 @@ int radeon_cp_stop( DRM_IOCTL_ARGS ) int ret; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); @@ -1425,7 +1426,7 @@ int radeon_cp_reset( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); @@ -1446,7 +1447,7 @@ int radeon_cp_idle( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return radeon_do_cp_idle( dev_priv ); } @@ -1456,7 +1457,7 @@ int radeon_engine_reset( DRM_IOCTL_ARGS ) DRM_DEVICE; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); return radeon_do_engine_reset( dev ); } @@ -1515,7 +1516,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) for ( i = start ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 || (buf->pending && + if ( buf->filp == 0 || (buf->pending && buf_priv->age <= done_age) ) { dev_priv->stats.requested_bufs++; buf->pending = 0; @@ -1542,7 +1543,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) drm_buf_t *buf; int i, t; int start; - u32 done_age = DRM_READ32(&dev_priv->scratch[1]); + u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); if ( ++dev_priv->last_buf >= dma->buf_count ) dev_priv->last_buf = 0; @@ -1554,7 +1555,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) for ( i = start ; i < dma->buf_count ; i++ ) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if ( buf->pid == 0 || (buf->pending && + if ( buf->filp == 0 || (buf->pending && buf_priv->age <= done_age) ) { dev_priv->stats.requested_bufs++; buf->pending = 0; @@ -1619,7 +1620,7 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) return DRM_ERR(EBUSY); } -static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) +static int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) { int i; drm_buf_t *buf; @@ -1628,7 +1629,7 @@ static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) buf = radeon_freelist_get( dev ); if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ - buf->pid = DRM_CURRENTPID; + buf->filp = filp; if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) @@ -1649,7 +1650,7 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) int ret = 0; drm_dma_t d; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); @@ -1672,7 +1673,7 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS ) d.granted_count = 0; if ( d.request_count ) { - ret = radeon_cp_get_buffers( dev, &d ); + ret = radeon_cp_get_buffers( filp, dev, &d ); } DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); diff --git a/shared/radeon_drm.h b/shared/radeon_drm.h index 512d36b9..3ab57309 100644 --- a/shared/radeon_drm.h +++ b/shared/radeon_drm.h @@ -396,7 +396,7 @@ typedef struct drm_radeon_init { enum { RADEON_INIT_CP = 0x01, RADEON_CLEANUP_CP = 0x02, - RADEON_INIT_R200_CP = 0x03, + RADEON_INIT_R200_CP = 0x03 } func; unsigned long sarea_priv_offset; int is_pci; diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h index fb8fbafe..7faffa7a 100644 --- a/shared/radeon_drv.h +++ b/shared/radeon_drv.h @@ -31,8 +31,8 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head , (val)) +#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ typedef struct drm_radeon_freelist { unsigned int age; @@ -53,6 +53,7 @@ typedef struct drm_radeon_ring_buffer { int space; int high_mark; + drm_local_map_t *ring_rptr; } drm_radeon_ring_buffer_t; typedef struct drm_radeon_depth_clear_t { @@ -67,7 +68,7 @@ struct mem_block { struct mem_block *prev; int start; int size; - int pid; /* 0: free, -1: heap, other: real pids */ + DRMFILE filp; /* 0: free, -1: heap, other: real files */ }; typedef struct drm_radeon_private { @@ -126,13 +127,13 @@ typedef struct drm_radeon_private { drm_radeon_depth_clear_t depth_clear; - drm_map_t *sarea; - drm_map_t *fb; - drm_map_t *mmio; - drm_map_t *cp_ring; - drm_map_t *ring_rptr; - drm_map_t *buffers; - drm_map_t *agp_textures; + drm_local_map_t *sarea; + drm_local_map_t *fb; + drm_local_map_t *mmio; + drm_local_map_t *cp_ring; + drm_local_map_t *ring_rptr; + drm_local_map_t *buffers; + drm_local_map_t *agp_textures; struct mem_block *agp_heap; struct mem_block *fb_heap; @@ -183,7 +184,7 @@ extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); extern int radeon_mem_free( DRM_IOCTL_ARGS ); extern int radeon_mem_init_heap( DRM_IOCTL_ARGS ); extern void radeon_mem_takedown( struct mem_block **heap ); -extern void radeon_mem_release( struct mem_block *heap ); +extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap ); /* radeon_irq.c */ extern int radeon_irq_emit( DRM_IOCTL_ARGS ); @@ -267,8 +268,10 @@ extern void radeon_do_release(drm_device_t *dev); #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 +#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) + #define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( &dev_priv->scratch[(x)] ) \ + ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) @@ -687,15 +690,10 @@ extern void radeon_do_release(drm_device_t *dev); #define RADEON_RING_HIGH_MARK 128 - -#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) -#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) - -#define RADEON_READ(reg) DRM_READ32( (volatile u32 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) ) - -#define RADEON_READ8(reg) DRM_READ8( (volatile u8 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) ) +#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) +#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) +#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) +#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) #define RADEON_WRITE_PLL( addr, val ) \ do { \ @@ -772,16 +770,6 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); * Misc helper macros */ -#define LOCK_TEST_WITH_RETURN( dev ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); \ - return DRM_ERR(EINVAL); \ - } \ -} while (0) - - /* Perfbox functionality only. */ #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ @@ -859,7 +847,7 @@ do { \ #define COMMIT_RING() do { \ /* Flush writes to ring */ \ - DRM_READMEMORYBARRIER(); \ + DRM_READMEMORYBARRIER(dev_priv->mmio); \ GET_RING_HEAD( &dev_priv->ring ); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ /* read from PCI bus to ensure correct posting */ \ diff --git a/shared/radeon_irq.c b/shared/radeon_irq.c index 596706bf..9199fbbf 100644 --- a/shared/radeon_irq.c +++ b/shared/radeon_irq.c @@ -179,7 +179,7 @@ int radeon_irq_emit( DRM_IOCTL_ARGS ) drm_radeon_irq_emit_t emit; int result; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); diff --git a/shared/radeon_mem.c b/shared/radeon_mem.c index 7ca10753..c3cbd3a9 100644 --- a/shared/radeon_mem.c +++ b/shared/radeon_mem.c @@ -40,7 +40,7 @@ */ static struct mem_block *split_block(struct mem_block *p, int start, int size, - int pid ) + DRMFILE filp ) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -49,7 +49,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->pid = 0; + newblock->filp = 0; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -65,7 +65,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->pid = 0; + newblock->filp = 0; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -75,20 +75,20 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, out: /* Our block is in the middle */ - p->pid = pid; + p->filp = filp; return p; } static struct mem_block *alloc_block( struct mem_block *heap, int size, - int align2, int pid ) + int align2, DRMFILE filp ) { struct mem_block *p; int mask = (1 << align2)-1; for (p = heap->next ; p != heap ; p = p->next) { int start = (p->start + mask) & ~mask; - if (p->pid == 0 && start + size <= p->start + p->size) - return split_block( p, start, size, pid ); + if (p->filp == 0 && start + size <= p->start + p->size) + return split_block( p, start, size, filp ); } return NULL; @@ -108,25 +108,25 @@ static struct mem_block *find_block( struct mem_block *heap, int start ) static void free_block( struct mem_block *p ) { - p->pid = 0; + p->filp = 0; - /* Assumes a single contiguous range. Needs a special pid in + /* Assumes a single contiguous range. Needs a special filp in * 'heap' to stop it being subsumed. */ - if (p->next->pid == 0) { + if (p->next->filp == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; p->next->prev = p; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } - if (p->prev->pid == 0) { + if (p->prev->filp == 0) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; q->next->prev = q; - DRM_FREE(p); + DRM_FREE(p, sizeof(*q)); } } @@ -141,47 +141,46 @@ static int init_heap(struct mem_block **heap, int start, int size) *heap = DRM_MALLOC(sizeof(**heap)); if (!*heap) { - DRM_FREE( blocks ); + DRM_FREE( blocks, sizeof(*blocks) ); return -ENOMEM; } blocks->start = start; blocks->size = size; - blocks->pid = 0; + blocks->filp = 0; blocks->next = blocks->prev = *heap; memset( *heap, 0, sizeof(**heap) ); - (*heap)->pid = -1; + (*heap)->filp = (DRMFILE) -1; (*heap)->next = (*heap)->prev = blocks; return 0; } -/* Free all blocks associated with the releasing pid. +/* Free all blocks associated with the releasing file. */ -void radeon_mem_release( struct mem_block *heap ) +void radeon_mem_release( DRMFILE filp, struct mem_block *heap ) { - int pid = DRM_CURRENTPID; struct mem_block *p; if (!heap || !heap->next) return; for (p = heap->next ; p != heap ; p = p->next) { - if (p->pid == pid) - p->pid = 0; + if (p->filp == filp) + p->filp = 0; } - /* Assumes a single contiguous range. Needs a special pid in + /* Assumes a single contiguous range. Needs a special filp in * 'heap' to stop it being subsumed. */ for (p = heap->next ; p != heap ; p = p->next) { - while (p->pid == 0 && p->next->pid == 0) { + while (p->filp == 0 && p->next->filp == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; p->next->prev = p; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } } } @@ -198,10 +197,10 @@ void radeon_mem_takedown( struct mem_block **heap ) for (p = (*heap)->next ; p != *heap ; ) { struct mem_block *q = p; p = p->next; - DRM_FREE(q); + DRM_FREE(q, sizeof(*q)); } - DRM_FREE( *heap ); + DRM_FREE( *heap, sizeof(**heap) ); *heap = 0; } @@ -248,7 +247,7 @@ int radeon_mem_alloc( DRM_IOCTL_ARGS ) alloc.alignment = 12; block = alloc_block( *heap, alloc.size, alloc.alignment, - DRM_CURRENTPID ); + filp ); if (!block) return DRM_ERR(ENOMEM); @@ -287,7 +286,7 @@ int radeon_mem_free( DRM_IOCTL_ARGS ) if (!block) return DRM_ERR(EFAULT); - if (block->pid != DRM_CURRENTPID) + if (block->filp != filp) return DRM_ERR(EPERM); free_block( block ); diff --git a/shared/radeon_state.c b/shared/radeon_state.c index d9bc948c..86cbead5 100644 --- a/shared/radeon_state.c +++ b/shared/radeon_state.c @@ -1063,7 +1063,8 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, #define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) -static int radeon_cp_dispatch_texture( drm_device_t *dev, +static int radeon_cp_dispatch_texture( DRMFILE filp, + drm_device_t *dev, drm_radeon_texture_t *tex, drm_radeon_tex_image_t *image ) { @@ -1216,7 +1217,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, } } - buf->pid = DRM_CURRENTPID; + buf->filp = filp; buf->used = (dwords + 8) * sizeof(u32); radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); radeon_cp_discard_buffer( dev, buf ); @@ -1273,7 +1274,7 @@ int radeon_cp_clear( DRM_IOCTL_ARGS ) drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, sizeof(clear) ); @@ -1342,7 +1343,7 @@ int radeon_cp_flip( DRM_IOCTL_ARGS ) drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1362,7 +1363,7 @@ int radeon_cp_swap( DRM_IOCTL_ARGS ) drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "\n" ); - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1386,7 +1387,7 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS ) drm_radeon_vertex_t vertex; drm_radeon_tcl_prim_t prim; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1416,9 +1417,9 @@ int radeon_cp_vertex( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1473,7 +1474,7 @@ int radeon_cp_indices( DRM_IOCTL_ARGS ) drm_radeon_tcl_prim_t prim; int count; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1503,9 +1504,9 @@ int radeon_cp_indices( DRM_IOCTL_ARGS ) buf = dma->buflist[elts.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1568,7 +1569,7 @@ int radeon_cp_texture( DRM_IOCTL_ARGS ) drm_radeon_tex_image_t image; int ret; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); @@ -1585,7 +1586,7 @@ int radeon_cp_texture( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - ret = radeon_cp_dispatch_texture( dev, &tex, &image ); + ret = radeon_cp_dispatch_texture( filp, dev, &tex, &image ); COMMIT_RING(); return ret; @@ -1598,7 +1599,7 @@ int radeon_cp_stipple( DRM_IOCTL_ARGS ) drm_radeon_stipple_t stipple; u32 mask[32]; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, sizeof(stipple) ); @@ -1623,7 +1624,7 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS ) drm_radeon_indirect_t indirect; RING_LOCALS; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1645,9 +1646,9 @@ int radeon_cp_indirect( DRM_IOCTL_ARGS ) buf = dma->buflist[indirect.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } if ( buf->pending ) { @@ -1700,7 +1701,7 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS ) int i; unsigned char laststate; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -1725,9 +1726,9 @@ int radeon_cp_vertex2( DRM_IOCTL_ARGS ) buf = dma->buflist[vertex.idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "process %d using buffer owned by %p\n", + DRM_CURRENTPID, buf->filp ); return DRM_ERR(EINVAL); } @@ -2027,7 +2028,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) drm_radeon_cmd_header_t header; int orig_nbox; - LOCK_TEST_WITH_RETURN( dev ); + LOCK_TEST_WITH_RETURN( dev, filp ); if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); @@ -2096,8 +2097,9 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID || buf->pending ) { - DRM_ERROR( "bad buffer\n" ); + if ( buf->filp != filp || buf->pending ) { + DRM_ERROR( "bad buffer %p %p %d\n", + buf->filp, filp, buf->pending); return DRM_ERR(EINVAL); } |