start on the radeon + other fixups

This commit is contained in:
Alan Hourihane 2001-05-04 11:22:02 +00:00
parent 9c4211f93d
commit e1770afb48
11 changed files with 221 additions and 115 deletions

View file

@ -76,6 +76,18 @@ do { \
#define DRM_OS_COPYFROMUSR(arg1, arg2, arg3) \
copyin(arg2, arg1, arg3)
#define DRM_OS_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_OS_WRITEMEMORYBARRIER DRM_OS_READMEMORYBARRIER
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
typedef unsigned long atomic_t;

View file

@ -76,6 +76,18 @@ do { \
#define DRM_OS_COPYFROMUSR(arg1, arg2, arg3) \
copyin(arg2, arg1, arg3)
#define DRM_OS_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_OS_WRITEMEMORYBARRIER DRM_OS_READMEMORYBARRIER
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
typedef unsigned long atomic_t;

View file

@ -514,13 +514,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
if ( !irq )
DRM_OS_RETURN(EINVAL);
down( &dev->struct_sem );
DRM_OS_LOCK;
if ( dev->irq ) {
up( &dev->struct_sem );
DRM_OS_UNLOCK;
DRM_OS_RETURN(EBUSY);
}
dev->irq = irq;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
@ -546,9 +546,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
ret = request_irq( dev->irq, DRM(dma_service),
0, dev->devname, dev );
if ( ret < 0 ) {
down( &dev->struct_sem );
DRM_OS_LOCK;
dev->irq = 0;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
return ret;
}
@ -562,10 +562,10 @@ int DRM(irq_uninstall)( drm_device_t *dev )
{
int irq;
down( &dev->struct_sem );
DRM_OS_LOCK;
irq = dev->irq;
dev->irq = 0;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
if ( !irq )
DRM_OS_RETURN(EINVAL);
@ -579,8 +579,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
return 0;
}
int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
int DRM(control)( DRM_OS_IOCTL )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;

View file

@ -281,6 +281,9 @@ do { \
#define DRM_OS_COPYFROMUSR(arg1, arg2, arg3) \
copy_from_user(arg1, arg2, arg3)
#define DRM_OS_READMEMORYBARRIER mb()
#define DRM_OS_WRITEMEMORYBARRIER wmb()
/* Internal functions */
/* drm_drv.h */

View file

@ -514,13 +514,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
if ( !irq )
DRM_OS_RETURN(EINVAL);
down( &dev->struct_sem );
DRM_OS_LOCK;
if ( dev->irq ) {
up( &dev->struct_sem );
DRM_OS_UNLOCK;
DRM_OS_RETURN(EBUSY);
}
dev->irq = irq;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
@ -546,9 +546,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
ret = request_irq( dev->irq, DRM(dma_service),
0, dev->devname, dev );
if ( ret < 0 ) {
down( &dev->struct_sem );
DRM_OS_LOCK;
dev->irq = 0;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
return ret;
}
@ -562,10 +562,10 @@ int DRM(irq_uninstall)( drm_device_t *dev )
{
int irq;
down( &dev->struct_sem );
DRM_OS_LOCK;
irq = dev->irq;
dev->irq = 0;
up( &dev->struct_sem );
DRM_OS_UNLOCK;
if ( !irq )
DRM_OS_RETURN(EINVAL);
@ -579,8 +579,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
return 0;
}
int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
int DRM(control)( DRM_OS_IOCTL )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;

View file

@ -281,6 +281,9 @@ do { \
#define DRM_OS_COPYFROMUSR(arg1, arg2, arg3) \
copy_from_user(arg1, arg2, arg3)
#define DRM_OS_READMEMORYBARRIER mb()
#define DRM_OS_WRITEMEMORYBARRIER wmb()
/* Internal functions */
/* drm_drv.h */

View file

@ -32,6 +32,12 @@
#ifdef __linux__
#include <linux/config.h>
#endif
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <opt_drm_linux.h>
#endif
#include "gamma.h"
#include "drmP.h"
#include "gamma_drv.h"
@ -49,6 +55,26 @@
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }
#ifdef __FreeBSD__
static int gamma_probe(device_t dev)
{
const char *s = 0;
switch (pci_get_devid(dev)) {
case 0x00083d3d:
s = "3DLabs Gamma";
break;
}
if (s) {
device_set_desc(dev, s);
return 0;
}
return ENXIO;
}
#endif
#define __HAVE_COUNTERS 5
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
@ -80,3 +106,7 @@
#ifdef __FreeBSD__
#include "drm_sysctl.h"
#endif
#ifdef __FreeBSD__
DRIVER_MODULE(gamma, pci, gamma_driver, gamma_devclass, 0, 0);
#endif

View file

@ -44,7 +44,7 @@ typedef struct drm_mga_primary_buffer {
u32 tail;
int space;
volatile int wrapped;
volatile long wrapped;
volatile u32 *status;

View file

@ -30,10 +30,23 @@
*/
#define __NO_VERSION__
#ifdef __linux__
#include <linux/config.h>
#endif
#include "radeon.h"
#include "drmP.h"
#include "radeon_drv.h"
#ifdef __linux__
#include "linux/un.h"
#endif
#ifdef __FreeBSD__
#include <machine/param.h>
#include <sys/mman.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <vm/vm_map.h>
#endif
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
@ -57,10 +70,9 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp,
int byte_count;
int i;
if (!dma) return -EINVAL;
if (!dma) return DRM_OS_RETURN(EINVAL);
if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
return -EFAULT;
DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) );
count = request.count;
order = drm_order(request.size);
@ -81,23 +93,25 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp,
DRM_DEBUG("page_order: %d\n", page_order);
DRM_DEBUG("total: %d\n", total);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
if (dev->queue_count) return -EBUSY; /* Not while in use */
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
DRM_OS_RETURN(EINVAL);
if (dev->queue_count)
DRM_OS_RETURN(EBUSY); /* Not while in use */
spin_lock(&dev->count_lock);
DRM_OS_SPINLOCK(&dev->count_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
return -EBUSY;
DRM_OS_SPINUNLOCK(&dev->count_lock);
DRM_OS_RETURN(EBUSY);
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
DRM_OS_SPINUNLOCK(&dev->count_lock);
down(&dev->struct_sem);
DRM_OS_LOCK;
entry = &dma->bufs[order];
if (entry->buf_count) {
up(&dev->struct_sem);
DRM_OS_UNLOCK;
atomic_dec(&dev->buf_alloc);
return -ENOMEM; /* May only call once for each order */
DRM_OS_RETURN(ENOMEM); /* May only call once for each order */
}
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
@ -105,7 +119,7 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp,
if (!entry->buflist) {
up(&dev->struct_sem);
atomic_dec(&dev->buf_alloc);
return -ENOMEM;
DRM_OS_RETURN(ENOMEM);
}
memset(entry->buflist, 0, count * sizeof(*entry->buflist));
@ -170,8 +184,7 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp,
request.count = entry->buf_count;
request.size = size;
if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request)))
return -EFAULT;
DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) );
dma->flags = _DRM_DMA_USE_AGP;
@ -180,55 +193,57 @@ int radeon_addbufs_agp(struct inode *inode, struct file *filp,
}
#endif
int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
int radeon_addbufs( DRM_OS_IOCTL )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_OS_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_buf_desc_t request;
DRM_OS_PRIV;
if (!dev_priv || dev_priv->is_pci) return -EINVAL;
if (!dev_priv || dev_priv->is_pci) DRM_OS_RETURN(EINVAL);
if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
return -EFAULT;
DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) );
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (request.flags & _DRM_AGP_BUFFER)
return radeon_addbufs_agp(inode, filp, cmd, arg);
else
#endif
return -EINVAL;
DRM_OS_RETURN(EINVAL);
}
int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
int radeon_mapbufs( DRM_OS_IOCTL )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_OS_DEVICE;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
int retcode = 0;
const int zero = 0;
#ifdef __linux__
unsigned long virtual;
unsigned long address;
#endif
#ifdef __FreeBSD__
vm_offset_t virtual;
vm_offset_t address;
#endif
drm_buf_map_t request;
int i;
DRM_OS_PRIV;
if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL;
if (!dma || !dev_priv || dev_priv->is_pci) DRM_OS_RETURN(EINVAL);
DRM_DEBUG("\n");
spin_lock(&dev->count_lock);
DRM_OS_SPINLOCK(&dev->count_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
return -EBUSY;
DRM_OS_SPINUNLOCK(&dev->count_lock);
DRM_OS_RETURN(EBUSY);
}
++dev->buf_use; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
DRM_OS_SPINUNLOCK(&dev->count_lock);
if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request)))
return -EFAULT;
DRM_OS_KRNFROMUSR( request, (drm_buf_map_t *)data, sizeof(request) );
if (request.count >= dma->buf_count) {
if (dma->flags & _DRM_DMA_USE_AGP) {
@ -236,53 +251,101 @@ int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
map = dev_priv->buffers;
if (!map) {
retcode = -EINVAL;
retcode = EINVAL;
goto done;
}
down(&current->mm->mmap_sem);
virtual = do_mmap(filp, 0, map->size,
PROT_READ|PROT_WRITE,
#ifdef __linux__
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write( &current->mm->mmap_sem );
#endif
virtual = do_mmap( filp, 0, map->size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
(unsigned long)map->offset );
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write( &current->mm->mmap_sem );
#endif
#endif
#ifdef __FreeBSD__
retcode = vm_mmap(&p->p_vmspace->vm_map,
&virtual,
round_page(dma->byte_count),
PROT_READ|PROT_WRITE, VM_PROT_ALL,
MAP_SHARED,
(unsigned long)map->offset);
up(&current->mm->mmap_sem);
SLIST_FIRST(&kdev->si_hlist),
(unsigned long)map->offset );
#endif
} else {
down(&current->mm->mmap_sem);
virtual = do_mmap(filp, 0, dma->byte_count,
PROT_READ|PROT_WRITE, MAP_SHARED, 0);
up(&current->mm->mmap_sem);
#ifdef __linux__
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write( &current->mm->mmap_sem );
#endif
virtual = do_mmap( filp, 0, dma->byte_count,
PROT_READ | PROT_WRITE,
MAP_SHARED, 0 );
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write( &current->mm->mmap_sem );
#endif
#endif
#ifdef __FreeBSD__
retcode = vm_mmap(&p->p_vmspace->vm_map,
&virtual,
round_page(dma->byte_count),
PROT_READ|PROT_WRITE, VM_PROT_ALL,
MAP_SHARED,
SLIST_FIRST(&kdev->si_hlist),
0);
#endif
}
if (virtual > -1024UL) {
#ifdef __linux__
if ( virtual > -1024UL ) {
/* Real error */
retcode = (signed long)virtual;
goto done;
}
#endif
#ifdef __FreeBSD__
if (retcode)
goto done;
#endif
request.virtual = (void *)virtual;
for (i = 0; i < dma->buf_count; i++) {
if (copy_to_user(&request.list[i].idx,
if (DRM_OS_COPYTOUSR(&request.list[i].idx,
&dma->buflist[i]->idx,
sizeof(request.list[0].idx))) {
retcode = -EFAULT;
retcode = EFAULT;
goto done;
}
if (copy_to_user(&request.list[i].total,
if (DRM_OS_COPYTOUSR(&request.list[i].total,
&dma->buflist[i]->total,
sizeof(request.list[0].total))) {
retcode = -EFAULT;
retcode = EFAULT;
goto done;
}
if (copy_to_user(&request.list[i].used,
if (DRM_OS_COPYTOUSR(&request.list[i].used,
&zero,
sizeof(zero))) {
retcode = -EFAULT;
retcode = EFAULT;
goto done;
}
address = virtual + dma->buflist[i]->offset;
if (copy_to_user(&request.list[i].address,
if (DRM_OS_COPYTOUSR(&request.list[i].address,
&address,
sizeof(address))) {
retcode = -EFAULT;
retcode = EFAULT;
goto done;
}
}
@ -291,8 +354,7 @@ int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
request.count = dma->buf_count;
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request)))
return -EFAULT;
DRM_OS_KRNTOUSR( (drm_buf_map_t *)data, request, sizeof(request) );
return retcode;
DRM_OS_RETURN(retcode);
}

View file

@ -33,8 +33,10 @@
#include "drmP.h"
#include "radeon_drv.h"
#ifdef __linux__
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
#endif
#define RADEON_FIFO_DEBUG 0
@ -356,7 +358,7 @@ static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
& RADEON_RB2D_DC_BUSY) ) {
return 0;
}
udelay( 1 );
DRM_OS_DELAY( 1 );
}
#if RADEON_FIFO_DEBUG
@ -375,7 +377,7 @@ static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
& RADEON_RBBM_FIFOCNT_MASK );
if ( slots >= entries ) return 0;
udelay( 1 );
DRM_OS_DELAY( 1 );
}
#if RADEON_FIFO_DEBUG
@ -398,7 +400,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
radeon_do_pixcache_flush( dev_priv );
return 0;
}
udelay( 1 );
DRM_OS_DELAY( 1 );
}
#if RADEON_FIFO_DEBUG

