From e1dba5c3a73078dec24f07a6d685435677db94a4 Mon Sep 17 00:00:00 2001 From: Daryll Strauss Date: Tue, 7 Dec 1999 03:37:16 +0000 Subject: Move Mesa to xc/extras Update to the latest Mesa 3.2 code Fix the Q3Demo bugs (white railgun and texture mapping) Simplify driver texture mapping routines Fix device driver for 2.3 kernels Improve performance --- libdrm/xf86drm.c | 55 +++++++++++++++++---------------- linux-core/drmP.h | 91 ++++++++++++++++++++++++++++++++++++++++++++----------- linux/bufs.c | 5 +-- linux/drm.h | 7 +++-- linux/drmP.h | 91 ++++++++++++++++++++++++++++++++++++++++++++----------- linux/fops.c | 11 +++++-- linux/lists.c | 35 +++++++++------------ linux/lock.c | 34 +++++++++------------ linux/memory.c | 21 ++++++++----- linux/proc.c | 7 +++-- linux/vm.c | 65 ++++++++++++++++++++++++++++++--------- shared-core/drm.h | 7 +++-- shared/drm.h | 7 +++-- tests/drmstat.c | 30 +++++++++--------- 14 files changed, 313 insertions(+), 153 deletions(-) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a5aef4c6..0d3b90a8 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -1,6 +1,6 @@ /* xf86drm.c -- User-level interface to DRM device * Created: Tue Jan 5 08:16:21 1999 by faith@precisioninsight.com - * Revised: Wed Aug 4 07:54:23 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 11:34:13 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.43 1999/08/04 18:14:43 faith Exp $ - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.4 1999/09/25 14:37:49 dawes Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.5 1999/10/13 22:33:07 dawes Exp $ * */ @@ -57,7 +57,7 @@ # ifdef DRM_USE_MALLOC # define _DRM_MALLOC malloc # define _DRM_FREE free -extern int xf86InstallSIGIOHandler(int fd, void (*f)(int)); +extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); extern int xf86RemoveSIGIOHandler(int fd); # else # include @@ -174,6 +174,28 @@ static int drmOpenDevice(const char *path, long dev, return drm_open(path); } +static int drmOpenByBusid(const char *busid) +{ + int i; + char dev_name[64]; + char *buf; + int fd; + + for (i = 0; i < 8; i++) { + sprintf(dev_name, "/dev/graphics/card%d", i); + if ((fd = drm_open(dev_name)) >= 0) { + buf = drmGetBusid(fd); + if (buf && !strcmp(buf, busid)) { + drmFreeBusid(buf); + return fd; + } + if (buf) drmFreeBusid(buf); + close(fd); + } + } + return -1; +} + static int drmOpenByName(const char *name) { int i; @@ -237,29 +259,6 @@ static int drmOpenByName(const char *name) return -1; } -static int drmOpenByBusid(const char *busid) -{ - int i; - char dev_name[64]; - char *buf; - int fd; - - for (i = 0; i < 8; i++) { - sprintf(dev_name, "/dev/graphics/card%d", i); - if ((fd = drm_open(dev_name)) >= 0) { - buf = drmGetBusid(fd); - if (buf && !strcmp(buf, busid)) { - drmFreeBusid(buf); - return fd; - } - if (buf) drmFreeBusid(buf); - close(fd); - } - } - return -1; -} - - /* drmOpen looks up the specified name and busid, and opens the device found. The entry in /dev/graphics is created if necessary (and if root). A file descriptor is returned. On error, the return value is @@ -838,7 +837,7 @@ void *drmGetContextTag(int fd, drmContext context) } #if defined(XFree86Server) || defined(DRM_USE_MALLOC) -static void drmSIGIOHandler(int interrupt) +static void drmSIGIOHandler(int interrupt, void *closure) { unsigned long key; void *value; @@ -890,7 +889,7 @@ int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *)) entry = drmGetEntry(fd); entry->f = f; - return xf86InstallSIGIOHandler(fd, drmSIGIOHandler); + return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0); } int drmRemoveSIGIOHandler(int fd) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 37b9d053..966e6e05 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1,6 +1,6 @@ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Tue Oct 12 08:51:07 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 16:06:49 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -83,33 +83,77 @@ #define DRM_MEM_BUFLISTS 14 /* Backward compatibility section */ + /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ #ifndef _PAGE_PWT - /* The name of _PAGE_WT was changed to - _PAGE_PWT in Linux 2.2.6 */ #define _PAGE_PWT _PAGE_WT #endif - /* Wait queue declarations changes in 2.3.1 */ + /* Wait queue declarations changed in 2.3.1 */ #ifndef DECLARE_WAITQUEUE #define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL } typedef struct wait_queue *wait_queue_head_t; #define init_waitqueue_head(q) *q = NULL; #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) + /* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */ +#ifndef _PAGE_PSE +#define _PAGE_PSE _PAGE_4M +#endif + + /* vm_offset changed to vm_pgoff in 2.3.25 */ +#if LINUX_VERSION_CODE < 0x020319 +#define VM_OFFSET(vma) ((vma)->vm_offset) +#else +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) +#endif + /* *_nopage return values defined in 2.3.26 */ +#ifndef NOPAGE_SIGBUS +#define NOPAGE_SIGBUS 0 +#endif +#ifndef NOPAGE_OOM +#define NOPAGE_OOM 0 +#endif + /* Generic cmpxchg added in 2.3.x */ +#if CPU != 386 +#ifndef __HAVE_ARCH_CMPXCHG + /* Include this here so that driver can be + used with older kernels. */ +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long prev; + switch (size) { + case 1: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 2: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 4: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + } + return old; +} + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ + (unsigned long)(n),sizeof(*(ptr)))) +#endif +#else + /* Compiling for a 386 proper... */ +#error DRI not supported on Intel 80386 +#endif /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ @@ -436,6 +480,7 @@ extern ssize_t drm_read(struct file *filp, char *buf, size_t count, extern int drm_write_string(drm_device_t *dev, const char *s); /* Mapping support (vm.c) */ +#if LINUX_VERSION_CODE < 0x020317 extern unsigned long drm_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write_access); @@ -445,6 +490,18 @@ extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma, extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma, unsigned long address, int write_access); +#else + /* Return type changed in 2.3.23 */ +extern struct page *drm_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +#endif extern void drm_vm_open(struct vm_area_struct *vma); extern void drm_vm_close(struct vm_area_struct *vma); extern int drm_mmap_dma(struct file *filp, diff --git a/linux/bufs.c b/linux/bufs.c index e9879099..780c4fb6 100644 --- a/linux/bufs.c +++ b/linux/bufs.c @@ -1,6 +1,6 @@ /* bufs.c -- IOCTLs to manage buffers -*- linux-c -*- * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 22:48:10 1999 by faith@precisioninsight.com + * Revised: Fri Dec 3 12:11:11 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -89,10 +89,11 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, case _DRM_SHM: - DRM_DEBUG("%ld %d\n", map->size, drm_order(map->size)); map->handle = (void *)drm_alloc_pages(drm_order(map->size) - PAGE_SHIFT, DRM_MEM_SAREA); + DRM_DEBUG("%ld %d %p\n", map->size, drm_order(map->size), + map->handle); if (!map->handle) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -ENOMEM; diff --git a/linux/drm.h b/linux/drm.h index 324e2002..320db51e 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 17:11:19 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -26,7 +26,10 @@ * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $ - * + * + * Acknowledgements: + * Dec 1999, Richard Henderson , move to generic cmpxchg. + * */ #ifndef _DRM_H_ diff --git a/linux/drmP.h b/linux/drmP.h index 37b9d053..966e6e05 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -1,6 +1,6 @@ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Tue Oct 12 08:51:07 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 16:06:49 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -83,33 +83,77 @@ #define DRM_MEM_BUFLISTS 14 /* Backward compatibility section */ + /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ #ifndef _PAGE_PWT - /* The name of _PAGE_WT was changed to - _PAGE_PWT in Linux 2.2.6 */ #define _PAGE_PWT _PAGE_WT #endif - /* Wait queue declarations changes in 2.3.1 */ + /* Wait queue declarations changed in 2.3.1 */ #ifndef DECLARE_WAITQUEUE #define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL } typedef struct wait_queue *wait_queue_head_t; #define init_waitqueue_head(q) *q = NULL; #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) + /* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */ +#ifndef _PAGE_PSE +#define _PAGE_PSE _PAGE_4M +#endif + + /* vm_offset changed to vm_pgoff in 2.3.25 */ +#if LINUX_VERSION_CODE < 0x020319 +#define VM_OFFSET(vma) ((vma)->vm_offset) +#else +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) +#endif + /* *_nopage return values defined in 2.3.26 */ +#ifndef NOPAGE_SIGBUS +#define NOPAGE_SIGBUS 0 +#endif +#ifndef NOPAGE_OOM +#define NOPAGE_OOM 0 +#endif + /* Generic cmpxchg added in 2.3.x */ +#if CPU != 386 +#ifndef __HAVE_ARCH_CMPXCHG + /* Include this here so that driver can be + used with older kernels. */ +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long prev; + switch (size) { + case 1: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 2: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + case 4: + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" + : "=a"(prev) + : "q"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; + } + return old; +} + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ + (unsigned long)(n),sizeof(*(ptr)))) +#endif +#else + /* Compiling for a 386 proper... */ +#error DRI not supported on Intel 80386 +#endif /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ @@ -436,6 +480,7 @@ extern ssize_t drm_read(struct file *filp, char *buf, size_t count, extern int drm_write_string(drm_device_t *dev, const char *s); /* Mapping support (vm.c) */ +#if LINUX_VERSION_CODE < 0x020317 extern unsigned long drm_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write_access); @@ -445,6 +490,18 @@ extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma, extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma, unsigned long address, int write_access); +#else + /* Return type changed in 2.3.23 */ +extern struct page *drm_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access); +#endif extern void drm_vm_open(struct vm_area_struct *vma); extern void drm_vm_close(struct vm_area_struct *vma); extern int drm_mmap_dma(struct file *filp, diff --git a/linux/fops.c b/linux/fops.c index 403a19bb..47eacb83 100644 --- a/linux/fops.c +++ b/linux/fops.c @@ -1,6 +1,6 @@ /* fops.c -- File operations for DRM -*- linux-c -*- * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com - * Revised: Tue Oct 12 08:48:59 1999 by faith@precisioninsight.com + * Revised: Fri Dec 3 10:26:26 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -75,8 +75,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, f_count = %d\n", - current->pid, dev->device, dev->open_count, filp->f_count); + DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", + current->pid, dev->device, dev->open_count); return 0; } @@ -211,7 +211,12 @@ int drm_write_string(drm_device_t *dev, const char *s) send -= count; } +#if LINUX_VERSION_CODE < 0x020315 if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); +#else + /* Parameter added in 2.3.21 */ + if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN); +#endif DRM_DEBUG("waking\n"); wake_up_interruptible(&dev->buf_readers); return 0; diff --git a/linux/lists.c b/linux/lists.c index 3d1263d0..b84561f2 100644 --- a/linux/lists.c +++ b/linux/lists.c @@ -1,6 +1,6 @@ /* lists.c -- Buffer list handling routines -*- linux-c -*- * Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 09:27:01 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -130,11 +130,9 @@ int drm_freelist_destroy(drm_freelist_t *bl) int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) { - unsigned int old; - unsigned int new; - char failed; + drm_buf_t *old, *prev; int count = 0; - drm_device_dma_t *dma = dev->dma; + drm_device_dma_t *dma = dev->dma; if (!dma) { DRM_ERROR("No DMA support\n"); @@ -155,15 +153,14 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) #endif buf->list = DRM_LIST_FREE; do { - old = (unsigned long)bl->next; - buf->next = (void *)old; - new = (unsigned long)buf; - _DRM_CAS(&bl->next, old, new, failed); + old = bl->next; + bl->next = old; + prev = cmpxchg(&bl->next, old, buf); if (++count > DRM_LOOPING_LIMIT) { DRM_ERROR("Looping\n"); return 1; } - } while (failed); + } while (prev != old); atomic_inc(&bl->count); if (atomic_read(&bl->count) > dma->buf_count) { DRM_ERROR("%d of %d buffers free after addition of %d\n", @@ -180,9 +177,7 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) static drm_buf_t *drm_freelist_try(drm_freelist_t *bl) { - unsigned int old; - unsigned int new; - char failed; + drm_buf_t *old, *new, *prev; drm_buf_t *buf; int count = 0; @@ -190,20 +185,18 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl) /* Get buffer */ do { - old = (unsigned int)bl->next; - if (!old) { - return NULL; - } - new = (unsigned long)bl->next->next; - _DRM_CAS(&bl->next, old, new, failed); + old = bl->next; + if (!old) return NULL; + new = bl->next->next; + prev = cmpxchg(&bl->next, old, new); if (++count > DRM_LOOPING_LIMIT) { DRM_ERROR("Looping\n"); return NULL; } - } while (failed); + } while (prev != old); atomic_dec(&bl->count); - buf = (drm_buf_t *)old; + buf = old; buf->next = NULL; buf->list = DRM_LIST_NONE; DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n", diff --git a/linux/lock.c b/linux/lock.c index ab1c0742..e8c1eff1 100644 --- a/linux/lock.c +++ b/linux/lock.c @@ -1,6 +1,6 @@ /* lock.c -- IOCTLs for locking -*- linux-c -*- * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com - * Revised: Tue Oct 12 08:51:06 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -48,17 +48,15 @@ int drm_unblock(struct inode *inode, struct file *filp, unsigned int cmd, int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) { - unsigned int old; - unsigned int new; - char failed; + unsigned int old, new, prev; DRM_DEBUG("%d attempts\n", context); 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); + prev = cmpxchg(lock, old, new); + } while (prev != old); if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -83,16 +81,14 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) int drm_lock_transfer(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { - unsigned int old; - unsigned int new; - char failed; + unsigned int old, new, prev; dev->lock.pid = 0; do { - old = *lock; - new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + old = *lock; + new = context | _DRM_LOCK_HELD; + prev = cmpxchg(lock, old, new); + } while (prev != old); DRM_DEBUG("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context); return 1; } @@ -100,18 +96,16 @@ int drm_lock_transfer(drm_device_t *dev, int drm_lock_free(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { - unsigned int old; - unsigned int new; - char failed; + unsigned int old, new, prev; pid_t pid = dev->lock.pid; DRM_DEBUG("%d\n", context); dev->lock.pid = 0; do { - old = *lock; - new = 0; - _DRM_CAS(lock, old, new, failed); - } while (failed); + 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", context, diff --git a/linux/memory.c b/linux/memory.c index b3fc4fca..af8d510b 100644 --- a/linux/memory.c +++ b/linux/memory.c @@ -1,6 +1,6 @@ /* memory.c -- Memory management wrappers for DRM -*- linux-c -*- * Created: Thu Feb 4 14:00:34 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 13:04:33 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 10:28:18 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -42,7 +42,7 @@ typedef struct drm_mem_stats { } drm_mem_stats_t; static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; -static unsigned long drm_ram_available = 0; +static unsigned long drm_ram_available = 0; /* In pages */ static unsigned long drm_ram_used = 0; static drm_mem_stats_t drm_mem_stats[] = { [DRM_MEM_DMA] = { "dmabufs" }, @@ -77,7 +77,12 @@ void drm_mem_init(void) } si_meminfo(&si); +#if LINUX_VERSION_CODE < 0x020317 + /* Changed to page count in 2.3.23 */ + drm_ram_available = si.totalram >> PAGE_SHIFT; +#else drm_ram_available = si.totalram; +#endif drm_ram_used = 0; } @@ -95,10 +100,11 @@ static int _drm_mem_info(char *buf, char **start, off_t offset, int len, " | outstanding \n"); DRM_PROC_PRINT("type alloc freed fail bytes freed" " | allocs bytes\n\n"); - DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n", - "system", 0, 0, 0, drm_ram_available); - DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n", - "locked", 0, 0, 0, drm_ram_used); + DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", + "system", 0, 0, 0, + drm_ram_available << (PAGE_SHIFT - 10)); + DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", + "locked", 0, 0, 0, drm_ram_used >> 10); DRM_PROC_PRINT("\n"); for (pt = drm_mem_stats; pt->name; pt++) { DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", @@ -207,7 +213,8 @@ unsigned long drm_alloc_pages(int order, int area) unsigned int sz; spin_lock(&drm_mem_lock); - if (drm_ram_used > +(DRM_RAM_PERCENT * drm_ram_available) / 100) { + if ((drm_ram_used >> PAGE_SHIFT) + > (DRM_RAM_PERCENT * drm_ram_available) / 100) { spin_unlock(&drm_mem_lock); return 0; } diff --git a/linux/proc.c b/linux/proc.c index 0883d718..33a5b20e 100644 --- a/linux/proc.c +++ b/linux/proc.c @@ -1,6 +1,6 @@ /* proc.c -- /proc support for DRM -*- linux-c -*- * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com + * Revised: Fri Dec 3 09:44:16 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -382,7 +382,8 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len, vma->vm_flags & VM_MAYSHARE ? 's' : 'p', vma->vm_flags & VM_LOCKED ? 'l' : '-', vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_offset ); + VM_OFFSET(vma)); + #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c", @@ -393,7 +394,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len, pgprot & _PAGE_PCD ? 'u' : 'c', pgprot & _PAGE_ACCESSED ? 'a' : '-', pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_4M ? 'm' : 'k', + pgprot & _PAGE_PSE ? 'm' : 'k', pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); #endif DRM_PROC_PRINT("\n"); diff --git a/linux/vm.c b/linux/vm.c index 89803784..d649a6e7 100644 --- a/linux/vm.c +++ b/linux/vm.c @@ -1,6 +1,6 @@ /* vm.c -- Memory mapping for DRM -*- linux-c -*- * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 22:48:11 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 16:54:35 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -50,18 +50,32 @@ struct vm_operations_struct drm_vm_dma_ops = { close: drm_vm_close, }; +#if LINUX_VERSION_CODE < 0x020317 unsigned long drm_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +#else + /* Return type changed in 2.3.23 */ +struct page *drm_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access) +#endif { DRM_DEBUG("0x%08lx, %d\n", address, write_access); - return 0; /* Disallow mremap */ + return NOPAGE_SIGBUS; /* Disallow mremap */ } +#if LINUX_VERSION_CODE < 0x020317 unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +#else + /* Return type changed in 2.3.23 */ +struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access) +#endif { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; @@ -69,8 +83,8 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma, unsigned long offset; unsigned long page; - if (address > vma->vm_end) return 0; /* Disallow mremap */ - if (!dev->lock.hw_lock) return 0; /* Nothing allocated */ + if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; page = offset >> PAGE_SHIFT; @@ -78,12 +92,23 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma, atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical); +#if LINUX_VERSION_CODE < 0x020317 return physical; +#else + return mem_map + MAP_NR(physical); +#endif } +#if LINUX_VERSION_CODE < 0x020317 unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +#else + /* Return type changed in 2.3.23 */ +struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, + unsigned long address, + int write_access) +#endif { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; @@ -92,17 +117,21 @@ unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma, unsigned long offset; unsigned long page; - if (!dma) return 0; /* Error */ - if (address > vma->vm_end) return 0; /* Disallow mremap */ - if (!dma->pagelist) return 0; /* Nothing allocated */ + if (!dma) return NOPAGE_SIGBUS; /* Error */ + if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ + if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */ - offset = address - vma->vm_start; /* vm_offset should be 0 */ + offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ page = offset >> PAGE_SHIFT; physical = dma->pagelist[page] + (offset & (~PAGE_MASK)); atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical); +#if LINUX_VERSION_CODE < 0x020317 return physical; +#else + return mem_map + MAP_NR(physical); +#endif } void drm_vm_open(struct vm_area_struct *vma) @@ -169,7 +198,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) unsigned long length = vma->vm_end - vma->vm_start; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_offset); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ if ((length >> PAGE_SHIFT) != dma->page_count) return -EINVAL; @@ -195,9 +224,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) int i; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_offset); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); - if (!vma->vm_offset) return drm_mmap_dma(filp, vma); + if (!VM_OFFSET(vma)) return drm_mmap_dma(filp, vma); /* A sequential search of a linked list is fine here because: 1) there will only be @@ -208,7 +237,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) bit longer. */ for (i = 0; i < dev->map_count; i++) { map = dev->maplist[i]; - if (map->offset == vma->vm_offset) break; + if (map->offset == VM_OFFSET(vma)) break; } if (i >= dev->map_count) return -EINVAL; @@ -222,7 +251,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) switch (map->type) { case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: - if (vma->vm_offset >= __pa(high_memory)) { + if (VM_OFFSET(vma) >= __pa(high_memory)) { #if defined(__i386__) if (boot_cpu_data.x86 > 3) { pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; @@ -232,7 +261,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_IO; /* not in core dump */ } if (remap_page_range(vma->vm_start, - vma->vm_offset, + VM_OFFSET(vma), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; @@ -249,7 +278,15 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) } vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ if (map->flags & _DRM_READ_ONLY) { +#if defined(__i386__) pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; +#else + /* Ye gads this is ugly. With more thought + we could move this up higher and use + `protection_map' instead. */ + vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect( + __pte(pgprot_val(vma->vm_page_prot))))); +#endif } diff --git a/shared-core/drm.h b/shared-core/drm.h index 324e2002..320db51e 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 17:11:19 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -26,7 +26,10 @@ * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $ - * + * + * Acknowledgements: + * Dec 1999, Richard Henderson , move to generic cmpxchg. + * */ #ifndef _DRM_H_ diff --git a/shared/drm.h b/shared/drm.h index 324e2002..320db51e 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 17:11:19 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -26,7 +26,10 @@ * * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $ - * + * + * Acknowledgements: + * Dec 1999, Richard Henderson , move to generic cmpxchg. + * */ #ifndef _DRM_H_ diff --git a/tests/drmstat.c b/tests/drmstat.c index ed235d7f..4ee43f04 100644 --- a/tests/drmstat.c +++ b/tests/drmstat.c @@ -1,6 +1,6 @@ /* drmstat.c -- DRM device status and testing program * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com - * Revised: Sun Aug 1 11:02:00 1999 by faith@precisioninsight.com + * Revised: Mon Dec 6 10:33:46 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -218,8 +218,8 @@ int main(int argc, char **argv) info->list[i].low_mark, info->list[i].high_mark); } - printf("===== /proc/drm/1/meminfo =====\n"); - sprintf(buf, "cat /proc/drm/1/meminfo"); + printf("===== /proc/graphics/0/mem =====\n"); + sprintf(buf, "cat /proc/graphics/0/mem"); system(buf); #if 1 if (!(bufs = drmMapBufs(fd))) { @@ -234,8 +234,8 @@ int main(int argc, char **argv) bufs->list[i].total, bufs->list[i].address); } - printf("===== /proc/drm/1/vmainfo =====\n"); - sprintf(buf, "cat /proc/drm/1/vmainfo"); + printf("===== /proc/graphics/0/vma =====\n"); + sprintf(buf, "cat /proc/graphics/0/vma"); system(buf); #endif break; @@ -249,8 +249,8 @@ int main(int argc, char **argv) return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); - printf("===== /proc/drm/1/meminfo =====\n"); - sprintf(buf, "cat /proc/drm/1/meminfo"); + printf("===== /proc/graphics/0/mem =====\n"); + sprintf(buf, "cat /proc/graphics/0/mem"); system(buf); break; case 'r': @@ -266,8 +266,8 @@ int main(int argc, char **argv) return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); - printf("===== /proc/drm/1/meminfo =====\n"); - sprintf(buf, "cat /proc/drm/1/meminfo"); + printf("===== /proc/graphics/0/mem =====\n"); + sprintf(buf, "cat /proc/graphics/0/mem"); system(buf); break; case 's': @@ -315,11 +315,11 @@ int main(int argc, char **argv) printf("===== /proc/%d/maps =====\n", getpid()); sprintf(buf, "cat /proc/%d/maps", getpid()); system(buf); - printf("===== /proc/drm/1/meminfo =====\n"); - sprintf(buf, "cat /proc/drm/1/meminfo"); + printf("===== /proc/grphics/0/mem =====\n"); + sprintf(buf, "cat /proc/graphics/0/mem"); system(buf); - printf("===== /proc/drm/1/vmainfo =====\n"); - sprintf(buf, "cat /proc/drm/1/vmainfo"); + printf("===== /proc/graphics/0/vma =====\n"); + sprintf(buf, "cat /proc/graphics/0/vma"); system(buf); printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) @@ -336,8 +336,8 @@ int main(int argc, char **argv) for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); - printf("===== /proc/drm/1/vmainfo =====\n"); - sprintf(buf, "cat /proc/drm/1/vmainfo"); + printf("===== /proc/graphics/0/vma =====\n"); + sprintf(buf, "cat /proc/graphics/0/vma"); system(buf); break; case 'L': -- cgit v1.2.3