View file

@ -126,29 +126,21 @@ typedef struct drm_radeon_buf_priv {
} drm_radeon_buf_priv_t;
/* radeon_cp.c */
extern int radeon_cp_init( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_start( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_stop( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_idle( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_engine_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_init( DRM_OS_IOCTL );
extern int radeon_cp_start( DRM_OS_IOCTL );
extern int radeon_cp_stop( DRM_OS_IOCTL );
extern int radeon_cp_reset( DRM_OS_IOCTL );
extern int radeon_cp_idle( DRM_OS_IOCTL );
extern int radeon_engine_reset( DRM_OS_IOCTL );
extern int radeon_fullscreen( DRM_OS_IOCTL );
extern int radeon_cp_buffers( DRM_OS_IOCTL );
extern void radeon_freelist_reset( drm_device_t *dev );
extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
static inline void
static __inline__ void
radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
{
ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32);
@ -161,21 +153,13 @@ extern int radeon_do_cleanup_cp( drm_device_t *dev );
extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
/* radeon_state.c */
extern int radeon_cp_clear( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indices( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_texture( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_clear( DRM_OS_IOCTL );
extern int radeon_cp_swap( DRM_OS_IOCTL );
extern int radeon_cp_vertex( DRM_OS_IOCTL );
extern int radeon_cp_indices( DRM_OS_IOCTL );
extern int radeon_cp_texture( DRM_OS_IOCTL );
extern int radeon_cp_stipple( DRM_OS_IOCTL );
extern int radeon_cp_indirect( DRM_OS_IOCTL );
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
@ -530,12 +514,12 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
static inline u32 _RADEON_READ(u32 *addr)
{
mb();
DRM_OS_READMEMORYBARRIER;
return *(volatile u32 *)addr;
}
#define RADEON_WRITE(reg,val) \
do { \
wmb(); \
DRM_OS_WRITEMEMORYBARRIER; \
RADEON_DEREF(reg) = val; \
} while (0)
#else
@ -548,12 +532,12 @@ do { \
#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
static inline u8 _RADEON_READ8(u8 *addr)
{
mb();
DRM_OS_READMEMORYBARRIER;
return *(volatile u8 *)addr;
}
#define RADEON_WRITE8(reg,val) \
do { \
wmb(); \
DRM_OS_WRITEMEMORYBARRIER; \
RADEON_DEREF8( reg ) = val; \
} while (0)
#else
@ -693,7 +677,7 @@ do { \
* Ring control
*/
#define radeon_flush_write_combine() mb()
#define radeon_flush_write_combine() DRM_OS_READMEMORYBARRIER
#define RADEON_VERBOSE 0