diff options
-rw-r--r-- | bsd-core/ati_pcigart.c | 87 | ||||
-rw-r--r-- | bsd-core/drmP.h | 64 | ||||
-rw-r--r-- | bsd-core/drm_agpsupport.c | 54 | ||||
-rw-r--r-- | bsd-core/drm_auth.c | 44 | ||||
-rw-r--r-- | bsd-core/drm_bufs.c | 388 | ||||
-rw-r--r-- | bsd-core/drm_context.c | 191 | ||||
-rw-r--r-- | bsd-core/drm_dma.c | 77 | ||||
-rw-r--r-- | bsd-core/drm_drawable.c | 7 | ||||
-rw-r--r-- | bsd-core/drm_drv.c | 555 | ||||
-rw-r--r-- | bsd-core/drm_fops.c | 61 | ||||
-rw-r--r-- | bsd-core/drm_ioctl.c | 84 | ||||
-rw-r--r-- | bsd-core/drm_lock.c | 17 | ||||
-rw-r--r-- | bsd-core/drm_memory.c | 161 | ||||
-rw-r--r-- | bsd-core/drm_os_freebsd.h | 209 | ||||
-rw-r--r-- | bsd-core/drm_os_netbsd.h | 378 | ||||
-rw-r--r-- | bsd-core/drm_scatter.c | 115 | ||||
-rw-r--r-- | bsd-core/drm_sysctl.c | 123 | ||||
-rw-r--r-- | bsd-core/drm_vm.c | 26 | ||||
-rw-r--r-- | bsd-core/mga/Makefile | 20 | ||||
-rw-r--r-- | bsd-core/mga_drv.c (renamed from linux/mga.h) | 69 | ||||
-rw-r--r-- | bsd-core/r128/Makefile | 20 | ||||
-rw-r--r-- | bsd-core/r128_drv.c | 86 | ||||
-rw-r--r-- | bsd-core/radeon/Makefile | 20 | ||||
-rw-r--r-- | bsd-core/radeon_drv.c | 76 | ||||
-rw-r--r-- | bsd-core/sis/Makefile | 25 | ||||
-rw-r--r-- | bsd-core/tdfx/Makefile | 20 | ||||
-rw-r--r-- | bsd-core/tdfx_drv.c (renamed from bsd/tdfx/tdfx_drv.c) | 5 | ||||
-rw-r--r-- | bsd/Imakefile | 19 | ||||
-rw-r--r-- | bsd/ati_pcigart.h | 87 | ||||
-rw-r--r-- | bsd/drm.h | 38 | ||||
-rw-r--r-- | bsd/drmP.h | 64 | ||||
-rw-r--r-- | bsd/drm_agpsupport.h | 54 | ||||
-rw-r--r-- | bsd/drm_auth.h | 44 | ||||
-rw-r--r-- | bsd/drm_bufs.h | 388 | ||||
-rw-r--r-- | bsd/drm_context.h | 191 | ||||
-rw-r--r-- | bsd/drm_dma.h | 77 | ||||
-rw-r--r-- | bsd/drm_drawable.h | 7 | ||||
-rw-r--r-- | bsd/drm_drv.h | 555 | ||||
-rw-r--r-- | bsd/drm_fops.h | 61 | ||||
-rw-r--r-- | bsd/drm_init.h | 3 | ||||
-rw-r--r-- | bsd/drm_ioctl.h | 84 | ||||
-rw-r--r-- | bsd/drm_lists.h | 37 | ||||
-rw-r--r-- | bsd/drm_lock.h | 17 | ||||
-rw-r--r-- | bsd/drm_memory.h | 161 | ||||
-rw-r--r-- | bsd/drm_os_freebsd.h | 209 | ||||
-rw-r--r-- | bsd/drm_os_netbsd.h | 378 | ||||
-rw-r--r-- | bsd/drm_scatter.h | 115 | ||||
-rw-r--r-- | bsd/drm_sysctl.h | 123 | ||||
-rw-r--r-- | bsd/drm_vm.h | 26 | ||||
-rw-r--r-- | bsd/gamma.h (renamed from bsd/gamma/gamma.h) | 0 | ||||
-rw-r--r-- | bsd/gamma/Makefile | 20 | ||||
-rw-r--r-- | bsd/gamma_dma.c | 569 | ||||
-rw-r--r-- | bsd/gamma_drv.c (renamed from bsd/sis/sis_drv.c) | 70 | ||||
-rw-r--r-- | bsd/gamma_drv.h (renamed from bsd/gamma/gamma_drv.h) | 6 | ||||
-rw-r--r-- | bsd/i810.h (renamed from bsd/i810/i810.h) | 0 | ||||
-rw-r--r-- | bsd/i810_dma.c | 1223 | ||||
-rw-r--r-- | bsd/i810_drv.c | 96 | ||||
-rw-r--r-- | bsd/i810_drv.h (renamed from bsd/i810/i810_drv.h) | 18 | ||||
-rw-r--r-- | bsd/i830.h (renamed from bsd/i830/i830.h) | 0 | ||||
-rw-r--r-- | bsd/i830_dma.c | 1420 | ||||
-rw-r--r-- | bsd/i830_drv.c | 104 | ||||
-rw-r--r-- | bsd/i830_drv.h (renamed from bsd/i830/i830_drv.h) | 0 | ||||
-rw-r--r-- | bsd/mga/Makefile | 20 | ||||
-rw-r--r-- | bsd/mga_drv.c | 66 | ||||
-rw-r--r-- | bsd/r128/Makefile | 20 | ||||
-rw-r--r-- | bsd/r128/r128.h | 81 | ||||
-rw-r--r-- | bsd/r128_drv.c | 86 | ||||
-rw-r--r-- | bsd/radeon/Makefile | 20 | ||||
-rw-r--r-- | bsd/radeon_drv.c | 76 | ||||
-rw-r--r-- | bsd/sis/Makefile | 25 | ||||
-rw-r--r-- | bsd/sis/sis.h | 45 | ||||
-rw-r--r-- | bsd/sis/sis_drm.h | 30 | ||||
-rw-r--r-- | bsd/sis/sis_drv.h | 42 | ||||
-rw-r--r-- | bsd/sis/sis_ds.c | 398 | ||||
-rw-r--r-- | bsd/sis/sis_ds.h | 163 | ||||
-rw-r--r-- | bsd/sis/sis_mm.c | 300 | ||||
-rw-r--r-- | bsd/sis_drm.h | 10 | ||||
-rw-r--r-- | bsd/tdfx.h (renamed from bsd/tdfx/tdfx.h) | 0 | ||||
-rw-r--r-- | bsd/tdfx/Makefile | 20 | ||||
-rw-r--r-- | bsd/tdfx_drv.c | 99 | ||||
-rw-r--r-- | libdrm/xf86drm.c | 9 | ||||
-rw-r--r-- | linux-core/drmP.h | 4 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 16 | ||||
-rw-r--r-- | linux-core/drm_os_linux.h | 56 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 61 | ||||
-rw-r--r-- | linux-core/i830_drv.c | 47 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 51 | ||||
-rw-r--r-- | linux-core/r128_drv.c | 59 | ||||
-rw-r--r-- | linux-core/radeon_drv.c | 63 | ||||
-rw-r--r-- | linux-core/sis_drv.c | 25 | ||||
-rw-r--r-- | linux-core/tdfx_drv.c | 19 | ||||
-rw-r--r-- | linux/drm.h | 30 | ||||
-rw-r--r-- | linux/drmP.h | 4 | ||||
-rw-r--r-- | linux/drm_drv.h | 16 | ||||
-rw-r--r-- | linux/drm_os_linux.h | 56 | ||||
-rw-r--r-- | linux/gamma.h | 25 | ||||
-rw-r--r-- | linux/gamma_drv.c | 45 | ||||
-rw-r--r-- | linux/i810.h | 41 | ||||
-rw-r--r-- | linux/i810_drv.c | 61 | ||||
-rw-r--r-- | linux/i830.h | 27 | ||||
-rw-r--r-- | linux/i830_drv.c | 47 | ||||
-rw-r--r-- | linux/mga_drv.c | 51 | ||||
-rw-r--r-- | linux/r128_drv.c | 59 | ||||
-rw-r--r-- | linux/radeon.h | 81 | ||||
-rw-r--r-- | linux/radeon_drv.c | 63 | ||||
-rw-r--r-- | linux/sis.h | 25 | ||||
-rw-r--r-- | linux/sis_drv.c | 25 | ||||
-rw-r--r-- | linux/tdfx_drv.c | 19 | ||||
-rw-r--r-- | shared-core/drm.h | 30 | ||||
-rw-r--r-- | shared-core/mga_dma.c (renamed from linux/mga_dma.c) | 149 | ||||
-rw-r--r-- | shared-core/mga_drm.h (renamed from linux/mga_drm.h) | 0 | ||||
-rw-r--r-- | shared-core/mga_drv.h (renamed from bsd/mga/mga_drv.h) | 61 | ||||
-rw-r--r-- | shared-core/mga_state.c (renamed from linux/mga_state.c) | 117 | ||||
-rw-r--r-- | shared-core/mga_ucode.h (renamed from bsd/mga/mga_ucode.h) | 0 | ||||
-rw-r--r-- | shared-core/mga_warp.c (renamed from linux/mga_warp.c) | 10 | ||||
-rw-r--r-- | shared-core/r128_cce.c (renamed from linux/r128_cce.c) | 201 | ||||
-rw-r--r-- | shared-core/r128_drm.h (renamed from linux/r128_drm.h) | 0 | ||||
-rw-r--r-- | shared-core/r128_drv.h (renamed from bsd/r128/r128_drv.h) | 110 | ||||
-rw-r--r-- | shared-core/r128_state.c (renamed from linux/r128_state.c) | 373 | ||||
-rw-r--r-- | shared-core/radeon_cp.c (renamed from linux/radeon_cp.c) | 187 | ||||
-rw-r--r-- | shared-core/radeon_drm.h (renamed from linux/radeon_drm.h) | 0 | ||||
-rw-r--r-- | shared-core/radeon_drv.h (renamed from linux/radeon_drv.h) | 101 | ||||
-rw-r--r-- | shared-core/radeon_state.c (renamed from linux/radeon_state.c) | 357 | ||||
-rw-r--r-- | shared/drm.h | 30 | ||||
-rw-r--r-- | shared/mga.h (renamed from bsd/mga/mga.h) | 27 | ||||
-rw-r--r-- | shared/mga_dma.c | 786 | ||||
-rw-r--r-- | shared/mga_drm.h | 325 | ||||
-rw-r--r-- | shared/mga_drv.h (renamed from linux/mga_drv.h) | 64 | ||||
-rw-r--r-- | shared/mga_state.c | 1078 | ||||
-rw-r--r-- | shared/mga_ucode.h (renamed from linux/mga_ucode.h) | 0 | ||||
-rw-r--r-- | shared/mga_warp.c | 212 | ||||
-rw-r--r-- | shared/r128.h (renamed from linux/r128.h) | 29 | ||||
-rw-r--r-- | shared/r128_cce.c | 1010 | ||||
-rw-r--r-- | shared/r128_drm.h | 308 | ||||
-rw-r--r-- | shared/r128_drv.h (renamed from linux/r128_drv.h) | 80 | ||||
-rw-r--r-- | shared/r128_state.c | 1566 | ||||
-rw-r--r-- | shared/radeon.h (renamed from bsd/radeon/radeon.h) | 42 | ||||
-rw-r--r-- | shared/radeon_cp.c | 1287 | ||||
-rw-r--r-- | shared/radeon_drm.h | 467 | ||||
-rw-r--r-- | shared/radeon_drv.h | 760 | ||||
-rw-r--r-- | shared/radeon_state.c | 1856 |
141 files changed, 18140 insertions, 5315 deletions
diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index 8b486c10..28723f56 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -27,7 +27,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" #if PAGE_SIZE == 8192 @@ -46,40 +45,20 @@ static unsigned long DRM(ati_alloc_pcigart_table)( void ) { unsigned long address; - struct page *page; - int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER ); - if ( address == 0UL ) { - return 0; - } + DRM_DEBUG( "\n" ); - page = virt_to_page( address ); + address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK ); - for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { - atomic_inc( &page->count ); - SetPageReserved( page ); - } - - DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address ); + DRM_DEBUG( "returning 0x%08lx\n", address ); return address; } static void DRM(ati_free_pcigart_table)( unsigned long address ) { - struct page *page; - int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - page = virt_to_page( address ); + DRM_DEBUG( "\n" ); - for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { - atomic_dec( &page->count ); - ClearPageReserved( page ); - } - - free_pages( address, ATI_PCIGART_TABLE_ORDER ); + free( (void *)address, DRM(M_DRM)); } int DRM(ati_pcigart_init)( drm_device_t *dev, @@ -89,7 +68,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, drm_sg_mem_t *entry = dev->sg; unsigned long address = 0; unsigned long pages; - u32 *pci_gart, page_base, bus_address = 0; + u32 *pci_gart=0, page_base, bus_address = 0; int i, j, ret = 0; if ( !entry ) { @@ -103,41 +82,36 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, goto done; } - if ( !dev->pdev ) { - DRM_ERROR( "PCI device unknown!\n" ); - goto done; - } - - bus_address = pci_map_single(dev->pdev, (void *)address, + /* FIXME non-vtophys==bustophys-arches */ + bus_address = vtophys( address ); + /*pci_map_single(dev->pdev, (void *)address, ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); - if (bus_address == 0) { + PCI_DMA_TODEVICE);*/ +/* if (bus_address == 0) { DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_free_pcigart_table)( address ); + DRM(ati_free_pcigart_table)( (unsigned long)address ); address = 0; goto done; - } + }*/ pci_gart = (u32 *)address; pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) ? entry->pages : ATI_MAX_PCIGART_PAGES; - memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); + bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); for ( i = 0 ; i < pages ; i++ ) { /* we need to support large memory configurations */ - entry->busaddr[i] = pci_map_single(dev->pdev, - page_address( entry->pagelist[i] ), - PAGE_SIZE, - PCI_DMA_TODEVICE); - if (entry->busaddr[i] == 0) { + /* 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, address, bus_address ); + 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++) { @@ -148,11 +122,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, ret = 1; -#if defined(__i386__) || defined(__x86_64__) - asm volatile ( "wbinvd" ::: "memory" ); -#else - mb(); -#endif + DRM_READMEMORYBARRIER(); done: *addr = address; @@ -165,8 +135,6 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, dma_addr_t bus_addr) { drm_sg_mem_t *entry = dev->sg; - unsigned long pages; - int i; /* we need to support large memory configurations */ if ( !entry ) { @@ -174,21 +142,6 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, return 0; } - if ( bus_addr ) { - pci_unmap_single(dev->pdev, bus_addr, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); - - pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) - ? entry->pages : ATI_MAX_PCIGART_PAGES; - - for ( i = 0 ; i < pages ; i++ ) { - if ( !entry->busaddr[i] ) break; - pci_unmap_single(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_TODEVICE); - } - } - if ( addr ) { DRM(ati_free_pcigart_table)( addr ); } diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 5841ea96..f323e8ef 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -69,7 +69,11 @@ typedef struct drm_file drm_file_t; /* There's undoubtably more of this file to go into these OS dependent ones. */ +#ifdef __FreeBSD__ #include "drm_os_freebsd.h" +#elif defined __NetBSD__ +#include "drm_os_netbsd.h" +#endif #include "drm.h" @@ -239,8 +243,8 @@ typedef struct drm_waitlist { drm_buf_t **rp; /* Read pointer */ drm_buf_t **wp; /* Write pointer */ drm_buf_t **end; /* End pointer */ - DRM_OS_SPINTYPE read_lock; - DRM_OS_SPINTYPE write_lock; + DRM_SPINTYPE read_lock; + DRM_SPINTYPE write_lock; } drm_waitlist_t; typedef struct drm_freelist { @@ -252,7 +256,7 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ atomic_t wfh; /* If waiting for high mark */ - DRM_OS_SPINTYPE lock; + DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -374,6 +378,7 @@ typedef struct drm_sg_mem { void *virtual; int pages; struct page **pagelist; + dma_addr_t *busaddr; } drm_sg_mem_t; typedef struct drm_sigdata { @@ -388,20 +393,24 @@ typedef struct drm_map_list_entry { } drm_map_list_entry_t; struct drm_device { +#ifdef __NetBSD__ + struct device device; /* NetBSD's softc is an extension of struct device */ +#endif const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ int unique_len; /* Length of unique field */ +#ifdef __FreeBSD__ device_t device; /* Device instance from newbus */ +#endif dev_t devnode; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ int blocked; /* Blocked due to VC switch? */ int flags; /* Flags to open(2) */ int writable; /* Opened with FWRITE */ - struct proc_dir_entry *root; /* Root for this device's entries */ /* Locks */ - DRM_OS_SPINTYPE count_lock; /* For inuse, open_count, buf_use */ + DRM_SPINTYPE count_lock; /* For inuse, open_count, buf_use */ struct lock dev_lock; /* For others */ /* Usage Counters */ int open_count; /* Outstanding files open */ @@ -437,12 +446,17 @@ struct drm_device { drm_device_dma_t *dma; /* Optional pointer for DMA support */ /* Context support */ +#ifdef __FreeBSD__ int irq; /* Interrupt used by board */ struct resource *irqr; /* Resource for interrupt used by board */ +#elif defined(__NetBSD__) + struct pci_attach_args pa; + pci_intr_handle_t ih; +#endif void *irqh; /* Handle from bus_setup_intr */ - __volatile__ long context_flag; /* Context swapping flag */ - __volatile__ long interrupt_flag; /* Interruption handler flag */ - __volatile__ long dma_flag; /* DMA dispatch flag */ + atomic_t context_flag; /* Context swapping flag */ + atomic_t interrupt_flag; /* Interruption handler flag */ + atomic_t dma_flag; /* DMA dispatch flag */ struct callout timer; /* Timer for delaying ctx switch */ wait_queue_head_t context_wait; /* Processes waiting on ctx switch */ int last_checked; /* Last context checked for DMA */ @@ -463,7 +477,11 @@ struct drm_device { char *buf_rp; /* Read pointer */ char *buf_wp; /* Write pointer */ char *buf_end; /* End pointer */ +#ifdef __FreeBSD__ struct sigio *buf_sigio; /* Processes waiting for SIGIO */ +#elif defined(__NetBSD__) + pid_t buf_pgid; +#endif struct selinfo buf_sel; /* Workspace for select/poll */ int buf_selecting;/* True if poll sleeper */ wait_queue_head_t buf_readers; /* Processes waiting to read */ @@ -475,16 +493,8 @@ struct drm_device { #if __REALLY_HAVE_AGP drm_agp_head_t *agp; #endif - struct pci_dev *pdev; -#ifdef __alpha__ -#if LINUX_VERSION_CODE < 0x020403 - struct pci_controler *hose; -#else - struct pci_controller *hose; -#endif -#endif drm_sg_mem_t *sg; /* Scatter gather memory */ - unsigned long *ctx_bitmap; + atomic_t *ctx_bitmap; void *dev_private; drm_sigdata_t sigdata; /* For block_all_signals */ sigset_t sigmask; @@ -500,7 +510,7 @@ extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); /* Driver support (drm_drv.h) */ -extern int DRM(version)( DRM_OS_IOCTL ); +extern int DRM(version)( DRM_IOCTL_ARGS ); extern int DRM(write_string)(drm_device_t *dev, const char *s); /* Memory management support (drm_memory.h) */ @@ -511,9 +521,6 @@ extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, 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 unsigned long DRM(alloc_pages)(int order, int area); -extern void DRM(free_pages)(unsigned long address, int order, - 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); @@ -571,9 +578,9 @@ extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); #if __HAVE_DMA_IRQ extern int DRM(irq_install)( drm_device_t *dev, int irq ); extern int DRM(irq_uninstall)( drm_device_t *dev ); -extern void DRM(dma_service)( DRM_OS_IRQ_ARGS ); +extern void DRM(dma_service)( DRM_IRQ_ARGS ); #if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( DRM_OS_TASKQUEUE_ARGS ); +extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ); #endif #endif #if DRM_DMA_HISTOGRAM @@ -608,15 +615,6 @@ extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); extern int DRM(agp_unbind_memory)(agp_memory *handle); #endif - /* Proc support (drm_proc.h) */ -extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int DRM(proc_cleanup)(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); - #if __HAVE_SG /* Scatter Gather Support (drm_scatter.h) */ extern void DRM(sg_cleanup)(drm_sg_mem_t *entry); @@ -633,4 +631,4 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, #endif #endif /* __KERNEL__ */ -#endif +#endif /* _DRM_P_H_ */ diff --git a/bsd-core/drm_agpsupport.c b/bsd-core/drm_agpsupport.c index ac12c867..66de1053 100644 --- a/bsd-core/drm_agpsupport.c +++ b/bsd-core/drm_agpsupport.c @@ -31,15 +31,9 @@ #include "drmP.h" -#include <vm/vm.h> -#include <vm/pmap.h> -#if __REALLY_HAVE_AGP -#include <sys/agpio.h> -#endif - -int DRM(agp_info)(DRM_OS_IOCTL) +int DRM(agp_info)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; struct agp_info *kern; drm_agp_info_t info; @@ -61,9 +55,9 @@ int DRM(agp_info)(DRM_OS_IOCTL) return 0; } -int DRM(agp_acquire)(DRM_OS_IOCTL) +int DRM(agp_acquire)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int retcode; if (!dev->agp || dev->agp->acquired) return EINVAL; @@ -73,9 +67,9 @@ int DRM(agp_acquire)(DRM_OS_IOCTL) return 0; } -int DRM(agp_release)(DRM_OS_IOCTL) +int DRM(agp_release)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; if (!dev->agp || !dev->agp->acquired) return EINVAL; @@ -89,14 +83,14 @@ void DRM(agp_do_release)(void) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (agpdev) agp_release(agpdev); } -int DRM(agp_enable)(DRM_OS_IOCTL) +int DRM(agp_enable)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_mode_t mode; if (!dev->agp || !dev->agp->acquired) return EINVAL; @@ -110,9 +104,9 @@ int DRM(agp_enable)(DRM_OS_IOCTL) return 0; } -int DRM(agp_alloc)(DRM_OS_IOCTL) +int DRM(agp_alloc)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_buffer_t request; drm_agp_mem_t *entry; void *handle; @@ -165,9 +159,9 @@ static drm_agp_mem_t * DRM(agp_lookup_entry)(drm_device_t *dev, void *handle) return NULL; } -int DRM(agp_unbind)(DRM_OS_IOCTL) +int DRM(agp_unbind)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; @@ -187,9 +181,9 @@ int DRM(agp_unbind)(DRM_OS_IOCTL) return retcode; } -int DRM(agp_bind)(DRM_OS_IOCTL) +int DRM(agp_bind)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; @@ -209,9 +203,9 @@ int DRM(agp_bind)(DRM_OS_IOCTL) return 0; } -int DRM(agp_free)(DRM_OS_IOCTL) +int DRM(agp_free)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_buffer_t request; drm_agp_mem_t *entry; @@ -235,7 +229,7 @@ drm_agp_head_t *DRM(agp_init)(void) drm_agp_head_t *head = NULL; int agp_available = 1; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) agp_available = 0; @@ -267,9 +261,9 @@ drm_agp_head_t *DRM(agp_init)(void) default: } #endif - DRM_INFO("AGP at 0x%08x %dMB\n", + DRM_INFO("AGP at 0x%08lx %dMB\n", head->info.ai_aperture_base, - head->info.ai_aperture_size >> 20); + (int)(head->info.ai_aperture_size >> 20)); } return head; } @@ -284,7 +278,7 @@ agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) return NULL; @@ -295,7 +289,7 @@ int DRM(agp_free_memory)(agp_memory *handle) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return 0; @@ -307,7 +301,7 @@ int DRM(agp_bind_memory)(agp_memory *handle, off_t start) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; @@ -318,7 +312,7 @@ int DRM(agp_unbind_memory)(agp_memory *handle) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; diff --git a/bsd-core/drm_auth.c b/bsd-core/drm_auth.c index db0c0118..0b411d14 100644 --- a/bsd-core/drm_auth.c +++ b/bsd-core/drm_auth.c @@ -29,7 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" static int DRM(hash_magic)(drm_magic_t magic) @@ -43,14 +42,14 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) drm_magic_entry_t *pt; int hash = DRM(hash_magic)(magic); - DRM_OS_LOCK; + DRM_LOCK; for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { if (pt->magic == magic) { retval = pt->priv; break; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; return retval; } @@ -63,13 +62,13 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) hash = DRM(hash_magic)(magic); entry = (drm_magic_entry_t*) DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC); - if (!entry) DRM_OS_RETURN(ENOMEM); + if (!entry) return DRM_ERR(ENOMEM); memset(entry, 0, sizeof(*entry)); entry->magic = magic; entry->priv = priv; entry->next = NULL; - DRM_OS_LOCK; + DRM_LOCK; if (dev->magiclist[hash].tail) { dev->magiclist[hash].tail->next = entry; dev->magiclist[hash].tail = entry; @@ -77,7 +76,7 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) dev->magiclist[hash].head = entry; dev->magiclist[hash].tail = entry; } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -91,7 +90,7 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) DRM_DEBUG("%d\n", magic); hash = DRM(hash_magic)(magic); - DRM_OS_LOCK; + DRM_LOCK; for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { if (pt->magic == magic) { if (dev->magiclist[hash].head == pt) { @@ -103,28 +102,27 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) if (prev) { prev->next = pt->next; } - DRM_OS_UNLOCK; - DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC); + DRM_UNLOCK; return 0; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } -int DRM(getmagic)(DRM_OS_IOCTL) +int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; drm_auth_t auth; - static DRM_OS_SPINTYPE lock; + static DRM_SPINTYPE lock; static int first = 1; - DRM_OS_DEVICE; - DRM_OS_PRIV; + DRM_DEVICE; + DRM_PRIV; if (first) { - DRM_OS_SPININIT(lock, "drm getmagic"); + DRM_SPININIT(lock, "drm getmagic"); first = 0; } @@ -133,10 +131,10 @@ int DRM(getmagic)(DRM_OS_IOCTL) auth.magic = priv->magic; } else { do { - DRM_OS_SPINLOCK(&lock); + DRM_SPINLOCK(&lock); if (!sequence) ++sequence; /* reserve 0 */ auth.magic = sequence++; - DRM_OS_SPINUNLOCK(&lock); + DRM_SPINUNLOCK(&lock); } while (DRM(find_file)(dev, auth.magic)); priv->magic = auth.magic; DRM(add_magic)(dev, priv, auth.magic); @@ -144,18 +142,18 @@ int DRM(getmagic)(DRM_OS_IOCTL) DRM_DEBUG("%u\n", auth.magic); - DRM_OS_KRNTOUSR((drm_auth_t *)data, auth, sizeof(auth)); + DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth)); return 0; } -int DRM(authmagic)(DRM_OS_IOCTL) +int DRM(authmagic)(DRM_IOCTL_ARGS) { drm_auth_t auth; drm_file_t *file; - DRM_OS_DEVICE; + DRM_DEVICE; - DRM_OS_KRNFROMUSR(auth, (drm_auth_t *)data, sizeof(auth)); + DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth)); DRM_DEBUG("%u\n", auth.magic); if ((file = DRM(find_file)(dev, auth.magic))) { @@ -163,5 +161,5 @@ int DRM(authmagic)(DRM_OS_IOCTL) DRM(remove_magic)(dev, auth.magic); return 0; } - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index d55b36d8..46dc1c9a 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -29,14 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ -#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> -#include <vm/vm_param.h> #include "drmP.h" #ifndef __HAVE_PCI_DMA @@ -74,18 +66,18 @@ int DRM(order)( unsigned long size ) return order; } -int DRM(addmap)( DRM_OS_IOCTL ) +int DRM(addmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_t *map; drm_map_list_entry_t *list; - + if (!(dev->flags & (FREAD|FWRITE))) - DRM_OS_RETURN(EACCES); /* Require read/write */ + return DRM_ERR(EACCES); /* Require read/write */ map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); if ( !map ) - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); *map = *(drm_map_t *)data; @@ -95,30 +87,17 @@ int DRM(addmap)( DRM_OS_IOCTL ) */ if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n", map->offset, map->size, map->type ); if ( (map->offset & PAGE_MASK) || (map->size & PAGE_MASK) ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } map->mtrr = -1; map->handle = 0; - TAILQ_FOREACH(list, dev->maplist, link) { - drm_map_t *entry = list->map; - if ( (entry->offset >= map->offset - && (entry->offset) < (map->offset + map->size) ) - || ((entry->offset + entry->size) >= map->offset - && (entry->offset + entry->size) < (map->offset + map->size) ) - || ((entry->offset < map->offset) - && (entry->offset + entry->size) >= (map->offset + map->size) ) ) - DRM_DEBUG("map collission: add(0x%lx-0x%lx), current(0x%lx-0x%lx)\n", - entry->offset, entry->offset + entry->size - 1, - map->offset, map->offset + map->size - 1); - } - switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: @@ -126,7 +105,7 @@ int DRM(addmap)( DRM_OS_IOCTL ) if ( map->offset + map->size < map->offset ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } #endif #ifdef __alpha__ @@ -135,23 +114,41 @@ int DRM(addmap)( DRM_OS_IOCTL ) #if __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { - map->mtrr = mtrr_add( map->offset, map->size, - MTRR_TYPE_WRCOMB, 1 ); - } +#ifdef __FreeBSD__ + int retcode = 0, act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + map->mtrr=1; +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + 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 ); #endif + } +#endif /* __REALLY_HAVE_MTRR */ map->handle = DRM(ioremap)( map->offset, map->size ); break; case _DRM_SHM: DRM_INFO( "%ld %d %d\n", map->size, DRM(order)( map->size ), PAGE_SHIFT); - map->handle = (void *)DRM(alloc_pages) - (DRM(order)(map->size) - PAGE_SHIFT, DRM_MEM_SAREA); + map->handle = (void *)DRM(alloc)(map->size, 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 ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } map->offset = (unsigned long)map->handle; if ( map->flags & _DRM_CONTAINS_LOCK ) { @@ -170,27 +167,27 @@ int DRM(addmap)( DRM_OS_IOCTL ) case _DRM_SCATTER_GATHER: if (!dev->sg) { DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } map->offset = map->offset + dev->sg->handle; break; default: DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS); if(!list) { DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } memset(list, 0, sizeof(*list)); list->map = map; - DRM_OS_LOCK; + DRM_LOCK; TAILQ_INSERT_TAIL(dev->maplist, list, link); - DRM_OS_UNLOCK; + DRM_UNLOCK; *(drm_map_t *)data = *map; @@ -205,17 +202,17 @@ int DRM(addmap)( DRM_OS_IOCTL ) * isn't in use. */ -int DRM(rmmap)( DRM_OS_IOCTL ) +int DRM(rmmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_list_entry_t *list; drm_map_t *map; drm_map_t request; int found_maps = 0; - DRM_OS_KRNFROMUSR( request, (drm_map_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map = list->map; if(map->handle == request.handle && @@ -226,8 +223,8 @@ int DRM(rmmap)( DRM_OS_IOCTL ) * find anything. */ if(list == NULL) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } TAILQ_REMOVE(dev->maplist, list, link); DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); @@ -240,16 +237,32 @@ int DRM(rmmap)( DRM_OS_IOCTL ) #if __REALLY_HAVE_MTRR if (map->mtrr >= 0) { int retcode; - retcode = mtrr_del(map->mtrr, - map->offset, - map->size); +#ifdef __FreeBSD__ + int act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_REMOVE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + mtrrmap.base = map->offset; + mtrrmap.len = map->size; + mtrrmap.type = 0; + mtrrmap.flags = 0; + mtrrmap.owner = p->p_pid; + retcode = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL); DRM_DEBUG("mtrr_del = %d\n", retcode); +#endif } #endif DRM(ioremapfree)(map->handle, map->size); break; case _DRM_SHM: - DRM(free_pages)( (unsigned long)map->handle, DRM(order)(map->size), DRM_MEM_SAREA ); + DRM(free)( map->handle, map->size, DRM_MEM_SAREA ); break; case _DRM_AGP: case _DRM_SCATTER_GATHER: @@ -257,7 +270,7 @@ int DRM(rmmap)( DRM_OS_IOCTL ) } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -270,8 +283,8 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) if (entry->seg_count) { for (i = 0; i < entry->seg_count; i++) { - DRM(free_pages)(entry->seglist[i], - entry->page_order, + DRM(free)((void *)entry->seglist[i], + entry->buf_size, DRM_MEM_DMA); } DRM(free)(entry->seglist, @@ -304,9 +317,9 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) } #if __REALLY_HAVE_AGP -int DRM(addbufs_agp)( DRM_OS_IOCTL ) +int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; drm_buf_entry_t *entry; @@ -323,9 +336,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) int i; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -348,38 +361,38 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) DRM_DEBUG( "total: %d\n", total ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( dev->queue_count ) - DRM_OS_RETURN(EBUSY); /* Not while in use */ + return DRM_ERR(EBUSY); /* Not while in use */ - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -436,9 +449,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -458,12 +471,12 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); dma->flags = _DRM_DMA_USE_AGP; @@ -473,9 +486,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) #endif /* __REALLY_HAVE_AGP */ #if __HAVE_PCI_DMA -int DRM(addbufs_pci)( DRM_OS_IOCTL ) +int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int count; @@ -494,9 +507,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) unsigned long *temp_pagelist; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -507,43 +520,43 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) order, dev->queue_count ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( dev->queue_count ) - DRM_OS_RETURN(EBUSY); /* Not while in use */ + return DRM_ERR(EBUSY); /* Not while in use */ alignment = (request.flags & _DRM_PAGE_ALIGN) ? round_page(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -553,9 +566,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(free)( entry->buflist, count * sizeof(*entry->buflist), DRM_MEM_BUFS ); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->seglist, 0, count * sizeof(*entry->seglist) ); @@ -571,9 +584,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(free)( entry->seglist, count * sizeof(*entry->seglist), DRM_MEM_SEGS ); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->pagelist = temp_pagelist; @@ -586,7 +599,7 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) page_count = 0; while ( entry->buf_count < count ) { - page = DRM(alloc_pages)( page_order, DRM_MEM_DMA ); + page = (unsigned long)DRM(alloc)( size, DRM_MEM_DMA ); if ( !page ) break; entry->seglist[entry->seg_count++] = page; for ( i = 0 ; i < (1 << page_order) ; i++ ) { @@ -631,9 +644,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -652,12 +665,12 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); atomic_dec( &dev->buf_alloc ); return 0; @@ -666,9 +679,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) #endif /* __HAVE_PCI_DMA */ #if __REALLY_HAVE_SG -int DRM(addbufs_sg)( DRM_OS_IOCTL ) +int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; drm_buf_entry_t *entry; @@ -685,9 +698,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) int i; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -710,37 +723,37 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) DRM_DEBUG( "total: %d\n", total ); 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 */ + return DRM_ERR(EINVAL); + if ( dev->queue_count ) return DRM_ERR(EBUSY); /* Not while in use */ - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -772,9 +785,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( buf->dev_private, 0, buf->dev_priv_size ); @@ -803,9 +816,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -825,12 +838,12 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); dma->flags = _DRM_DMA_USE_SG; @@ -839,11 +852,11 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) } #endif /* __REALLY_HAVE_SG */ -int DRM(addbufs)( DRM_OS_IOCTL ) +int DRM(addbufs)( DRM_IOCTL_ARGS ) { drm_buf_desc_t request; - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) @@ -858,29 +871,29 @@ int DRM(addbufs)( DRM_OS_IOCTL ) #if __HAVE_PCI_DMA return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); #else - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); #endif } -int DRM(infobufs)( DRM_OS_IOCTL ) +int DRM(infobufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_info_t request; int i; int count; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( atomic_read( &dev->buf_alloc ) ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } ++dev->buf_use; /* Can't allocate more after this call */ - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_KRNFROMUSR( request, (drm_buf_info_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { if ( dma->bufs[i].buf_count ) ++count; @@ -894,19 +907,19 @@ int DRM(infobufs)( DRM_OS_IOCTL ) drm_buf_desc_t *to = &request.list[count]; drm_buf_entry_t *from = &dma->bufs[i]; drm_freelist_t *list = &dma->bufs[i].freelist; - if ( DRM_OS_COPYTOUSR( &to->count, + if ( DRM_COPY_TO_USER( &to->count, &from->buf_count, sizeof(from->buf_count) ) || - DRM_OS_COPYTOUSR( &to->size, + DRM_COPY_TO_USER( &to->size, &from->buf_size, sizeof(from->buf_size) ) || - DRM_OS_COPYTOUSR( &to->low_mark, + DRM_COPY_TO_USER( &to->low_mark, &list->low_mark, sizeof(list->low_mark) ) || - DRM_OS_COPYTOUSR( &to->high_mark, + DRM_COPY_TO_USER( &to->high_mark, &list->high_mark, sizeof(list->high_mark) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); DRM_DEBUG( "%d %d %d %d %d\n", i, @@ -920,34 +933,34 @@ int DRM(infobufs)( DRM_OS_IOCTL ) } request.count = count; - DRM_OS_KRNTOUSR( (drm_buf_info_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) ); return 0; } -int DRM(markbufs)( DRM_OS_IOCTL ) +int DRM(markbufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int order; drm_buf_entry_t *entry; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); DRM_DEBUG( "%d, %d, %d\n", request.size, request.low_mark, request.high_mark ); order = DRM(order)( request.size ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); entry = &dma->bufs[order]; if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); entry->freelist.low_mark = request.low_mark; entry->freelist.high_mark = request.high_mark; @@ -955,35 +968,35 @@ int DRM(markbufs)( DRM_OS_IOCTL ) return 0; } -int DRM(freebufs)( DRM_OS_IOCTL ) +int DRM(freebufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_free_t request; int i; int idx; drm_buf_t *buf; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_free_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) ); DRM_DEBUG( "%d\n", request.count ); for ( i = 0 ; i < request.count ; i++ ) { - if ( DRM_OS_COPYFROMUSR( &idx, + if ( DRM_COPY_FROM_USER( &idx, &request.list[i], sizeof(idx) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "Index %d (of %d max)\n", idx, dma->buf_count - 1 ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_OS_CURRENTPID ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_OS_CURRENTPID, buf->pid ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); } @@ -991,32 +1004,43 @@ int DRM(freebufs)( DRM_OS_IOCTL ) return 0; } -int DRM(mapbufs)( DRM_OS_IOCTL ) +int DRM(mapbufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; int retcode = 0; const int zero = 0; vm_offset_t virtual, address; +#ifdef __FreeBSD__ #if __FreeBSD_version >= 500000 struct vmspace *vms = p->td_proc->p_vmspace; #else struct vmspace *vms = p->p_vmspace; #endif +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + struct vnode *vn; +#endif /* __NetBSD__ */ + drm_buf_map_t request; int i; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( atomic_read( &dev->buf_alloc ) ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } dev->buf_use++; /* Can't allocate more after this call */ - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); + + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) ); - DRM_OS_KRNFROMUSR( request, (drm_buf_map_t *)data, sizeof(request) ); +#ifdef __NetBSD__ + if(!vfinddev(kdev, VCHR, &vn)) + return 0; /* FIXME: Shouldn't this be EINVAL or something? */ +#endif /* __NetBSD__ */ if ( request.count >= dma->buf_count ) { if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || @@ -1028,6 +1052,7 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) goto done; } +#ifdef __FreeBSD__ virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); retcode = vm_mmap(&vms->vm_map, &virtual, @@ -1036,7 +1061,18 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), (unsigned long)map->offset ); +#elif defined(__NetBSD__) + virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); + retcode = uvm_mmap(&vms->vm_map, + (vaddr_t *)&virtual, + round_page(map->size), + UVM_PROT_READ | UVM_PROT_WRITE, + UVM_PROT_ALL, MAP_SHARED, + &vn->v_uobj, map->offset, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); +#endif /* __NetBSD__ */ } else { +#ifdef __FreeBSD__ virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); retcode = vm_mmap(&vms->vm_map, &virtual, @@ -1045,32 +1081,42 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), 0); +#elif defined(__NetBSD__) + virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); + retcode = uvm_mmap(&vms->vm_map, + (vaddr_t *)&virtual, + round_page(dma->byte_count), + UVM_PROT_READ | UVM_PROT_WRITE, + UVM_PROT_ALL, MAP_SHARED, + &vn->v_uobj, 0, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); +#endif /* __NetBSD__ */ } if (retcode) goto done; request.virtual = (void *)virtual; for ( i = 0 ; i < dma->buf_count ; i++ ) { - if ( DRM_OS_COPYTOUSR( &request.list[i].idx, + if ( DRM_COPY_TO_USER( &request.list[i].idx, &dma->buflist[i]->idx, sizeof(request.list[0].idx) ) ) { retcode = EFAULT; goto done; } - if ( DRM_OS_COPYTOUSR( &request.list[i].total, + if ( DRM_COPY_TO_USER( &request.list[i].total, &dma->buflist[i]->total, sizeof(request.list[0].total) ) ) { retcode = EFAULT; goto done; } - if ( DRM_OS_COPYTOUSR( &request.list[i].used, + if ( DRM_COPY_TO_USER( &request.list[i].used, &zero, sizeof(zero) ) ) { retcode = EFAULT; goto done; } address = virtual + dma->buflist[i]->offset; /* *** */ - if ( DRM_OS_COPYTOUSR( &request.list[i].address, + if ( DRM_COPY_TO_USER( &request.list[i].address, &address, sizeof(address) ) ) { retcode = EFAULT; @@ -1083,9 +1129,9 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode ); - DRM_OS_KRNTOUSR( (drm_buf_map_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_map_t *)data, request, sizeof(request) ); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } #endif /* __HAVE_DMA */ diff --git a/bsd-core/drm_context.c b/bsd-core/drm_context.c index 8d676a23..0274a8b7 100644 --- a/bsd-core/drm_context.c +++ b/bsd-core/drm_context.c @@ -29,7 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" #if __HAVE_CTX_BITMAP @@ -44,10 +43,10 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) if ( !dev->ctx_bitmap ) goto failed; if ( ctx_handle < DRM_MAX_CTXBITMAP ) { - DRM_OS_LOCK; + DRM_LOCK; clear_bit( ctx_handle, dev->ctx_bitmap ); dev->context_sareas[ctx_handle] = NULL; - DRM_OS_UNLOCK; + DRM_UNLOCK; return; } failed: @@ -62,7 +61,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) if(!dev->ctx_bitmap) return -1; - DRM_OS_LOCK; + DRM_LOCK; bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP ); if ( bit < DRM_MAX_CTXBITMAP ) { set_bit( bit, dev->ctx_bitmap ); @@ -80,7 +79,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) DRM_MEM_MAPS); if(!ctx_sareas) { clear_bit(bit, dev->ctx_bitmap); - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } dev->context_sareas = ctx_sareas; @@ -93,16 +92,16 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) DRM_MEM_MAPS); if(!dev->context_sareas) { clear_bit(bit, dev->ctx_bitmap); - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } dev->context_sareas[bit] = NULL; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; return bit; } - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } @@ -111,17 +110,17 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) int i; int temp; - DRM_OS_LOCK; - dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE, + DRM_LOCK; + dev->ctx_bitmap = (atomic_t *) DRM(alloc)( PAGE_SIZE, DRM_MEM_CTXBITMAP ); if ( dev->ctx_bitmap == NULL ) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(ENOMEM); + DRM_UNLOCK; + return DRM_ERR(ENOMEM); } memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE ); dev->context_sareas = NULL; dev->max_context = -1; - DRM_OS_UNLOCK; + DRM_UNLOCK; for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { temp = DRM(ctxbitmap_next)( dev ); @@ -133,55 +132,55 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) { - DRM_OS_LOCK; + DRM_LOCK; if( dev->context_sareas ) DRM(free)( dev->context_sareas, sizeof(*dev->context_sareas) * dev->max_context, DRM_MEM_MAPS ); DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP ); - DRM_OS_UNLOCK; + DRM_UNLOCK; } /* ================================================================ * Per Context SAREA Support */ -int DRM(getsareactx)( DRM_OS_IOCTL ) +int DRM(getsareactx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_priv_map_t request; drm_map_t *map; - DRM_OS_KRNFROMUSR( request, (drm_ctx_priv_map_t *)data, + DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } map = dev->context_sareas[request.ctx_id]; - DRM_OS_UNLOCK; + DRM_UNLOCK; request.handle = map->handle; - DRM_OS_KRNTOUSR( (drm_ctx_priv_map_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_priv_map_t *)data, request, sizeof(request) ); return 0; } -int DRM(setsareactx)( DRM_OS_IOCTL ) +int DRM(setsareactx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_priv_map_t request; drm_map_t *map = NULL; drm_map_list_entry_t *list; - DRM_OS_KRNFROMUSR( request, (drm_ctx_priv_map_t *)data, + DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map=list->map; if(map->handle == request.handle) @@ -189,8 +188,8 @@ int DRM(setsareactx)( DRM_OS_IOCTL ) } bad: - DRM_OS_UNLOCK; - return -EINVAL; + DRM_UNLOCK; + return DRM_ERR(EINVAL); found: map = list->map; @@ -200,7 +199,7 @@ found: if (request.ctx_id >= (unsigned) dev->max_context) goto bad; dev->context_sareas[request.ctx_id] = map; - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -214,7 +213,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) if ( test_and_set_bit( 0, &dev->context_flag ) ) { DRM_ERROR( "Reentering -- FIXME\n" ); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } #if __HAVE_DMA_HISTOGRAM @@ -256,41 +255,41 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) #endif clear_bit( 0, &dev->context_flag ); - DRM_OS_WAKEUP( &dev->context_wait ); + DRM_WAKEUP( (void *)&dev->context_wait ); return 0; } -int DRM(resctx)( DRM_OS_IOCTL ) +int DRM(resctx)( DRM_IOCTL_ARGS ) { drm_ctx_res_t res; drm_ctx_t ctx; int i; - DRM_OS_KRNFROMUSR( res, (drm_ctx_res_t *)data, sizeof(res) ); + DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if ( res.count >= DRM_RESERVED_CONTEXTS ) { memset( &ctx, 0, sizeof(ctx) ); for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { ctx.handle = i; - if ( DRM_OS_COPYTOUSR( &res.contexts[i], + if ( DRM_COPY_TO_USER( &res.contexts[i], &i, sizeof(i) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); } } res.count = DRM_RESERVED_CONTEXTS; - DRM_OS_KRNTOUSR( (drm_ctx_res_t *)data, res, sizeof(res) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) ); return 0; } -int DRM(addctx)( DRM_OS_IOCTL ) +int DRM(addctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); ctx.handle = DRM(ctxbitmap_next)( dev ); if ( ctx.handle == DRM_KERNEL_CONTEXT ) { @@ -301,51 +300,51 @@ int DRM(addctx)( DRM_OS_IOCTL ) if ( ctx.handle == -1 ) { DRM_DEBUG( "Not enough free contexts.\n" ); /* Should this return -EBUSY instead? */ - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(modctx)( DRM_OS_IOCTL ) +int DRM(modctx)( DRM_IOCTL_ARGS ) { /* This does nothing */ return 0; } -int DRM(getctx)( DRM_OS_IOCTL ) +int DRM(getctx)( DRM_IOCTL_ARGS ) { drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); /* This is 0, because we don't handle any context flags */ ctx.flags = 0; - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(switchctx)( DRM_OS_IOCTL ) +int DRM(switchctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); return DRM(context_switch)( dev, dev->last_context, ctx.handle ); } -int DRM(newctx)( DRM_OS_IOCTL ) +int DRM(newctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); DRM(context_switch_complete)( dev, ctx.handle ); @@ -353,12 +352,12 @@ int DRM(newctx)( DRM_OS_IOCTL ) return 0; } -int DRM(rmctx)( DRM_OS_IOCTL ) +int DRM(rmctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); if ( ctx.handle != DRM_KERNEL_CONTEXT ) { @@ -387,7 +386,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (test_and_set_bit(0, &dev->context_flag)) { DRM_ERROR("Reentering -- FIXME\n"); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } #if __HAVE_DMA_HISTOGRAM @@ -398,7 +397,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (new >= dev->queue_count) { clear_bit(0, &dev->context_flag); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (new == dev->last_context) { @@ -411,7 +410,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (atomic_read(&q->use_count) == 1) { atomic_dec(&q->use_count); clear_bit(0, &dev->context_flag); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM(flags) & DRM_FLAG_NOCTX) { @@ -450,7 +449,7 @@ int DRM(context_switch_complete)(drm_device_t *dev, int new) #endif clear_bit(0, &dev->context_flag); - DRM_OS_WAKEUP_INT(&dev->context_wait); + DRM_WAKEUP_INT(&dev->context_wait); return 0; } @@ -514,7 +513,7 @@ static int DRM(alloc_queue)(drm_device_t *dev) atomic_dec(&dev->queuelist[i]->use_count); } /* Allocate a new queue */ - DRM_OS_LOCK; + DRM_LOCK; queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); memset(queue, 0, sizeof(*queue)); @@ -532,19 +531,19 @@ static int DRM(alloc_queue)(drm_device_t *dev) newslots, DRM_MEM_QUEUES); if (!dev->queuelist) { - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG("out of memory\n"); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } } dev->queuelist[dev->queue_count-1] = queue; - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG("%d (new)\n", dev->queue_count - 1); return dev->queue_count - 1; } -int DRM(resctx)( DRM_OS_IOCTL ) +int DRM(resctx)( DRM_IOCTL_ARGS ) { drm_ctx_res_t res; drm_ctx_t ctx; @@ -552,31 +551,31 @@ int DRM(resctx)( DRM_OS_IOCTL ) DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - DRM_OS_KRNFROMUSR( res, (drm_ctx_res_t *)data, sizeof(res) ); + DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if (DRM_OS_COPYTOUSR(&res.contexts[i], + if (DRM_COPY_TO_USER(&res.contexts[i], &i, sizeof(i))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); } } res.count = DRM_RESERVED_CONTEXTS; - DRM_OS_KRNTOUSR( (drm_ctx_res_t *)data, res, sizeof(res) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) ); return 0; } -int DRM(addctx)( DRM_OS_IOCTL ) +int DRM(addctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { /* Init kernel's context and get a new one. */ @@ -586,35 +585,35 @@ int DRM(addctx)( DRM_OS_IOCTL ) DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); DRM_DEBUG("%d\n", ctx.handle); - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(modctx)( DRM_OS_IOCTL ) +int DRM(modctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); if (ctx.handle < 0 || ctx.handle >= dev->queue_count) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM_BUFCOUNT(&q->waitlist)) { atomic_dec(&q->use_count); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } q->flags = ctx.flags; @@ -623,52 +622,52 @@ int DRM(modctx)( DRM_OS_IOCTL ) return 0; } -int DRM(getctx)( DRM_OS_IOCTL ) +int DRM(getctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); if (ctx.handle >= dev->queue_count) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } ctx.flags = q->flags; atomic_dec(&q->use_count); - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(switchctx)( DRM_OS_IOCTL ) +int DRM(switchctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); return DRM(context_switch)(dev, dev->last_context, ctx.handle); } -int DRM(newctx)( DRM_OS_IOCTL ) +int DRM(newctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); DRM(context_switch_complete)(dev, ctx.handle); @@ -676,25 +675,25 @@ int DRM(newctx)( DRM_OS_IOCTL ) return 0; } -int DRM(rmctx)( DRM_OS_IOCTL ) +int DRM(rmctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; drm_buf_t *buf; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); - if (ctx.handle >= dev->queue_count) DRM_OS_RETURN(EINVAL); + if (ctx.handle >= dev->queue_count) return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } atomic_inc(&q->finalization); /* Mark queue in finalization state */ @@ -717,7 +716,7 @@ int DRM(rmctx)( DRM_OS_IOCTL ) /* Wakeup blocked processes */ wakeup( &q->block_read ); wakeup( &q->block_write ); - DRM_OS_WAKEUP_INT( &q->flush_queue ); + DRM_WAKEUP_INT( &q->flush_queue ); /* Finalization over. Queue is made available when both use_count and finalization become 0, which won't diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c index 7c31a6e2..3e4a5e17 100644 --- a/bsd-core/drm_dma.c +++ b/bsd-core/drm_dma.c @@ -29,10 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - #include "drmP.h" #ifndef __HAVE_DMA_WAITQUEUE @@ -59,7 +55,7 @@ int DRM(dma_setup)( drm_device_t *dev ) dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER ); if ( !dev->dma ) - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); memset( dev->dma, 0, sizeof(*dev->dma) ); @@ -85,8 +81,8 @@ void DRM(dma_takedown)(drm_device_t *dev) dma->bufs[i].buf_count, dma->bufs[i].seg_count); for (j = 0; j < dma->bufs[i].seg_count; j++) { - DRM(free_pages)(dma->bufs[i].seglist[j], - dma->bufs[i].page_order, + DRM(free)((void *)dma->bufs[i].seglist[j], + dma->bufs[i].buf_size, DRM_MEM_DMA); } DRM(free)(dma->bufs[i].seglist, @@ -197,7 +193,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) #endif if ( buf->dma_wait ) { - wakeup( &buf->dma_wait ); + wakeup( (void *)&buf->dma_wait ); buf->dma_wait = 0; } #if __HAVE_DMA_FREELIST @@ -248,7 +244,7 @@ void DRM(clear_next_buffer)(drm_device_t *dev) dma->next_buffer = NULL; if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) { - DRM_OS_WAKEUP_INT(&dma->next_queue->flush_queue); + DRM_WAKEUP_INT(&dma->next_queue->flush_queue); } dma->next_queue = NULL; } @@ -340,7 +336,7 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) if (!_DRM_LOCK_IS_HELD(context)) { DRM_ERROR("No lock held during \"while locked\"" " request\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (d->context != _DRM_LOCKING_CONTEXT(context) && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) { @@ -348,7 +344,7 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) " \"while locked\" request\n", _DRM_LOCKING_CONTEXT(context), d->context); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } q = dev->queuelist[DRM_KERNEL_CONTEXT]; while_locked = 1; @@ -378,19 +374,19 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) atomic_dec(&q->use_count); DRM_ERROR("Index %d (of %d max)\n", d->send_indices[i], dma->buf_count - 1); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf = dma->buflist[ idx ]; - if (buf->pid != DRM_OS_CURRENTPID) { + if (buf->pid != DRM_CURRENTPID) { atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer owned by %d\n", - DRM_OS_CURRENTPID, buf->pid); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, buf->pid); + return DRM_ERR(EINVAL); } if (buf->list != DRM_LIST_NONE) { atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer %d on list %d\n", - DRM_OS_CURRENTPID, buf->idx, buf->list); + DRM_CURRENTPID, buf->idx, buf->list); } buf->used = d->send_sizes[i]; buf->while_locked = while_locked; @@ -403,14 +399,14 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) DRM_ERROR("Queueing pending buffer:" " buffer %d, offset %d\n", d->send_indices[i], i); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (buf->waiting) { atomic_dec(&q->use_count); DRM_ERROR("Queueing waiting buffer:" " buffer %d, offset %d\n", d->send_indices[i], i); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf->waiting = 1; if (atomic_read(&q->use_count) == 1 @@ -444,16 +440,16 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, buf->waiting, buf->pending); } - buf->pid = DRM_OS_CURRENTPID; - if (DRM_OS_COPYTOUSR(&d->request_indices[i], + buf->pid = DRM_CURRENTPID; + if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); - if (DRM_OS_COPYTOUSR(&d->request_sizes[i], + if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); ++d->granted_count; } @@ -511,15 +507,15 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) int retcode; if ( !irq ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); - DRM_OS_LOCK; + DRM_LOCK; if ( dev->irq ) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EBUSY); + DRM_UNLOCK; + return DRM_ERR(EBUSY); } dev->irq = irq; - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); @@ -548,10 +544,10 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, DRM(dma_service), dev, &dev->irqh); if ( retcode ) { - DRM_OS_LOCK; + DRM_LOCK; bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irqr); dev->irq = 0; - DRM_OS_UNLOCK; + DRM_UNLOCK; return retcode; } @@ -565,13 +561,13 @@ int DRM(irq_uninstall)( drm_device_t *dev ) { int irq; - DRM_OS_LOCK; + DRM_LOCK; irq = dev->irq; dev->irq = 0; - DRM_OS_UNLOCK; + DRM_UNLOCK; if ( !irq ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); @@ -583,12 +579,12 @@ int DRM(irq_uninstall)( drm_device_t *dev ) return 0; } -int DRM(control)( DRM_OS_IOCTL ) +int DRM(control)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_control_t ctl; - DRM_OS_KRNFROMUSR( ctl, (drm_control_t *) data, sizeof(ctl) ); + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); switch ( ctl.func ) { case DRM_INST_HANDLER: @@ -596,25 +592,24 @@ int DRM(control)( DRM_OS_IOCTL ) case DRM_UNINST_HANDLER: return DRM(irq_uninstall)( dev ); default: - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } } #else -int DRM(control)( DRM_OS_IOCTL ) +int DRM(control)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; drm_control_t ctl; - DRM_OS_KRNFROMUSR( ctl, (drm_control_t *) data, sizeof(ctl) ); + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); switch ( ctl.func ) { case DRM_INST_HANDLER: case DRM_UNINST_HANDLER: return 0; default: - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } } diff --git a/bsd-core/drm_drawable.c b/bsd-core/drm_drawable.c index f57d8628..30841067 100644 --- a/bsd-core/drm_drawable.c +++ b/bsd-core/drm_drawable.c @@ -29,22 +29,21 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -int DRM(adddraw)( DRM_OS_IOCTL ) +int DRM(adddraw)( DRM_IOCTL_ARGS ) { drm_draw_t draw; draw.handle = 0; /* NOOP */ DRM_DEBUG("%d\n", draw.handle); - DRM_OS_KRNTOUSR( (drm_draw_t *)data, draw, sizeof(draw) ); + DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) ); return 0; } -int DRM(rmdraw)( DRM_OS_IOCTL ) +int DRM(rmdraw)( DRM_IOCTL_ARGS ) { return 0; /* NOOP */ } diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index ee5e3fbe..8d75e698 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -116,16 +116,8 @@ #define DRIVER_IOCTLS #endif #ifndef DRIVER_FOPS -#if DRM_LINUX -#include <sys/file.h> -#include <sys/proc.h> -#include <machine/../linux/linux.h> -#include <machine/../linux/linux_proto.h> -#include "drm_linux.h" -#endif #endif - /* * The default number of instances (minor numbers) to initialize. */ @@ -133,9 +125,15 @@ #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)) @@ -146,11 +144,13 @@ MODULE_DEPEND(DRIVER_NAME, agp, 1, 1, 1); #if DRM_LINUX MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); #endif +#endif /* __FreeBSD__ */ -static drm_device_t *DRM(device); -static int *DRM(minor); -static int DRM(numdevs) = 0; - +#ifdef __NetBSD__ +#define CDEV_MAJOR 90 +#define DRIVER_SOFTC(unit) \ + ((drm_device_t *) device_lookup(&DRM(_cd), unit)) +#endif /* __NetBSD__ */ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, @@ -212,7 +212,7 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, #endif -#if __REALLY_HAVE_SG +#if __HAVE_SG [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif @@ -222,28 +222,18 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) +const char *DRM(find_description)(int vendor, int device); +#ifdef __FreeBSD__ static int DRM(probe)(device_t dev) { - const char *s = 0; + const char *s = NULL; int pciid=pci_get_devid(dev); int vendor = (pciid & 0x0000ffff); int device = (pciid & 0xffff0000) >> 16; - int i=0, done=0; - DRM_INFO("Checking PCI vendor=%d, device=%d\n", vendor, device); - while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) { - if ( (DRM(devicelist)[i].vendor == vendor) && - (DRM(devicelist)[i].device == device) ) { - done=1; - if ( DRM(devicelist)[i].supported ) - s = DRM(devicelist)[i].name; - else - DRM_INFO("%s not supported\n", DRM(devicelist)[i].name); - } - i++; - } + s = DRM(find_description)(vendor, device); if (s) { device_set_desc(dev, s); return 0; @@ -262,7 +252,6 @@ static int DRM(detach)(device_t dev) DRM(cleanup)(dev); return 0; } - static device_method_t DRM(methods)[] = { /* Device interface */ DEVMETHOD(device_probe, DRM( probe)), @@ -301,6 +290,78 @@ static struct cdevsw 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(probe)(struct device *parent, struct cfdata *match, void *aux) +{ + 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; + return 0; +} + +void DRM(attach)(struct device *parent, struct device *self, void *aux) +{ + struct pci_attach_args *pa = aux; + drm_device_t *dev = (drm_device_t *)self; + + memcpy(&dev->pa, aux, sizeof(dev->pa)); +
+ DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id))); + DRM(init)(dev); +} + +int DRM(detach)(struct device *self, int flags) +{ + DRM(cleanup)((drm_device_t *)self); + return 0; +} + +int DRM(activate)(struct device *self, enum devact act) +{ + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: + /* FIXME */ + break; + } + return (0); +} + +#endif + +const char *DRM(find_description)(int vendor, int device) { + const char *s = NULL; + int i=0, done=0; + + while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) { + if ( (DRM(devicelist)[i].vendor == vendor) && + (DRM(devicelist)[i].device == device) ) { + done=1; + if ( DRM(devicelist)[i].supported ) + s = DRM(devicelist)[i].name; + else + DRM_INFO("%s not supported\n", DRM(devicelist)[i].name); + } + i++; + } + return s; +} + static int DRM(setup)( drm_device_t *dev ) { int i; @@ -365,7 +426,7 @@ static int DRM(setup)( drm_device_t *dev ) dev->maplist = DRM(alloc)(sizeof(*dev->maplist), DRM_MEM_MAPS); - if(dev->maplist == NULL) DRM_OS_RETURN(ENOMEM); + if(dev->maplist == NULL) return DRM_ERR(ENOMEM); memset(dev->maplist, 0, sizeof(*dev->maplist)); TAILQ_INIT(dev->maplist); dev->map_count = 0; @@ -397,7 +458,11 @@ static int DRM(setup)( drm_device_t *dev ) dev->buf_rp = dev->buf; dev->buf_wp = dev->buf; dev->buf_end = dev->buf + DRM_BSZ; +#ifdef __FreeBSD__ dev->buf_sigio = NULL; +#elif defined(__NetBSD__) + dev->buf_pgid = 0; +#endif dev->buf_readers = 0; dev->buf_writers = 0; dev->buf_selecting = 0; @@ -430,7 +495,7 @@ static int DRM(takedown)( drm_device_t *dev ) if ( dev->irq ) DRM(irq_uninstall)( dev ); #endif - DRM_OS_LOCK; + DRM_LOCK; callout_stop( &dev->timer ); if ( dev->devname ) { @@ -495,18 +560,36 @@ static int DRM(takedown)( drm_device_t *dev ) #if __REALLY_HAVE_MTRR if ( map->mtrr >= 0 ) { int retcode; - retcode = mtrr_del( map->mtrr, - map->offset, - map->size ); +#ifdef __FreeBSD__ + int act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + map->mtrr=1; +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + mtrrmap.base = map->offset; + 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 ); break; case _DRM_SHM: - DRM(free_pages)((unsigned long)map->handle, - DRM(order)(map->size) - - PAGE_SHIFT, + DRM(free)(map->handle, + map->size, DRM_MEM_SAREA); break; @@ -560,206 +643,190 @@ static int DRM(takedown)( drm_device_t *dev ) if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; - DRM_OS_WAKEUP_INT(&dev->lock.lock_queue); + DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } -/* - * Figure out how many instances to initialize. - */ -static int drm_count_cards(void) -{ - int num = 0; -#if defined(DRIVER_CARD_LIST) - int i; - drm_pci_list_t *l; - u16 device, vendor; - struct pci_dev *pdev = NULL; -#endif - - DRM_DEBUG( "\n" ); - -#if defined(DRIVER_COUNT_CARDS) - num = DRIVER_COUNT_CARDS(); -#elif defined(DRIVER_CARD_LIST) - for (i = 0, l = DRIVER_CARD_LIST; l[i].vendor != 0; i++) { - pdev = NULL; - vendor = l[i].vendor; - device = l[i].device; - if(device == 0xffff) device = PCI_ANY_ID; - if(vendor == 0xffff) vendor = PCI_ANY_ID; - while ((pdev = pci_find_device(vendor, device, pdev))) { - num++; /* FIXME: What about two cards of the same device id? */ - } - } -#else - num = DRIVER_NUM_CARDS; -#endif - DRM_DEBUG("numdevs = %d\n", num); - return num; -} - -/* drm_init is called via init_module at module load time, or via - * linux/init/main.c (this is not currently supported). +/* linux: drm_init is called via init_module at module load time, or via + * 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; - int i; +#endif #if __HAVE_CTX_BITMAP int retcode; #endif DRM_DEBUG( "\n" ); - -#ifdef MODULE - DRM(parse_options)( drm_opts ); -#endif - - DRM(numdevs) = drm_count_cards(); - /* Force at least one instance. */ - if (DRM(numdevs) <= 0) - DRM(numdevs) = 1; - - DRM(device) = DRM_OS_MALLOC(sizeof(*DRM(device)) * DRM(numdevs)); - if (!DRM(device)) { - DRM_OS_RETURN(ENOMEM); - } - DRM(minor) = DRM_OS_MALLOC(sizeof(*(DRM(minor))) * DRM(numdevs)); - if (!DRM(minor)) { - DRM_OS_FREE(DRM(device)); - DRM_OS_RETURN(ENOMEM); - } - DRIVER_PREINIT(); - - for (i = 0; i < DRM(numdevs); i++) { - int unit = device_get_unit(nbdev); - /* FIXME??? - multihead !!! */ - dev = device_get_softc(nbdev); - memset( (void *)dev, 0, sizeof(*dev) ); - DRM(minor)[i]=unit; - DRM_OS_SPININIT(dev->count_lock, "drm device"); - lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); - dev->device = nbdev; - dev->devnode = make_dev( &DRM(cdevsw), - unit, - DRM_DEV_UID, - DRM_DEV_GID, - DRM_DEV_MODE, - "dri/card%d", unit ); - dev->name = DRIVER_NAME; - DRM(mem_init)(); - DRM(sysctl_init)(dev); - TAILQ_INIT(&dev->files); +#ifdef __FreeBSD__ + unit = device_get_unit(nbdev); + dev = device_get_softc(nbdev); + memset( (void *)dev, 0, sizeof(*dev) ); + dev->device = nbdev; + dev->devnode = make_dev( &DRM(cdevsw), + unit, + DRM_DEV_UID, + DRM_DEV_GID, + DRM_DEV_MODE, + "dri/card%d", unit ); +#elif defined(__NetBSD__) + unit = minor(dev->device.dv_unit); +#endif + DRM_SPININIT(dev->count_lock, "drm device"); + lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); + dev->name = DRIVER_NAME; + DRM(mem_init)(); + DRM(sysctl_init)(dev); + TAILQ_INIT(&dev->files); #if __REALLY_HAVE_AGP - dev->agp = DRM(agp_init)(); + dev->agp = DRM(agp_init)(); #if __MUST_HAVE_AGP - if ( dev->agp == NULL ) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); - DRM(takedown)( dev ); - DRM_OS_RETURN(ENOMEM); - } + if ( dev->agp == NULL ) { + DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); #endif + DRM(takedown)( dev ); + return DRM_ERR(ENOMEM); + } +#endif /* __MUST_HAVE_AGP */ #if __REALLY_HAVE_MTRR - if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024, - MTRR_TYPE_WRCOMB, - 1 ); -#endif -#endif + if (dev->agp) { +#ifdef __FreeBSD__ + int retcode = 0, act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = dev->agp->info.ai_aperture_base; + mrdesc.mr_len = dev->agp->info.ai_aperture_size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + dev->agp->agp_mtrr=1; +#elif defined __NetBSD__ + 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; + dev->agp->agp_mtrr = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +#endif /* __NetBSD__ */ + } +#endif /* __REALLY_HAVE_MTRR */ +#endif /* __REALLY_HAVE_AGP */ #if __HAVE_CTX_BITMAP - retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); - DRM(takedown)( dev ); - return retcode; - } + retcode = DRM(ctxbitmap_init)( dev ); + if( retcode ) { + DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); #endif - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - DRM(minor)[i] ); + DRM(takedown)( dev ); + return retcode; } +#endif + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, + unit ); DRIVER_POSTINIT(); return 0; } -/* drm_cleanup is called via cleanup_module at module unload time. +/* linux: drm_cleanup is called via cleanup_module at module unload time. + * 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; - int i; +#endif +#if __REALLY_HAVE_MTRR +#ifdef __NetBSD__ + struct mtrr mtrrmap; + int one = 1; +#endif /* __NetBSD__ */ +#endif /* __REALLY_HAVE_MTRR */ DRM_DEBUG( "\n" ); - for (i = DRM(numdevs) - 1; i >= 0; i--) { - /* FIXME??? - multihead */ - dev = device_get_softc(nbdev); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); +#ifdef __FreeBSD__ + dev = device_get_softc(nbdev); +#endif + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); +#endif #if __HAVE_CTX_BITMAP - DRM(ctxbitmap_cleanup)( dev ); + DRM(ctxbitmap_cleanup)( dev ); #endif #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR - if ( dev->agp && dev->agp->agp_mtrr >= 0) { - int retval; - retval = mtrr_del( dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024 ); - DRM_DEBUG( "mtrr_del=%d\n", retval ); - } + if ( dev->agp && dev->agp->agp_mtrr >= 0) { +#if defined(__NetBSD__) + mtrrmap.base = dev->agp->info.ai_aperture_base; + mtrrmap.len = dev->agp->info.ai_aperture_size; + mtrrmap.type = 0; + mtrrmap.flags = 0; + retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +#endif + } #endif - DRM(takedown)( dev ); + DRM(takedown)( dev ); #if __REALLY_HAVE_AGP - if ( dev->agp ) { - DRM(agp_uninit)(); - DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); - dev->agp = NULL; - } -#endif + if ( dev->agp ) { + DRM(agp_uninit)(); + DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); + dev->agp = NULL; } +#endif DRIVER_POSTCLEANUP(); - DRM_OS_FREE(DRM(minor)); - DRM_OS_FREE(DRM(device)); - DRM(numdevs) = 0; } -int DRM(version)( DRM_OS_IOCTL ) +int DRM(version)( DRM_IOCTL_ARGS ) { drm_version_t version; int len; - DRM_OS_KRNFROMUSR( version, (drm_version_t *)data, sizeof(version) ); + DRM_COPY_FROM_USER_IOCTL( version, (drm_version_t *)data, sizeof(version) ); #define DRM_COPY( name, value ) \ len = strlen( value ); \ if ( len > name##_len ) len = name##_len; \ name##_len = strlen( value ); \ if ( len && name ) { \ - if ( DRM_OS_COPYTOUSR( name, value, len ) ) \ - DRM_OS_RETURN(EFAULT); \ + if ( DRM_COPY_TO_USER( name, value, len ) ) \ + return DRM_ERR(EFAULT); \ } version.version_major = DRIVER_MAJOR; @@ -770,48 +837,40 @@ int DRM(version)( DRM_OS_IOCTL ) DRM_COPY( version.date, DRIVER_DATE ); DRM_COPY( version.desc, DRIVER_DESC ); - DRM_OS_KRNTOUSR( (drm_version_t *)data, version, sizeof(version) ); + DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) ); return 0; } -int DRM( open)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) +int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_device_t *dev = NULL; int retcode = 0; - int i; - for (i = 0; i < DRM(numdevs); i++) { - /* FIXME ??? - multihead */ - dev = DRIVER_SOFTC(minor(kdev)); - } - if (!dev) { - DRM_OS_RETURN(ENODEV); - } + dev = DRIVER_SOFTC(minor(kdev)); DRM_DEBUG( "open_count = %d\n", dev->open_count ); - device_busy(dev->device); retcode = DRM(open_helper)(kdev, flags, fmt, p, dev); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - DRM_OS_SPINLOCK( &dev->count_lock ); - if ( !dev->open_count++ ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - return DRM(setup)( dev ); - } - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); +#ifdef __FreeBSD__ + device_busy(dev->device); +#endif + if ( !dev->open_count++ ) + retcode = DRM(setup)( dev ); + DRM_SPINUNLOCK( &dev->count_lock ); } - device_unbusy(dev->device); return retcode; } -int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) +int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_file_t *priv; - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int retcode = 0; DRM_DEBUG( "open_count = %d\n", dev->open_count ); @@ -827,13 +886,18 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) * Begin inline drm_release */ +#ifdef __FreeBSD__ + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + DRM_CURRENTPID, (long)dev->device, dev->open_count ); +#elif defined(__NetBSD__) DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", - DRM_OS_CURRENTPID, (long)dev->device, dev->open_count ); + DRM_CURRENTPID, (long)&dev->device, dev->open_count); +#endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_OS_CURRENTPID) { + && dev->lock.pid == DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", - DRM_OS_CURRENTPID, + DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); #if HAVE_DRIVER_RELEASE DRIVER_RELEASE(); @@ -853,7 +917,7 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) for (;;) { if ( !dev->lock.hw_lock ) { /* Device has been unregistered */ - retcode = EINTR; + retcode = DRM_ERR(EINTR); break; } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, @@ -884,9 +948,15 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) DRM(reclaim_buffers)( dev, priv->pid ); #endif +#if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) + funsetown(&dev->buf_sigio); +#elif defined(__FreeBSD__) funsetown(dev->buf_sigio); +#elif defined(__NetBSD__) + dev->buf_pgid = 0; +#endif /* __NetBSD__ */ - DRM_OS_LOCK; + DRM_LOCK; priv = DRM(find_file_by_proc)(dev, p); if (priv) { priv->refs--; @@ -894,7 +964,7 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) TAILQ_REMOVE(&dev->files, priv, link); } } - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); @@ -903,42 +973,48 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); +#ifdef __FreeBSD__ + device_unbusy(dev->device); +#endif if ( !--dev->open_count ) { if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) { DRM_ERROR( "Device busy: %ld %d\n", (unsigned long)atomic_read( &dev->ioctl_count ), dev->blocked ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } - DRM_OS_SPINUNLOCK( &dev->count_lock ); - device_unbusy(dev->device); + DRM_SPINUNLOCK( &dev->count_lock ); return DRM(takedown)( dev ); } - DRM_OS_SPINUNLOCK( &dev->count_lock ); - + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(retcode); + return retcode; } /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_OS_IOCTL ) +int DRM(ioctl)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; d_ioctl_t *func; int nr = DRM_IOCTL_NR(cmd); - DRM_OS_PRIV; + DRM_PRIV; atomic_inc( &dev->ioctl_count ); atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; +#ifdef __FreeBSD__ + DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", + DRM_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated ); +#elif defined(__NetBSD__) DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", - DRM_OS_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated ); + DRM_CURRENTPID, cmd, nr, (long)&dev->device, priv->authenticated ); +#endif switch (cmd) { case FIONBIO: @@ -950,6 +1026,7 @@ int DRM(ioctl)( DRM_OS_IOCTL ) dev->flags |= FASYNC; return 0; +#ifdef __FreeBSD__ case FIOSETOWN: atomic_dec(&dev->ioctl_count); return fsetown(*(int *)data, &dev->buf_sigio); @@ -959,6 +1036,18 @@ int DRM(ioctl)( DRM_OS_IOCTL ) *(int *) data = fgetown(dev->buf_sigio); return 0; } +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + case TIOCSPGRP: + atomic_dec(&dev->ioctl_count); + dev->buf_pgid = *(int *)data; + return 0; + + case TIOCGPGRP: + atomic_dec(&dev->ioctl_count); + *(int *)data = dev->buf_pgid; + return 0; +#endif /* __NetBSD__ */ if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = EINVAL; @@ -969,7 +1058,7 @@ int DRM(ioctl)( DRM_OS_IOCTL ) if ( !func ) { DRM_DEBUG( "no function\n" ); retcode = EINVAL; - } else if ( ( ioctl->root_only && DRM_OS_CHECKSUSER ) + } else if ( ( ioctl->root_only && DRM_SUSER(p) ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { @@ -978,12 +1067,12 @@ int DRM(ioctl)( DRM_OS_IOCTL ) } atomic_dec( &dev->ioctl_count ); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } -int DRM(lock)( DRM_OS_IOCTL ) +int DRM(lock)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_lock_t lock; int ret = 0; #if __HAVE_MULTIPLE_DMA_QUEUES @@ -995,24 +1084,24 @@ int DRM(lock)( DRM_OS_IOCTL ) dev->lck_start = start = get_cycles(); #endif - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); if ( lock.context == DRM_KERNEL_CONTEXT ) { DRM_ERROR( "Process %d using kernel context %d\n", - DRM_OS_CURRENTPID, lock.context ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, lock.context ); + return DRM_ERR(EINVAL); } DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock.context, DRM_OS_CURRENTPID, + lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags ); #if __HAVE_DMA_QUEUE if ( lock.context < 0 ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); #elif __HAVE_MULTIPLE_DMA_QUEUES if ( lock.context < 0 || lock.context >= dev->queue_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[lock.context]; #endif @@ -1028,14 +1117,14 @@ int DRM(lock)( DRM_OS_IOCTL ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_OS_CURRENTPID; + dev->lock.pid = DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ } /* Contention */ - ret = tsleep(&dev->lock.lock_queue, + ret = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, "drmlk2", 0); @@ -1074,21 +1163,21 @@ int DRM(lock)( DRM_OS_IOCTL ) atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); #endif - DRM_OS_RETURN(ret); + return DRM_ERR(ret); } -int DRM(unlock)( DRM_OS_IOCTL ) +int DRM(unlock)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_lock_t lock; - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ) ; + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ) ; if ( lock.context == DRM_KERNEL_CONTEXT ) { DRM_ERROR( "Process %d using kernel context %d\n", - DRM_OS_CURRENTPID, lock.context ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, lock.context ); + return DRM_ERR(EINVAL); } atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); @@ -1141,7 +1230,7 @@ SYSUNINIT(DRM( unregister), SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_unregister_ * Linux emulation IOCTL */ static int -DRM(linux_ioctl)(DRM_OS_STRUCTPROC *p, struct linux_ioctl_args* args) +DRM(linux_ioctl)(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) { #if (__FreeBSD_version >= 500000) struct file *fp = p->td_proc->p_fd->fd_ofiles[args->fd]; diff --git a/bsd-core/drm_fops.c b/bsd-core/drm_fops.c index 53af39cd..ed85a8de 100644 --- a/bsd-core/drm_fops.c +++ b/bsd-core/drm_fops.c @@ -30,14 +30,9 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" - -#include <sys/signalvar.h> -#include <sys/poll.h> - -drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_OS_STRUCTPROC *p) +drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 uid_t uid = p->td_proc->p_ucred->cr_svuid; @@ -56,7 +51,7 @@ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_OS_STRUCTPROC *p) /* DRM(open) is called whenever a process opens /dev/drm. */ -int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, +int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, drm_device_t *dev) { int m = minor(kdev); @@ -66,9 +61,9 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, return EBUSY; /* No exclusive opens */ dev->flags = flags; if (!DRM(cpu_valid)()) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); - DRM_DEBUG("pid = %d, minor = %d\n", DRM_OS_CURRENTPID, m); + DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); /* FIXME: linux mallocs and bzeros here */ priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); @@ -89,15 +84,14 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, priv->minor = m; priv->devXX = dev; priv->ioctl_count = 0; - priv->authenticated = !DRM_OS_CHECKSUSER; - lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, p); + priv->authenticated = !DRM_SUSER(p); + DRM_LOCK; TAILQ_INSERT_TAIL(&dev->files, priv, link); - lockmgr(&dev->dev_lock, LK_RELEASE, 0, p); + DRM_UNLOCK; } - +#ifdef __FreeBSD__ kdev->si_drv1 = dev; - - +#endif return 0; } @@ -108,7 +102,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag) { - DRM_OS_DEVICE; + DRM_DEVICE; int left; int avail; int send; @@ -156,6 +150,9 @@ int DRM(write_string)(drm_device_t *dev, const char *s) int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; int send = strlen(s); int count; +#ifdef __NetBSD__ + struct proc *p; +#endif /* __NetBSD__ */ DRM_DEBUG("%d left, %d to send (%p, %p)\n", left, send, dev->buf_rp, dev->buf_wp); @@ -186,19 +183,33 @@ int DRM(write_string)(drm_device_t *dev, const char *s) } DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); +#ifdef __FreeBSD__ if (dev->buf_sigio) { DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid); +#if __FreeBSD_version >= 500000 + pgsigio(&dev->buf_sigio, SIGIO, 0); +#else pgsigio(dev->buf_sigio, SIGIO, 0); +#endif /* __FreeBSD_version */ } +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + if (dev->buf_pgid) { + DRM_DEBUG("dev->buf_pgid=%d\n", dev->buf_pgid); + if(dev->buf_pgid > 0) + 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); return 0; } -int DRM(poll)(dev_t kdev, int events, DRM_OS_STRUCTPROC *p) +int DRM(poll)(dev_t kdev, int events, DRM_STRUCTPROC *p) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int s; int revents = 0; @@ -217,7 +228,15 @@ int DRM(poll)(dev_t kdev, int events, DRM_OS_STRUCTPROC *p) int DRM(write)(dev_t kdev, struct uio *uio, int ioflag) { - DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", - curproc->p_pid, ((drm_device_t *)kdev->si_drv1)->device, ((drm_device_t *)kdev->si_drv1)->open_count); - return 0; +#if DRM_DEBUG_CODE + DRM_DEVICE; +#endif +#ifdef __FreeBSD__ + DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", + curproc->p_pid, dev->device, dev->open_count); +#elif defined(__NetBSD__) + DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", + curproc->p_pid, &dev->device, dev->open_count); +#endif + return 0; } diff --git a/bsd-core/drm_ioctl.c b/bsd-core/drm_ioctl.c index 1e8281e6..63562fef 100644 --- a/bsd-core/drm_ioctl.c +++ b/bsd-core/drm_ioctl.c @@ -29,20 +29,18 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -#include <sys/bus.h> -#include <pci/pcivar.h> -int DRM(irq_busid)( DRM_OS_IOCTL ) +int DRM(irq_busid)( DRM_IOCTL_ARGS ) { +#ifdef __FreeBSD__ drm_irq_busid_t id; devclass_t pci; device_t bus, dev; device_t *kids; int error, i, num_kids; - DRM_OS_KRNFROMUSR( id, (drm_irq_busid_t *)data, sizeof(id) ); + DRM_COPY_FROM_USER_IOCTL( id, (drm_irq_busid_t *)data, sizeof(id) ); pci = devclass_find("pci"); if (!pci) @@ -71,49 +69,53 @@ int DRM(irq_busid)( DRM_OS_IOCTL ) DRM_DEBUG("%d:%d:%d => IRQ %d\n", id.busnum, id.devnum, id.funcnum, id.irq); - DRM_OS_KRNTOUSR( (drm_irq_busid_t *)data, id, sizeof(id) ); + DRM_COPY_TO_USER_IOCTL( (drm_irq_busid_t *)data, id, sizeof(id) ); return 0; +#else + /* don't support interrupt-driven drivers on Net yet */ + return ENOENT; +#endif } -int DRM(getunique)( DRM_OS_IOCTL ) +int DRM(getunique)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_unique_t u; - DRM_OS_KRNFROMUSR( u, (drm_unique_t *)data, sizeof(u) ); + DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) ); if (u.unique_len >= dev->unique_len) { - if (DRM_OS_COPYTOUSR(u.unique, dev->unique, dev->unique_len)) - DRM_OS_RETURN(EFAULT); + if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len)) + return DRM_ERR(EFAULT); } u.unique_len = dev->unique_len; - DRM_OS_KRNTOUSR( (drm_unique_t *)data, u, sizeof(u) ); + DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) ); return 0; } -int DRM(setunique)( DRM_OS_IOCTL ) +int DRM(setunique)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_unique_t u; if (dev->unique_len || dev->unique) - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); - DRM_OS_KRNFROMUSR( u, (drm_unique_t *)data, sizeof(u) ); + DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) ); if (!u.unique_len || u.unique_len > 1024) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); dev->unique_len = u.unique_len; dev->unique = DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER); - if(!dev->unique) DRM_OS_RETURN(ENOMEM); + if(!dev->unique) return DRM_ERR(ENOMEM); - if (DRM_OS_COPYFROMUSR(dev->unique, u.unique, dev->unique_len)) - DRM_OS_RETURN(EFAULT); + if (DRM_COPY_FROM_USER(dev->unique, u.unique, dev->unique_len)) + return DRM_ERR(EFAULT); dev->unique[dev->unique_len] = '\0'; @@ -121,7 +123,7 @@ int DRM(setunique)( DRM_OS_IOCTL ) DRM_MEM_DRIVER); if(!dev->devname) { DRM(free)(dev->devname, sizeof(*dev->devname), DRM_MEM_DRIVER); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } sprintf(dev->devname, "%s@%s", dev->name, dev->unique); @@ -130,23 +132,23 @@ int DRM(setunique)( DRM_OS_IOCTL ) } -int DRM(getmap)( DRM_OS_IOCTL ) +int DRM(getmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_t map; drm_map_t *mapinlist; drm_map_list_entry_t *list; int idx; int i = 0; - DRM_OS_KRNFROMUSR( map, (drm_map_t *)data, sizeof(map) ); + DRM_COPY_FROM_USER_IOCTL( map, (drm_map_t *)data, sizeof(map) ); idx = map.offset; - DRM_OS_LOCK; + DRM_LOCK; if (idx < 0 || idx >= dev->map_count) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } TAILQ_FOREACH(list, dev->maplist, link) { @@ -163,28 +165,28 @@ int DRM(getmap)( DRM_OS_IOCTL ) i++; } - DRM_OS_UNLOCK; + DRM_UNLOCK; if (!list) return EINVAL; - DRM_OS_KRNTOUSR( (drm_map_t *)data, map, sizeof(map) ); + DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, map, sizeof(map) ); return 0; } -int DRM(getclient)( DRM_OS_IOCTL ) +int DRM(getclient)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_client_t client; drm_file_t *pt; int idx; int i = 0; - DRM_OS_KRNFROMUSR( client, (drm_client_t *)data, sizeof(client) ); + DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) ); idx = client.idx; - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(pt, &dev->files, link) { if (i==idx) { @@ -193,29 +195,29 @@ int DRM(getclient)( DRM_OS_IOCTL ) client.uid = pt->uid; client.magic = pt->magic; client.iocs = pt->ioctl_count; - DRM_OS_UNLOCK; + DRM_UNLOCK; *(drm_client_t *)data = client; return 0; } i++; } - DRM_OS_UNLOCK; + DRM_UNLOCK; - DRM_OS_KRNTOUSR( (drm_client_t *)data, client, sizeof(client) ); + DRM_COPY_TO_USER_IOCTL( (drm_client_t *)data, client, sizeof(client) ); return 0; } -int DRM(getstats)( DRM_OS_IOCTL ) +int DRM(getstats)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_stats_t stats; int i; memset(&stats, 0, sizeof(stats)); - DRM_OS_LOCK; + DRM_LOCK; for (i = 0; i < dev->counters; i++) { if (dev->types[i] == _DRM_STAT_LOCK) @@ -229,9 +231,9 @@ int DRM(getstats)( DRM_OS_IOCTL ) stats.count = dev->counters; - DRM_OS_UNLOCK; + DRM_UNLOCK; - DRM_OS_KRNTOUSR( (drm_stats_t *)data, stats, sizeof(stats) ); + DRM_COPY_TO_USER_IOCTL( (drm_stats_t *)data, stats, sizeof(stats) ); return 0; } diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 863a228c..5e9294bc 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -29,16 +29,15 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -int DRM(block)( DRM_OS_IOCTL ) +int DRM(block)( DRM_IOCTL_ARGS ) { DRM_DEBUG("\n"); return 0; } -int DRM(unblock)( DRM_OS_IOCTL ) +int DRM(unblock)( DRM_IOCTL_ARGS ) { DRM_DEBUG("\n"); return 0; @@ -109,7 +108,7 @@ int DRM(lock_free)(drm_device_t *dev, pid); return 1; } - DRM_OS_WAKEUP_INT(&dev->lock.lock_queue); + DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); return 0; } @@ -125,7 +124,7 @@ static int DRM(flush_queue)(drm_device_t *dev, int context) if (atomic_read(&q->use_count) > 1) { atomic_inc(&q->block_write); atomic_inc(&q->block_count); - error = tsleep(&q->flush_queue, PZERO|PCATCH, "drmfq", 0); + error = tsleep((void *)&q->flush_queue, PZERO|PCATCH, "drmfq", 0); if (error) return error; atomic_dec(&q->block_count); @@ -147,7 +146,7 @@ static int DRM(flush_unblock_queue)(drm_device_t *dev, int context) if (atomic_read(&q->use_count) > 1) { if (atomic_read(&q->block_write)) { atomic_dec(&q->block_write); - DRM_OS_WAKEUP_INT(&q->write_queue); + DRM_WAKEUP_INT((void *)&q->write_queue); } } atomic_dec(&q->use_count); @@ -194,15 +193,15 @@ int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags) return ret; } -int DRM(finish)( DRM_OS_IOCTL ) +int DRM(finish)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; int ret = 0; drm_lock_t lock; DRM_DEBUG("\n"); - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags); DRM(flush_unblock)(dev, lock.context, lock.flags); diff --git a/bsd-core/drm_memory.c b/bsd-core/drm_memory.c index 97f2bb81..f7dc547a 100644 --- a/bsd-core/drm_memory.c +++ b/bsd-core/drm_memory.c @@ -29,20 +29,16 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -#include <vm/vm.h> -#include <vm/pmap.h> -#if __REALLY_HAVE_AGP -#include <sys/agpio.h> -#endif +#ifdef __FreeBSD__ #define malloctype DRM(M_DRM) /* The macros confliced in the MALLOC_DEFINE */ MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures"); #undef malloctype +#endif typedef struct drm_mem_stats { const char *name; @@ -53,7 +49,7 @@ typedef struct drm_mem_stats { unsigned long bytes_freed; } drm_mem_stats_t; -static DRM_OS_SPINTYPE DRM(mem_lock); +static DRM_SPINTYPE DRM(mem_lock); static unsigned long DRM(ram_available) = 0; /* In pages */ static unsigned long DRM(ram_used) = 0; static drm_mem_stats_t DRM(mem_stats)[] = { @@ -85,7 +81,7 @@ void DRM(mem_init)(void) { drm_mem_stats_t *mem; - DRM_OS_SPININIT(DRM(mem_lock), "drm memory"); + DRM_SPININIT(DRM(mem_lock), "drm memory"); for (mem = DRM(mem_stats); mem->name; ++mem) { mem->succeed_count = 0; @@ -99,8 +95,8 @@ void DRM(mem_init)(void) DRM(ram_used) = 0; } +#ifdef __FreeBSD__ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ - static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS { drm_mem_stats_t *pt; @@ -137,11 +133,12 @@ int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS { int ret; - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ret = DRM(_mem_info)(oidp, arg1, arg2, req); - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return ret; } +#endif void *DRM(alloc)(size_t size, int area) { @@ -152,16 +149,20 @@ void *DRM(alloc)(size_t size, int area) return NULL; } +#ifdef __FreeBSD__ if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); +#elif defined(__NetBSD__) + if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) { +#endif + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].succeed_count; DRM(mem_stats)[area].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } @@ -203,70 +204,23 @@ void DRM(free)(void *pt, size_t size, int area) int free_count; if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); - else free(pt, DRM(M_DRM)); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + else +#ifdef __FreeBSD__ + free(pt, DRM(M_DRM)); +#elif defined(__NetBSD__) + free(pt, M_DEVBUF); +#endif + DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[area].bytes_freed += size; free_count = ++DRM(mem_stats)[area].free_count; alloc_count = DRM(mem_stats)[area].succeed_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", free_count, alloc_count); } } -unsigned long DRM(alloc_pages)(int order, int area) -{ - vm_offset_t address; - unsigned long bytes = PAGE_SIZE << order; - - - address = (vm_offset_t) contigmalloc(bytes, DRM(M_DRM), M_WAITOK, 0, ~0, 1, 0); - if (!address) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); - ++DRM(mem_stats)[area].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - return 0; - } - DRM_OS_SPINLOCK(&DRM(mem_lock)); - ++DRM(mem_stats)[area].succeed_count; - DRM(mem_stats)[area].bytes_allocated += bytes; - DRM(ram_used) += bytes; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - - - /* Zero outside the lock */ - memset((void *)address, 0, bytes); - - - return address; -} - -void DRM(free_pages)(unsigned long address, int order, int area) -{ - unsigned long bytes = PAGE_SIZE << order; - int alloc_count; - int free_count; - - if (!address) { - DRM_MEM_ERROR(area, "Attempt to free address 0\n"); - } else { - contigfree((void *) address, bytes, DRM(M_DRM)); - } - - DRM_OS_SPINLOCK(&DRM(mem_lock)); - free_count = ++DRM(mem_stats)[area].free_count; - alloc_count = DRM(mem_stats)[area].succeed_count; - DRM(mem_stats)[area].bytes_freed += bytes; - DRM(ram_used) -= bytes; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - if (free_count > alloc_count) { - DRM_MEM_ERROR(area, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } -} - void *DRM(ioremap)(unsigned long offset, unsigned long size) { void *pt; @@ -278,18 +232,20 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size) } if (!(pt = pmap_mapdev(offset, size))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } +/* unused so far */ +#if 0 void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) { void *pt; @@ -302,17 +258,18 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) /* FIXME FOR BSD */ if (!(pt = ioremap_nocache(offset, size))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } +#endif void DRM(ioremapfree)(void *pt, unsigned long size) { @@ -325,11 +282,11 @@ void DRM(ioremapfree)(void *pt, unsigned long size) else pmap_unmapdev((vm_offset_t) pt, size); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Excess frees: %d frees, %d allocs\n", @@ -348,16 +305,16 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) } if ((handle = DRM(agp_allocate_memory)(pages, type))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated += pages << PAGE_SHIFT; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return handle; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } @@ -369,16 +326,16 @@ int DRM(free_agp)(agp_memory *handle, int pages) if (!handle) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Attempt to free NULL AGP handle\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM(agp_free_memory)(handle)) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed += pages << PAGE_SHIFT; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Excess frees: %d frees, %d allocs\n", @@ -386,13 +343,13 @@ int DRM(free_agp)(agp_memory *handle, int pages) } return 0; } - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } int DRM(bind_agp)(agp_memory *handle, unsigned int start) { int retcode; - device_t dev = agp_find_device(); + device_t dev = DRM_AGP_FIND_DEVICE(); struct agp_memory_info info; if (!dev) @@ -401,22 +358,22 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start) if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (!(retcode = DRM(agp_bind_memory)(handle, start))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; agp_memory_info(dev, handle, &info); DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated += info.ami_size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - DRM_OS_RETURN(0); + DRM_SPINUNLOCK(&DRM(mem_lock)); + return DRM_ERR(0); } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - DRM_OS_RETURN(retcode); + DRM_SPINUNLOCK(&DRM(mem_lock)); + return DRM_ERR(retcode); } int DRM(unbind_agp)(agp_memory *handle) @@ -424,7 +381,7 @@ int DRM(unbind_agp)(agp_memory *handle) int alloc_count; int free_count; int retcode = EINVAL; - device_t dev = agp_find_device(); + device_t dev = DRM_AGP_FIND_DEVICE(); struct agp_memory_info info; if (!dev) @@ -433,25 +390,25 @@ int DRM(unbind_agp)(agp_memory *handle) if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to unbind NULL AGP handle\n"); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } agp_memory_info(dev, handle, &info); if ((retcode = DRM(agp_unbind_memory)(handle))) - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed += info.ami_size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Excess frees: %d frees, %d allocs\n", free_count, alloc_count); } - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } #endif diff --git a/bsd-core/drm_os_freebsd.h b/bsd-core/drm_os_freebsd.h index 72c5baf6..23838139 100644 --- a/bsd-core/drm_os_freebsd.h +++ b/bsd-core/drm_os_freebsd.h @@ -12,12 +12,26 @@ #include <sys/uio.h> #include <sys/filio.h> #include <sys/sysctl.h> -#include <sys/select.h> +#include <sys/bus.h> +#include <sys/signalvar.h> +#include <sys/poll.h> #include <vm/vm.h> #include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <vm/vm_map.h> +#include <vm/vm_param.h> +#include <machine/param.h> #include <machine/pmap.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/mman.h> +#include <sys/rman.h> +#include <sys/memrange.h> +#include <pci/pcivar.h> #if __FreeBSD_version >= 500000 #include <sys/selinfo.h> +#else +#include <sys/select.h> #endif #include <sys/bus.h> #if __FreeBSD_version >= 400005 @@ -31,11 +45,27 @@ #define __REALLY_HAVE_AGP __HAVE_AGP #endif -#define __REALLY_HAVE_MTRR 0 -#define __REALLY_HAVE_SG 0 +#define __REALLY_HAVE_MTRR (__HAVE_MTRR) +#define __REALLY_HAVE_SG (__HAVE_SG) #if __REALLY_HAVE_AGP #include <pci/agpvar.h> +#include <sys/agpio.h> +#endif + +#include <opt_drm.h> +#if DRM_DEBUG +#undef DRM_DEBUG_CODE +#define DRM_DEBUG_CODE 2 +#endif +#undef DRM_DEBUG + +#if DRM_LINUX +#include <sys/file.h> +#include <sys/proc.h> +#include <machine/../linux/linux.h> +#include <machine/../linux/linux_proto.h> +#include "drm_linux.h" #endif #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ @@ -43,49 +73,51 @@ #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 145 #if __FreeBSD_version >= 500000 -#define DRM_OS_SPINTYPE struct mtx -#define DRM_OS_SPININIT(l,name) mtx_init(&l, name, MTX_DEF) -#define DRM_OS_SPINLOCK(l) mtx_lock(l) -#define DRM_OS_SPINUNLOCK(u) mtx_unlock(u); -#define DRM_OS_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curthread) -#define DRM_OS_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, curthread) -#define DRM_OS_CURPROC curthread -#define DRM_OS_STRUCTPROC struct thread -#define DRM_OS_CURRENTPID curthread->td_proc->p_pid -#define DRM_OS_IOCTL dev_t kdev, u_long cmd, caddr_t data, int flags, struct thread *p -#define DRM_OS_CHECKSUSER suser(p->td_proc) +#define DRM_CURPROC curthread +#define DRM_STRUCTPROC struct thread +#define DRM_SPINTYPE struct mtx +#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF) +#define DRM_SPINLOCK(l) mtx_lock(l) +#define DRM_SPINUNLOCK(u) mtx_unlock(u); +#define DRM_CURRENTPID curthread->td_proc->p_pid #else -#define DRM_OS_CURPROC curproc -#define DRM_OS_STRUCTPROC struct proc -#define DRM_OS_SPINTYPE struct simplelock -#define DRM_OS_SPININIT(l,name) simple_lock_init(&l) -#define DRM_OS_SPINLOCK(l) simple_lock(l) -#define DRM_OS_SPINUNLOCK(u) simple_unlock(u); -#define DRM_OS_IOCTL dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p -#define DRM_OS_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc) -#define DRM_OS_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc) -#define DRM_OS_CURRENTPID curproc->p_pid -#define DRM_OS_CHECKSUSER suser(p) +#define DRM_CURPROC curproc +#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_SPINUNLOCK(u) simple_unlock(u); +#define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_OS_TASKQUEUE_ARGS void *dev, int pending -#define DRM_OS_IRQ_ARGS void *device -#define DRM_OS_DEVICE drm_device_t *dev = kdev->si_drv1 -#define DRM_OS_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_OS_FREE(pt) free( pt, DRM(M_DRM) ) -#define DRM_OS_VTOPHYS(addr) vtophys(addr) - -#define DRM_OS_PRIV \ +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +#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) +#define DRM_TASKQUEUE_ARGS void *dev, int pending +#define DRM_IRQ_ARGS void *device +#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_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() agp_find_device() +#define DRM_ERR(v) v + +#define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ if (!priv) { \ DRM_DEBUG("can't find authenticator\n"); \ return EINVAL; \ } -#define DRM_OS_DELAY( udelay ) \ +#define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ microtime(&tv1); \ @@ -95,34 +127,53 @@ do { \ while (((tv2.tv_sec-tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec) < udelay ); \ } while (0) -#define DRM_OS_RETURN(v) return v; - +#define DRM_GETSAREA() \ +do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + drm_map_t *map = listentry->map; \ + if (map->type == _DRM_SHM && \ + map->flags & _DRM_CONTAINS_LOCK) { \ + dev_priv->sarea = map; \ + break; \ + } \ + } \ +} while (0) -#define DRM_OS_KRNTOUSR(arg1, arg2, arg3) \ +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ *arg1 = arg2 -#define DRM_OS_KRNFROMUSR(arg1, arg2, arg3) \ +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ arg1 = *arg2 -#define DRM_OS_COPYTOUSR(arg1, arg2, arg3) \ +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ copyout(arg2, arg1, arg3) -#define DRM_OS_COPYFROMUSR(arg1, arg2, 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's be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!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_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); +/* From machine/bus_at386.h on i386 */ +#define DRM_READMEMORYBARRIER() \ +do { \ + __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \ +} while (0) -#define DRM_OS_WRITEMEMORYBARRIER DRM_OS_READMEMORYBARRIER +#define DRM_WRITEMEMORYBARRIER() \ +do { \ + __asm __volatile("" : : : "memory"); \ +} while (0) -#define DRM_OS_WAKEUP(w) wakeup(w) -#define DRM_OS_WAKEUP_INT(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP_INT(w) wakeup(w) -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) round_page(addr) #define malloctype DRM(M_DRM) /* The macros confliced in the MALLOC_DEFINE */ @@ -137,7 +188,10 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; -typedef unsigned long atomic_t; +#define cpu_to_le32(x) (x) + +typedef u_int32_t 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; @@ -145,14 +199,14 @@ typedef u_int16_t u16; typedef u_int8_t u8; #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_long(p, 1) -#define atomic_dec(p) atomic_subtract_long(p, 1) -#define atomic_add(n, p) atomic_add_long(p, n) -#define atomic_sub(n, p) atomic_subtract_long(p, n) +#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) /* Fake this */ -static __inline unsigned int -test_and_set_bit(int b, volatile unsigned long *p) +static __inline atomic_t +test_and_set_bit(int b, atomic_t *p) { int s = splhigh(); unsigned int m = 1<<b; @@ -163,25 +217,25 @@ test_and_set_bit(int b, volatile unsigned long *p) } static __inline void -clear_bit(int b, volatile unsigned long *p) +clear_bit(int b, atomic_t *p) { - atomic_clear_long(p + (b >> 5), 1 << (b & 0x1f)); + atomic_clear_int(p + (b >> 5), 1 << (b & 0x1f)); } static __inline void -set_bit(int b, volatile unsigned long *p) +set_bit(int b, atomic_t *p) { - atomic_set_long(p + (b >> 5), 1 << (b & 0x1f)); + atomic_set_int(p + (b >> 5), 1 << (b & 0x1f)); } static __inline int -test_bit(int b, volatile unsigned long *p) +test_bit(int b, atomic_t *p) { return p[b >> 5] & (1 << (b & 0x1f)); } static __inline int -find_first_zero_bit(volatile unsigned long *p, int max) +find_first_zero_bit(atomic_t *p, int max) { int b; @@ -227,24 +281,23 @@ find_first_zero_bit(volatile unsigned long *p, int max) } while (0) /* Redefinitions to make templating easy */ -#define wait_queue_head_t long +#define wait_queue_head_t atomic_t #define agp_memory void #define jiffies ticks /* Macros to make printf easier */ #define DRM_ERROR(fmt, arg...) \ - printf("error: " "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg) + printf("error: " "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ## arg) #define DRM_MEM_ERROR(area, fmt, arg...) \ - printf("error: " "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \ - DRM(mem_stats)[area].name , ##arg) -#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ##arg) + printf("error: " "[" DRM_NAME ":%s:%s] *ERROR* " fmt , \ + __func__, DRM(mem_stats)[area].name , ##arg) +#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ## arg) #if DRM_DEBUG_CODE #define DRM_DEBUG(fmt, arg...) \ do { \ - if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ - ##arg); \ + if (DRM(flags) & DRM_FLAG_DEBUG) \ + printf("[" DRM_NAME ":%s] " fmt , __func__ , ## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -294,9 +347,9 @@ extern d_write_t DRM(write); extern d_poll_t DRM(poll); extern d_mmap_t DRM(mmap); extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, - DRM_OS_STRUCTPROC *p, drm_device_t *dev); + DRM_STRUCTPROC *p, drm_device_t *dev); extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, - DRM_OS_STRUCTPROC *p); + DRM_STRUCTPROC *p); /* Misc. IOCTL support (drm_ioctl.h) */ extern d_ioctl_t DRM(irq_busid); @@ -348,7 +401,7 @@ extern d_ioctl_t DRM(mapbufs); extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; /* DMA support (drm_dma.h) */ -#if __HAVE_DMA_IRQ +#if __HAVE_DMA extern d_ioctl_t DRM(control); #endif diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h new file mode 100644 index 00000000..2082c047 --- /dev/null +++ b/bsd-core/drm_os_netbsd.h @@ -0,0 +1,378 @@ +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/stat.h> +#include <sys/proc.h> +#include <sys/lock.h> +#include <sys/fcntl.h> +#include <sys/uio.h> +#include <sys/filio.h> +#include <sys/sysctl.h> +#include <sys/select.h> +#include <sys/device.h> +#include <sys/mman.h> +#include <uvm/uvm.h> +#include <sys/vnode.h> +#include <sys/poll.h> +/* For TIOCSPGRP/TIOCGPGRP */ +#include <sys/ttycom.h> + +#include <uvm/uvm.h> + +#include <machine/pmap.h> +#include <machine/bus.h> +#include <sys/resourcevar.h> +#include <machine/sysarch.h> +#include <machine/mtrr.h> + +#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_SG 0 + +#if __REALLY_HAVE_AGP +#include <dev/pci/agpvar.h> +#include <sys/agpio.h> +#endif + +#define device_t struct device * +extern struct cfdriver DRM(_cd); + +#if DRM_DEBUG +#undef DRM_DEBUG_CODE +#define DRM_DEBUG_CODE 2 +#endif +#undef DRM_DEBUG + +#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 DRM_CURPROC curproc +#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_SPINUNLOCK(u) simple_unlock(u); +#define DRM_CURRENTPID curproc->p_pid + +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +#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_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) +#define DRM_FREE(pt) 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_PRIV \ + drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ + if (!priv) { \ + DRM_DEBUG("can't find authenticator\n"); \ + return EINVAL; \ + } + +#define DRM_UDELAY( udelay ) \ +do { \ + struct timeval tv1, tv2; \ + microtime(&tv1); \ + do { \ + microtime(&tv2); \ + } \ + while (((tv2.tv_sec-tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec) < udelay ); \ +} while (0) + +#define DRM_GETSAREA() \ +do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + drm_map_t *map = listentry->map; \ + if (map->type == _DRM_SHM && \ + map->flags & _DRM_CONTAINS_LOCK) { \ + dev_priv->sarea = map; \ + break; \ + } \ + } \ +} while (0) + +#define return DRM_ERR(v) return v; +#define DRM_ERR(v) v + +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ + *arg1 = arg2 +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ + arg1 = *arg2 +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ + copyout(arg2, arg1, arg3) +#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) + +#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_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP_INT(w) wakeup(w) + +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +typedef struct drm_chipinfo +{ + int vendor; + int device; + int supported; + char *name; +} drm_chipinfo_t; + +typedef u_int32_t dma_addr_t; +typedef volatile 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; +typedef dev_type_ioctl(d_ioctl_t); +typedef vaddr_t vm_offset_t; + +#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) + +/* FIXME: Is NetBSD's kernel non-reentrant? */ +#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 atomic_t +test_and_set_bit(int b, atomic_t *p) +{ + int s = splhigh(); + unsigned int m = 1<<b; + unsigned int r = *p & m; + *p |= m; + splx(s); + return r; +} + +static __inline void +clear_bit(int b, atomic_t *p) +{ + atomic_clear_int(p + (b >> 5), 1 << (b & 0x1f)); +} + +static __inline void +set_bit(int b, atomic_t *p) +{ + atomic_set_int(p + (b >> 5), 1 << (b & 0x1f)); +} + +static __inline int +test_bit(int b, atomic_t *p) +{ + return p[b >> 5] & (1 << (b & 0x1f)); +} + +static __inline int +find_first_zero_bit(atomic_t *p, int max) +{ + int b; + + for (b = 0; b < max; b += 32) { + if (p[b >> 5] != ~0) { + for (;;) { + if ((p[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return 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 + + /* Macros to make printf easier */ +#define DRM_ERROR(fmt, arg...) \ +do { \ + printf("error: [" DRM_NAME ":%s] *ERROR* ", __func__ ); \ + printf( fmt,## arg ); \ +} while (0) + +#define DRM_MEM_ERROR(area, fmt, arg...) \ + printf("error: [" DRM_NAME ":%s:%s] *ERROR* " fmt , \ + __func__, DRM(mem_stats)[area].name ,## arg) +#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt ,## arg) + +#if DRM_DEBUG_CODE +#define DRM_DEBUG(fmt, arg...) \ + do { \ + if (DRM(flags) & DRM_FLAG_DEBUG) \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + } while (0) +#else +#define DRM_DEBUG(fmt, arg...) do { } while (0) +#endif + +#define DRM_PROC_LIMIT (PAGE_SIZE-80) + +#define DRM_SYSCTL_PRINT(fmt, arg...) \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + error = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (error) return error; + +#define DRM_SYSCTL_PRINT_RET(ret, fmt, arg...) \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + error = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (error) { ret; return error; } + + +#define DRM_FIND_MAP(dest, o) \ + do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + if ( listentry->map->offset == o ) { \ + dest = listentry->map; \ + break; \ + } \ + } \ + } while (0) + +/* Internal functions */ + +/* 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)); +extern dev_type_write(DRM(write)); +extern dev_type_poll(DRM(poll)); +extern dev_type_mmap(DRM(mmap)); +extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, + DRM_STRUCTPROC *p, drm_device_t *dev); +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 07e8e4e5..c16b7c05 100644 --- a/bsd-core/drm_scatter.c +++ b/bsd-core/drm_scatter.c @@ -27,25 +27,15 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ -#include <linux/config.h> -#include <linux/vmalloc.h> #include "drmP.h" #define DEBUG_SCATTER 0 +#if __REALLY_HAVE_SG + void DRM(sg_cleanup)( drm_sg_mem_t *entry ) { - struct page *page; - int i; - - for ( i = 0 ; i < entry->pages ; i++ ) { - page = entry->pagelist[i]; - if ( page ) - ClearPageReserved( page ); - } - - vfree( entry->virtual ); + free( entry->virtual, DRM(M_DRM) ); DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), @@ -58,35 +48,28 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry ) DRM_MEM_SGLISTS ); } -int DRM(sg_alloc)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int DRM(sg_alloc)( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_scatter_gather_t request; drm_sg_mem_t *entry; - unsigned long pages, i, j; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; + unsigned long pages; DRM_DEBUG( "%s\n", __FUNCTION__ ); if ( dev->sg ) - return -EINVAL; + return EINVAL; - if ( copy_from_user( &request, - (drm_scatter_gather_t *)arg, - sizeof(request) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data, + sizeof(request) ); entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS ); if ( !entry ) - return -ENOMEM; + return ENOMEM; - memset( entry, 0, sizeof(*entry) ); + bzero( entry, sizeof(*entry) ); - pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; + pages = round_page(request.size) / PAGE_SIZE; DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages ); entry->pages = pages; @@ -94,10 +77,10 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM_MEM_PAGES ); if ( !entry->pagelist ) { DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); + bzero(entry->pagelist, pages * sizeof(*entry->pagelist)); entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); @@ -108,11 +91,11 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) ); + bzero( (void *)entry->busaddr, pages * sizeof(*entry->busaddr) ); - entry->virtual = vmalloc_32( pages << PAGE_SHIFT ); + entry->virtual = malloc( pages << PAGE_SHIFT, DRM(M_DRM), M_WAITOK ); if ( !entry->virtual ) { DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), @@ -123,45 +106,21 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - /* This also forces the mapping of COW pages, so our page list - * will be valid. Please don't remove it... - */ - memset( entry->virtual, 0, pages << PAGE_SHIFT ); + bzero( entry->virtual, pages << PAGE_SHIFT ); entry->handle = (unsigned long)entry->virtual; DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); - for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) { - pgd = pgd_offset_k( i ); - if ( !pgd_present( *pgd ) ) - goto failed; - - pmd = pmd_offset( pgd, i ); - if ( !pmd_present( *pmd ) ) - goto failed; - - pte = pte_offset( pmd, i ); - if ( !pte_present( *pte ) ) - goto failed; - - entry->pagelist[j] = pte_page( *pte ); - - SetPageReserved( entry->pagelist[j] ); - } - request.handle = entry->handle; - if ( copy_to_user( (drm_scatter_gather_t *)arg, - &request, - sizeof(request) ) ) { - DRM(sg_cleanup)( entry ); - return -EFAULT; - } + DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data, + request, + sizeof(request) ); dev->sg = entry; @@ -207,29 +166,24 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, return 0; - failed: DRM(sg_cleanup)( entry ); - return -ENOMEM; + return ENOMEM; } -int DRM(sg_free)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int DRM(sg_free)( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_scatter_gather_t request; drm_sg_mem_t *entry; - if ( copy_from_user( &request, - (drm_scatter_gather_t *)arg, - sizeof(request) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data, + sizeof(request) ); entry = dev->sg; dev->sg = NULL; if ( !entry || entry->handle != request.handle ) - return -EINVAL; + return EINVAL; DRM_DEBUG( "sg free virtual = %p\n", entry->virtual ); @@ -237,3 +191,16 @@ int DRM(sg_free)( struct inode *inode, struct file *filp, return 0; } + +#else /* __REALLY_HAVE_SG */ + +int DRM(sg_alloc)( DRM_IOCTL_ARGS ) +{ + return DRM_ERR(EINVAL); +} +int DRM(sg_free)( DRM_IOCTL_ARGS ) +{ + return DRM_ERR(EINVAL); +} + +#endif diff --git a/bsd-core/drm_sysctl.c b/bsd-core/drm_sysctl.c index 02e4b28d..4e007445 100644 --- a/bsd-core/drm_sysctl.c +++ b/bsd-core/drm_sysctl.c @@ -1,4 +1,10 @@ -SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics"); +/* + * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ + */ + +#ifdef __FreeBSD__ + +#include <sys/sysctl.h> static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS; @@ -32,8 +38,7 @@ struct DRM(sysctl_list) { #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0])) struct drm_sysctl_info { - struct sysctl_oid oids[DRM_SYSCTL_ENTRIES + 1]; - struct sysctl_oid_list list; + struct sysctl_ctx_list ctx; char name[2]; }; @@ -41,65 +46,62 @@ int DRM(sysctl_init)(drm_device_t *dev) { struct drm_sysctl_info *info; struct sysctl_oid *oid; - struct sysctl_oid *top; + struct sysctl_oid *top, *drioid; int i; - /* Find the next free slot under hw.graphics */ + info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER); + if ( !info ) + return 1; + bzero(info, sizeof *info); + dev->sysctl = info; + + /* Add the sysctl node for DRI if it doesn't already exist */ + drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics"); + if (!drioid) + return 1; + + /* Find the next free slot under hw.dri */ i = 0; - SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) { + SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) { if (i <= oid->oid_arg2) i = oid->oid_arg2 + 1; } + if (i>9) + return 1; - info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER); - dev->sysctl = info; - - /* Construct the node under hw.graphics */ + /* Add the hw.dri.x for our device */ info->name[0] = '0' + i; info->name[1] = 0; - oid = &info->oids[DRM_SYSCTL_ENTRIES]; - bzero(oid, sizeof(*oid)); - oid->oid_parent = &sysctl__hw_dri_children; - oid->oid_number = OID_AUTO; - oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW; - oid->oid_arg1 = &info->list; - oid->oid_arg2 = i; - oid->oid_name = info->name; - oid->oid_handler = 0; - oid->oid_fmt = "N"; - SLIST_INIT(&info->list); - sysctl_register_oid(oid); - top = oid; - + top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL); + if (!top) + return 1; + for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) { - oid = &info->oids[i]; - bzero(oid, sizeof(*oid)); - oid->oid_parent = top->oid_arg1; - oid->oid_number = OID_AUTO; - oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD; - oid->oid_arg1 = dev; - oid->oid_arg2 = 0; - oid->oid_name = DRM(sysctl_list)[i].name; - oid->oid_handler = DRM(sysctl_list[)i].f; - oid->oid_fmt = "A"; - sysctl_register_oid(oid); + oid = sysctl_add_oid( &info->ctx, + SYSCTL_CHILDREN(top), + OID_AUTO, + DRM(sysctl_list)[i].name, + CTLTYPE_INT | CTLFLAG_RD, + dev, + 0, + DRM(sysctl_list)[i].f, + "A", + NULL); + if (!oid) + return 1; } - return 0; } int DRM(sysctl_cleanup)(drm_device_t *dev) { - int i; - - DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl); - for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++) - sysctl_unregister_oid(&dev->sysctl->oids[i]); + int error; + error = sysctl_ctx_free( &dev->sysctl->ctx ); DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER); dev->sysctl = NULL; - return 0; + return error; } static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS @@ -166,9 +168,9 @@ static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_vm_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -217,9 +219,9 @@ static int DRM(queues_info) DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_queues_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -267,9 +269,9 @@ static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_bufs_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -301,9 +303,9 @@ static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_clients_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -386,9 +388,9 @@ static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_vma_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } #endif @@ -515,9 +517,22 @@ static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = _drm_histo_info(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } #endif + +#elif defined(__NetBSD__) +/* stub it out for now, sysctl is only for debugging */ +int DRM(sysctl_init)(drm_device_t *dev) +{ + return 0; +} + +int DRM(sysctl_cleanup)(drm_device_t *dev) +{ + return 0; +} +#endif diff --git a/bsd-core/drm_vm.c b/bsd-core/drm_vm.c index a06fb448..70a5b0e6 100644 --- a/bsd-core/drm_vm.c +++ b/bsd-core/drm_vm.c @@ -1,9 +1,11 @@ -#include <vm/vm.h> -#include <vm/pmap.h> +#ifdef __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) +#endif { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; unsigned long physical; unsigned long page; @@ -14,27 +16,30 @@ static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) page = offset >> PAGE_SHIFT; physical = dma->pagelist[page]; - DRM_DEBUG("0x%08x (page %lu) => 0x%08lx\n", offset, page, physical); + DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); return atop(physical); } +#ifdef __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_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_map_t *map = NULL; drm_map_list_entry_t *listentry=NULL; - /*drm_file_t *priv;*/ + drm_file_t *priv; /* DRM_DEBUG("offset = 0x%x\n", offset);*/ - /*XXX Fixme */ - /*priv = DRM(find_file_by_proc)(dev, p); + priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); if (!priv) { DRM_DEBUG("can't find authenticator\n"); return EINVAL; } - if (!priv->authenticated) DRM_OS_RETURN(EACCES);*/ + if (!priv->authenticated) return DRM_ERR(EACCES); if (dev->dma && offset >= 0 @@ -59,7 +64,7 @@ int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) DRM_DEBUG("can't find map\n"); return -1; } - if (((map->flags&_DRM_RESTRICTED) && suser(curproc))) { + if (((map->flags&_DRM_RESTRICTED) && DRM_SUSER(DRM_CURPROC))) { DRM_DEBUG("restricted map\n"); return -1; } @@ -69,6 +74,7 @@ int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) case _DRM_REGISTERS: case _DRM_AGP: return atop(offset); + case _DRM_SCATTER_GATHER: case _DRM_SHM: return atop(vtophys(offset)); default: diff --git a/bsd-core/mga/Makefile b/bsd-core/mga/Makefile index bbaeaa56..82c7a382 100644 --- a/bsd-core/mga/Makefile +++ b/bsd-core/mga/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD= mga NOMAN= YES SRCS= mga_drv.c mga_state.c mga_warp.c mga_dma.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS+= ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS+= ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#MGA_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(MGA_OPTS) >> opt_drm_linux.h +.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/linux/mga.h b/bsd-core/mga_drv.c index 277aa202..8b69b41b 100644 --- a/linux/mga.h +++ b/bsd-core/mga_drv.c @@ -1,6 +1,7 @@ -/* mga.h -- Matrox G200/G400 DRM template customization -*- linux-c -*- - * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com +/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- + * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * @@ -24,44 +25,42 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Authors: + * Rickard E. (Rik) Faith <faith@valinux.com> * Gareth Hughes <gareth@valinux.com> */ -#ifndef __MGA_H__ -#define __MGA_H__ +#include <sys/types.h> -/* This remains constant for all DRM template files. - */ -#define DRM(x) mga_##x - -/* General customization: - */ -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 1 -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 1 - -/* Driver customization: - */ -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \ -} while (0) - -/* DMA customization: - */ -#define __HAVE_DMA 1 - -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_mga_private_t *dev_priv = dev->dev_private; \ - return mga_do_wait_for_idle( dev_priv ); \ -} while (0) +#include "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" -/* Buffer customization: +/* 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. */ -#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t +drm_chipinfo_t DRM(devicelist)[] = { + {0x102b, 0x0520, 0, "Matrox G200 (PCI)"}, + {0x102b, 0x0521, 1, "Matrox G200 (AGP)"}, + {0x102b, 0x0525, 1, "Matrox G400/G450 (AGP)"}, + {0x102b, 0x2527, 1, "Matrox G550 (AGP)"}, + {0, 0, 0, NULL} +}; -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_mga_private_t *)((dev)->dev_private))->buffers +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" -#endif +DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0); diff --git a/bsd-core/r128/Makefile b/bsd-core/r128/Makefile index ae5622ed..99b728bc 100644 --- a/bsd-core/r128/Makefile +++ b/bsd-core/r128/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD = r128 NOMAN= YES SRCS = r128_cce.c r128_drv.c r128_state.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS += device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS += ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS += ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#R128_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(R128_OPTS) >> opt_drm_linux.h +.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-core/r128_drv.c b/bsd-core/r128_drv.c new file mode 100644 index 00000000..1a8046fb --- /dev/null +++ b/bsd-core/r128_drv.c @@ -0,0 +1,86 @@ +/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- + * Created: Mon Dec 13 09:47:27 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 + * VA LINUX SYSTEMS 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 "r128.h" +#include "drmP.h" +#include "drm.h" +#include "r128_drm.h" +#include "r128_drv.h" +#if __REALLY_HAVE_SG +#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, 0x4c45, __REALLY_HAVE_SG, "ATI Rage 128 Mobility LE (PCI)"}, + {0x1002, 0x4c46, 1, "ATI Rage 128 Mobility LF (AGP)"}, + {0x1002, 0x4d46, 1, "ATI Rage 128 Mobility MF (AGP)"}, + {0x1002, 0x4d4c, 1, "ATI Rage 128 Mobility ML (AGP)"}, + {0x1002, 0x5044, __REALLY_HAVE_SG, "ATI Rage 128 Pro PD (PCI)"}, + {0x1002, 0x5046, 1, "ATI Rage 128 Pro PF (AGP)"}, + {0x1002, 0x5050, __REALLY_HAVE_SG, "ATI Rage 128 Pro PP (PCI)"}, + {0x1002, 0x5052, __REALLY_HAVE_SG, "ATI Rage 128 Pro PR (PCI)"}, + {0x1002, 0x5245, __REALLY_HAVE_SG, "ATI Rage 128 RE (PCI)"}, + {0x1002, 0x5246, 1, "ATI Rage 128 RF (AGP)"}, + {0x1002, 0x5247, 1, "ATI Rage 128 RG (AGP)"}, + {0x1002, 0x524b, __REALLY_HAVE_SG, "ATI Rage 128 RK (PCI)"}, + {0x1002, 0x524c, 1, "ATI Rage 128 RL (AGP)"}, + {0x1002, 0x534d, 1, "ATI Rage 128 SM (AGP)"}, + {0x1002, 0x5446, 1, "ATI Rage 128 Pro Ultra TF (AGP)"}, + {0x1002, 0x544C, 1, "ATI Rage 128 Pro Ultra TL (AGP)"}, + {0x1002, 0x5452, 1, "ATI Rage 128 Pro Ultra TR (AGP)"}, + {0, 0, 0, NULL} +}; + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_sysctl.h" +#include "drm_vm.h" +#if __HAVE_SG +#include "drm_scatter.h" +#endif + +DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0); diff --git a/bsd-core/radeon/Makefile b/bsd-core/radeon/Makefile index b1d77bf4..844586a1 100644 --- a/bsd-core/radeon/Makefile +++ b/bsd-core/radeon/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD = radeon NOMAN= YES SRCS = radeon_cp.c radeon_drv.c radeon_state.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS += device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS += ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS += ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#RADEON_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(RADEON_OPTS) >> opt_drm_linux.h +.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-core/radeon_drv.c b/bsd-core/radeon_drv.c new file mode 100644 index 00000000..fe69fbb8 --- /dev/null +++ b/bsd-core/radeon_drv.c @@ -0,0 +1,76 @@ +/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*- + * Created: Wed Feb 14 17:10:04 2001 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 + * VA LINUX SYSTEMS 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> + */ + +#include <sys/types.h> + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#if __REALLY_HAVE_SG +#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)"}, + {0, 0, 0, NULL} +}; + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" +#if __HAVE_SG +#include "drm_scatter.h" +#endif + +DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0); diff --git a/bsd-core/sis/Makefile b/bsd-core/sis/Makefile deleted file mode 100644 index 07b41caa..00000000 --- a/bsd-core/sis/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# $FreeBSD$ - -KMOD= sis -NOMAN= YES -SRCS= sis_drv.c sis_ds.c sis_mm.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h -CFLAGS+= ${DEBUG_FLAGS} -I. -I.. - -@: - ln -sf /sys @ - -machine: - ln -sf /sys/i386/include machine - -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#SIS_OPTS= "\#define DRM_LINUX" 1 -.endif - -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(SIS_OPTS) >> opt_drm_linux.h - -.include <bsd.kmod.mk> diff --git a/bsd-core/tdfx/Makefile b/bsd-core/tdfx/Makefile index d177ff60..149e3112 100644 --- a/bsd-core/tdfx/Makefile +++ b/bsd-core/tdfx/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD= tdfx NOMAN= YES SRCS= tdfx_drv.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS+= ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS+= ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#TDFX_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(TDFX_OPTS) >> opt_drm_linux.h +.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/tdfx/tdfx_drv.c b/bsd-core/tdfx_drv.c index 29d19558..8bc8c57d 100644 --- a/bsd/tdfx/tdfx_drv.c +++ b/bsd-core/tdfx_drv.c @@ -32,9 +32,6 @@ #include <sys/types.h> -#include <sys/bus.h> -#include <pci/pcivar.h> -#include <opt_drm_linux.h> #include "tdfx.h" #include "drmP.h" @@ -97,4 +94,6 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_vm.h" #include "drm_sysctl.h" +#ifdef __FreeBSD__ DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0); +#endif /* __FreeBSD__ */ diff --git a/bsd/Imakefile b/bsd/Imakefile index d18f1873..4923ea5b 100644 --- a/bsd/Imakefile +++ b/bsd/Imakefile @@ -1,3 +1,4 @@ + XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile,v 1.8 2001/12/13 00:24:45 alanh Exp $ XCOMM This is a kludge until we determine how best to build the @@ -18,3 +19,21 @@ all:: clean:: $(MAKE) -f Makefile.bsd clean + +LinkSourceFile(mga.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_dma.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_drm.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_drv.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_state.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_ucode.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(mga_warp.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(r128.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(r128_cce.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(r128_drm.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(r128_drv.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(r128_state.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(radeon.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(radeon_cp.c,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(radeon_drm.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(radeon_drv.h,$(XF86OSSRC)/shared/drm/kernel) +LinkSourceFile(radeon_state.c,$(XF86OSSRC)/shared/drm/kernel) diff --git a/bsd/ati_pcigart.h b/bsd/ati_pcigart.h index 8b486c10..28723f56 100644 --- a/bsd/ati_pcigart.h +++ b/bsd/ati_pcigart.h @@ -27,7 +27,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" #if PAGE_SIZE == 8192 @@ -46,40 +45,20 @@ static unsigned long DRM(ati_alloc_pcigart_table)( void ) { unsigned long address; - struct page *page; - int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER ); - if ( address == 0UL ) { - return 0; - } + DRM_DEBUG( "\n" ); - page = virt_to_page( address ); + address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK ); - for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { - atomic_inc( &page->count ); - SetPageReserved( page ); - } - - DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address ); + DRM_DEBUG( "returning 0x%08lx\n", address ); return address; } static void DRM(ati_free_pcigart_table)( unsigned long address ) { - struct page *page; - int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); - - page = virt_to_page( address ); + DRM_DEBUG( "\n" ); - for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { - atomic_dec( &page->count ); - ClearPageReserved( page ); - } - - free_pages( address, ATI_PCIGART_TABLE_ORDER ); + free( (void *)address, DRM(M_DRM)); } int DRM(ati_pcigart_init)( drm_device_t *dev, @@ -89,7 +68,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, drm_sg_mem_t *entry = dev->sg; unsigned long address = 0; unsigned long pages; - u32 *pci_gart, page_base, bus_address = 0; + u32 *pci_gart=0, page_base, bus_address = 0; int i, j, ret = 0; if ( !entry ) { @@ -103,41 +82,36 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, goto done; } - if ( !dev->pdev ) { - DRM_ERROR( "PCI device unknown!\n" ); - goto done; - } - - bus_address = pci_map_single(dev->pdev, (void *)address, + /* FIXME non-vtophys==bustophys-arches */ + bus_address = vtophys( address ); + /*pci_map_single(dev->pdev, (void *)address, ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); - if (bus_address == 0) { + PCI_DMA_TODEVICE);*/ +/* if (bus_address == 0) { DRM_ERROR( "unable to map PCIGART pages!\n" ); - DRM(ati_free_pcigart_table)( address ); + DRM(ati_free_pcigart_table)( (unsigned long)address ); address = 0; goto done; - } + }*/ pci_gart = (u32 *)address; pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) ? entry->pages : ATI_MAX_PCIGART_PAGES; - memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); + bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); for ( i = 0 ; i < pages ; i++ ) { /* we need to support large memory configurations */ - entry->busaddr[i] = pci_map_single(dev->pdev, - page_address( entry->pagelist[i] ), - PAGE_SIZE, - PCI_DMA_TODEVICE); - if (entry->busaddr[i] == 0) { + /* 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, address, bus_address ); + 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++) { @@ -148,11 +122,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, ret = 1; -#if defined(__i386__) || defined(__x86_64__) - asm volatile ( "wbinvd" ::: "memory" ); -#else - mb(); -#endif + DRM_READMEMORYBARRIER(); done: *addr = address; @@ -165,8 +135,6 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, dma_addr_t bus_addr) { drm_sg_mem_t *entry = dev->sg; - unsigned long pages; - int i; /* we need to support large memory configurations */ if ( !entry ) { @@ -174,21 +142,6 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev, return 0; } - if ( bus_addr ) { - pci_unmap_single(dev->pdev, bus_addr, - ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, - PCI_DMA_TODEVICE); - - pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) - ? entry->pages : ATI_MAX_PCIGART_PAGES; - - for ( i = 0 ; i < pages ; i++ ) { - if ( !entry->busaddr[i] ) break; - pci_unmap_single(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_TODEVICE); - } - } - if ( addr ) { DRM(ati_free_pcigart_table)( addr ); } @@ -35,8 +35,31 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) +#include <linux/config.h> +#include <asm/ioctl.h> /* For _IO* macros */ +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include <sys/ioccom.h> -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include <sys/ioccom.h> +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#endif #define XFREE86_VERSION(major,minor,patch,snap) \ ((major << 16) | (minor << 8) | patch) @@ -62,7 +85,7 @@ #define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */ -#define DRM_RAM_PERCENT 50 /* How much system ram can we lock? */ +#define DRM_RAM_PERCENT 10 /* How much system ram can we lock? */ #define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */ #define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */ @@ -78,6 +101,10 @@ typedef unsigned int drm_magic_t; /* Warning: If you change this structure, make sure you change * XF86DRIClipRectRec in the server as well */ +/* KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ + typedef struct drm_clip_rect { unsigned short x1; unsigned short y1; @@ -357,10 +384,9 @@ typedef struct drm_scatter_gather { #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) @@ -69,7 +69,11 @@ typedef struct drm_file drm_file_t; /* There's undoubtably more of this file to go into these OS dependent ones. */ +#ifdef __FreeBSD__ #include "drm_os_freebsd.h" +#elif defined __NetBSD__ +#include "drm_os_netbsd.h" +#endif #include "drm.h" @@ -239,8 +243,8 @@ typedef struct drm_waitlist { drm_buf_t **rp; /* Read pointer */ drm_buf_t **wp; /* Write pointer */ drm_buf_t **end; /* End pointer */ - DRM_OS_SPINTYPE read_lock; - DRM_OS_SPINTYPE write_lock; + DRM_SPINTYPE read_lock; + DRM_SPINTYPE write_lock; } drm_waitlist_t; typedef struct drm_freelist { @@ -252,7 +256,7 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ atomic_t wfh; /* If waiting for high mark */ - DRM_OS_SPINTYPE lock; + DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -374,6 +378,7 @@ typedef struct drm_sg_mem { void *virtual; int pages; struct page **pagelist; + dma_addr_t *busaddr; } drm_sg_mem_t; typedef struct drm_sigdata { @@ -388,20 +393,24 @@ typedef struct drm_map_list_entry { } drm_map_list_entry_t; struct drm_device { +#ifdef __NetBSD__ + struct device device; /* NetBSD's softc is an extension of struct device */ +#endif const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ int unique_len; /* Length of unique field */ +#ifdef __FreeBSD__ device_t device; /* Device instance from newbus */ +#endif dev_t devnode; /* Device number for mknod */ char *devname; /* For /proc/interrupts */ int blocked; /* Blocked due to VC switch? */ int flags; /* Flags to open(2) */ int writable; /* Opened with FWRITE */ - struct proc_dir_entry *root; /* Root for this device's entries */ /* Locks */ - DRM_OS_SPINTYPE count_lock; /* For inuse, open_count, buf_use */ + DRM_SPINTYPE count_lock; /* For inuse, open_count, buf_use */ struct lock dev_lock; /* For others */ /* Usage Counters */ int open_count; /* Outstanding files open */ @@ -437,12 +446,17 @@ struct drm_device { drm_device_dma_t *dma; /* Optional pointer for DMA support */ /* Context support */ +#ifdef __FreeBSD__ int irq; /* Interrupt used by board */ struct resource *irqr; /* Resource for interrupt used by board */ +#elif defined(__NetBSD__) + struct pci_attach_args pa; + pci_intr_handle_t ih; +#endif void *irqh; /* Handle from bus_setup_intr */ - __volatile__ long context_flag; /* Context swapping flag */ - __volatile__ long interrupt_flag; /* Interruption handler flag */ - __volatile__ long dma_flag; /* DMA dispatch flag */ + atomic_t context_flag; /* Context swapping flag */ + atomic_t interrupt_flag; /* Interruption handler flag */ + atomic_t dma_flag; /* DMA dispatch flag */ struct callout timer; /* Timer for delaying ctx switch */ wait_queue_head_t context_wait; /* Processes waiting on ctx switch */ int last_checked; /* Last context checked for DMA */ @@ -463,7 +477,11 @@ struct drm_device { char *buf_rp; /* Read pointer */ char *buf_wp; /* Write pointer */ char *buf_end; /* End pointer */ +#ifdef __FreeBSD__ struct sigio *buf_sigio; /* Processes waiting for SIGIO */ +#elif defined(__NetBSD__) + pid_t buf_pgid; +#endif struct selinfo buf_sel; /* Workspace for select/poll */ int buf_selecting;/* True if poll sleeper */ wait_queue_head_t buf_readers; /* Processes waiting to read */ @@ -475,16 +493,8 @@ struct drm_device { #if __REALLY_HAVE_AGP drm_agp_head_t *agp; #endif - struct pci_dev *pdev; -#ifdef __alpha__ -#if LINUX_VERSION_CODE < 0x020403 - struct pci_controler *hose; -#else - struct pci_controller *hose; -#endif -#endif drm_sg_mem_t *sg; /* Scatter gather memory */ - unsigned long *ctx_bitmap; + atomic_t *ctx_bitmap; void *dev_private; drm_sigdata_t sigdata; /* For block_all_signals */ sigset_t sigmask; @@ -500,7 +510,7 @@ extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); /* Driver support (drm_drv.h) */ -extern int DRM(version)( DRM_OS_IOCTL ); +extern int DRM(version)( DRM_IOCTL_ARGS ); extern int DRM(write_string)(drm_device_t *dev, const char *s); /* Memory management support (drm_memory.h) */ @@ -511,9 +521,6 @@ extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, 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 unsigned long DRM(alloc_pages)(int order, int area); -extern void DRM(free_pages)(unsigned long address, int order, - 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); @@ -571,9 +578,9 @@ extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); #if __HAVE_DMA_IRQ extern int DRM(irq_install)( drm_device_t *dev, int irq ); extern int DRM(irq_uninstall)( drm_device_t *dev ); -extern void DRM(dma_service)( DRM_OS_IRQ_ARGS ); +extern void DRM(dma_service)( DRM_IRQ_ARGS ); #if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( DRM_OS_TASKQUEUE_ARGS ); +extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ); #endif #endif #if DRM_DMA_HISTOGRAM @@ -608,15 +615,6 @@ extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); extern int DRM(agp_unbind_memory)(agp_memory *handle); #endif - /* Proc support (drm_proc.h) */ -extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int DRM(proc_cleanup)(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); - #if __HAVE_SG /* Scatter Gather Support (drm_scatter.h) */ extern void DRM(sg_cleanup)(drm_sg_mem_t *entry); @@ -633,4 +631,4 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, #endif #endif /* __KERNEL__ */ -#endif +#endif /* _DRM_P_H_ */ diff --git a/bsd/drm_agpsupport.h b/bsd/drm_agpsupport.h index ac12c867..66de1053 100644 --- a/bsd/drm_agpsupport.h +++ b/bsd/drm_agpsupport.h @@ -31,15 +31,9 @@ #include "drmP.h" -#include <vm/vm.h> -#include <vm/pmap.h> -#if __REALLY_HAVE_AGP -#include <sys/agpio.h> -#endif - -int DRM(agp_info)(DRM_OS_IOCTL) +int DRM(agp_info)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; struct agp_info *kern; drm_agp_info_t info; @@ -61,9 +55,9 @@ int DRM(agp_info)(DRM_OS_IOCTL) return 0; } -int DRM(agp_acquire)(DRM_OS_IOCTL) +int DRM(agp_acquire)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int retcode; if (!dev->agp || dev->agp->acquired) return EINVAL; @@ -73,9 +67,9 @@ int DRM(agp_acquire)(DRM_OS_IOCTL) return 0; } -int DRM(agp_release)(DRM_OS_IOCTL) +int DRM(agp_release)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; if (!dev->agp || !dev->agp->acquired) return EINVAL; @@ -89,14 +83,14 @@ void DRM(agp_do_release)(void) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (agpdev) agp_release(agpdev); } -int DRM(agp_enable)(DRM_OS_IOCTL) +int DRM(agp_enable)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_mode_t mode; if (!dev->agp || !dev->agp->acquired) return EINVAL; @@ -110,9 +104,9 @@ int DRM(agp_enable)(DRM_OS_IOCTL) return 0; } -int DRM(agp_alloc)(DRM_OS_IOCTL) +int DRM(agp_alloc)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_buffer_t request; drm_agp_mem_t *entry; void *handle; @@ -165,9 +159,9 @@ static drm_agp_mem_t * DRM(agp_lookup_entry)(drm_device_t *dev, void *handle) return NULL; } -int DRM(agp_unbind)(DRM_OS_IOCTL) +int DRM(agp_unbind)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; @@ -187,9 +181,9 @@ int DRM(agp_unbind)(DRM_OS_IOCTL) return retcode; } -int DRM(agp_bind)(DRM_OS_IOCTL) +int DRM(agp_bind)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_binding_t request; drm_agp_mem_t *entry; int retcode; @@ -209,9 +203,9 @@ int DRM(agp_bind)(DRM_OS_IOCTL) return 0; } -int DRM(agp_free)(DRM_OS_IOCTL) +int DRM(agp_free)(DRM_IOCTL_ARGS) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_agp_buffer_t request; drm_agp_mem_t *entry; @@ -235,7 +229,7 @@ drm_agp_head_t *DRM(agp_init)(void) drm_agp_head_t *head = NULL; int agp_available = 1; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) agp_available = 0; @@ -267,9 +261,9 @@ drm_agp_head_t *DRM(agp_init)(void) default: } #endif - DRM_INFO("AGP at 0x%08x %dMB\n", + DRM_INFO("AGP at 0x%08lx %dMB\n", head->info.ai_aperture_base, - head->info.ai_aperture_size >> 20); + (int)(head->info.ai_aperture_size >> 20)); } return head; } @@ -284,7 +278,7 @@ agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev) return NULL; @@ -295,7 +289,7 @@ int DRM(agp_free_memory)(agp_memory *handle) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return 0; @@ -307,7 +301,7 @@ int DRM(agp_bind_memory)(agp_memory *handle, off_t start) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; @@ -318,7 +312,7 @@ int DRM(agp_unbind_memory)(agp_memory *handle) { device_t agpdev; - agpdev = agp_find_device(); + agpdev = DRM_AGP_FIND_DEVICE(); if (!agpdev || !handle) return EINVAL; diff --git a/bsd/drm_auth.h b/bsd/drm_auth.h index db0c0118..0b411d14 100644 --- a/bsd/drm_auth.h +++ b/bsd/drm_auth.h @@ -29,7 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" static int DRM(hash_magic)(drm_magic_t magic) @@ -43,14 +42,14 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) drm_magic_entry_t *pt; int hash = DRM(hash_magic)(magic); - DRM_OS_LOCK; + DRM_LOCK; for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { if (pt->magic == magic) { retval = pt->priv; break; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; return retval; } @@ -63,13 +62,13 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) hash = DRM(hash_magic)(magic); entry = (drm_magic_entry_t*) DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC); - if (!entry) DRM_OS_RETURN(ENOMEM); + if (!entry) return DRM_ERR(ENOMEM); memset(entry, 0, sizeof(*entry)); entry->magic = magic; entry->priv = priv; entry->next = NULL; - DRM_OS_LOCK; + DRM_LOCK; if (dev->magiclist[hash].tail) { dev->magiclist[hash].tail->next = entry; dev->magiclist[hash].tail = entry; @@ -77,7 +76,7 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) dev->magiclist[hash].head = entry; dev->magiclist[hash].tail = entry; } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -91,7 +90,7 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) DRM_DEBUG("%d\n", magic); hash = DRM(hash_magic)(magic); - DRM_OS_LOCK; + DRM_LOCK; for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { if (pt->magic == magic) { if (dev->magiclist[hash].head == pt) { @@ -103,28 +102,27 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) if (prev) { prev->next = pt->next; } - DRM_OS_UNLOCK; - DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC); + DRM_UNLOCK; return 0; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } -int DRM(getmagic)(DRM_OS_IOCTL) +int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; drm_auth_t auth; - static DRM_OS_SPINTYPE lock; + static DRM_SPINTYPE lock; static int first = 1; - DRM_OS_DEVICE; - DRM_OS_PRIV; + DRM_DEVICE; + DRM_PRIV; if (first) { - DRM_OS_SPININIT(lock, "drm getmagic"); + DRM_SPININIT(lock, "drm getmagic"); first = 0; } @@ -133,10 +131,10 @@ int DRM(getmagic)(DRM_OS_IOCTL) auth.magic = priv->magic; } else { do { - DRM_OS_SPINLOCK(&lock); + DRM_SPINLOCK(&lock); if (!sequence) ++sequence; /* reserve 0 */ auth.magic = sequence++; - DRM_OS_SPINUNLOCK(&lock); + DRM_SPINUNLOCK(&lock); } while (DRM(find_file)(dev, auth.magic)); priv->magic = auth.magic; DRM(add_magic)(dev, priv, auth.magic); @@ -144,18 +142,18 @@ int DRM(getmagic)(DRM_OS_IOCTL) DRM_DEBUG("%u\n", auth.magic); - DRM_OS_KRNTOUSR((drm_auth_t *)data, auth, sizeof(auth)); + DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth)); return 0; } -int DRM(authmagic)(DRM_OS_IOCTL) +int DRM(authmagic)(DRM_IOCTL_ARGS) { drm_auth_t auth; drm_file_t *file; - DRM_OS_DEVICE; + DRM_DEVICE; - DRM_OS_KRNFROMUSR(auth, (drm_auth_t *)data, sizeof(auth)); + DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth)); DRM_DEBUG("%u\n", auth.magic); if ((file = DRM(find_file)(dev, auth.magic))) { @@ -163,5 +161,5 @@ int DRM(authmagic)(DRM_OS_IOCTL) DRM(remove_magic)(dev, auth.magic); return 0; } - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } diff --git a/bsd/drm_bufs.h b/bsd/drm_bufs.h index d55b36d8..46dc1c9a 100644 --- a/bsd/drm_bufs.h +++ b/bsd/drm_bufs.h @@ -29,14 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ -#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> -#include <vm/vm_param.h> #include "drmP.h" #ifndef __HAVE_PCI_DMA @@ -74,18 +66,18 @@ int DRM(order)( unsigned long size ) return order; } -int DRM(addmap)( DRM_OS_IOCTL ) +int DRM(addmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_t *map; drm_map_list_entry_t *list; - + if (!(dev->flags & (FREAD|FWRITE))) - DRM_OS_RETURN(EACCES); /* Require read/write */ + return DRM_ERR(EACCES); /* Require read/write */ map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ); if ( !map ) - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); *map = *(drm_map_t *)data; @@ -95,30 +87,17 @@ int DRM(addmap)( DRM_OS_IOCTL ) */ if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n", map->offset, map->size, map->type ); if ( (map->offset & PAGE_MASK) || (map->size & PAGE_MASK) ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } map->mtrr = -1; map->handle = 0; - TAILQ_FOREACH(list, dev->maplist, link) { - drm_map_t *entry = list->map; - if ( (entry->offset >= map->offset - && (entry->offset) < (map->offset + map->size) ) - || ((entry->offset + entry->size) >= map->offset - && (entry->offset + entry->size) < (map->offset + map->size) ) - || ((entry->offset < map->offset) - && (entry->offset + entry->size) >= (map->offset + map->size) ) ) - DRM_DEBUG("map collission: add(0x%lx-0x%lx), current(0x%lx-0x%lx)\n", - entry->offset, entry->offset + entry->size - 1, - map->offset, map->offset + map->size - 1); - } - switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: @@ -126,7 +105,7 @@ int DRM(addmap)( DRM_OS_IOCTL ) if ( map->offset + map->size < map->offset ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } #endif #ifdef __alpha__ @@ -135,23 +114,41 @@ int DRM(addmap)( DRM_OS_IOCTL ) #if __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { - map->mtrr = mtrr_add( map->offset, map->size, - MTRR_TYPE_WRCOMB, 1 ); - } +#ifdef __FreeBSD__ + int retcode = 0, act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + map->mtrr=1; +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + 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 ); #endif + } +#endif /* __REALLY_HAVE_MTRR */ map->handle = DRM(ioremap)( map->offset, map->size ); break; case _DRM_SHM: DRM_INFO( "%ld %d %d\n", map->size, DRM(order)( map->size ), PAGE_SHIFT); - map->handle = (void *)DRM(alloc_pages) - (DRM(order)(map->size) - PAGE_SHIFT, DRM_MEM_SAREA); + map->handle = (void *)DRM(alloc)(map->size, 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 ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } map->offset = (unsigned long)map->handle; if ( map->flags & _DRM_CONTAINS_LOCK ) { @@ -170,27 +167,27 @@ int DRM(addmap)( DRM_OS_IOCTL ) case _DRM_SCATTER_GATHER: if (!dev->sg) { DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } map->offset = map->offset + dev->sg->handle; break; default: DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS); if(!list) { DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } memset(list, 0, sizeof(*list)); list->map = map; - DRM_OS_LOCK; + DRM_LOCK; TAILQ_INSERT_TAIL(dev->maplist, list, link); - DRM_OS_UNLOCK; + DRM_UNLOCK; *(drm_map_t *)data = *map; @@ -205,17 +202,17 @@ int DRM(addmap)( DRM_OS_IOCTL ) * isn't in use. */ -int DRM(rmmap)( DRM_OS_IOCTL ) +int DRM(rmmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_list_entry_t *list; drm_map_t *map; drm_map_t request; int found_maps = 0; - DRM_OS_KRNFROMUSR( request, (drm_map_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map = list->map; if(map->handle == request.handle && @@ -226,8 +223,8 @@ int DRM(rmmap)( DRM_OS_IOCTL ) * find anything. */ if(list == NULL) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } TAILQ_REMOVE(dev->maplist, list, link); DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); @@ -240,16 +237,32 @@ int DRM(rmmap)( DRM_OS_IOCTL ) #if __REALLY_HAVE_MTRR if (map->mtrr >= 0) { int retcode; - retcode = mtrr_del(map->mtrr, - map->offset, - map->size); +#ifdef __FreeBSD__ + int act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_REMOVE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + mtrrmap.base = map->offset; + mtrrmap.len = map->size; + mtrrmap.type = 0; + mtrrmap.flags = 0; + mtrrmap.owner = p->p_pid; + retcode = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL); DRM_DEBUG("mtrr_del = %d\n", retcode); +#endif } #endif DRM(ioremapfree)(map->handle, map->size); break; case _DRM_SHM: - DRM(free_pages)( (unsigned long)map->handle, DRM(order)(map->size), DRM_MEM_SAREA ); + DRM(free)( map->handle, map->size, DRM_MEM_SAREA ); break; case _DRM_AGP: case _DRM_SCATTER_GATHER: @@ -257,7 +270,7 @@ int DRM(rmmap)( DRM_OS_IOCTL ) } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -270,8 +283,8 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) if (entry->seg_count) { for (i = 0; i < entry->seg_count; i++) { - DRM(free_pages)(entry->seglist[i], - entry->page_order, + DRM(free)((void *)entry->seglist[i], + entry->buf_size, DRM_MEM_DMA); } DRM(free)(entry->seglist, @@ -304,9 +317,9 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) } #if __REALLY_HAVE_AGP -int DRM(addbufs_agp)( DRM_OS_IOCTL ) +int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; drm_buf_entry_t *entry; @@ -323,9 +336,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) int i; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -348,38 +361,38 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) DRM_DEBUG( "total: %d\n", total ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( dev->queue_count ) - DRM_OS_RETURN(EBUSY); /* Not while in use */ + return DRM_ERR(EBUSY); /* Not while in use */ - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -436,9 +449,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -458,12 +471,12 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); dma->flags = _DRM_DMA_USE_AGP; @@ -473,9 +486,9 @@ int DRM(addbufs_agp)( DRM_OS_IOCTL ) #endif /* __REALLY_HAVE_AGP */ #if __HAVE_PCI_DMA -int DRM(addbufs_pci)( DRM_OS_IOCTL ) +int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int count; @@ -494,9 +507,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) unsigned long *temp_pagelist; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -507,43 +520,43 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) order, dev->queue_count ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( dev->queue_count ) - DRM_OS_RETURN(EBUSY); /* Not while in use */ + return DRM_ERR(EBUSY); /* Not while in use */ alignment = (request.flags & _DRM_PAGE_ALIGN) ? round_page(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -553,9 +566,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(free)( entry->buflist, count * sizeof(*entry->buflist), DRM_MEM_BUFS ); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->seglist, 0, count * sizeof(*entry->seglist) ); @@ -571,9 +584,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(free)( entry->seglist, count * sizeof(*entry->seglist), DRM_MEM_SEGS ); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->pagelist = temp_pagelist; @@ -586,7 +599,7 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) page_count = 0; while ( entry->buf_count < count ) { - page = DRM(alloc_pages)( page_order, DRM_MEM_DMA ); + page = (unsigned long)DRM(alloc)( size, DRM_MEM_DMA ); if ( !page ) break; entry->seglist[entry->seg_count++] = page; for ( i = 0 ; i < (1 << page_order) ; i++ ) { @@ -631,9 +644,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -652,12 +665,12 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); atomic_dec( &dev->buf_alloc ); return 0; @@ -666,9 +679,9 @@ int DRM(addbufs_pci)( DRM_OS_IOCTL ) #endif /* __HAVE_PCI_DMA */ #if __REALLY_HAVE_SG -int DRM(addbufs_sg)( DRM_OS_IOCTL ) +int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; drm_buf_entry_t *entry; @@ -685,9 +698,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) int i; drm_buf_t **temp_buflist; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); count = request.count; order = DRM(order)( request.size ); @@ -710,37 +723,37 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) DRM_DEBUG( "total: %d\n", total ); 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 */ + return DRM_ERR(EINVAL); + if ( dev->queue_count ) return DRM_ERR(EBUSY); /* Not while in use */ - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( dev->buf_use ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } atomic_inc( &dev->buf_alloc ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_LOCK; + DRM_LOCK; entry = &dma->bufs[order]; if ( entry->buf_count ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); /* May only call once for each order */ + return DRM_ERR(ENOMEM); /* May only call once for each order */ } if (count < 0 || count > 4096) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -772,9 +785,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } memset( buf->dev_private, 0, buf->dev_priv_size ); @@ -803,9 +816,9 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) if(!temp_buflist) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(entry); - DRM_OS_UNLOCK; + DRM_UNLOCK; atomic_dec( &dev->buf_alloc ); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -825,12 +838,12 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - DRM_OS_UNLOCK; + DRM_UNLOCK; request.count = entry->buf_count; request.size = size; - DRM_OS_KRNTOUSR( (drm_buf_desc_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_desc_t *)data, request, sizeof(request) ); dma->flags = _DRM_DMA_USE_SG; @@ -839,11 +852,11 @@ int DRM(addbufs_sg)( DRM_OS_IOCTL ) } #endif /* __REALLY_HAVE_SG */ -int DRM(addbufs)( DRM_OS_IOCTL ) +int DRM(addbufs)( DRM_IOCTL_ARGS ) { drm_buf_desc_t request; - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) @@ -858,29 +871,29 @@ int DRM(addbufs)( DRM_OS_IOCTL ) #if __HAVE_PCI_DMA return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); #else - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); #endif } -int DRM(infobufs)( DRM_OS_IOCTL ) +int DRM(infobufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_info_t request; int i; int count; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( atomic_read( &dev->buf_alloc ) ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } ++dev->buf_use; /* Can't allocate more after this call */ - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_KRNFROMUSR( request, (drm_buf_info_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { if ( dma->bufs[i].buf_count ) ++count; @@ -894,19 +907,19 @@ int DRM(infobufs)( DRM_OS_IOCTL ) drm_buf_desc_t *to = &request.list[count]; drm_buf_entry_t *from = &dma->bufs[i]; drm_freelist_t *list = &dma->bufs[i].freelist; - if ( DRM_OS_COPYTOUSR( &to->count, + if ( DRM_COPY_TO_USER( &to->count, &from->buf_count, sizeof(from->buf_count) ) || - DRM_OS_COPYTOUSR( &to->size, + DRM_COPY_TO_USER( &to->size, &from->buf_size, sizeof(from->buf_size) ) || - DRM_OS_COPYTOUSR( &to->low_mark, + DRM_COPY_TO_USER( &to->low_mark, &list->low_mark, sizeof(list->low_mark) ) || - DRM_OS_COPYTOUSR( &to->high_mark, + DRM_COPY_TO_USER( &to->high_mark, &list->high_mark, sizeof(list->high_mark) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); DRM_DEBUG( "%d %d %d %d %d\n", i, @@ -920,34 +933,34 @@ int DRM(infobufs)( DRM_OS_IOCTL ) } request.count = count; - DRM_OS_KRNTOUSR( (drm_buf_info_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) ); return 0; } -int DRM(markbufs)( DRM_OS_IOCTL ) +int DRM(markbufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int order; drm_buf_entry_t *entry; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_desc_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); DRM_DEBUG( "%d, %d, %d\n", request.size, request.low_mark, request.high_mark ); order = DRM(order)( request.size ); if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); entry = &dma->bufs[order]; if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); entry->freelist.low_mark = request.low_mark; entry->freelist.high_mark = request.high_mark; @@ -955,35 +968,35 @@ int DRM(markbufs)( DRM_OS_IOCTL ) return 0; } -int DRM(freebufs)( DRM_OS_IOCTL ) +int DRM(freebufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_buf_free_t request; int i; int idx; drm_buf_t *buf; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_KRNFROMUSR( request, (drm_buf_free_t *)data, sizeof(request) ); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) ); DRM_DEBUG( "%d\n", request.count ); for ( i = 0 ; i < request.count ; i++ ) { - if ( DRM_OS_COPYFROMUSR( &idx, + if ( DRM_COPY_FROM_USER( &idx, &request.list[i], sizeof(idx) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "Index %d (of %d max)\n", idx, dma->buf_count - 1 ); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_OS_CURRENTPID ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_OS_CURRENTPID, buf->pid ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); } @@ -991,32 +1004,43 @@ int DRM(freebufs)( DRM_OS_IOCTL ) return 0; } -int DRM(mapbufs)( DRM_OS_IOCTL ) +int DRM(mapbufs)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; int retcode = 0; const int zero = 0; vm_offset_t virtual, address; +#ifdef __FreeBSD__ #if __FreeBSD_version >= 500000 struct vmspace *vms = p->td_proc->p_vmspace; #else struct vmspace *vms = p->p_vmspace; #endif +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + struct vnode *vn; +#endif /* __NetBSD__ */ + drm_buf_map_t request; int i; - if ( !dma ) DRM_OS_RETURN(EINVAL); + if ( !dma ) return DRM_ERR(EINVAL); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); if ( atomic_read( &dev->buf_alloc ) ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } dev->buf_use++; /* Can't allocate more after this call */ - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINUNLOCK( &dev->count_lock ); + + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) ); - DRM_OS_KRNFROMUSR( request, (drm_buf_map_t *)data, sizeof(request) ); +#ifdef __NetBSD__ + if(!vfinddev(kdev, VCHR, &vn)) + return 0; /* FIXME: Shouldn't this be EINVAL or something? */ +#endif /* __NetBSD__ */ if ( request.count >= dma->buf_count ) { if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) || @@ -1028,6 +1052,7 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) goto done; } +#ifdef __FreeBSD__ virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); retcode = vm_mmap(&vms->vm_map, &virtual, @@ -1036,7 +1061,18 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), (unsigned long)map->offset ); +#elif defined(__NetBSD__) + virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); + retcode = uvm_mmap(&vms->vm_map, + (vaddr_t *)&virtual, + round_page(map->size), + UVM_PROT_READ | UVM_PROT_WRITE, + UVM_PROT_ALL, MAP_SHARED, + &vn->v_uobj, map->offset, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); +#endif /* __NetBSD__ */ } else { +#ifdef __FreeBSD__ virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); retcode = vm_mmap(&vms->vm_map, &virtual, @@ -1045,32 +1081,42 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), 0); +#elif defined(__NetBSD__) + virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ); + retcode = uvm_mmap(&vms->vm_map, + (vaddr_t *)&virtual, + round_page(dma->byte_count), + UVM_PROT_READ | UVM_PROT_WRITE, + UVM_PROT_ALL, MAP_SHARED, + &vn->v_uobj, 0, + p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur); +#endif /* __NetBSD__ */ } if (retcode) goto done; request.virtual = (void *)virtual; for ( i = 0 ; i < dma->buf_count ; i++ ) { - if ( DRM_OS_COPYTOUSR( &request.list[i].idx, + if ( DRM_COPY_TO_USER( &request.list[i].idx, &dma->buflist[i]->idx, sizeof(request.list[0].idx) ) ) { retcode = EFAULT; goto done; } - if ( DRM_OS_COPYTOUSR( &request.list[i].total, + if ( DRM_COPY_TO_USER( &request.list[i].total, &dma->buflist[i]->total, sizeof(request.list[0].total) ) ) { retcode = EFAULT; goto done; } - if ( DRM_OS_COPYTOUSR( &request.list[i].used, + if ( DRM_COPY_TO_USER( &request.list[i].used, &zero, sizeof(zero) ) ) { retcode = EFAULT; goto done; } address = virtual + dma->buflist[i]->offset; /* *** */ - if ( DRM_OS_COPYTOUSR( &request.list[i].address, + if ( DRM_COPY_TO_USER( &request.list[i].address, &address, sizeof(address) ) ) { retcode = EFAULT; @@ -1083,9 +1129,9 @@ int DRM(mapbufs)( DRM_OS_IOCTL ) DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode ); - DRM_OS_KRNTOUSR( (drm_buf_map_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_buf_map_t *)data, request, sizeof(request) ); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } #endif /* __HAVE_DMA */ diff --git a/bsd/drm_context.h b/bsd/drm_context.h index 8d676a23..0274a8b7 100644 --- a/bsd/drm_context.h +++ b/bsd/drm_context.h @@ -29,7 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" #if __HAVE_CTX_BITMAP @@ -44,10 +43,10 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) if ( !dev->ctx_bitmap ) goto failed; if ( ctx_handle < DRM_MAX_CTXBITMAP ) { - DRM_OS_LOCK; + DRM_LOCK; clear_bit( ctx_handle, dev->ctx_bitmap ); dev->context_sareas[ctx_handle] = NULL; - DRM_OS_UNLOCK; + DRM_UNLOCK; return; } failed: @@ -62,7 +61,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) if(!dev->ctx_bitmap) return -1; - DRM_OS_LOCK; + DRM_LOCK; bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP ); if ( bit < DRM_MAX_CTXBITMAP ) { set_bit( bit, dev->ctx_bitmap ); @@ -80,7 +79,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) DRM_MEM_MAPS); if(!ctx_sareas) { clear_bit(bit, dev->ctx_bitmap); - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } dev->context_sareas = ctx_sareas; @@ -93,16 +92,16 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) DRM_MEM_MAPS); if(!dev->context_sareas) { clear_bit(bit, dev->ctx_bitmap); - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } dev->context_sareas[bit] = NULL; } } - DRM_OS_UNLOCK; + DRM_UNLOCK; return bit; } - DRM_OS_UNLOCK; + DRM_UNLOCK; return -1; } @@ -111,17 +110,17 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) int i; int temp; - DRM_OS_LOCK; - dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE, + DRM_LOCK; + dev->ctx_bitmap = (atomic_t *) DRM(alloc)( PAGE_SIZE, DRM_MEM_CTXBITMAP ); if ( dev->ctx_bitmap == NULL ) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(ENOMEM); + DRM_UNLOCK; + return DRM_ERR(ENOMEM); } memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE ); dev->context_sareas = NULL; dev->max_context = -1; - DRM_OS_UNLOCK; + DRM_UNLOCK; for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { temp = DRM(ctxbitmap_next)( dev ); @@ -133,55 +132,55 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) { - DRM_OS_LOCK; + DRM_LOCK; if( dev->context_sareas ) DRM(free)( dev->context_sareas, sizeof(*dev->context_sareas) * dev->max_context, DRM_MEM_MAPS ); DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP ); - DRM_OS_UNLOCK; + DRM_UNLOCK; } /* ================================================================ * Per Context SAREA Support */ -int DRM(getsareactx)( DRM_OS_IOCTL ) +int DRM(getsareactx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_priv_map_t request; drm_map_t *map; - DRM_OS_KRNFROMUSR( request, (drm_ctx_priv_map_t *)data, + DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } map = dev->context_sareas[request.ctx_id]; - DRM_OS_UNLOCK; + DRM_UNLOCK; request.handle = map->handle; - DRM_OS_KRNTOUSR( (drm_ctx_priv_map_t *)data, request, sizeof(request) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_priv_map_t *)data, request, sizeof(request) ); return 0; } -int DRM(setsareactx)( DRM_OS_IOCTL ) +int DRM(setsareactx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_priv_map_t request; drm_map_t *map = NULL; drm_map_list_entry_t *list; - DRM_OS_KRNFROMUSR( request, (drm_ctx_priv_map_t *)data, + DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, sizeof(request) ); - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(list, dev->maplist, link) { map=list->map; if(map->handle == request.handle) @@ -189,8 +188,8 @@ int DRM(setsareactx)( DRM_OS_IOCTL ) } bad: - DRM_OS_UNLOCK; - return -EINVAL; + DRM_UNLOCK; + return DRM_ERR(EINVAL); found: map = list->map; @@ -200,7 +199,7 @@ found: if (request.ctx_id >= (unsigned) dev->max_context) goto bad; dev->context_sareas[request.ctx_id] = map; - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } @@ -214,7 +213,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) if ( test_and_set_bit( 0, &dev->context_flag ) ) { DRM_ERROR( "Reentering -- FIXME\n" ); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } #if __HAVE_DMA_HISTOGRAM @@ -256,41 +255,41 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) #endif clear_bit( 0, &dev->context_flag ); - DRM_OS_WAKEUP( &dev->context_wait ); + DRM_WAKEUP( (void *)&dev->context_wait ); return 0; } -int DRM(resctx)( DRM_OS_IOCTL ) +int DRM(resctx)( DRM_IOCTL_ARGS ) { drm_ctx_res_t res; drm_ctx_t ctx; int i; - DRM_OS_KRNFROMUSR( res, (drm_ctx_res_t *)data, sizeof(res) ); + DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if ( res.count >= DRM_RESERVED_CONTEXTS ) { memset( &ctx, 0, sizeof(ctx) ); for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { ctx.handle = i; - if ( DRM_OS_COPYTOUSR( &res.contexts[i], + if ( DRM_COPY_TO_USER( &res.contexts[i], &i, sizeof(i) ) ) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); } } res.count = DRM_RESERVED_CONTEXTS; - DRM_OS_KRNTOUSR( (drm_ctx_res_t *)data, res, sizeof(res) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) ); return 0; } -int DRM(addctx)( DRM_OS_IOCTL ) +int DRM(addctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); ctx.handle = DRM(ctxbitmap_next)( dev ); if ( ctx.handle == DRM_KERNEL_CONTEXT ) { @@ -301,51 +300,51 @@ int DRM(addctx)( DRM_OS_IOCTL ) if ( ctx.handle == -1 ) { DRM_DEBUG( "Not enough free contexts.\n" ); /* Should this return -EBUSY instead? */ - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(modctx)( DRM_OS_IOCTL ) +int DRM(modctx)( DRM_IOCTL_ARGS ) { /* This does nothing */ return 0; } -int DRM(getctx)( DRM_OS_IOCTL ) +int DRM(getctx)( DRM_IOCTL_ARGS ) { drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); /* This is 0, because we don't handle any context flags */ ctx.flags = 0; - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(switchctx)( DRM_OS_IOCTL ) +int DRM(switchctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); return DRM(context_switch)( dev, dev->last_context, ctx.handle ); } -int DRM(newctx)( DRM_OS_IOCTL ) +int DRM(newctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); DRM(context_switch_complete)( dev, ctx.handle ); @@ -353,12 +352,12 @@ int DRM(newctx)( DRM_OS_IOCTL ) return 0; } -int DRM(rmctx)( DRM_OS_IOCTL ) +int DRM(rmctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG( "%d\n", ctx.handle ); if ( ctx.handle != DRM_KERNEL_CONTEXT ) { @@ -387,7 +386,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (test_and_set_bit(0, &dev->context_flag)) { DRM_ERROR("Reentering -- FIXME\n"); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } #if __HAVE_DMA_HISTOGRAM @@ -398,7 +397,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (new >= dev->queue_count) { clear_bit(0, &dev->context_flag); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (new == dev->last_context) { @@ -411,7 +410,7 @@ int DRM(context_switch)(drm_device_t *dev, int old, int new) if (atomic_read(&q->use_count) == 1) { atomic_dec(&q->use_count); clear_bit(0, &dev->context_flag); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM(flags) & DRM_FLAG_NOCTX) { @@ -450,7 +449,7 @@ int DRM(context_switch_complete)(drm_device_t *dev, int new) #endif clear_bit(0, &dev->context_flag); - DRM_OS_WAKEUP_INT(&dev->context_wait); + DRM_WAKEUP_INT(&dev->context_wait); return 0; } @@ -514,7 +513,7 @@ static int DRM(alloc_queue)(drm_device_t *dev) atomic_dec(&dev->queuelist[i]->use_count); } /* Allocate a new queue */ - DRM_OS_LOCK; + DRM_LOCK; queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); memset(queue, 0, sizeof(*queue)); @@ -532,19 +531,19 @@ static int DRM(alloc_queue)(drm_device_t *dev) newslots, DRM_MEM_QUEUES); if (!dev->queuelist) { - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG("out of memory\n"); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } } dev->queuelist[dev->queue_count-1] = queue; - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG("%d (new)\n", dev->queue_count - 1); return dev->queue_count - 1; } -int DRM(resctx)( DRM_OS_IOCTL ) +int DRM(resctx)( DRM_IOCTL_ARGS ) { drm_ctx_res_t res; drm_ctx_t ctx; @@ -552,31 +551,31 @@ int DRM(resctx)( DRM_OS_IOCTL ) DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - DRM_OS_KRNFROMUSR( res, (drm_ctx_res_t *)data, sizeof(res) ); + DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) ); if (res.count >= DRM_RESERVED_CONTEXTS) { memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if (DRM_OS_COPYTOUSR(&res.contexts[i], + if (DRM_COPY_TO_USER(&res.contexts[i], &i, sizeof(i))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); } } res.count = DRM_RESERVED_CONTEXTS; - DRM_OS_KRNTOUSR( (drm_ctx_res_t *)data, res, sizeof(res) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) ); return 0; } -int DRM(addctx)( DRM_OS_IOCTL ) +int DRM(addctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { /* Init kernel's context and get a new one. */ @@ -586,35 +585,35 @@ int DRM(addctx)( DRM_OS_IOCTL ) DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); DRM_DEBUG("%d\n", ctx.handle); - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(modctx)( DRM_OS_IOCTL ) +int DRM(modctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); if (ctx.handle < 0 || ctx.handle >= dev->queue_count) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM_BUFCOUNT(&q->waitlist)) { atomic_dec(&q->use_count); - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); } q->flags = ctx.flags; @@ -623,52 +622,52 @@ int DRM(modctx)( DRM_OS_IOCTL ) return 0; } -int DRM(getctx)( DRM_OS_IOCTL ) +int DRM(getctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); if (ctx.handle >= dev->queue_count) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } ctx.flags = q->flags; atomic_dec(&q->use_count); - DRM_OS_KRNTOUSR( (drm_ctx_t *)data, ctx, sizeof(ctx) ); + DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) ); return 0; } -int DRM(switchctx)( DRM_OS_IOCTL ) +int DRM(switchctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); return DRM(context_switch)(dev, dev->last_context, ctx.handle); } -int DRM(newctx)( DRM_OS_IOCTL ) +int DRM(newctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); DRM(context_switch_complete)(dev, ctx.handle); @@ -676,25 +675,25 @@ int DRM(newctx)( DRM_OS_IOCTL ) return 0; } -int DRM(rmctx)( DRM_OS_IOCTL ) +int DRM(rmctx)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_ctx_t ctx; drm_queue_t *q; drm_buf_t *buf; - DRM_OS_KRNFROMUSR( ctx, (drm_ctx_t *)data, sizeof(ctx) ); + DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) ); DRM_DEBUG("%d\n", ctx.handle); - if (ctx.handle >= dev->queue_count) DRM_OS_RETURN(EINVAL); + if (ctx.handle >= dev->queue_count) return DRM_ERR(EINVAL); q = dev->queuelist[ctx.handle]; atomic_inc(&q->use_count); if (atomic_read(&q->use_count) == 1) { /* No longer in use */ atomic_dec(&q->use_count); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } atomic_inc(&q->finalization); /* Mark queue in finalization state */ @@ -717,7 +716,7 @@ int DRM(rmctx)( DRM_OS_IOCTL ) /* Wakeup blocked processes */ wakeup( &q->block_read ); wakeup( &q->block_write ); - DRM_OS_WAKEUP_INT( &q->flush_queue ); + DRM_WAKEUP_INT( &q->flush_queue ); /* Finalization over. Queue is made available when both use_count and finalization become 0, which won't diff --git a/bsd/drm_dma.h b/bsd/drm_dma.h index 7c31a6e2..3e4a5e17 100644 --- a/bsd/drm_dma.h +++ b/bsd/drm_dma.h @@ -29,10 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - #include "drmP.h" #ifndef __HAVE_DMA_WAITQUEUE @@ -59,7 +55,7 @@ int DRM(dma_setup)( drm_device_t *dev ) dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER ); if ( !dev->dma ) - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); memset( dev->dma, 0, sizeof(*dev->dma) ); @@ -85,8 +81,8 @@ void DRM(dma_takedown)(drm_device_t *dev) dma->bufs[i].buf_count, dma->bufs[i].seg_count); for (j = 0; j < dma->bufs[i].seg_count; j++) { - DRM(free_pages)(dma->bufs[i].seglist[j], - dma->bufs[i].page_order, + DRM(free)((void *)dma->bufs[i].seglist[j], + dma->bufs[i].buf_size, DRM_MEM_DMA); } DRM(free)(dma->bufs[i].seglist, @@ -197,7 +193,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) #endif if ( buf->dma_wait ) { - wakeup( &buf->dma_wait ); + wakeup( (void *)&buf->dma_wait ); buf->dma_wait = 0; } #if __HAVE_DMA_FREELIST @@ -248,7 +244,7 @@ void DRM(clear_next_buffer)(drm_device_t *dev) dma->next_buffer = NULL; if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) { - DRM_OS_WAKEUP_INT(&dma->next_queue->flush_queue); + DRM_WAKEUP_INT(&dma->next_queue->flush_queue); } dma->next_queue = NULL; } @@ -340,7 +336,7 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) if (!_DRM_LOCK_IS_HELD(context)) { DRM_ERROR("No lock held during \"while locked\"" " request\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (d->context != _DRM_LOCKING_CONTEXT(context) && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) { @@ -348,7 +344,7 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) " \"while locked\" request\n", _DRM_LOCKING_CONTEXT(context), d->context); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } q = dev->queuelist[DRM_KERNEL_CONTEXT]; while_locked = 1; @@ -378,19 +374,19 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) atomic_dec(&q->use_count); DRM_ERROR("Index %d (of %d max)\n", d->send_indices[i], dma->buf_count - 1); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf = dma->buflist[ idx ]; - if (buf->pid != DRM_OS_CURRENTPID) { + if (buf->pid != DRM_CURRENTPID) { atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer owned by %d\n", - DRM_OS_CURRENTPID, buf->pid); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, buf->pid); + return DRM_ERR(EINVAL); } if (buf->list != DRM_LIST_NONE) { atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer %d on list %d\n", - DRM_OS_CURRENTPID, buf->idx, buf->list); + DRM_CURRENTPID, buf->idx, buf->list); } buf->used = d->send_sizes[i]; buf->while_locked = while_locked; @@ -403,14 +399,14 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) DRM_ERROR("Queueing pending buffer:" " buffer %d, offset %d\n", d->send_indices[i], i); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (buf->waiting) { atomic_dec(&q->use_count); DRM_ERROR("Queueing waiting buffer:" " buffer %d, offset %d\n", d->send_indices[i], i); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } buf->waiting = 1; if (atomic_read(&q->use_count) == 1 @@ -444,16 +440,16 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, buf->waiting, buf->pending); } - buf->pid = DRM_OS_CURRENTPID; - if (DRM_OS_COPYTOUSR(&d->request_indices[i], + buf->pid = DRM_CURRENTPID; + if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); - if (DRM_OS_COPYTOUSR(&d->request_sizes[i], + if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - DRM_OS_RETURN(EFAULT); + return DRM_ERR(EFAULT); ++d->granted_count; } @@ -511,15 +507,15 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) int retcode; if ( !irq ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); - DRM_OS_LOCK; + DRM_LOCK; if ( dev->irq ) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EBUSY); + DRM_UNLOCK; + return DRM_ERR(EBUSY); } dev->irq = irq; - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); @@ -548,10 +544,10 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, DRM(dma_service), dev, &dev->irqh); if ( retcode ) { - DRM_OS_LOCK; + DRM_LOCK; bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irqr); dev->irq = 0; - DRM_OS_UNLOCK; + DRM_UNLOCK; return retcode; } @@ -565,13 +561,13 @@ int DRM(irq_uninstall)( drm_device_t *dev ) { int irq; - DRM_OS_LOCK; + DRM_LOCK; irq = dev->irq; dev->irq = 0; - DRM_OS_UNLOCK; + DRM_UNLOCK; if ( !irq ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); @@ -583,12 +579,12 @@ int DRM(irq_uninstall)( drm_device_t *dev ) return 0; } -int DRM(control)( DRM_OS_IOCTL ) +int DRM(control)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_control_t ctl; - DRM_OS_KRNFROMUSR( ctl, (drm_control_t *) data, sizeof(ctl) ); + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); switch ( ctl.func ) { case DRM_INST_HANDLER: @@ -596,25 +592,24 @@ int DRM(control)( DRM_OS_IOCTL ) case DRM_UNINST_HANDLER: return DRM(irq_uninstall)( dev ); default: - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } } #else -int DRM(control)( DRM_OS_IOCTL ) +int DRM(control)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; drm_control_t ctl; - DRM_OS_KRNFROMUSR( ctl, (drm_control_t *) data, sizeof(ctl) ); + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); switch ( ctl.func ) { case DRM_INST_HANDLER: case DRM_UNINST_HANDLER: return 0; default: - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } } diff --git a/bsd/drm_drawable.h b/bsd/drm_drawable.h index f57d8628..30841067 100644 --- a/bsd/drm_drawable.h +++ b/bsd/drm_drawable.h @@ -29,22 +29,21 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -int DRM(adddraw)( DRM_OS_IOCTL ) +int DRM(adddraw)( DRM_IOCTL_ARGS ) { drm_draw_t draw; draw.handle = 0; /* NOOP */ DRM_DEBUG("%d\n", draw.handle); - DRM_OS_KRNTOUSR( (drm_draw_t *)data, draw, sizeof(draw) ); + DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) ); return 0; } -int DRM(rmdraw)( DRM_OS_IOCTL ) +int DRM(rmdraw)( DRM_IOCTL_ARGS ) { return 0; /* NOOP */ } diff --git a/bsd/drm_drv.h b/bsd/drm_drv.h index ee5e3fbe..8d75e698 100644 --- a/bsd/drm_drv.h +++ b/bsd/drm_drv.h @@ -116,16 +116,8 @@ #define DRIVER_IOCTLS #endif #ifndef DRIVER_FOPS -#if DRM_LINUX -#include <sys/file.h> -#include <sys/proc.h> -#include <machine/../linux/linux.h> -#include <machine/../linux/linux_proto.h> -#include "drm_linux.h" -#endif #endif - /* * The default number of instances (minor numbers) to initialize. */ @@ -133,9 +125,15 @@ #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)) @@ -146,11 +144,13 @@ MODULE_DEPEND(DRIVER_NAME, agp, 1, 1, 1); #if DRM_LINUX MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); #endif +#endif /* __FreeBSD__ */ -static drm_device_t *DRM(device); -static int *DRM(minor); -static int DRM(numdevs) = 0; - +#ifdef __NetBSD__ +#define CDEV_MAJOR 90 +#define DRIVER_SOFTC(unit) \ + ((drm_device_t *) device_lookup(&DRM(_cd), unit)) +#endif /* __NetBSD__ */ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, @@ -212,7 +212,7 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, #endif -#if __REALLY_HAVE_SG +#if __HAVE_SG [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 }, #endif @@ -222,28 +222,18 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) ) +const char *DRM(find_description)(int vendor, int device); +#ifdef __FreeBSD__ static int DRM(probe)(device_t dev) { - const char *s = 0; + const char *s = NULL; int pciid=pci_get_devid(dev); int vendor = (pciid & 0x0000ffff); int device = (pciid & 0xffff0000) >> 16; - int i=0, done=0; - DRM_INFO("Checking PCI vendor=%d, device=%d\n", vendor, device); - while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) { - if ( (DRM(devicelist)[i].vendor == vendor) && - (DRM(devicelist)[i].device == device) ) { - done=1; - if ( DRM(devicelist)[i].supported ) - s = DRM(devicelist)[i].name; - else - DRM_INFO("%s not supported\n", DRM(devicelist)[i].name); - } - i++; - } + s = DRM(find_description)(vendor, device); if (s) { device_set_desc(dev, s); return 0; @@ -262,7 +252,6 @@ static int DRM(detach)(device_t dev) DRM(cleanup)(dev); return 0; } - static device_method_t DRM(methods)[] = { /* Device interface */ DEVMETHOD(device_probe, DRM( probe)), @@ -301,6 +290,78 @@ static struct cdevsw 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(probe)(struct device *parent, struct cfdata *match, void *aux) +{ + 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; + return 0; +} + +void DRM(attach)(struct device *parent, struct device *self, void *aux) +{ + struct pci_attach_args *pa = aux; + drm_device_t *dev = (drm_device_t *)self; + + memcpy(&dev->pa, aux, sizeof(dev->pa)); +
+ DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id))); + DRM(init)(dev); +} + +int DRM(detach)(struct device *self, int flags) +{ + DRM(cleanup)((drm_device_t *)self); + return 0; +} + +int DRM(activate)(struct device *self, enum devact act) +{ + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: + /* FIXME */ + break; + } + return (0); +} + +#endif + +const char *DRM(find_description)(int vendor, int device) { + const char *s = NULL; + int i=0, done=0; + + while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) { + if ( (DRM(devicelist)[i].vendor == vendor) && + (DRM(devicelist)[i].device == device) ) { + done=1; + if ( DRM(devicelist)[i].supported ) + s = DRM(devicelist)[i].name; + else + DRM_INFO("%s not supported\n", DRM(devicelist)[i].name); + } + i++; + } + return s; +} + static int DRM(setup)( drm_device_t *dev ) { int i; @@ -365,7 +426,7 @@ static int DRM(setup)( drm_device_t *dev ) dev->maplist = DRM(alloc)(sizeof(*dev->maplist), DRM_MEM_MAPS); - if(dev->maplist == NULL) DRM_OS_RETURN(ENOMEM); + if(dev->maplist == NULL) return DRM_ERR(ENOMEM); memset(dev->maplist, 0, sizeof(*dev->maplist)); TAILQ_INIT(dev->maplist); dev->map_count = 0; @@ -397,7 +458,11 @@ static int DRM(setup)( drm_device_t *dev ) dev->buf_rp = dev->buf; dev->buf_wp = dev->buf; dev->buf_end = dev->buf + DRM_BSZ; +#ifdef __FreeBSD__ dev->buf_sigio = NULL; +#elif defined(__NetBSD__) + dev->buf_pgid = 0; +#endif dev->buf_readers = 0; dev->buf_writers = 0; dev->buf_selecting = 0; @@ -430,7 +495,7 @@ static int DRM(takedown)( drm_device_t *dev ) if ( dev->irq ) DRM(irq_uninstall)( dev ); #endif - DRM_OS_LOCK; + DRM_LOCK; callout_stop( &dev->timer ); if ( dev->devname ) { @@ -495,18 +560,36 @@ static int DRM(takedown)( drm_device_t *dev ) #if __REALLY_HAVE_MTRR if ( map->mtrr >= 0 ) { int retcode; - retcode = mtrr_del( map->mtrr, - map->offset, - map->size ); +#ifdef __FreeBSD__ + int act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = map->offset; + mrdesc.mr_len = map->size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + map->mtrr=1; +#elif defined __NetBSD__ + struct mtrr mtrrmap; + int one = 1; + mtrrmap.base = map->offset; + 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 ); break; case _DRM_SHM: - DRM(free_pages)((unsigned long)map->handle, - DRM(order)(map->size) - - PAGE_SHIFT, + DRM(free)(map->handle, + map->size, DRM_MEM_SAREA); break; @@ -560,206 +643,190 @@ static int DRM(takedown)( drm_device_t *dev ) if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ dev->lock.pid = 0; - DRM_OS_WAKEUP_INT(&dev->lock.lock_queue); + DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } - DRM_OS_UNLOCK; + DRM_UNLOCK; return 0; } -/* - * Figure out how many instances to initialize. - */ -static int drm_count_cards(void) -{ - int num = 0; -#if defined(DRIVER_CARD_LIST) - int i; - drm_pci_list_t *l; - u16 device, vendor; - struct pci_dev *pdev = NULL; -#endif - - DRM_DEBUG( "\n" ); - -#if defined(DRIVER_COUNT_CARDS) - num = DRIVER_COUNT_CARDS(); -#elif defined(DRIVER_CARD_LIST) - for (i = 0, l = DRIVER_CARD_LIST; l[i].vendor != 0; i++) { - pdev = NULL; - vendor = l[i].vendor; - device = l[i].device; - if(device == 0xffff) device = PCI_ANY_ID; - if(vendor == 0xffff) vendor = PCI_ANY_ID; - while ((pdev = pci_find_device(vendor, device, pdev))) { - num++; /* FIXME: What about two cards of the same device id? */ - } - } -#else - num = DRIVER_NUM_CARDS; -#endif - DRM_DEBUG("numdevs = %d\n", num); - return num; -} - -/* drm_init is called via init_module at module load time, or via - * linux/init/main.c (this is not currently supported). +/* linux: drm_init is called via init_module at module load time, or via + * 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; - int i; +#endif #if __HAVE_CTX_BITMAP int retcode; #endif DRM_DEBUG( "\n" ); - -#ifdef MODULE - DRM(parse_options)( drm_opts ); -#endif - - DRM(numdevs) = drm_count_cards(); - /* Force at least one instance. */ - if (DRM(numdevs) <= 0) - DRM(numdevs) = 1; - - DRM(device) = DRM_OS_MALLOC(sizeof(*DRM(device)) * DRM(numdevs)); - if (!DRM(device)) { - DRM_OS_RETURN(ENOMEM); - } - DRM(minor) = DRM_OS_MALLOC(sizeof(*(DRM(minor))) * DRM(numdevs)); - if (!DRM(minor)) { - DRM_OS_FREE(DRM(device)); - DRM_OS_RETURN(ENOMEM); - } - DRIVER_PREINIT(); - - for (i = 0; i < DRM(numdevs); i++) { - int unit = device_get_unit(nbdev); - /* FIXME??? - multihead !!! */ - dev = device_get_softc(nbdev); - memset( (void *)dev, 0, sizeof(*dev) ); - DRM(minor)[i]=unit; - DRM_OS_SPININIT(dev->count_lock, "drm device"); - lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); - dev->device = nbdev; - dev->devnode = make_dev( &DRM(cdevsw), - unit, - DRM_DEV_UID, - DRM_DEV_GID, - DRM_DEV_MODE, - "dri/card%d", unit ); - dev->name = DRIVER_NAME; - DRM(mem_init)(); - DRM(sysctl_init)(dev); - TAILQ_INIT(&dev->files); +#ifdef __FreeBSD__ + unit = device_get_unit(nbdev); + dev = device_get_softc(nbdev); + memset( (void *)dev, 0, sizeof(*dev) ); + dev->device = nbdev; + dev->devnode = make_dev( &DRM(cdevsw), + unit, + DRM_DEV_UID, + DRM_DEV_GID, + DRM_DEV_MODE, + "dri/card%d", unit ); +#elif defined(__NetBSD__) + unit = minor(dev->device.dv_unit); +#endif + DRM_SPININIT(dev->count_lock, "drm device"); + lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); + dev->name = DRIVER_NAME; + DRM(mem_init)(); + DRM(sysctl_init)(dev); + TAILQ_INIT(&dev->files); #if __REALLY_HAVE_AGP - dev->agp = DRM(agp_init)(); + dev->agp = DRM(agp_init)(); #if __MUST_HAVE_AGP - if ( dev->agp == NULL ) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); - DRM(takedown)( dev ); - DRM_OS_RETURN(ENOMEM); - } + if ( dev->agp == NULL ) { + DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); #endif + DRM(takedown)( dev ); + return DRM_ERR(ENOMEM); + } +#endif /* __MUST_HAVE_AGP */ #if __REALLY_HAVE_MTRR - if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024, - MTRR_TYPE_WRCOMB, - 1 ); -#endif -#endif + if (dev->agp) { +#ifdef __FreeBSD__ + int retcode = 0, act; + struct mem_range_desc mrdesc; + mrdesc.mr_base = dev->agp->info.ai_aperture_base; + mrdesc.mr_len = dev->agp->info.ai_aperture_size; + mrdesc.mr_flags = MDF_WRITECOMBINE; + act = MEMRANGE_SET_UPDATE; + bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME)); + retcode = mem_range_attr_set(&mrdesc, &act); + dev->agp->agp_mtrr=1; +#elif defined __NetBSD__ + 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; + dev->agp->agp_mtrr = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +#endif /* __NetBSD__ */ + } +#endif /* __REALLY_HAVE_MTRR */ +#endif /* __REALLY_HAVE_AGP */ #if __HAVE_CTX_BITMAP - retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); - DRM(takedown)( dev ); - return retcode; - } + retcode = DRM(ctxbitmap_init)( dev ); + if( retcode ) { + DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); #endif - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - DRM(minor)[i] ); + DRM(takedown)( dev ); + return retcode; } +#endif + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, + unit ); DRIVER_POSTINIT(); return 0; } -/* drm_cleanup is called via cleanup_module at module unload time. +/* linux: drm_cleanup is called via cleanup_module at module unload time. + * 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; - int i; +#endif +#if __REALLY_HAVE_MTRR +#ifdef __NetBSD__ + struct mtrr mtrrmap; + int one = 1; +#endif /* __NetBSD__ */ +#endif /* __REALLY_HAVE_MTRR */ DRM_DEBUG( "\n" ); - for (i = DRM(numdevs) - 1; i >= 0; i--) { - /* FIXME??? - multihead */ - dev = device_get_softc(nbdev); - DRM(sysctl_cleanup)( dev ); - destroy_dev(dev->devnode); +#ifdef __FreeBSD__ + dev = device_get_softc(nbdev); +#endif + DRM(sysctl_cleanup)( dev ); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); +#endif #if __HAVE_CTX_BITMAP - DRM(ctxbitmap_cleanup)( dev ); + DRM(ctxbitmap_cleanup)( dev ); #endif #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR - if ( dev->agp && dev->agp->agp_mtrr >= 0) { - int retval; - retval = mtrr_del( dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024 ); - DRM_DEBUG( "mtrr_del=%d\n", retval ); - } + if ( dev->agp && dev->agp->agp_mtrr >= 0) { +#if defined(__NetBSD__) + mtrrmap.base = dev->agp->info.ai_aperture_base; + mtrrmap.len = dev->agp->info.ai_aperture_size; + mtrrmap.type = 0; + mtrrmap.flags = 0; + retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); +#endif + } #endif - DRM(takedown)( dev ); + DRM(takedown)( dev ); #if __REALLY_HAVE_AGP - if ( dev->agp ) { - DRM(agp_uninit)(); - DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); - dev->agp = NULL; - } -#endif + if ( dev->agp ) { + DRM(agp_uninit)(); + DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS ); + dev->agp = NULL; } +#endif DRIVER_POSTCLEANUP(); - DRM_OS_FREE(DRM(minor)); - DRM_OS_FREE(DRM(device)); - DRM(numdevs) = 0; } -int DRM(version)( DRM_OS_IOCTL ) +int DRM(version)( DRM_IOCTL_ARGS ) { drm_version_t version; int len; - DRM_OS_KRNFROMUSR( version, (drm_version_t *)data, sizeof(version) ); + DRM_COPY_FROM_USER_IOCTL( version, (drm_version_t *)data, sizeof(version) ); #define DRM_COPY( name, value ) \ len = strlen( value ); \ if ( len > name##_len ) len = name##_len; \ name##_len = strlen( value ); \ if ( len && name ) { \ - if ( DRM_OS_COPYTOUSR( name, value, len ) ) \ - DRM_OS_RETURN(EFAULT); \ + if ( DRM_COPY_TO_USER( name, value, len ) ) \ + return DRM_ERR(EFAULT); \ } version.version_major = DRIVER_MAJOR; @@ -770,48 +837,40 @@ int DRM(version)( DRM_OS_IOCTL ) DRM_COPY( version.date, DRIVER_DATE ); DRM_COPY( version.desc, DRIVER_DESC ); - DRM_OS_KRNTOUSR( (drm_version_t *)data, version, sizeof(version) ); + DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) ); return 0; } -int DRM( open)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) +int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_device_t *dev = NULL; int retcode = 0; - int i; - for (i = 0; i < DRM(numdevs); i++) { - /* FIXME ??? - multihead */ - dev = DRIVER_SOFTC(minor(kdev)); - } - if (!dev) { - DRM_OS_RETURN(ENODEV); - } + dev = DRIVER_SOFTC(minor(kdev)); DRM_DEBUG( "open_count = %d\n", dev->open_count ); - device_busy(dev->device); retcode = DRM(open_helper)(kdev, flags, fmt, p, dev); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - DRM_OS_SPINLOCK( &dev->count_lock ); - if ( !dev->open_count++ ) { - DRM_OS_SPINUNLOCK( &dev->count_lock ); - return DRM(setup)( dev ); - } - DRM_OS_SPINUNLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); +#ifdef __FreeBSD__ + device_busy(dev->device); +#endif + if ( !dev->open_count++ ) + retcode = DRM(setup)( dev ); + DRM_SPINUNLOCK( &dev->count_lock ); } - device_unbusy(dev->device); return retcode; } -int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) +int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) { drm_file_t *priv; - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int retcode = 0; DRM_DEBUG( "open_count = %d\n", dev->open_count ); @@ -827,13 +886,18 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) * Begin inline drm_release */ +#ifdef __FreeBSD__ + DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", + DRM_CURRENTPID, (long)dev->device, dev->open_count ); +#elif defined(__NetBSD__) DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", - DRM_OS_CURRENTPID, (long)dev->device, dev->open_count ); + DRM_CURRENTPID, (long)&dev->device, dev->open_count); +#endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_OS_CURRENTPID) { + && dev->lock.pid == DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", - DRM_OS_CURRENTPID, + DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); #if HAVE_DRIVER_RELEASE DRIVER_RELEASE(); @@ -853,7 +917,7 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) for (;;) { if ( !dev->lock.hw_lock ) { /* Device has been unregistered */ - retcode = EINTR; + retcode = DRM_ERR(EINTR); break; } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, @@ -884,9 +948,15 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) DRM(reclaim_buffers)( dev, priv->pid ); #endif +#if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) + funsetown(&dev->buf_sigio); +#elif defined(__FreeBSD__) funsetown(dev->buf_sigio); +#elif defined(__NetBSD__) + dev->buf_pgid = 0; +#endif /* __NetBSD__ */ - DRM_OS_LOCK; + DRM_LOCK; priv = DRM(find_file_by_proc)(dev, p); if (priv) { priv->refs--; @@ -894,7 +964,7 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) TAILQ_REMOVE(&dev->files, priv, link); } } - DRM_OS_UNLOCK; + DRM_UNLOCK; DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); @@ -903,42 +973,48 @@ int DRM( close)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p) */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - DRM_OS_SPINLOCK( &dev->count_lock ); + DRM_SPINLOCK( &dev->count_lock ); +#ifdef __FreeBSD__ + device_unbusy(dev->device); +#endif if ( !--dev->open_count ) { if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) { DRM_ERROR( "Device busy: %ld %d\n", (unsigned long)atomic_read( &dev->ioctl_count ), dev->blocked ); - DRM_OS_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(EBUSY); + DRM_SPINUNLOCK( &dev->count_lock ); + return DRM_ERR(EBUSY); } - DRM_OS_SPINUNLOCK( &dev->count_lock ); - device_unbusy(dev->device); + DRM_SPINUNLOCK( &dev->count_lock ); return DRM(takedown)( dev ); } - DRM_OS_SPINUNLOCK( &dev->count_lock ); - + DRM_SPINUNLOCK( &dev->count_lock ); - DRM_OS_RETURN(retcode); + return retcode; } /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_OS_IOCTL ) +int DRM(ioctl)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; d_ioctl_t *func; int nr = DRM_IOCTL_NR(cmd); - DRM_OS_PRIV; + DRM_PRIV; atomic_inc( &dev->ioctl_count ); atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; +#ifdef __FreeBSD__ + DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", + DRM_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated ); +#elif defined(__NetBSD__) DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n", - DRM_OS_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated ); + DRM_CURRENTPID, cmd, nr, (long)&dev->device, priv->authenticated ); +#endif switch (cmd) { case FIONBIO: @@ -950,6 +1026,7 @@ int DRM(ioctl)( DRM_OS_IOCTL ) dev->flags |= FASYNC; return 0; +#ifdef __FreeBSD__ case FIOSETOWN: atomic_dec(&dev->ioctl_count); return fsetown(*(int *)data, &dev->buf_sigio); @@ -959,6 +1036,18 @@ int DRM(ioctl)( DRM_OS_IOCTL ) *(int *) data = fgetown(dev->buf_sigio); return 0; } +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + case TIOCSPGRP: + atomic_dec(&dev->ioctl_count); + dev->buf_pgid = *(int *)data; + return 0; + + case TIOCGPGRP: + atomic_dec(&dev->ioctl_count); + *(int *)data = dev->buf_pgid; + return 0; +#endif /* __NetBSD__ */ if ( nr >= DRIVER_IOCTL_COUNT ) { retcode = EINVAL; @@ -969,7 +1058,7 @@ int DRM(ioctl)( DRM_OS_IOCTL ) if ( !func ) { DRM_DEBUG( "no function\n" ); retcode = EINVAL; - } else if ( ( ioctl->root_only && DRM_OS_CHECKSUSER ) + } else if ( ( ioctl->root_only && DRM_SUSER(p) ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { @@ -978,12 +1067,12 @@ int DRM(ioctl)( DRM_OS_IOCTL ) } atomic_dec( &dev->ioctl_count ); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } -int DRM(lock)( DRM_OS_IOCTL ) +int DRM(lock)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_lock_t lock; int ret = 0; #if __HAVE_MULTIPLE_DMA_QUEUES @@ -995,24 +1084,24 @@ int DRM(lock)( DRM_OS_IOCTL ) dev->lck_start = start = get_cycles(); #endif - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); if ( lock.context == DRM_KERNEL_CONTEXT ) { DRM_ERROR( "Process %d using kernel context %d\n", - DRM_OS_CURRENTPID, lock.context ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, lock.context ); + return DRM_ERR(EINVAL); } DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock.context, DRM_OS_CURRENTPID, + lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags ); #if __HAVE_DMA_QUEUE if ( lock.context < 0 ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); #elif __HAVE_MULTIPLE_DMA_QUEUES if ( lock.context < 0 || lock.context >= dev->queue_count ) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); q = dev->queuelist[lock.context]; #endif @@ -1028,14 +1117,14 @@ int DRM(lock)( DRM_OS_IOCTL ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_OS_CURRENTPID; + dev->lock.pid = DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ } /* Contention */ - ret = tsleep(&dev->lock.lock_queue, + ret = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, "drmlk2", 0); @@ -1074,21 +1163,21 @@ int DRM(lock)( DRM_OS_IOCTL ) atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); #endif - DRM_OS_RETURN(ret); + return DRM_ERR(ret); } -int DRM(unlock)( DRM_OS_IOCTL ) +int DRM(unlock)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_lock_t lock; - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ) ; + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ) ; if ( lock.context == DRM_KERNEL_CONTEXT ) { DRM_ERROR( "Process %d using kernel context %d\n", - DRM_OS_CURRENTPID, lock.context ); - DRM_OS_RETURN(EINVAL); + DRM_CURRENTPID, lock.context ); + return DRM_ERR(EINVAL); } atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); @@ -1141,7 +1230,7 @@ SYSUNINIT(DRM( unregister), SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_unregister_ * Linux emulation IOCTL */ static int -DRM(linux_ioctl)(DRM_OS_STRUCTPROC *p, struct linux_ioctl_args* args) +DRM(linux_ioctl)(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) { #if (__FreeBSD_version >= 500000) struct file *fp = p->td_proc->p_fd->fd_ofiles[args->fd]; diff --git a/bsd/drm_fops.h b/bsd/drm_fops.h index 53af39cd..ed85a8de 100644 --- a/bsd/drm_fops.h +++ b/bsd/drm_fops.h @@ -30,14 +30,9 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" - -#include <sys/signalvar.h> -#include <sys/poll.h> - -drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_OS_STRUCTPROC *p) +drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 uid_t uid = p->td_proc->p_ucred->cr_svuid; @@ -56,7 +51,7 @@ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_OS_STRUCTPROC *p) /* DRM(open) is called whenever a process opens /dev/drm. */ -int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, +int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, drm_device_t *dev) { int m = minor(kdev); @@ -66,9 +61,9 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, return EBUSY; /* No exclusive opens */ dev->flags = flags; if (!DRM(cpu_valid)()) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); - DRM_DEBUG("pid = %d, minor = %d\n", DRM_OS_CURRENTPID, m); + DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); /* FIXME: linux mallocs and bzeros here */ priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); @@ -89,15 +84,14 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, priv->minor = m; priv->devXX = dev; priv->ioctl_count = 0; - priv->authenticated = !DRM_OS_CHECKSUSER; - lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, p); + priv->authenticated = !DRM_SUSER(p); + DRM_LOCK; TAILQ_INSERT_TAIL(&dev->files, priv, link); - lockmgr(&dev->dev_lock, LK_RELEASE, 0, p); + DRM_UNLOCK; } - +#ifdef __FreeBSD__ kdev->si_drv1 = dev; - - +#endif return 0; } @@ -108,7 +102,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_OS_STRUCTPROC *p, ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag) { - DRM_OS_DEVICE; + DRM_DEVICE; int left; int avail; int send; @@ -156,6 +150,9 @@ int DRM(write_string)(drm_device_t *dev, const char *s) int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ; int send = strlen(s); int count; +#ifdef __NetBSD__ + struct proc *p; +#endif /* __NetBSD__ */ DRM_DEBUG("%d left, %d to send (%p, %p)\n", left, send, dev->buf_rp, dev->buf_wp); @@ -186,19 +183,33 @@ int DRM(write_string)(drm_device_t *dev, const char *s) } DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio); +#ifdef __FreeBSD__ if (dev->buf_sigio) { DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid); +#if __FreeBSD_version >= 500000 + pgsigio(&dev->buf_sigio, SIGIO, 0); +#else pgsigio(dev->buf_sigio, SIGIO, 0); +#endif /* __FreeBSD_version */ } +#endif /* __FreeBSD__ */ +#ifdef __NetBSD__ + if (dev->buf_pgid) { + DRM_DEBUG("dev->buf_pgid=%d\n", dev->buf_pgid); + if(dev->buf_pgid > 0) + 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); return 0; } -int DRM(poll)(dev_t kdev, int events, DRM_OS_STRUCTPROC *p) +int DRM(poll)(dev_t kdev, int events, DRM_STRUCTPROC *p) { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; int s; int revents = 0; @@ -217,7 +228,15 @@ int DRM(poll)(dev_t kdev, int events, DRM_OS_STRUCTPROC *p) int DRM(write)(dev_t kdev, struct uio *uio, int ioflag) { - DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", - curproc->p_pid, ((drm_device_t *)kdev->si_drv1)->device, ((drm_device_t *)kdev->si_drv1)->open_count); - return 0; +#if DRM_DEBUG_CODE + DRM_DEVICE; +#endif +#ifdef __FreeBSD__ + DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", + curproc->p_pid, dev->device, dev->open_count); +#elif defined(__NetBSD__) + DRM_DEBUG("pid = %d, device = %p, open_count = %d\n", + curproc->p_pid, &dev->device, dev->open_count); +#endif + return 0; } diff --git a/bsd/drm_init.h b/bsd/drm_init.h index e2ab6080..adf421a4 100644 --- a/bsd/drm_init.h +++ b/bsd/drm_init.h @@ -29,10 +29,9 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -#if 0 && DRM_DEBUG_CODE +#if 1 && DRM_DEBUG_CODE int DRM(flags) = DRM_FLAG_DEBUG; #else int DRM(flags) = 0; diff --git a/bsd/drm_ioctl.h b/bsd/drm_ioctl.h index 1e8281e6..63562fef 100644 --- a/bsd/drm_ioctl.h +++ b/bsd/drm_ioctl.h @@ -29,20 +29,18 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -#include <sys/bus.h> -#include <pci/pcivar.h> -int DRM(irq_busid)( DRM_OS_IOCTL ) +int DRM(irq_busid)( DRM_IOCTL_ARGS ) { +#ifdef __FreeBSD__ drm_irq_busid_t id; devclass_t pci; device_t bus, dev; device_t *kids; int error, i, num_kids; - DRM_OS_KRNFROMUSR( id, (drm_irq_busid_t *)data, sizeof(id) ); + DRM_COPY_FROM_USER_IOCTL( id, (drm_irq_busid_t *)data, sizeof(id) ); pci = devclass_find("pci"); if (!pci) @@ -71,49 +69,53 @@ int DRM(irq_busid)( DRM_OS_IOCTL ) DRM_DEBUG("%d:%d:%d => IRQ %d\n", id.busnum, id.devnum, id.funcnum, id.irq); - DRM_OS_KRNTOUSR( (drm_irq_busid_t *)data, id, sizeof(id) ); + DRM_COPY_TO_USER_IOCTL( (drm_irq_busid_t *)data, id, sizeof(id) ); return 0; +#else + /* don't support interrupt-driven drivers on Net yet */ + return ENOENT; +#endif } -int DRM(getunique)( DRM_OS_IOCTL ) +int DRM(getunique)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_unique_t u; - DRM_OS_KRNFROMUSR( u, (drm_unique_t *)data, sizeof(u) ); + DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) ); if (u.unique_len >= dev->unique_len) { - if (DRM_OS_COPYTOUSR(u.unique, dev->unique, dev->unique_len)) - DRM_OS_RETURN(EFAULT); + if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len)) + return DRM_ERR(EFAULT); } u.unique_len = dev->unique_len; - DRM_OS_KRNTOUSR( (drm_unique_t *)data, u, sizeof(u) ); + DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) ); return 0; } -int DRM(setunique)( DRM_OS_IOCTL ) +int DRM(setunique)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_unique_t u; if (dev->unique_len || dev->unique) - DRM_OS_RETURN(EBUSY); + return DRM_ERR(EBUSY); - DRM_OS_KRNFROMUSR( u, (drm_unique_t *)data, sizeof(u) ); + DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) ); if (!u.unique_len || u.unique_len > 1024) - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); dev->unique_len = u.unique_len; dev->unique = DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER); - if(!dev->unique) DRM_OS_RETURN(ENOMEM); + if(!dev->unique) return DRM_ERR(ENOMEM); - if (DRM_OS_COPYFROMUSR(dev->unique, u.unique, dev->unique_len)) - DRM_OS_RETURN(EFAULT); + if (DRM_COPY_FROM_USER(dev->unique, u.unique, dev->unique_len)) + return DRM_ERR(EFAULT); dev->unique[dev->unique_len] = '\0'; @@ -121,7 +123,7 @@ int DRM(setunique)( DRM_OS_IOCTL ) DRM_MEM_DRIVER); if(!dev->devname) { DRM(free)(dev->devname, sizeof(*dev->devname), DRM_MEM_DRIVER); - DRM_OS_RETURN(ENOMEM); + return DRM_ERR(ENOMEM); } sprintf(dev->devname, "%s@%s", dev->name, dev->unique); @@ -130,23 +132,23 @@ int DRM(setunique)( DRM_OS_IOCTL ) } -int DRM(getmap)( DRM_OS_IOCTL ) +int DRM(getmap)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_map_t map; drm_map_t *mapinlist; drm_map_list_entry_t *list; int idx; int i = 0; - DRM_OS_KRNFROMUSR( map, (drm_map_t *)data, sizeof(map) ); + DRM_COPY_FROM_USER_IOCTL( map, (drm_map_t *)data, sizeof(map) ); idx = map.offset; - DRM_OS_LOCK; + DRM_LOCK; if (idx < 0 || idx >= dev->map_count) { - DRM_OS_UNLOCK; - DRM_OS_RETURN(EINVAL); + DRM_UNLOCK; + return DRM_ERR(EINVAL); } TAILQ_FOREACH(list, dev->maplist, link) { @@ -163,28 +165,28 @@ int DRM(getmap)( DRM_OS_IOCTL ) i++; } - DRM_OS_UNLOCK; + DRM_UNLOCK; if (!list) return EINVAL; - DRM_OS_KRNTOUSR( (drm_map_t *)data, map, sizeof(map) ); + DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, map, sizeof(map) ); return 0; } -int DRM(getclient)( DRM_OS_IOCTL ) +int DRM(getclient)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_client_t client; drm_file_t *pt; int idx; int i = 0; - DRM_OS_KRNFROMUSR( client, (drm_client_t *)data, sizeof(client) ); + DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) ); idx = client.idx; - DRM_OS_LOCK; + DRM_LOCK; TAILQ_FOREACH(pt, &dev->files, link) { if (i==idx) { @@ -193,29 +195,29 @@ int DRM(getclient)( DRM_OS_IOCTL ) client.uid = pt->uid; client.magic = pt->magic; client.iocs = pt->ioctl_count; - DRM_OS_UNLOCK; + DRM_UNLOCK; *(drm_client_t *)data = client; return 0; } i++; } - DRM_OS_UNLOCK; + DRM_UNLOCK; - DRM_OS_KRNTOUSR( (drm_client_t *)data, client, sizeof(client) ); + DRM_COPY_TO_USER_IOCTL( (drm_client_t *)data, client, sizeof(client) ); return 0; } -int DRM(getstats)( DRM_OS_IOCTL ) +int DRM(getstats)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_stats_t stats; int i; memset(&stats, 0, sizeof(stats)); - DRM_OS_LOCK; + DRM_LOCK; for (i = 0; i < dev->counters; i++) { if (dev->types[i] == _DRM_STAT_LOCK) @@ -229,9 +231,9 @@ int DRM(getstats)( DRM_OS_IOCTL ) stats.count = dev->counters; - DRM_OS_UNLOCK; + DRM_UNLOCK; - DRM_OS_KRNTOUSR( (drm_stats_t *)data, stats, sizeof(stats) ); + DRM_COPY_TO_USER_IOCTL( (drm_stats_t *)data, stats, sizeof(stats) ); return 0; } diff --git a/bsd/drm_lists.h b/bsd/drm_lists.h index 682f56b0..1ab55f90 100644 --- a/bsd/drm_lists.h +++ b/bsd/drm_lists.h @@ -29,7 +29,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" #if __HAVE_DMA_WAITLIST @@ -37,12 +36,12 @@ int DRM(waitlist_create)(drm_waitlist_t *bl, int count) { if (bl->count) - DRM_OS_RETURN( EINVAL ); + return DRM_ERR( EINVAL ); bl->bufs = DRM(alloc)((bl->count + 2) * sizeof(*bl->bufs), DRM_MEM_BUFLISTS); - if(!bl->bufs) DRM_OS_RETURN(ENOMEM); + if(!bl->bufs) return DRM_ERR(ENOMEM); memset(bl->bufs, 0, sizeof(*bl->bufs)); @@ -50,15 +49,15 @@ int DRM(waitlist_create)(drm_waitlist_t *bl, int count) bl->rp = bl->bufs; bl->wp = bl->bufs; bl->end = &bl->bufs[bl->count+1]; - DRM_OS_SPININIT( bl->write_lock, "writelock" ); - DRM_OS_SPININIT( bl->read_lock, "readlock" ); + DRM_SPININIT( bl->write_lock, "writelock" ); + DRM_SPININIT( bl->read_lock, "readlock" ); return 0; } int DRM(waitlist_destroy)(drm_waitlist_t *bl) { if (bl->rp != bl->wp) - DRM_OS_RETURN( EINVAL ); + return DRM_ERR( EINVAL ); if (bl->bufs) DRM(free)(bl->bufs, (bl->count + 2) * sizeof(*bl->bufs), DRM_MEM_BUFLISTS); @@ -78,19 +77,19 @@ int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf) if (!left) { DRM_ERROR("Overflow while adding buffer %d from pid %d\n", buf->idx, buf->pid); - DRM_OS_RETURN( EINVAL ); + return DRM_ERR( EINVAL ); } #if __HAVE_DMA_HISTOGRAM getnanotime(&buf->time_queued); #endif buf->list = DRM_LIST_WAIT; - DRM_OS_SPINLOCK(&bl->write_lock); + DRM_SPINLOCK(&bl->write_lock); s = spldrm(); *bl->wp = buf; if (++bl->wp >= bl->end) bl->wp = bl->bufs; splx(s); - DRM_OS_SPINUNLOCK(&bl->write_lock); + DRM_SPINUNLOCK(&bl->write_lock); return 0; } @@ -100,17 +99,17 @@ drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl) drm_buf_t *buf; int s; - DRM_OS_SPINLOCK(&bl->read_lock); + DRM_SPINLOCK(&bl->read_lock); s = spldrm(); buf = *bl->rp; if (bl->rp == bl->wp) { splx(s); - DRM_OS_SPINUNLOCK(&bl->read_lock); + DRM_SPINUNLOCK(&bl->read_lock); return NULL; } if (++bl->rp >= bl->end) bl->rp = bl->bufs; splx(s); - DRM_OS_SPINUNLOCK(&bl->read_lock); + DRM_SPINUNLOCK(&bl->read_lock); return buf; } @@ -129,7 +128,7 @@ int DRM(freelist_create)(drm_freelist_t *bl, int count) bl->low_mark = 0; bl->high_mark = 0; atomic_set(&bl->wfh, 0); - DRM_OS_SPININIT( bl->lock, "freelistlock" ); + DRM_SPININIT( bl->lock, "freelistlock" ); ++bl->initialized; return 0; } @@ -161,10 +160,10 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) #endif buf->list = DRM_LIST_FREE; - DRM_OS_SPINLOCK( &bl->lock ); + DRM_SPINLOCK( &bl->lock ); buf->next = bl->next; bl->next = buf; - DRM_OS_SPINUNLOCK( &bl->lock ); + DRM_SPINUNLOCK( &bl->lock ); atomic_inc(&bl->count); if (atomic_read(&bl->count) > dma->buf_count) { @@ -176,7 +175,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_OS_WAKEUP_INT(&bl->waiting); + DRM_WAKEUP_INT(&bl->waiting); } return 0; } @@ -188,14 +187,14 @@ static drm_buf_t *DRM(freelist_try)(drm_freelist_t *bl) if (!bl) return NULL; /* Get buffer */ - DRM_OS_SPINLOCK(&bl->lock); + DRM_SPINLOCK(&bl->lock); if (!bl->next) { - DRM_OS_SPINUNLOCK(&bl->lock); + DRM_SPINUNLOCK(&bl->lock); return NULL; } buf = bl->next; bl->next = bl->next->next; - DRM_OS_SPINUNLOCK(&bl->lock); + DRM_SPINUNLOCK(&bl->lock); atomic_dec(&bl->count); buf->next = NULL; diff --git a/bsd/drm_lock.h b/bsd/drm_lock.h index 863a228c..5e9294bc 100644 --- a/bsd/drm_lock.h +++ b/bsd/drm_lock.h @@ -29,16 +29,15 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -int DRM(block)( DRM_OS_IOCTL ) +int DRM(block)( DRM_IOCTL_ARGS ) { DRM_DEBUG("\n"); return 0; } -int DRM(unblock)( DRM_OS_IOCTL ) +int DRM(unblock)( DRM_IOCTL_ARGS ) { DRM_DEBUG("\n"); return 0; @@ -109,7 +108,7 @@ int DRM(lock_free)(drm_device_t *dev, pid); return 1; } - DRM_OS_WAKEUP_INT(&dev->lock.lock_queue); + DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); return 0; } @@ -125,7 +124,7 @@ static int DRM(flush_queue)(drm_device_t *dev, int context) if (atomic_read(&q->use_count) > 1) { atomic_inc(&q->block_write); atomic_inc(&q->block_count); - error = tsleep(&q->flush_queue, PZERO|PCATCH, "drmfq", 0); + error = tsleep((void *)&q->flush_queue, PZERO|PCATCH, "drmfq", 0); if (error) return error; atomic_dec(&q->block_count); @@ -147,7 +146,7 @@ static int DRM(flush_unblock_queue)(drm_device_t *dev, int context) if (atomic_read(&q->use_count) > 1) { if (atomic_read(&q->block_write)) { atomic_dec(&q->block_write); - DRM_OS_WAKEUP_INT(&q->write_queue); + DRM_WAKEUP_INT((void *)&q->write_queue); } } atomic_dec(&q->use_count); @@ -194,15 +193,15 @@ int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags) return ret; } -int DRM(finish)( DRM_OS_IOCTL ) +int DRM(finish)( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; int ret = 0; drm_lock_t lock; DRM_DEBUG("\n"); - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *)data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags); DRM(flush_unblock)(dev, lock.context, lock.flags); diff --git a/bsd/drm_memory.h b/bsd/drm_memory.h index 97f2bb81..f7dc547a 100644 --- a/bsd/drm_memory.h +++ b/bsd/drm_memory.h @@ -29,20 +29,16 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "drmP.h" -#include <vm/vm.h> -#include <vm/pmap.h> -#if __REALLY_HAVE_AGP -#include <sys/agpio.h> -#endif +#ifdef __FreeBSD__ #define malloctype DRM(M_DRM) /* The macros confliced in the MALLOC_DEFINE */ MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures"); #undef malloctype +#endif typedef struct drm_mem_stats { const char *name; @@ -53,7 +49,7 @@ typedef struct drm_mem_stats { unsigned long bytes_freed; } drm_mem_stats_t; -static DRM_OS_SPINTYPE DRM(mem_lock); +static DRM_SPINTYPE DRM(mem_lock); static unsigned long DRM(ram_available) = 0; /* In pages */ static unsigned long DRM(ram_used) = 0; static drm_mem_stats_t DRM(mem_stats)[] = { @@ -85,7 +81,7 @@ void DRM(mem_init)(void) { drm_mem_stats_t *mem; - DRM_OS_SPININIT(DRM(mem_lock), "drm memory"); + DRM_SPININIT(DRM(mem_lock), "drm memory"); for (mem = DRM(mem_stats); mem->name; ++mem) { mem->succeed_count = 0; @@ -99,8 +95,8 @@ void DRM(mem_init)(void) DRM(ram_used) = 0; } +#ifdef __FreeBSD__ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ - static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS { drm_mem_stats_t *pt; @@ -137,11 +133,12 @@ int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS { int ret; - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ret = DRM(_mem_info)(oidp, arg1, arg2, req); - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return ret; } +#endif void *DRM(alloc)(size_t size, int area) { @@ -152,16 +149,20 @@ void *DRM(alloc)(size_t size, int area) return NULL; } +#ifdef __FreeBSD__ if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); +#elif defined(__NetBSD__) + if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) { +#endif + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[area].succeed_count; DRM(mem_stats)[area].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } @@ -203,70 +204,23 @@ void DRM(free)(void *pt, size_t size, int area) int free_count; if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); - else free(pt, DRM(M_DRM)); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + else +#ifdef __FreeBSD__ + free(pt, DRM(M_DRM)); +#elif defined(__NetBSD__) + free(pt, M_DEVBUF); +#endif + DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[area].bytes_freed += size; free_count = ++DRM(mem_stats)[area].free_count; alloc_count = DRM(mem_stats)[area].succeed_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", free_count, alloc_count); } } -unsigned long DRM(alloc_pages)(int order, int area) -{ - vm_offset_t address; - unsigned long bytes = PAGE_SIZE << order; - - - address = (vm_offset_t) contigmalloc(bytes, DRM(M_DRM), M_WAITOK, 0, ~0, 1, 0); - if (!address) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); - ++DRM(mem_stats)[area].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - return 0; - } - DRM_OS_SPINLOCK(&DRM(mem_lock)); - ++DRM(mem_stats)[area].succeed_count; - DRM(mem_stats)[area].bytes_allocated += bytes; - DRM(ram_used) += bytes; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - - - /* Zero outside the lock */ - memset((void *)address, 0, bytes); - - - return address; -} - -void DRM(free_pages)(unsigned long address, int order, int area) -{ - unsigned long bytes = PAGE_SIZE << order; - int alloc_count; - int free_count; - - if (!address) { - DRM_MEM_ERROR(area, "Attempt to free address 0\n"); - } else { - contigfree((void *) address, bytes, DRM(M_DRM)); - } - - DRM_OS_SPINLOCK(&DRM(mem_lock)); - free_count = ++DRM(mem_stats)[area].free_count; - alloc_count = DRM(mem_stats)[area].succeed_count; - DRM(mem_stats)[area].bytes_freed += bytes; - DRM(ram_used) -= bytes; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - if (free_count > alloc_count) { - DRM_MEM_ERROR(area, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } -} - void *DRM(ioremap)(unsigned long offset, unsigned long size) { void *pt; @@ -278,18 +232,20 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size) } if (!(pt = pmap_mapdev(offset, size))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } +/* unused so far */ +#if 0 void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) { void *pt; @@ -302,17 +258,18 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) /* FIXME FOR BSD */ if (!(pt = ioremap_nocache(offset, size))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return pt; } +#endif void DRM(ioremapfree)(void *pt, unsigned long size) { @@ -325,11 +282,11 @@ void DRM(ioremapfree)(void *pt, unsigned long size) else pmap_unmapdev((vm_offset_t) pt, size); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Excess frees: %d frees, %d allocs\n", @@ -348,16 +305,16 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type) } if ((handle = DRM(agp_allocate_memory)(pages, type))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated += pages << PAGE_SHIFT; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return handle; } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); return NULL; } @@ -369,16 +326,16 @@ int DRM(free_agp)(agp_memory *handle, int pages) if (!handle) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Attempt to free NULL AGP handle\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (DRM(agp_free_memory)(handle)) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count; DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed += pages << PAGE_SHIFT; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Excess frees: %d frees, %d allocs\n", @@ -386,13 +343,13 @@ int DRM(free_agp)(agp_memory *handle, int pages) } return 0; } - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } int DRM(bind_agp)(agp_memory *handle, unsigned int start) { int retcode; - device_t dev = agp_find_device(); + device_t dev = DRM_AGP_FIND_DEVICE(); struct agp_memory_info info; if (!dev) @@ -401,22 +358,22 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start) if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to bind NULL AGP handle\n"); - DRM_OS_RETURN(EINVAL); + return DRM_ERR(EINVAL); } if (!(retcode = DRM(agp_bind_memory)(handle, start))) { - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; agp_memory_info(dev, handle, &info); DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated += info.ami_size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - DRM_OS_RETURN(0); + DRM_SPINUNLOCK(&DRM(mem_lock)); + return DRM_ERR(0); } - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); - DRM_OS_RETURN(retcode); + DRM_SPINUNLOCK(&DRM(mem_lock)); + return DRM_ERR(retcode); } int DRM(unbind_agp)(agp_memory *handle) @@ -424,7 +381,7 @@ int DRM(unbind_agp)(agp_memory *handle) int alloc_count; int free_count; int retcode = EINVAL; - device_t dev = agp_find_device(); + device_t dev = DRM_AGP_FIND_DEVICE(); struct agp_memory_info info; if (!dev) @@ -433,25 +390,25 @@ int DRM(unbind_agp)(agp_memory *handle) if (!handle) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Attempt to unbind NULL AGP handle\n"); - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } agp_memory_info(dev, handle, &info); if ((retcode = DRM(agp_unbind_memory)(handle))) - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); - DRM_OS_SPINLOCK(&DRM(mem_lock)); + DRM_SPINLOCK(&DRM(mem_lock)); free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count; alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count; DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed += info.ami_size; - DRM_OS_SPINUNLOCK(&DRM(mem_lock)); + DRM_SPINUNLOCK(&DRM(mem_lock)); if (free_count > alloc_count) { DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, "Excess frees: %d frees, %d allocs\n", free_count, alloc_count); } - DRM_OS_RETURN(retcode); + return DRM_ERR(retcode); } #endif diff --git a/bsd/drm_os_freebsd.h b/bsd/drm_os_freebsd.h index 72c5baf6..23838139 100644 --- a/bsd/drm_os_freebsd.h +++ b/bsd/drm_os_freebsd.h @@ -12,12 +12,26 @@ #include <sys/uio.h> #include <sys/filio.h> #include <sys/sysctl.h> -#include <sys/select.h> +#include <sys/bus.h> +#include <sys/signalvar.h> +#include <sys/poll.h> #include <vm/vm.h> #include <vm/pmap.h> +#include <vm/vm_extern.h> +#include <vm/vm_map.h> +#include <vm/vm_param.h> +#include <machine/param.h> #include <machine/pmap.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/mman.h> +#include <sys/rman.h> +#include <sys/memrange.h> +#include <pci/pcivar.h> #if __FreeBSD_version >= 500000 #include <sys/selinfo.h> +#else +#include <sys/select.h> #endif #include <sys/bus.h> #if __FreeBSD_version >= 400005 @@ -31,11 +45,27 @@ #define __REALLY_HAVE_AGP __HAVE_AGP #endif -#define __REALLY_HAVE_MTRR 0 -#define __REALLY_HAVE_SG 0 +#define __REALLY_HAVE_MTRR (__HAVE_MTRR) +#define __REALLY_HAVE_SG (__HAVE_SG) #if __REALLY_HAVE_AGP #include <pci/agpvar.h> +#include <sys/agpio.h> +#endif + +#include <opt_drm.h> +#if DRM_DEBUG +#undef DRM_DEBUG_CODE +#define DRM_DEBUG_CODE 2 +#endif +#undef DRM_DEBUG + +#if DRM_LINUX +#include <sys/file.h> +#include <sys/proc.h> +#include <machine/../linux/linux.h> +#include <machine/../linux/linux_proto.h> +#include "drm_linux.h" #endif #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ @@ -43,49 +73,51 @@ #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 145 #if __FreeBSD_version >= 500000 -#define DRM_OS_SPINTYPE struct mtx -#define DRM_OS_SPININIT(l,name) mtx_init(&l, name, MTX_DEF) -#define DRM_OS_SPINLOCK(l) mtx_lock(l) -#define DRM_OS_SPINUNLOCK(u) mtx_unlock(u); -#define DRM_OS_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curthread) -#define DRM_OS_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, curthread) -#define DRM_OS_CURPROC curthread -#define DRM_OS_STRUCTPROC struct thread -#define DRM_OS_CURRENTPID curthread->td_proc->p_pid -#define DRM_OS_IOCTL dev_t kdev, u_long cmd, caddr_t data, int flags, struct thread *p -#define DRM_OS_CHECKSUSER suser(p->td_proc) +#define DRM_CURPROC curthread +#define DRM_STRUCTPROC struct thread +#define DRM_SPINTYPE struct mtx +#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF) +#define DRM_SPINLOCK(l) mtx_lock(l) +#define DRM_SPINUNLOCK(u) mtx_unlock(u); +#define DRM_CURRENTPID curthread->td_proc->p_pid #else -#define DRM_OS_CURPROC curproc -#define DRM_OS_STRUCTPROC struct proc -#define DRM_OS_SPINTYPE struct simplelock -#define DRM_OS_SPININIT(l,name) simple_lock_init(&l) -#define DRM_OS_SPINLOCK(l) simple_lock(l) -#define DRM_OS_SPINUNLOCK(u) simple_unlock(u); -#define DRM_OS_IOCTL dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p -#define DRM_OS_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc) -#define DRM_OS_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc) -#define DRM_OS_CURRENTPID curproc->p_pid -#define DRM_OS_CHECKSUSER suser(p) +#define DRM_CURPROC curproc +#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_SPINUNLOCK(u) simple_unlock(u); +#define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_OS_TASKQUEUE_ARGS void *dev, int pending -#define DRM_OS_IRQ_ARGS void *device -#define DRM_OS_DEVICE drm_device_t *dev = kdev->si_drv1 -#define DRM_OS_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_OS_FREE(pt) free( pt, DRM(M_DRM) ) -#define DRM_OS_VTOPHYS(addr) vtophys(addr) - -#define DRM_OS_PRIV \ +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +#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) +#define DRM_TASKQUEUE_ARGS void *dev, int pending +#define DRM_IRQ_ARGS void *device +#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_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() agp_find_device() +#define DRM_ERR(v) v + +#define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ if (!priv) { \ DRM_DEBUG("can't find authenticator\n"); \ return EINVAL; \ } -#define DRM_OS_DELAY( udelay ) \ +#define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ microtime(&tv1); \ @@ -95,34 +127,53 @@ do { \ while (((tv2.tv_sec-tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec) < udelay ); \ } while (0) -#define DRM_OS_RETURN(v) return v; - +#define DRM_GETSAREA() \ +do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + drm_map_t *map = listentry->map; \ + if (map->type == _DRM_SHM && \ + map->flags & _DRM_CONTAINS_LOCK) { \ + dev_priv->sarea = map; \ + break; \ + } \ + } \ +} while (0) -#define DRM_OS_KRNTOUSR(arg1, arg2, arg3) \ +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ *arg1 = arg2 -#define DRM_OS_KRNFROMUSR(arg1, arg2, arg3) \ +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ arg1 = *arg2 -#define DRM_OS_COPYTOUSR(arg1, arg2, arg3) \ +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ copyout(arg2, arg1, arg3) -#define DRM_OS_COPYFROMUSR(arg1, arg2, 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's be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!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_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); +/* From machine/bus_at386.h on i386 */ +#define DRM_READMEMORYBARRIER() \ +do { \ + __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \ +} while (0) -#define DRM_OS_WRITEMEMORYBARRIER DRM_OS_READMEMORYBARRIER +#define DRM_WRITEMEMORYBARRIER() \ +do { \ + __asm __volatile("" : : : "memory"); \ +} while (0) -#define DRM_OS_WAKEUP(w) wakeup(w) -#define DRM_OS_WAKEUP_INT(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP_INT(w) wakeup(w) -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) round_page(addr) #define malloctype DRM(M_DRM) /* The macros confliced in the MALLOC_DEFINE */ @@ -137,7 +188,10 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; -typedef unsigned long atomic_t; +#define cpu_to_le32(x) (x) + +typedef u_int32_t 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; @@ -145,14 +199,14 @@ typedef u_int16_t u16; typedef u_int8_t u8; #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_long(p, 1) -#define atomic_dec(p) atomic_subtract_long(p, 1) -#define atomic_add(n, p) atomic_add_long(p, n) -#define atomic_sub(n, p) atomic_subtract_long(p, n) +#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) /* Fake this */ -static __inline unsigned int -test_and_set_bit(int b, volatile unsigned long *p) +static __inline atomic_t +test_and_set_bit(int b, atomic_t *p) { int s = splhigh(); unsigned int m = 1<<b; @@ -163,25 +217,25 @@ test_and_set_bit(int b, volatile unsigned long *p) } static __inline void -clear_bit(int b, volatile unsigned long *p) +clear_bit(int b, atomic_t *p) { - atomic_clear_long(p + (b >> 5), 1 << (b & 0x1f)); + atomic_clear_int(p + (b >> 5), 1 << (b & 0x1f)); } static __inline void -set_bit(int b, volatile unsigned long *p) +set_bit(int b, atomic_t *p) { - atomic_set_long(p + (b >> 5), 1 << (b & 0x1f)); + atomic_set_int(p + (b >> 5), 1 << (b & 0x1f)); } static __inline int -test_bit(int b, volatile unsigned long *p) +test_bit(int b, atomic_t *p) { return p[b >> 5] & (1 << (b & 0x1f)); } static __inline int -find_first_zero_bit(volatile unsigned long *p, int max) +find_first_zero_bit(atomic_t *p, int max) { int b; @@ -227,24 +281,23 @@ find_first_zero_bit(volatile unsigned long *p, int max) } while (0) /* Redefinitions to make templating easy */ -#define wait_queue_head_t long +#define wait_queue_head_t atomic_t #define agp_memory void #define jiffies ticks /* Macros to make printf easier */ #define DRM_ERROR(fmt, arg...) \ - printf("error: " "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg) + printf("error: " "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ## arg) #define DRM_MEM_ERROR(area, fmt, arg...) \ - printf("error: " "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \ - DRM(mem_stats)[area].name , ##arg) -#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ##arg) + printf("error: " "[" DRM_NAME ":%s:%s] *ERROR* " fmt , \ + __func__, DRM(mem_stats)[area].name , ##arg) +#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ## arg) #if DRM_DEBUG_CODE #define DRM_DEBUG(fmt, arg...) \ do { \ - if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ - ##arg); \ + if (DRM(flags) & DRM_FLAG_DEBUG) \ + printf("[" DRM_NAME ":%s] " fmt , __func__ , ## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -294,9 +347,9 @@ extern d_write_t DRM(write); extern d_poll_t DRM(poll); extern d_mmap_t DRM(mmap); extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, - DRM_OS_STRUCTPROC *p, drm_device_t *dev); + DRM_STRUCTPROC *p, drm_device_t *dev); extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, - DRM_OS_STRUCTPROC *p); + DRM_STRUCTPROC *p); /* Misc. IOCTL support (drm_ioctl.h) */ extern d_ioctl_t DRM(irq_busid); @@ -348,7 +401,7 @@ extern d_ioctl_t DRM(mapbufs); extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; /* DMA support (drm_dma.h) */ -#if __HAVE_DMA_IRQ +#if __HAVE_DMA extern d_ioctl_t DRM(control); #endif diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h new file mode 100644 index 00000000..2082c047 --- /dev/null +++ b/bsd/drm_os_netbsd.h @@ -0,0 +1,378 @@ +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/stat.h> +#include <sys/proc.h> +#include <sys/lock.h> +#include <sys/fcntl.h> +#include <sys/uio.h> +#include <sys/filio.h> +#include <sys/sysctl.h> +#include <sys/select.h> +#include <sys/device.h> +#include <sys/mman.h> +#include <uvm/uvm.h> +#include <sys/vnode.h> +#include <sys/poll.h> +/* For TIOCSPGRP/TIOCGPGRP */ +#include <sys/ttycom.h> + +#include <uvm/uvm.h> + +#include <machine/pmap.h> +#include <machine/bus.h> +#include <sys/resourcevar.h> +#include <machine/sysarch.h> +#include <machine/mtrr.h> + +#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_SG 0 + +#if __REALLY_HAVE_AGP +#include <dev/pci/agpvar.h> +#include <sys/agpio.h> +#endif + +#define device_t struct device * +extern struct cfdriver DRM(_cd); + +#if DRM_DEBUG +#undef DRM_DEBUG_CODE +#define DRM_DEBUG_CODE 2 +#endif +#undef DRM_DEBUG + +#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 DRM_CURPROC curproc +#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_SPINUNLOCK(u) simple_unlock(u); +#define DRM_CURRENTPID curproc->p_pid + +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +#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_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) +#define DRM_FREE(pt) 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_PRIV \ + drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ + if (!priv) { \ + DRM_DEBUG("can't find authenticator\n"); \ + return EINVAL; \ + } + +#define DRM_UDELAY( udelay ) \ +do { \ + struct timeval tv1, tv2; \ + microtime(&tv1); \ + do { \ + microtime(&tv2); \ + } \ + while (((tv2.tv_sec-tv1.tv_sec)*1000000 + tv2.tv_usec - tv1.tv_usec) < udelay ); \ +} while (0) + +#define DRM_GETSAREA() \ +do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + drm_map_t *map = listentry->map; \ + if (map->type == _DRM_SHM && \ + map->flags & _DRM_CONTAINS_LOCK) { \ + dev_priv->sarea = map; \ + break; \ + } \ + } \ +} while (0) + +#define return DRM_ERR(v) return v; +#define DRM_ERR(v) v + +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ + *arg1 = arg2 +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ + arg1 = *arg2 +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ + copyout(arg2, arg1, arg3) +#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) + +#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_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP_INT(w) wakeup(w) + +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +typedef struct drm_chipinfo +{ + int vendor; + int device; + int supported; + char *name; +} drm_chipinfo_t; + +typedef u_int32_t dma_addr_t; +typedef volatile 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; +typedef dev_type_ioctl(d_ioctl_t); +typedef vaddr_t vm_offset_t; + +#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) + +/* FIXME: Is NetBSD's kernel non-reentrant? */ +#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 atomic_t +test_and_set_bit(int b, atomic_t *p) +{ + int s = splhigh(); + unsigned int m = 1<<b; + unsigned int r = *p & m; + *p |= m; + splx(s); + return r; +} + +static __inline void +clear_bit(int b, atomic_t *p) +{ + atomic_clear_int(p + (b >> 5), 1 << (b & 0x1f)); +} + +static __inline void +set_bit(int b, atomic_t *p) +{ + atomic_set_int(p + (b >> 5), 1 << (b & 0x1f)); +} + +static __inline int +test_bit(int b, atomic_t *p) +{ + return p[b >> 5] & (1 << (b & 0x1f)); +} + +static __inline int +find_first_zero_bit(atomic_t *p, int max) +{ + int b; + + for (b = 0; b < max; b += 32) { + if (p[b >> 5] != ~0) { + for (;;) { + if ((p[b >> 5] & (1 << (b & 0x1f))) == 0) + return b; + b++; + } + } + } + return 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 + + /* Macros to make printf easier */ +#define DRM_ERROR(fmt, arg...) \ +do { \ + printf("error: [" DRM_NAME ":%s] *ERROR* ", __func__ ); \ + printf( fmt,## arg ); \ +} while (0) + +#define DRM_MEM_ERROR(area, fmt, arg...) \ + printf("error: [" DRM_NAME ":%s:%s] *ERROR* " fmt , \ + __func__, DRM(mem_stats)[area].name ,## arg) +#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt ,## arg) + +#if DRM_DEBUG_CODE +#define DRM_DEBUG(fmt, arg...) \ + do { \ + if (DRM(flags) & DRM_FLAG_DEBUG) \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + } while (0) +#else +#define DRM_DEBUG(fmt, arg...) do { } while (0) +#endif + +#define DRM_PROC_LIMIT (PAGE_SIZE-80) + +#define DRM_SYSCTL_PRINT(fmt, arg...) \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + error = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (error) return error; + +#define DRM_SYSCTL_PRINT_RET(ret, fmt, arg...) \ + snprintf(buf, sizeof(buf), fmt, ##arg); \ + error = SYSCTL_OUT(req, buf, strlen(buf)); \ + if (error) { ret; return error; } + + +#define DRM_FIND_MAP(dest, o) \ + do { \ + drm_map_list_entry_t *listentry; \ + TAILQ_FOREACH(listentry, dev->maplist, link) { \ + if ( listentry->map->offset == o ) { \ + dest = listentry->map; \ + break; \ + } \ + } \ + } while (0) + +/* Internal functions */ + +/* 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)); +extern dev_type_write(DRM(write)); +extern dev_type_poll(DRM(poll)); +extern dev_type_mmap(DRM(mmap)); +extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, + DRM_STRUCTPROC *p, drm_device_t *dev); +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 07e8e4e5..c16b7c05 100644 --- a/bsd/drm_scatter.h +++ b/bsd/drm_scatter.h @@ -27,25 +27,15 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ -#include <linux/config.h> -#include <linux/vmalloc.h> #include "drmP.h" #define DEBUG_SCATTER 0 +#if __REALLY_HAVE_SG + void DRM(sg_cleanup)( drm_sg_mem_t *entry ) { - struct page *page; - int i; - - for ( i = 0 ; i < entry->pages ; i++ ) { - page = entry->pagelist[i]; - if ( page ) - ClearPageReserved( page ); - } - - vfree( entry->virtual ); + free( entry->virtual, DRM(M_DRM) ); DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), @@ -58,35 +48,28 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry ) DRM_MEM_SGLISTS ); } -int DRM(sg_alloc)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int DRM(sg_alloc)( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_scatter_gather_t request; drm_sg_mem_t *entry; - unsigned long pages, i, j; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; + unsigned long pages; DRM_DEBUG( "%s\n", __FUNCTION__ ); if ( dev->sg ) - return -EINVAL; + return EINVAL; - if ( copy_from_user( &request, - (drm_scatter_gather_t *)arg, - sizeof(request) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data, + sizeof(request) ); entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS ); if ( !entry ) - return -ENOMEM; + return ENOMEM; - memset( entry, 0, sizeof(*entry) ); + bzero( entry, sizeof(*entry) ); - pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; + pages = round_page(request.size) / PAGE_SIZE; DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages ); entry->pages = pages; @@ -94,10 +77,10 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM_MEM_PAGES ); if ( !entry->pagelist ) { DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); + bzero(entry->pagelist, pages * sizeof(*entry->pagelist)); entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr), DRM_MEM_PAGES ); @@ -108,11 +91,11 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) ); + bzero( (void *)entry->busaddr, pages * sizeof(*entry->busaddr) ); - entry->virtual = vmalloc_32( pages << PAGE_SHIFT ); + entry->virtual = malloc( pages << PAGE_SHIFT, DRM(M_DRM), M_WAITOK ); if ( !entry->virtual ) { DRM(free)( entry->busaddr, entry->pages * sizeof(*entry->busaddr), @@ -123,45 +106,21 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS ); - return -ENOMEM; + return ENOMEM; } - /* This also forces the mapping of COW pages, so our page list - * will be valid. Please don't remove it... - */ - memset( entry->virtual, 0, pages << PAGE_SHIFT ); + bzero( entry->virtual, pages << PAGE_SHIFT ); entry->handle = (unsigned long)entry->virtual; DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); - for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) { - pgd = pgd_offset_k( i ); - if ( !pgd_present( *pgd ) ) - goto failed; - - pmd = pmd_offset( pgd, i ); - if ( !pmd_present( *pmd ) ) - goto failed; - - pte = pte_offset( pmd, i ); - if ( !pte_present( *pte ) ) - goto failed; - - entry->pagelist[j] = pte_page( *pte ); - - SetPageReserved( entry->pagelist[j] ); - } - request.handle = entry->handle; - if ( copy_to_user( (drm_scatter_gather_t *)arg, - &request, - sizeof(request) ) ) { - DRM(sg_cleanup)( entry ); - return -EFAULT; - } + DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data, + request, + sizeof(request) ); dev->sg = entry; @@ -207,29 +166,24 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp, return 0; - failed: DRM(sg_cleanup)( entry ); - return -ENOMEM; + return ENOMEM; } -int DRM(sg_free)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int DRM(sg_free)( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_scatter_gather_t request; drm_sg_mem_t *entry; - if ( copy_from_user( &request, - (drm_scatter_gather_t *)arg, - sizeof(request) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data, + sizeof(request) ); entry = dev->sg; dev->sg = NULL; if ( !entry || entry->handle != request.handle ) - return -EINVAL; + return EINVAL; DRM_DEBUG( "sg free virtual = %p\n", entry->virtual ); @@ -237,3 +191,16 @@ int DRM(sg_free)( struct inode *inode, struct file *filp, return 0; } + +#else /* __REALLY_HAVE_SG */ + +int DRM(sg_alloc)( DRM_IOCTL_ARGS ) +{ + return DRM_ERR(EINVAL); +} +int DRM(sg_free)( DRM_IOCTL_ARGS ) +{ + return DRM_ERR(EINVAL); +} + +#endif diff --git a/bsd/drm_sysctl.h b/bsd/drm_sysctl.h index 02e4b28d..4e007445 100644 --- a/bsd/drm_sysctl.h +++ b/bsd/drm_sysctl.h @@ -1,4 +1,10 @@ -SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics"); +/* + * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ + */ + +#ifdef __FreeBSD__ + +#include <sys/sysctl.h> static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS; static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS; @@ -32,8 +38,7 @@ struct DRM(sysctl_list) { #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0])) struct drm_sysctl_info { - struct sysctl_oid oids[DRM_SYSCTL_ENTRIES + 1]; - struct sysctl_oid_list list; + struct sysctl_ctx_list ctx; char name[2]; }; @@ -41,65 +46,62 @@ int DRM(sysctl_init)(drm_device_t *dev) { struct drm_sysctl_info *info; struct sysctl_oid *oid; - struct sysctl_oid *top; + struct sysctl_oid *top, *drioid; int i; - /* Find the next free slot under hw.graphics */ + info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER); + if ( !info ) + return 1; + bzero(info, sizeof *info); + dev->sysctl = info; + + /* Add the sysctl node for DRI if it doesn't already exist */ + drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics"); + if (!drioid) + return 1; + + /* Find the next free slot under hw.dri */ i = 0; - SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) { + SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) { if (i <= oid->oid_arg2) i = oid->oid_arg2 + 1; } + if (i>9) + return 1; - info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER); - dev->sysctl = info; - - /* Construct the node under hw.graphics */ + /* Add the hw.dri.x for our device */ info->name[0] = '0' + i; info->name[1] = 0; - oid = &info->oids[DRM_SYSCTL_ENTRIES]; - bzero(oid, sizeof(*oid)); - oid->oid_parent = &sysctl__hw_dri_children; - oid->oid_number = OID_AUTO; - oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW; - oid->oid_arg1 = &info->list; - oid->oid_arg2 = i; - oid->oid_name = info->name; - oid->oid_handler = 0; - oid->oid_fmt = "N"; - SLIST_INIT(&info->list); - sysctl_register_oid(oid); - top = oid; - + top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL); + if (!top) + return 1; + for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) { - oid = &info->oids[i]; - bzero(oid, sizeof(*oid)); - oid->oid_parent = top->oid_arg1; - oid->oid_number = OID_AUTO; - oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD; - oid->oid_arg1 = dev; - oid->oid_arg2 = 0; - oid->oid_name = DRM(sysctl_list)[i].name; - oid->oid_handler = DRM(sysctl_list[)i].f; - oid->oid_fmt = "A"; - sysctl_register_oid(oid); + oid = sysctl_add_oid( &info->ctx, + SYSCTL_CHILDREN(top), + OID_AUTO, + DRM(sysctl_list)[i].name, + CTLTYPE_INT | CTLFLAG_RD, + dev, + 0, + DRM(sysctl_list)[i].f, + "A", + NULL); + if (!oid) + return 1; } - return 0; } int DRM(sysctl_cleanup)(drm_device_t *dev) { - int i; - - DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl); - for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++) - sysctl_unregister_oid(&dev->sysctl->oids[i]); + int error; + error = sysctl_ctx_free( &dev->sysctl->ctx ); DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER); dev->sysctl = NULL; - return 0; + return error; } static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS @@ -166,9 +168,9 @@ static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_vm_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -217,9 +219,9 @@ static int DRM(queues_info) DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_queues_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -267,9 +269,9 @@ static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_bufs_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -301,9 +303,9 @@ static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_clients_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } @@ -386,9 +388,9 @@ static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = DRM(_vma_info)(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } #endif @@ -515,9 +517,22 @@ static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS drm_device_t *dev = arg1; int ret; - DRM_OS_LOCK; + DRM_LOCK; ret = _drm_histo_info(oidp, arg1, arg2, req); - DRM_OS_UNLOCK; + DRM_UNLOCK; return ret; } #endif + +#elif defined(__NetBSD__) +/* stub it out for now, sysctl is only for debugging */ +int DRM(sysctl_init)(drm_device_t *dev) +{ + return 0; +} + +int DRM(sysctl_cleanup)(drm_device_t *dev) +{ + return 0; +} +#endif diff --git a/bsd/drm_vm.h b/bsd/drm_vm.h index a06fb448..70a5b0e6 100644 --- a/bsd/drm_vm.h +++ b/bsd/drm_vm.h @@ -1,9 +1,11 @@ -#include <vm/vm.h> -#include <vm/pmap.h> +#ifdef __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) +#endif { - drm_device_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; unsigned long physical; unsigned long page; @@ -14,27 +16,30 @@ static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) page = offset >> PAGE_SHIFT; physical = dma->pagelist[page]; - DRM_DEBUG("0x%08x (page %lu) => 0x%08lx\n", offset, page, physical); + DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); return atop(physical); } +#ifdef __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_t *dev = kdev->si_drv1; + DRM_DEVICE; drm_map_t *map = NULL; drm_map_list_entry_t *listentry=NULL; - /*drm_file_t *priv;*/ + drm_file_t *priv; /* DRM_DEBUG("offset = 0x%x\n", offset);*/ - /*XXX Fixme */ - /*priv = DRM(find_file_by_proc)(dev, p); + priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); if (!priv) { DRM_DEBUG("can't find authenticator\n"); return EINVAL; } - if (!priv->authenticated) DRM_OS_RETURN(EACCES);*/ + if (!priv->authenticated) return DRM_ERR(EACCES); if (dev->dma && offset >= 0 @@ -59,7 +64,7 @@ int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) DRM_DEBUG("can't find map\n"); return -1; } - if (((map->flags&_DRM_RESTRICTED) && suser(curproc))) { + if (((map->flags&_DRM_RESTRICTED) && DRM_SUSER(DRM_CURPROC))) { DRM_DEBUG("restricted map\n"); return -1; } @@ -69,6 +74,7 @@ int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) case _DRM_REGISTERS: case _DRM_AGP: return atop(offset); + case _DRM_SCATTER_GATHER: case _DRM_SHM: return atop(vtophys(offset)); default: diff --git a/bsd/gamma/gamma.h b/bsd/gamma.h index 232ed018..232ed018 100644 --- a/bsd/gamma/gamma.h +++ b/bsd/gamma.h diff --git a/bsd/gamma/Makefile b/bsd/gamma/Makefile index 97bb1b69..6b99427a 100644 --- a/bsd/gamma/Makefile +++ b/bsd/gamma/Makefile @@ -1,9 +1,10 @@ # $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_linux.h +SRCS += device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS += ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS += ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#TDFX_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(TDFX_OPTS) >> opt_drm_linux.h +.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 new file mode 100644 index 00000000..e7ca0695 --- /dev/null +++ b/bsd/gamma_dma.c @@ -0,0 +1,569 @@ +/* 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 *)device; + 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(dev, 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; +} diff --git a/bsd/sis/sis_drv.c b/bsd/gamma_drv.c index 3cdc27d3..153420fb 100644 --- a/bsd/sis/sis_drv.c +++ b/bsd/gamma_drv.c @@ -1,4 +1,5 @@ -/* sis.c -- sis driver -*- linux-c -*- +/* 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. @@ -10,11 +11,11 @@ * 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 @@ -23,61 +24,56 @@ * 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 <sys/bus.h> -#include <pci/pcivar.h> -#include <opt_drm_linux.h> - -#include "sis.h" +#include "gamma.h" #include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" +#include "drm.h" +#include "gamma_drm.h" +#include "gamma_drv.h" + +#define DRIVER_AUTHOR "VA Linux Systems Inc." -#define DRIVER_AUTHOR "SIS" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20010503" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 +#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)[] = { - {0x1039, 0x0300, 1, "SIS 300"}, - {0x1039, 0x0540, 1, "SIS 540"}, - {0x1039, 0x0630, 1, "SIS 630"}, + {0x3d3d, 0x0008, 1, "3DLabs Gamma"}, {0, 0, 0, NULL} }; -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 }, \ - /* AGP Memory Management */ \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 1 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 1 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 1 } -#if 0 /* these don't appear to be defined */ - /* SIS Stereo */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } -#endif #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_agpsupport.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" @@ -87,4 +83,4 @@ drm_chipinfo_t DRM(devicelist)[] = { #include "drm_vm.h" #include "drm_sysctl.h" -DRIVER_MODULE(sis, pci, sis_driver, sis_devclass, 0, 0); +DRIVER_MODULE(gamma, pci, gamma_driver, gamma_devclass, 0, 0); diff --git a/bsd/gamma/gamma_drv.h b/bsd/gamma_drv.h index f8665516..69250b9e 100644 --- a/bsd/gamma/gamma_drv.h +++ b/bsd/gamma_drv.h @@ -44,10 +44,10 @@ typedef struct drm_gamma_private { #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_OS_CURRENTPID ) { \ + dev->lock.pid != DRM_CURRENTPID ) { \ DRM_ERROR( "%s called without lock held\n", \ __FUNCTION__ ); \ - DRM_OS_RETURN( EINVAL ); \ + return DRM_ERR( EINVAL ); \ } \ } while (0) @@ -58,7 +58,7 @@ 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_OS_IOCTL ); +extern int gamma_dma( DRM_IOCTL_ARGS ); extern int gamma_find_devices(void); extern int gamma_found(void); diff --git a/bsd/i810/i810.h b/bsd/i810.h index a5152bc0..a5152bc0 100644 --- a/bsd/i810/i810.h +++ b/bsd/i810.h diff --git a/bsd/i810_dma.c b/bsd/i810_dma.c new file mode 100644 index 00000000..d860fafe --- /dev/null +++ b/bsd/i810_dma.c @@ -0,0 +1,1223 @@ +/* i810_dma.c -- DMA support for the i810 -*- linux-c -*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@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> + * Jeff Hartmann <jhartmann@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + + +#include "i810.h" +#include "drmP.h" +#include "drm.h" +#include "i810_drm.h" +#include "i810_drv.h" + +#define I810_BUF_FREE 2 +#define I810_BUF_CLIENT 1 +#define I810_BUF_HARDWARE 0 + +#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 (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); + +static __inline__ void i810_print_status_page(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = dev->dev_private; + u32 *temp = (u32 *)dev_priv->hw_status_page; + int i; + + DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); + DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]); + DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]); + DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); + DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); + for(i = 6; i < dma->buf_count + 6; i++) { + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); + } +} + +static drm_buf_t *i810_freelist_get(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + int i; + char failed; + + /* Linear search might not be the best solution */ + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + /* In use is already a pointer */ + _DRM_CAS(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT, + failed); + if (!failed) + return buf; + } + return NULL; +} + +/* This should only be called if the buffer is not sent to the hardware + * yet, the hardware updates in use for us once its on the ring buffer. + */ + +static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) +{ + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + char failed; + + /* In use is already a pointer */ + _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE, failed); + if(failed) { + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return DRM_ERR( EINVAL ); + } + + return 0; +} + +#if 0 +int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) +{ + DRM_DEVICE; + drm_i810_private_t *dev_priv; + drm_buf_t *buf; + drm_i810_buf_priv_t *buf_priv; + + lock_kernel(); + dev_priv = dev->dev_private; + buf = dev_priv->mmap_buffer; + buf_priv = buf->dev_private; + + vma->vm_flags |= (VM_IO | VM_DONTCOPY); + vma->vm_file = filp; + + buf_priv->currently_mapped = I810_BUF_MAPPED; + unlock_kernel(); + + if (remap_page_range(vma->vm_start, + VM_OFFSET(vma), + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) return DRM_ERR(EAGAIN); + return 0; +} +#endif + +static int i810_map_buffer(drm_buf_t *buf, struct file *filp) +{ + DRM_DEVICE; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_i810_private_t *dev_priv = dev->dev_private; + struct file_operations *old_fops; + int retcode = 0; + + if(buf_priv->currently_mapped == I810_BUF_MAPPED) return DRM_ERR(EINVAL); + + if(VM_DONTCOPY != 0) { +#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; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("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 + } else { + buf_priv->virtual = buf_priv->kernel_virtual; + buf_priv->currently_mapped = I810_BUF_MAPPED; + } + return retcode; +} + +static int i810_unmap_buffer(drm_buf_t *buf) +{ + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + int retcode = 0; + + if(VM_DONTCOPY != 0) { + if(buf_priv->currently_mapped != I810_BUF_MAPPED) + return DRM_ERR(EINVAL); +#if LINUX_VERSION_CODE <= 0x020402 + down( ¤t->mm->mmap_sem ); +#else + down_write( ¤t->mm->mmap_sem ); +#endif + 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 + } + buf_priv->currently_mapped = I810_BUF_UNMAPPED; + buf_priv->virtual = 0; + + return retcode; +} + +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; + + buf = i810_freelist_get(dev); + if (!buf) { + retcode = -ENOMEM; + DRM_DEBUG("retcode=%d\n", retcode); + return DRM_ERR(retcode); + } + + retcode = i810_map_buffer(buf, filp); + if(retcode) { + i810_freelist_put(dev, buf); + DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + return retcode; + } + buf->pid = priv->pid; + buf_priv = buf->dev_private; + d->granted = 1; + d->request_idx = buf->idx; + d->request_size = buf->total; + d->virtual = buf_priv->virtual; + + return retcode; +} + +static unsigned long i810_alloc_page(drm_device_t *dev) +{ + unsigned long address; + + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&virt_to_page(address)->count); + set_bit(PG_locked, &virt_to_page(address)->flags); + + return address; +} + +static void i810_free_page(drm_device_t *dev, unsigned long page) +{ + if(page == 0UL) + return; + + atomic_dec(&virt_to_page(page)->count); + clear_bit(PG_locked, &virt_to_page(page)->flags); + DRM_WAKEUP(&virt_to_page(page)->wait); + free_page(page); + return; +} + +static int i810_dma_cleanup(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + + if(dev->dev_private) { + int i; + drm_i810_private_t *dev_priv = + (drm_i810_private_t *) dev->dev_private; + + if(dev_priv->ring.virtual_start) { + DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, + dev_priv->ring.Size); + } + if(dev_priv->hw_status_page != 0UL) { + i810_free_page(dev, dev_priv->hw_status_page); + /* Need to rewrite hardware status page */ + I810_WRITE(0x02080, 0x1ffff000); + } + DRM(free)(dev->dev_private, sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + dev->dev_private = NULL; + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + } + } + return 0; +} + +static int i810_wait_ring(drm_device_t *dev, int n) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; + unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + + end = jiffies + (HZ*3); + while (ring->space < n) { + int i; + + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; + + if (ring->head != last_head) + end = jiffies + (HZ*3); + + iters++; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; + } + + for (i = 0 ; i < 2000 ; i++) ; + } + +out_wait_ring: + return iters; +} + +static void i810_kernel_lost_context(drm_device_t *dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I810_READ(LP_RING + RING_TAIL); + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; +} + +static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv) +{ + drm_device_dma_t *dma = dev->dma; + int my_idx = 24; + u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); + int i; + + if(dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return DRM_ERR(EINVAL); + } + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + buf_priv->in_use = hw_status++; + buf_priv->my_use_idx = my_idx; + my_idx += 4; + + *buf_priv->in_use = I810_BUF_FREE; + + buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, + buf->total); + } + return 0; +} + +static int i810_dma_initialize(drm_device_t *dev, + drm_i810_private_t *dev_priv, + drm_i810_init_t *init) +{ + drm_map_list_entry_t *listentry; + + memset(dev_priv, 0, sizeof(drm_i810_private_t)); + + TAILQ_FOREACH(listentry, dev->maplist, link) { + drm_map_t *map = listentry->map; + if (map->type == _DRM_SHM && + map->flags & _DRM_CONTAINS_LOCK) { + dev_priv->sarea = map; + break; + } + } + + if(!dev_priv->sarea_map) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("can not find sarea!\n"); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset ); + if(!dev_priv->mmio_map) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset ); + if(!dev_priv->buffer_map) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("can not find dma buffer map!\n"); + return DRM_ERR(EINVAL); + } + + dev_priv->sarea_priv = (drm_i810_sarea_t *) + ((u8 *)dev_priv->sarea_map->handle + + init->sarea_priv_offset); + + atomic_set(&dev_priv->flush_done, 0); + init_waitqueue_head(&dev_priv->flush_queue); + + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; + + dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + + init->ring_start, + init->ring_size); + + if (dev_priv->ring.virtual_start == NULL) { + dev->dev_private = (void *) dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return DRM_ERR(ENOMEM); + } + + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + + dev_priv->w = init->w; + dev_priv->h = init->h; + dev_priv->pitch = init->pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->depth_offset = init->depth_offset; + + dev_priv->front_di1 = init->front_offset | init->pitch_bits; + dev_priv->back_di1 = init->back_offset | init->pitch_bits; + dev_priv->zi1 = init->depth_offset | init->pitch_bits; + + /* Program Hardware Status Page */ + dev_priv->hw_status_page = i810_alloc_page(dev); + if(dev_priv->hw_status_page == 0UL) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return DRM_ERR(ENOMEM); + } + memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); + DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); + + I810_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 */ + if(i810_freelist_init(dev, dev_priv) != 0) { + dev->dev_private = (void *)dev_priv; + i810_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" + " the freelist\n"); + return DRM_ERR(ENOMEM); + } + dev->dev_private = (void *)dev_priv; + + return 0; +} + +int i810_dma_init( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_i810_private_t *dev_priv; + drm_i810_init_t init; + int retcode = 0; + + DRM_COPY_FROM_USER_IOCTL( init, (drm_i810_init_t *) data, sizeof(init) ); + + switch(init.func) { + case I810_INIT_DMA: + dev_priv = DRM(alloc)(sizeof(drm_i810_private_t), + DRM_MEM_DRIVER); + if(dev_priv == NULL) return DRM_ERR(ENOMEM); + retcode = i810_dma_initialize(dev, dev_priv, &init); + break; + case I810_CLEANUP_DMA: + retcode = i810_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; + } + + return DRM_ERR(retcode); +} + + + +/* Most efficient way to verify state for the i810 is as it is + * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. + */ +static void i810EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); + + OUT_RING( GFX_OP_COLOR_FACTOR ); + OUT_RING( code[I810_CTXREG_CF1] ); + + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[I810_CTXREG_ST1] ); + + for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i810EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); + + OUT_RING( GFX_OP_MAP_INFO ); + OUT_RING( code[I810_TEXREG_MI1] ); + OUT_RING( code[I810_TEXREG_MI2] ); + OUT_RING( code[I810_TEXREG_MI3] ); + + for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + +/* Need to do some additional checking when setting the dest buffer. + */ +static void i810EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 ); + + tmp = code[I810_DESTREG_DI1]; + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( tmp ); + } else + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); + + /* invarient: + */ + OUT_RING( CMD_OP_Z_BUFFER_INFO ); + OUT_RING( dev_priv->zi1 ); + + OUT_RING( GFX_OP_DESTBUFFER_VARS ); + OUT_RING( code[I810_DESTREG_DV1] ); + + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( code[I810_DESTREG_DR1] ); + OUT_RING( code[I810_DESTREG_DR2] ); + OUT_RING( code[I810_DESTREG_DR3] ); + OUT_RING( code[I810_DESTREG_DR4] ); + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + + +static void i810EmitState( drm_device_t *dev ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + + if (dirty & I810_UPLOAD_BUFFERS) { + i810EmitDestVerified( dev, sarea_priv->BufferState ); + sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; + } + + if (dirty & I810_UPLOAD_CTX) { + i810EmitContextVerified( dev, sarea_priv->ContextState ); + sarea_priv->dirty &= ~I810_UPLOAD_CTX; + } + + if (dirty & I810_UPLOAD_TEX0) { + i810EmitTexVerified( dev, sarea_priv->TexState[0] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX0; + } + + if (dirty & I810_UPLOAD_TEX1) { + i810EmitTexVerified( dev, sarea_priv->TexState[1] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX1; + } +} + + + +/* need to verify + */ +static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int i; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + unsigned int x = pbox->x1; + unsigned int y = pbox->y1; + unsigned int width = (pbox->x2 - x) * cpp; + unsigned int height = pbox->y2 - y; + unsigned int start = y * pitch + x * cpp; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + if ( flags & I810_FRONT ) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_BACK ) { + DRM_DEBUG("clear back\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->back_offset + start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_DEPTH ) { + DRM_DEBUG("clear depth\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->depth_offset + start ); + OUT_RING( clear_zval ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + } +} + +static void i810_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int ofs = dev_priv->back_offset; + int i; + RING_LOCALS; + + DRM_DEBUG("swapbuffers\n"); + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox; i++, pbox++) + { + unsigned int w = pbox->x2 - pbox->x1; + unsigned int h = pbox->y2 - pbox->y1; + unsigned int dst = pbox->x1*cpp + pbox->y1*pitch; + unsigned int start = ofs + dst; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox[i].x1, pbox[i].y1, + pbox[i].x2, pbox[i].y2); + + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); + OUT_RING( pitch | (0xCC << 16)); + OUT_RING( (h << 16) | (w * cpp)); + OUT_RING( dst ); + OUT_RING( pitch ); + OUT_RING( start ); + ADVANCE_LP_RING(); + } +} + + +static void i810_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + int i = 0; + char failed; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + if (discard) { + _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE, failed); + if (failed) + DRM_DEBUG("xxxx 2\n"); + } + + if (used > 4*1024) + used = 0; + + if (sarea_priv->dirty) + i810EmitState( dev ); + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); + + dev_priv->counter++; + DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG( "i810_dma_dispatch\n"); + DRM_DEBUG( "start : %lx\n", start); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); + + if (buf_priv->currently_mapped == I810_BUF_MAPPED) { + *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | + sarea_priv->vertex_prim | + ((used/4)-2)); + + if (used & 4) { + *(u32 *)((u32)buf_priv->virtual + used) = 0; + used += 4; + } + + i810_unmap_buffer(buf); + } + + if (used) { + do { + if (i < nbox) { + BEGIN_LP_RING(4); + OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + SC_ENABLE ); + OUT_RING( GFX_OP_SCISSOR_INFO ); + OUT_RING( box[i].x1 | (box[i].y1<<16) ); + OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); + ADVANCE_LP_RING(); + } + + BEGIN_LP_RING(4); + OUT_RING( CMD_OP_BATCH_BUFFER ); + OUT_RING( start | BB1_PROTECTED ); + OUT_RING( start + used - 4 ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + + } while (++i < nbox); + } + + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); + + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( 0 ); + } + + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + + +/* Interrupts are only for flushing */ +void i810_dma_service(int irq, void *device, struct pt_regs *regs) +{ + drm_device_t *dev = (drm_device_t *)device; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u16 temp; + + atomic_inc(&dev->counts[_DRM_STAT_IRQ]); + temp = I810_READ16(I810REG_INT_IDENTITY_R); + temp = temp & ~(0x6000); + if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, + temp); /* Clear all interrupts */ + else + return; + + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +void i810_dma_immediate_bh(void *device) +{ + drm_device_t *dev = (drm_device_t *) device; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + + atomic_set(&dev_priv->flush_done, 1); + DRM_WAKEUP_INT(&dev_priv->flush_queue); +} + +static inline void i810_dma_emit_flush(drm_device_t *dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + +/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ +/* atomic_set(&dev_priv->flush_done, 1); */ +/* DRM_WAKEUP_INT(&dev_priv->flush_queue); */ +} + +static inline void i810_dma_quiescent_emit(drm_device_t *dev) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + BEGIN_LP_RING(4); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + +/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */ +/* atomic_set(&dev_priv->flush_done, 1); */ +/* DRM_WAKEUP_INT(&dev_priv->flush_queue); */ +} + +void i810_dma_quiescent(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + unsigned long end; + + if(dev_priv == NULL) { + return; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i810_dma_quiescent_emit(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + return; +} + +static int i810_flush_queue(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + unsigned long end; + int i, ret = 0; + + if(dev_priv == NULL) { + return 0; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i810_dma_emit_flush(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; /* Can't restart */ + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + char failed; + _DRM_CAS(buf_priv->in_use, I810_BUF_HARDWARE, + I810_BUF_FREE, failed); + + if (!failed) + DRM_DEBUG("reclaimed from HARDWARE\n"); + if (used == I810_BUF_CLIENT) + DRM_DEBUG("still on client HARDWARE\n"); + } + + return ret; +} + +/* Must be called with the lock held */ +void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + if (!dma) return; + if (!dev->dev_private) return; + if (!dma->buflist) return; + + i810_flush_queue(dev); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + + if (buf->pid == pid && buf_priv) { + char failed; + _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_FREE, failed); + + if (!failed) + + DRM_DEBUG("reclaimed from client\n"); + if(buf_priv->currently_mapped == I810_BUF_MAPPED) + buf_priv->currently_mapped = I810_BUF_UNMAPPED; + } + } +} + +int i810_flush_ioctl( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + + DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + i810_flush_queue(dev); + return 0; +} + + +int i810_dma_vertex( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + drm_i810_vertex_t vertex; + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_i810_vertex_t *) data, sizeof(vertex) ); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL); + + i810_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], + vertex.discard, vertex.used ); + + atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]); + atomic_inc(&dev->counts[_DRM_STAT_DMA]); + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + + + +int i810_clear_bufs( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_i810_clear_t clear; + + DRM_COPY_FROM_USER_IOCTL( clear, (drm_i810_clear_t *) data, sizeof(clear) ); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_clear_bufs called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + /* GH: Someone's doing nasty things... */ + if (!dev->dev_private) { + return DRM_ERR(EINVAL); + } + + i810_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth ); + return 0; +} + +int i810_swap_bufs( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + + DRM_DEBUG("i810_swap_bufs\n"); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_swap_buf called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + i810_dma_dispatch_swap( dev ); + return 0; +} + +int i810_getage( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + + sarea_priv->last_dispatch = (int) hw_status[5]; + return 0; +} + +int i810_getbuf( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + int retcode = 0; + drm_i810_dma_t d; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + + DRM_DEBUG("getbuf\n"); + DRM_COPY_FROM_USER_IOCTL( d, (drm_i810_dma_t *) data, sizeof(d) ); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + d.granted = 0; + + retcode = i810_dma_get_buffer(dev, &d, filp); + + DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", + DRM_CURRENTPID, retcode, d.granted); + + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *) data, d, sizeof(d) ); + sarea_priv->last_dispatch = (int) hw_status[5]; + + return DRM_ERR(retcode); +} + +int i810_copybuf( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_i810_copy_t d; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) + dev_priv->sarea_priv; + drm_buf_t *buf; + drm_i810_buf_priv_t *buf_priv; + drm_device_dma_t *dma = dev->dma; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return DRM_ERR( EINVAL ); + } + + DRM_COPY_FROM_USER_IOCTL( d, (drm_i810_copy_t *) data, sizeof(d) ); + + if(d.idx < 0 || d.idx > dma->buf_count) return DRM_ERR(EINVAL); + buf = dma->buflist[ d.idx ]; + buf_priv = buf->dev_private; + if (buf_priv->currently_mapped != I810_BUF_MAPPED) return DRM_ERR(EPERM); + if(d.used < 0 || d.used > buf->total) return DRM_ERR(EINVAL); + + if (DRM_COPY_FROM_USER(buf_priv->virtual, d.address, d.used)) + return DRM_ERR( EFAULT ); + + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i810_docopy( DRM_IOCTL_ARGS ) +{ + if(VM_DONTCOPY == 0) return 1; + return 0; +} diff --git a/bsd/i810_drv.c b/bsd/i810_drv.c new file mode 100644 index 00000000..3d96cb48 --- /dev/null +++ b/bsd/i810_drv.c @@ -0,0 +1,96 @@ +/* i810_drv.c -- I810 driver -*- linux-c -*- + * Created: Mon Dec 13 01:56:22 1999 by jhartmann@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 + * VA LINUX SYSTEMS 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> + * Jeff Hartmann <jhartmann@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + + +#include <sys/types.h> +#include <sys/bus.h> +#include <pci/pcivar.h> + +#include "i810.h" +#include "drmP.h" +#include "drm.h" +#include "i810_drm.h" +#include "i810_drv.h" + +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i810" +#define DRIVER_DESC "Intel i810" +#define DRIVER_DATE "20010616" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + +/* Device IDs unknown. Can someone help? anholt@teleport.com */ +drm_chipinfo_t DRM(devicelist)[] = { + {0, 0, 0, NULL} +}; + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, + + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_lists.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" + +DRIVER_MODULE(i810, pci, i810_driver, i810_devclass, 0, 0); diff --git a/bsd/i810/i810_drv.h b/bsd/i810_drv.h index 7f65f1e8..ae7018d2 100644 --- a/bsd/i810/i810_drv.h +++ b/bsd/i810_drv.h @@ -79,22 +79,22 @@ typedef struct drm_i810_private { /* i810_dma.c */ extern int i810_dma_schedule(drm_device_t *dev, int locked); -extern int i810_getbuf( DRM_OS_IOCTL ); -extern int i810_dma_init( DRM_OS_IOCTL ); -extern int i810_flush_ioctl( DRM_OS_IOCTL ); -extern int i810_getage( DRM_OS_IOCTL ); +extern int i810_getbuf( DRM_IOCTL_ARGS ); +extern int i810_dma_init( DRM_IOCTL_ARGS ); +extern int i810_flush_ioctl( DRM_IOCTL_ARGS ); +extern int i810_getage( DRM_IOCTL_ARGS ); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); -extern int i810_copybuf( DRM_OS_IOCTL ); -extern int i810_docopy( DRM_OS_IOCTL ); +extern int i810_copybuf( DRM_IOCTL_ARGS ); +extern int i810_docopy( DRM_IOCTL_ARGS ); extern void i810_dma_quiescent(drm_device_t *dev); #define I810_VERBOSE 0 -int i810_dma_vertex( DRM_OS_IOCTL ); -int i810_swap_bufs( DRM_OS_IOCTL ); -int i810_clear_bufs( DRM_OS_IOCTL ); +int i810_dma_vertex( DRM_IOCTL_ARGS ); +int i810_swap_bufs( DRM_IOCTL_ARGS ); +int i810_clear_bufs( DRM_IOCTL_ARGS ); #define I810_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) diff --git a/bsd/i830/i830.h b/bsd/i830.h index fb7a0b32..fb7a0b32 100644 --- a/bsd/i830/i830.h +++ b/bsd/i830.h diff --git a/bsd/i830_dma.c b/bsd/i830_dma.c new file mode 100644 index 00000000..fbdc9523 --- /dev/null +++ b/bsd/i830_dma.c @@ -0,0 +1,1420 @@ +/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@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> + * Jeff Hartmann <jhartmann@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * Abraham vd Merwe <abraham@2d3d.co.za> + * + */ + +#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 */ + +/* in case we don't have a 2.3.99-pre6 kernel or later: */ +#ifndef VM_DONTCOPY +#define VM_DONTCOPY 0 +#endif + +#define I830_BUF_FREE 2 +#define I830_BUF_CLIENT 1 +#define I830_BUF_HARDWARE 0 + +#define I830_BUF_UNMAPPED 0 +#define I830_BUF_MAPPED 1 + +#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; + + +#define DO_IDLE_WORKAROUND() \ +do { \ + int _head; \ + int _tail; \ + int _i; \ + do { \ + _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; \ + _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; \ + for(_i = 0; _i < 65535; _i++); \ + } while(_head != _tail); \ +} while(0) + +#define I830_SYNC_WORKAROUND 0 + +#define BEGIN_LP_RING(n) do { \ + if (I830_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (I830_SYNC_WORKAROUND) \ + DO_IDLE_WORKAROUND(); \ + 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) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while(0) + +#define OUT_RING(n) do { \ + if (I830_VERBOSE) DRM_DEBUG(" 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) +{ + drm_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = dev->dev_private; + u32 *temp = (u32 *)dev_priv->hw_status_page; + int i; + + DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]); + DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]); + DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]); + DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); + DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); + for(i = 9; i < dma->buf_count + 9; i++) { + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 9, temp[i]); + } +} + +static drm_buf_t *i830_freelist_get(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + int i; + int used; + + /* Linear search might not be the best solution */ + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, + I830_BUF_CLIENT); + if(used == I830_BUF_FREE) { + return buf; + } + } + return NULL; +} + +/* This should only be called if the buffer is not sent to the hardware + * yet, the hardware updates in use for us once its on the ring buffer. + */ + +static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf) +{ + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + int used; + + /* In use is already a pointer */ + used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); + if(used != I830_BUF_CLIENT) { + DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); + return -EINVAL; + } + + return 0; +} + +static struct file_operations i830_buffer_fops = { + open: DRM(open), + flush: DRM(flush), + release: DRM(release), + ioctl: DRM(ioctl), + mmap: i830_mmap_buffers, + read: DRM(read), + fasync: DRM(fasync), + poll: DRM(poll), +}; + +int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + drm_i830_private_t *dev_priv; + drm_buf_t *buf; + drm_i830_buf_priv_t *buf_priv; + + lock_kernel(); + dev = priv->dev; + dev_priv = dev->dev_private; + buf = dev_priv->mmap_buffer; + buf_priv = buf->dev_private; + + vma->vm_flags |= (VM_IO | VM_DONTCOPY); + vma->vm_file = filp; + + buf_priv->currently_mapped = I830_BUF_MAPPED; + unlock_kernel(); + + if (remap_page_range(vma->vm_start, + VM_OFFSET(vma), + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) return -EAGAIN; + return 0; +} + +static int i830_map_buffer(drm_buf_t *buf, struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + drm_i830_private_t *dev_priv = dev->dev_private; + struct file_operations *old_fops; + int retcode = 0; + + if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL; + + if(VM_DONTCOPY != 0) { +#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 = &i830_buffer_fops; + dev_priv->mmap_buffer = buf; + buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, + PROT_READ|PROT_WRITE, + MAP_SHARED, + buf->bus_address); + dev_priv->mmap_buffer = NULL; + filp->f_op = old_fops; + if ((unsigned long)buf_priv->virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("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 + } else { + buf_priv->virtual = buf_priv->kernel_virtual; + buf_priv->currently_mapped = I830_BUF_MAPPED; + } + return retcode; +} + +static int i830_unmap_buffer(drm_buf_t *buf) +{ + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + int retcode = 0; + + if(VM_DONTCOPY != 0) { + if(buf_priv->currently_mapped != I830_BUF_MAPPED) + return -EINVAL; +#if LINUX_VERSION_CODE <= 0x020402 + down( ¤t->mm->mmap_sem ); +#else + down_write( ¤t->mm->mmap_sem ); +#endif +#if LINUX_VERSION_CODE < 0x020399 + retcode = do_munmap((unsigned long)buf_priv->virtual, + (size_t) buf->total); +#else + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, + (size_t) buf->total); +#endif +#if LINUX_VERSION_CODE <= 0x020402 + up( ¤t->mm->mmap_sem ); +#else + up_write( ¤t->mm->mmap_sem ); +#endif + } + buf_priv->currently_mapped = I830_BUF_UNMAPPED; + buf_priv->virtual = 0; + + return retcode; +} + +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; + + buf = i830_freelist_get(dev); + if (!buf) { + retcode = -ENOMEM; + DRM_DEBUG("retcode=%d\n", retcode); + return retcode; + } + + retcode = i830_map_buffer(buf, filp); + if(retcode) { + i830_freelist_put(dev, buf); + DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); + return retcode; + } + buf->pid = priv->pid; + buf_priv = buf->dev_private; + d->granted = 1; + d->request_idx = buf->idx; + d->request_size = buf->total; + d->virtual = buf_priv->virtual; + + return retcode; +} + +static unsigned long i830_alloc_page(drm_device_t *dev) +{ + unsigned long address; + + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&virt_to_page(address)->count); + set_bit(PG_locked, &virt_to_page(address)->flags); + + return address; +} + +static void i830_free_page(drm_device_t *dev, unsigned long page) +{ + if(page == 0UL) + return; + + atomic_dec(&virt_to_page(page)->count); + clear_bit(PG_locked, &virt_to_page(page)->flags); + wake_up(&virt_to_page(page)->wait); + free_page(page); + return; +} + +static int i830_dma_cleanup(drm_device_t *dev) +{ + drm_device_dma_t *dma = dev->dma; + + if(dev->dev_private) { + int i; + drm_i830_private_t *dev_priv = + (drm_i830_private_t *) dev->dev_private; + + if(dev_priv->ring.virtual_start) { + DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, + dev_priv->ring.Size); + } + if(dev_priv->hw_status_page != 0UL) { + i830_free_page(dev, dev_priv->hw_status_page); + /* Need to rewrite hardware status page */ + I830_WRITE(0x02080, 0x1ffff000); + } + DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), + DRM_MEM_DRIVER); + dev->dev_private = NULL; + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + } + } + return 0; +} + +static int i830_wait_ring(drm_device_t *dev, int n) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + int iters = 0; + unsigned long end; + unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + + end = jiffies + (HZ*3); + while (ring->space < n) { + int i; + + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; + + if (ring->head != last_head) { + end = jiffies + (HZ*3); + last_head = ring->head; + } + + iters++; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("space: %d wanted %d\n", ring->space, n); + DRM_ERROR("lockup\n"); + goto out_wait_ring; + } + + for (i = 0 ; i < 2000 ; i++) ; + } + +out_wait_ring: + return iters; +} + +static void i830_kernel_lost_context(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_ring_buffer_t *ring = &(dev_priv->ring); + + ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; + ring->tail = I830_READ(LP_RING + RING_TAIL); + ring->space = ring->head - (ring->tail+8); + if (ring->space < 0) ring->space += ring->Size; +} + +static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) +{ + drm_device_dma_t *dma = dev->dma; + int my_idx = 36; + u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); + int i; + + if(dma->buf_count > 1019) { + /* Not enough space in the status page for the freelist */ + return -EINVAL; + } + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + buf_priv->in_use = hw_status++; + buf_priv->my_use_idx = my_idx; + my_idx += 4; + + *buf_priv->in_use = I830_BUF_FREE; + + buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, + buf->total); + } + return 0; +} + +static int i830_dma_initialize(drm_device_t *dev, + drm_i830_private_t *dev_priv, + drm_i830_init_t *init) +{ + struct list_head *list; + + memset(dev_priv, 0, sizeof(drm_i830_private_t)); + + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea_map = r_list->map; + break; + } + } + + if(!dev_priv->sarea_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find sarea!\n"); + return -EINVAL; + } + DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset ); + if(!dev_priv->mmio_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find mmio map!\n"); + return -EINVAL; + } + DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset ); + if(!dev_priv->buffer_map) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not find dma buffer map!\n"); + return -EINVAL; + } + + dev_priv->sarea_priv = (drm_i830_sarea_t *) + ((u8 *)dev_priv->sarea_map->handle + + init->sarea_priv_offset); + + atomic_set(&dev_priv->flush_done, 0); + init_waitqueue_head(&dev_priv->flush_queue); + + dev_priv->ring.Start = init->ring_start; + dev_priv->ring.End = init->ring_end; + dev_priv->ring.Size = init->ring_size; + + dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + + init->ring_start, + init->ring_size); + + if (dev_priv->ring.virtual_start == NULL) { + dev->dev_private = (void *) dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return -ENOMEM; + } + + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + + dev_priv->w = init->w; + dev_priv->h = init->h; + dev_priv->pitch = init->pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->depth_offset = init->depth_offset; + + dev_priv->front_di1 = init->front_offset | init->pitch_bits; + dev_priv->back_di1 = init->back_offset | init->pitch_bits; + dev_priv->zi1 = init->depth_offset | init->pitch_bits; + + dev_priv->cpp = init->cpp; + /* We are using seperate values as placeholders for mechanisms for + * private backbuffer/depthbuffer usage. + */ + + dev_priv->back_pitch = init->back_pitch; + dev_priv->depth_pitch = init->depth_pitch; + + /* Program Hardware Status Page */ + dev_priv->hw_status_page = i830_alloc_page(dev); + if(dev_priv->hw_status_page == 0UL) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } + 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, virt_to_bus((void *)dev_priv->hw_status_page)); + DRM_DEBUG("Enabled hardware status page\n"); + + /* Now we need to init our freelist */ + if(i830_freelist_init(dev, dev_priv) != 0) { + dev->dev_private = (void *)dev_priv; + i830_dma_cleanup(dev); + DRM_ERROR("Not enough space in the status page for" + " the freelist\n"); + return -ENOMEM; + } + dev->dev_private = (void *)dev_priv; + + return 0; +} + +int i830_dma_init(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; + drm_i830_init_t init; + int retcode = 0; + + if (copy_from_user(&init, (drm_i830_init_t *)arg, sizeof(init))) + return -EFAULT; + + switch(init.func) { + case I830_INIT_DMA: + dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), + DRM_MEM_DRIVER); + if(dev_priv == NULL) return -ENOMEM; + retcode = i830_dma_initialize(dev, dev_priv, &init); + break; + case I830_CLEANUP_DMA: + retcode = i830_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; + } + + return retcode; +} + +/* Most efficient way to verify state for the i830 is as it is + * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. + */ +static void i830EmitContextVerified( drm_device_t *dev, + volatile 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_CTX_SETUP_SIZE ); + for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + +#if 0 + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) { + OUT_RING( tmp ); + j++; + } else { + printk("Skipping %d\n", i); + } +#else + OUT_RING( tmp ); + j++; +#endif + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexVerified( drm_device_t *dev, + volatile 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 ); + + 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] ); + + for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexBlendVerified( drm_device_t *dev, + volatile unsigned int *code, + volatile unsigned int num) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( num ); + + for ( i = 0 ; i < num ; i++ ) { + tmp = code[i]; + OUT_RING( tmp ); + j++; + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +static void i830EmitTexPalette( drm_device_t *dev, + unsigned int *palette, + int number, + int is_shared ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + + BEGIN_LP_RING( 258 ); + + if(is_shared == 1) { + OUT_RING(CMD_OP_MAP_PALETTE_LOAD | + MAP_PALETTE_NUM(0) | + MAP_PALETTE_BOTH); + } else { + OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); + } + for(i = 0; i < 256; i++) { + OUT_RING(palette[i]); + } + OUT_RING(0); +} + +/* Need to do some additional checking when setting the dest buffer. + */ +static void i830EmitDestVerified( drm_device_t *dev, + volatile 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 ); + + 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 ); + + 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( 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 ); + } else { + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); + } + + /* invarient: + */ + + + OUT_RING( GFX_OP_DESTBUFFER_VARS ); + OUT_RING( code[I830_DESTREG_DV1] ); + + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( code[I830_DESTREG_DR1] ); + OUT_RING( code[I830_DESTREG_DR2] ); + OUT_RING( code[I830_DESTREG_DR3] ); + OUT_RING( code[I830_DESTREG_DR4] ); + + /* Need to verify this */ + tmp = code[I830_DESTREG_SENABLE]; + if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { + OUT_RING( tmp ); + } else { + DRM_DEBUG("bad scissor enable\n"); + 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] ); + + 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; + + if (dirty & I830_UPLOAD_BUFFERS) { + i830EmitDestVerified( dev, sarea_priv->BufferState ); + sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; + } + + if (dirty & I830_UPLOAD_CTX) { + i830EmitContextVerified( dev, sarea_priv->ContextState ); + sarea_priv->dirty &= ~I830_UPLOAD_CTX; + } + + if (dirty & I830_UPLOAD_TEX0) { + i830EmitTexVerified( dev, sarea_priv->TexState[0] ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX0; + } + + if (dirty & I830_UPLOAD_TEX1) { + i830EmitTexVerified( dev, sarea_priv->TexState[1] ); + sarea_priv->dirty &= ~I830_UPLOAD_TEX1; + } + + if (dirty & I830_UPLOAD_TEXBLEND0) { + i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0], + sarea_priv->TexBlendStateWordsUsed[0]); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0; + } + + if (dirty & I830_UPLOAD_TEXBLEND1) { + i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1], + sarea_priv->TexBlendStateWordsUsed[1]); + sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1; + } + + if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + 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); + } + } +} + +static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval, + unsigned int clear_depthmask) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = dev_priv->cpp; + int i; + unsigned int BR13, CMD, D_CMD; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + switch(cpp) { + case 2: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + D_CMD = CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + D_CMD = XY_COLOR_BLT_CMD; + if(clear_depthmask & 0x00ffffff) + D_CMD |= XY_COLOR_BLT_WRITE_RGB; + if(clear_depthmask & 0xff000000) + D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; + break; + default: + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + D_CMD = CMD = XY_COLOR_BLT_CMD; + break; + } + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + if ( flags & I830_FRONT ) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( 0 ); + OUT_RING( clear_color ); + ADVANCE_LP_RING(); + } + + if ( flags & I830_BACK ) { + DRM_DEBUG("clear back\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( dev_priv->back_offset ); + OUT_RING( clear_color ); + ADVANCE_LP_RING(); + } + + if ( flags & I830_DEPTH ) { + DRM_DEBUG("clear depth\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( D_CMD ); + OUT_RING( BR13 ); + OUT_RING( (pbox->y1 << 16) | pbox->x1 ); + OUT_RING( (pbox->y2 << 16) | pbox->x2 ); + OUT_RING( dev_priv->depth_offset ); + OUT_RING( clear_zval ); + ADVANCE_LP_RING(); + } + } +} + +static void i830_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + 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"); + + switch(cpp) { + case 2: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + } + + i830_kernel_lost_context(dev); + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox; i++, pbox++) + { + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox->x1, pbox->y1, + pbox->x2, pbox->y2); + + 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( 0 /* front ofs always zero */ ); + OUT_RING( (pbox->y1 << 16) | + pbox->x1 ); + + OUT_RING( BR13 & 0xffff ); + OUT_RING( ofs ); + + ADVANCE_LP_RING(); + } +} + + +static void i830_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_clip_rect_t *box = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; + int i = 0, u; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + if (nbox > I830_NR_SAREA_CLIPRECTS) + nbox = I830_NR_SAREA_CLIPRECTS; + + if (discard) { + u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_HARDWARE); + if(u != I830_BUF_CLIENT) { + DRM_DEBUG("xxxx 2\n"); + } + } + + if (used > 4*1024) + used = 0; + + if (sarea_priv->dirty) + i830EmitState( dev ); + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); + + dev_priv->counter++; + DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); + DRM_DEBUG( "i830_dma_dispatch\n"); + DRM_DEBUG( "start : %lx\n", start); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); + + if (buf_priv->currently_mapped == I830_BUF_MAPPED) { + *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | + sarea_priv->vertex_prim | + ((used/4)-2)); + + if (used & 4) { + *(u32 *)((u32)buf_priv->virtual + used) = 0; + used += 4; + } + + i830_unmap_buffer(buf); + } + + if (used) { + do { + if (i < nbox) { + BEGIN_LP_RING(6); + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] ); + OUT_RING( box[i].x1 | (box[i].y1<<16) ); + OUT_RING( box[i].x2 | (box[i].y2<<16) ); + OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + 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); + } + + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); + + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I830_BUF_FREE ); + OUT_RING( 0 ); + } + + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + +/* Interrupts are only for flushing */ +void i830_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); + temp = temp & ~(0x6000); + if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, + temp); /* Clear all interrupts */ + else + return; + + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +void DRM(dma_immediate_bh)(void *device) +{ + drm_device_t *dev = (drm_device_t *) device; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +static inline void i830_dma_emit_flush(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + BEGIN_LP_RING(2); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +static inline void i830_dma_quiescent_emit(drm_device_t *dev) +{ + drm_i830_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + i830_kernel_lost_context(dev); + + BEGIN_LP_RING(4); + OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( 0 ); + OUT_RING( GFX_OP_USER_INTERRUPT ); + ADVANCE_LP_RING(); + + i830_wait_ring( dev, dev_priv->ring.Size - 8 ); + atomic_set(&dev_priv->flush_done, 1); + wake_up_interruptible(&dev_priv->flush_queue); +} + +void i830_dma_quiescent(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + unsigned long end; + + if(dev_priv == NULL) { + return; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i830_dma_quiescent_emit(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + return; +} + +static int i830_flush_queue(drm_device_t *dev) +{ + DECLARE_WAITQUEUE(entry, current); + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + unsigned long end; + int i, ret = 0; + + if(dev_priv == NULL) { + return 0; + } + atomic_set(&dev_priv->flush_done, 0); + add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + i830_dma_emit_flush(dev); + if (atomic_read(&dev_priv->flush_done) == 1) break; + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("lockup\n"); + break; + } + schedule_timeout(HZ*3); + if (signal_pending(current)) { + ret = -EINTR; /* Can't restart */ + break; + } + } + + current->state = TASK_RUNNING; + remove_wait_queue(&dev_priv->flush_queue, &entry); + + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, + I830_BUF_FREE); + + if (used == I830_BUF_HARDWARE) + DRM_DEBUG("reclaimed from HARDWARE\n"); + if (used == I830_BUF_CLIENT) + DRM_DEBUG("still on client HARDWARE\n"); + } + + return ret; +} + +/* Must be called with the lock held */ +void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + if (!dma) return; + if (!dev->dev_private) return; + if (!dma->buflist) return; + + i830_flush_queue(dev); + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i830_buf_priv_t *buf_priv = buf->dev_private; + + if (buf->pid == pid && buf_priv) { + int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, + I830_BUF_FREE); + + if (used == I830_BUF_CLIENT) + DRM_DEBUG("reclaimed from client\n"); + if(buf_priv->currently_mapped == I830_BUF_MAPPED) + buf_priv->currently_mapped = I830_BUF_UNMAPPED; + } + } +} + +int i830_flush_ioctl(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_DEBUG("i830_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_flush_ioctl called without lock held\n"); + return -EINVAL; + } + + i830_flush_queue(dev); + return 0; +} + +int i830_dma_vertex(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_device_dma_t *dma = dev->dma; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + drm_i830_vertex_t vertex; + + if (copy_from_user(&vertex, (drm_i830_vertex_t *)arg, sizeof(vertex))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; + + i830_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], + vertex.discard, vertex.used ); + + sarea_priv->last_enqueue = dev_priv->counter-1; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i830_clear_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_clear_t clear; + + if (copy_from_user(&clear, (drm_i830_clear_t *)arg, sizeof(clear))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_clear_bufs called without lock held\n"); + return -EINVAL; + } + + /* GH: Someone's doing nasty things... */ + if (!dev->dev_private) { + return -EINVAL; + } + + i830_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth, + clear.clear_depthmask); + return 0; +} + +int i830_swap_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_DEBUG("i830_swap_bufs\n"); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_swap_buf called without lock held\n"); + return -EINVAL; + } + + i830_dma_dispatch_swap( dev ); + return 0; +} + +int i830_getage(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 = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + + sarea_priv->last_dispatch = (int) hw_status[5]; + return 0; +} + +int i830_getbuf(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; + int retcode = 0; + drm_i830_dma_t d; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + + DRM_DEBUG("getbuf\n"); + if (copy_from_user(&d, (drm_i830_dma_t *)arg, sizeof(d))) + return -EFAULT; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma called without lock held\n"); + return -EINVAL; + } + + d.granted = 0; + + retcode = i830_dma_get_buffer(dev, &d, filp); + + DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n", + current->pid, retcode, d.granted); + + if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d))) + return -EFAULT; + sarea_priv->last_dispatch = (int) hw_status[5]; + + return retcode; +} + +int i830_copybuf(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_copy_t d; + drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; + u32 *hw_status = (u32 *)dev_priv->hw_status_page; + drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) + dev_priv->sarea_priv; + drm_buf_t *buf; + drm_i830_buf_priv_t *buf_priv; + drm_device_dma_t *dma = dev->dma; + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i830_dma called without lock held\n"); + return -EINVAL; + } + + if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d))) + return -EFAULT; + + if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL; + buf = dma->buflist[ d.idx ]; + buf_priv = buf->dev_private; + if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM; + + if(d.used < 0 || d.used > buf->total) return -EINVAL; + + if (copy_from_user(buf_priv->virtual, d.address, d.used)) + return -EFAULT; + + sarea_priv->last_dispatch = (int) hw_status[5]; + + return 0; +} + +int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + if(VM_DONTCOPY == 0) return 1; + return 0; +} diff --git a/bsd/i830_drv.c b/bsd/i830_drv.c new file mode 100644 index 00000000..ad31d1ef --- /dev/null +++ b/bsd/i830_drv.c @@ -0,0 +1,104 @@ +/* i830_drv.c -- I810 driver -*- linux-c -*- + * Created: Mon Dec 13 01:56:22 1999 by jhartmann@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 + * VA LINUX SYSTEMS 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> + * Jeff Hartmann <jhartmann@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Abraham vd Merwe <abraham@2d3d.co.za> + */ + +#include <linux/config.h> +#include "i830.h" +#include "drmP.h" +#include "drm.h" +#include "i830_drm.h" +#include "i830_drv.h" + +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i830" +#define DRIVER_DESC "Intel 830M" +#define DRIVER_DATE "20011004" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + +#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_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 }, + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + + +#include "drm_agpsupport.h" +#include "drm_auth.h" +#include "drm_bufs.h" +#include "drm_context.h" +#include "drm_dma.h" +#include "drm_drawable.h" +#include "drm_drv.h" + +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ + +/* JH- We have to hand expand the string ourselves because of the cpp. If + * anyone can think of a way that we can fit into the __setup macro without + * changing it, then please send the solution my way. + */ +static int __init i830_options( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", i830_options ); +#endif + +#include "drm_fops.h" +#include "drm_init.h" +#include "drm_ioctl.h" +#include "drm_lock.h" +#include "drm_lists.h" +#include "drm_memory.h" +#include "drm_proc.h" +#include "drm_vm.h" +#include "drm_stub.h" diff --git a/bsd/i830/i830_drv.h b/bsd/i830_drv.h index 4e9d6c80..4e9d6c80 100644 --- a/bsd/i830/i830_drv.h +++ b/bsd/i830_drv.h diff --git a/bsd/mga/Makefile b/bsd/mga/Makefile index bbaeaa56..82c7a382 100644 --- a/bsd/mga/Makefile +++ b/bsd/mga/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD= mga NOMAN= YES SRCS= mga_drv.c mga_state.c mga_warp.c mga_dma.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS+= ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS+= ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#MGA_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(MGA_OPTS) >> opt_drm_linux.h +.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/mga_drv.c b/bsd/mga_drv.c new file mode 100644 index 00000000..8b69b41b --- /dev/null +++ b/bsd/mga_drv.c @@ -0,0 +1,66 @@ +/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- + * Created: Mon Dec 13 01:56:22 1999 by jhartmann@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 + * VA LINUX SYSTEMS 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 "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" + +/* 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)[] = { + {0x102b, 0x0520, 0, "Matrox G200 (PCI)"}, + {0x102b, 0x0521, 1, "Matrox G200 (AGP)"}, + {0x102b, 0x0525, 1, "Matrox G400/G450 (AGP)"}, + {0x102b, 0x2527, 1, "Matrox G550 (AGP)"}, + {0, 0, 0, NULL} +}; + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" + +DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0); diff --git a/bsd/r128/Makefile b/bsd/r128/Makefile index ae5622ed..99b728bc 100644 --- a/bsd/r128/Makefile +++ b/bsd/r128/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD = r128 NOMAN= YES SRCS = r128_cce.c r128_drv.c r128_state.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS += device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS += ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS += ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#R128_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(R128_OPTS) >> opt_drm_linux.h +.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/r128/r128.h b/bsd/r128/r128.h deleted file mode 100644 index 926b4bfd..00000000 --- a/bsd/r128/r128.h +++ /dev/null @@ -1,81 +0,0 @@ -/* r128.h -- ATI Rage 128 DRM template customization -*- linux-c -*- - * Created: Wed Feb 14 16:07:10 2001 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 - * VA LINUX SYSTEMS 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 __R128_H__ -#define __R128_H__ - -/* This remains constant for all DRM template files. - */ -#define DRM(x) r128_##x - -/* General customization: - */ -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 0 -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 1 -#define __HAVE_SG 1 -#define __HAVE_PCI_DMA 1 - -/* Driver customization: - */ -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - r128_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \ -} while (0) - -/* DMA customization: - */ -#define __HAVE_DMA 1 - -#if 0 -/* GH: Remove this for now... */ -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - return r128_do_cce_idle( dev_priv ); \ -} while (0) -#endif - -/* Buffer customization: - */ -#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_r128_private_t *)((dev)->dev_private))->buffers - -#endif diff --git a/bsd/r128_drv.c b/bsd/r128_drv.c new file mode 100644 index 00000000..1a8046fb --- /dev/null +++ b/bsd/r128_drv.c @@ -0,0 +1,86 @@ +/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- + * Created: Mon Dec 13 09:47:27 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 + * VA LINUX SYSTEMS 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 "r128.h" +#include "drmP.h" +#include "drm.h" +#include "r128_drm.h" +#include "r128_drv.h" +#if __REALLY_HAVE_SG +#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, 0x4c45, __REALLY_HAVE_SG, "ATI Rage 128 Mobility LE (PCI)"}, + {0x1002, 0x4c46, 1, "ATI Rage 128 Mobility LF (AGP)"}, + {0x1002, 0x4d46, 1, "ATI Rage 128 Mobility MF (AGP)"}, + {0x1002, 0x4d4c, 1, "ATI Rage 128 Mobility ML (AGP)"}, + {0x1002, 0x5044, __REALLY_HAVE_SG, "ATI Rage 128 Pro PD (PCI)"}, + {0x1002, 0x5046, 1, "ATI Rage 128 Pro PF (AGP)"}, + {0x1002, 0x5050, __REALLY_HAVE_SG, "ATI Rage 128 Pro PP (PCI)"}, + {0x1002, 0x5052, __REALLY_HAVE_SG, "ATI Rage 128 Pro PR (PCI)"}, + {0x1002, 0x5245, __REALLY_HAVE_SG, "ATI Rage 128 RE (PCI)"}, + {0x1002, 0x5246, 1, "ATI Rage 128 RF (AGP)"}, + {0x1002, 0x5247, 1, "ATI Rage 128 RG (AGP)"}, + {0x1002, 0x524b, __REALLY_HAVE_SG, "ATI Rage 128 RK (PCI)"}, + {0x1002, 0x524c, 1, "ATI Rage 128 RL (AGP)"}, + {0x1002, 0x534d, 1, "ATI Rage 128 SM (AGP)"}, + {0x1002, 0x5446, 1, "ATI Rage 128 Pro Ultra TF (AGP)"}, + {0x1002, 0x544C, 1, "ATI Rage 128 Pro Ultra TL (AGP)"}, + {0x1002, 0x5452, 1, "ATI Rage 128 Pro Ultra TR (AGP)"}, + {0, 0, 0, NULL} +}; + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_sysctl.h" +#include "drm_vm.h" +#if __HAVE_SG +#include "drm_scatter.h" +#endif + +DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0); diff --git a/bsd/radeon/Makefile b/bsd/radeon/Makefile index b1d77bf4..844586a1 100644 --- a/bsd/radeon/Makefile +++ b/bsd/radeon/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD = radeon NOMAN= YES SRCS = radeon_cp.c radeon_drv.c radeon_state.c -SRCS += device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS += device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS += ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS += ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#RADEON_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(RADEON_OPTS) >> opt_drm_linux.h +.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/radeon_drv.c b/bsd/radeon_drv.c new file mode 100644 index 00000000..fe69fbb8 --- /dev/null +++ b/bsd/radeon_drv.c @@ -0,0 +1,76 @@ +/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*- + * Created: Wed Feb 14 17:10:04 2001 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 + * VA LINUX SYSTEMS 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> + */ + +#include <sys/types.h> + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#if __REALLY_HAVE_SG +#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)"}, + {0, 0, 0, NULL} +}; + +#include "drm_agpsupport.h" +#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_lock.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" +#if __HAVE_SG +#include "drm_scatter.h" +#endif + +DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0); diff --git a/bsd/sis/Makefile b/bsd/sis/Makefile deleted file mode 100644 index 07b41caa..00000000 --- a/bsd/sis/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# $FreeBSD$ - -KMOD= sis -NOMAN= YES -SRCS= sis_drv.c sis_ds.c sis_mm.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h -CFLAGS+= ${DEBUG_FLAGS} -I. -I.. - -@: - ln -sf /sys @ - -machine: - ln -sf /sys/i386/include machine - -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#SIS_OPTS= "\#define DRM_LINUX" 1 -.endif - -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(SIS_OPTS) >> opt_drm_linux.h - -.include <bsd.kmod.mk> diff --git a/bsd/sis/sis.h b/bsd/sis/sis.h deleted file mode 100644 index b257bb4a..00000000 --- a/bsd/sis/sis.h +++ /dev/null @@ -1,45 +0,0 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- - * - * 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. - * - */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/sis/sis.h,v 1.1 2001/12/13 00:24:51 alanh Exp $ */ - -#ifndef __SIS_H__ -#define __SIS_H__ - - -/* General customization: - */ -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 0 -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 1 - -/* Buffer customization: - */ -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_sis_private_t *)((dev)->dev_private))->buffers - -#endif diff --git a/bsd/sis/sis_drm.h b/bsd/sis/sis_drm.h deleted file mode 100644 index db11cf63..00000000 --- a/bsd/sis/sis_drm.h +++ /dev/null @@ -1,30 +0,0 @@ - -#ifndef _sis_drm_public_h_ -#define _sis_drm_public_h_ - -typedef struct { - int context; - unsigned int offset; - unsigned int size; - unsigned int free; -} drm_sis_mem_t; - -typedef struct { - unsigned int offset, size; -} drm_sis_agp_t; - -typedef struct { - unsigned int left, right; -} drm_sis_flip_t; - -#if defined(__KERNEL__) || defined(_KERNEL) - -int sis_fb_alloc(DRM_OS_IOCTL); -int sis_fb_free(DRM_OS_IOCTL); -int sisp_agp_init(DRM_OS_IOCTL); -int sisp_agp_alloc(DRM_OS_IOCTL); -int sisp_agp_free(DRM_OS_IOCTL); - -#endif - -#endif diff --git a/bsd/sis/sis_drv.h b/bsd/sis/sis_drv.h deleted file mode 100644 index b83a56a1..00000000 --- a/bsd/sis/sis_drv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- - * - * 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. - * - */ - -#ifndef _SIS_DRV_H_ -#define _SIS_DRV_H_ - -typedef struct drm_sis_private { - drm_map_t *buffers; -} drm_sis_private_t; - -/* Stereo ? - this was never committed */ - -int sis_flip( DRM_OS_IOCTL ); -int sis_flip_init( DRM_OS_IOCTL ); -int sis_flip_final( DRM_OS_IOCTL ); -void flip_final(void); - -#endif diff --git a/bsd/sis/sis_ds.c b/bsd/sis/sis_ds.c deleted file mode 100644 index 9bac886f..00000000 --- a/bsd/sis/sis_ds.c +++ /dev/null @@ -1,398 +0,0 @@ -/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw - * - * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. - * 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: - * Sung-Ching Lin <sclin@sis.com.tw> - * - */ - - -#include "sis.h" -#include "drmP.h" -#include "sis_ds.h" - -/* Set Data Structure, not check repeated value - * temporarily used - */ - -set_t *setInit(void) -{ - int i; - set_t *set; - - set = (set_t *)SD_MALLOC(sizeof(set_t)); - for(i = 0; i < SET_SIZE; i++){ - set->list[i].free_next = i+1; - set->list[i].alloc_next = -1; - } - set->list[SET_SIZE-1].free_next = -1; - set->free = 0; - set->alloc = -1; - set->trace = -1; - - return set; -} - -int setAdd(set_t *set, ITEM_TYPE item) -{ - int free = set->free; - - if(free != -1){ - set->list[free].val = item; - set->free = set->list[free].free_next; - } - else{ - return 0; - } - - set->list[free].alloc_next = set->alloc; - set->alloc = free; - set->list[free].free_next = -1; - - return 1; -} - -int setDel(set_t *set, ITEM_TYPE item) -{ - int alloc = set->alloc; - int prev = -1; - - while(alloc != -1){ - if(set->list[alloc].val == item){ - if(prev != -1) - set->list[prev].alloc_next = set->list[alloc].alloc_next; - else - set->alloc = set->list[alloc].alloc_next; - break; - } - prev = alloc; - alloc = set->list[alloc].alloc_next; - } - - if(alloc == -1) - return 0; - - set->list[alloc].free_next = set->free; - set->free = alloc; - set->list[alloc].alloc_next = -1; - - return 1; -} - -/* setFirst -> setAdd -> setNext is wrong */ - -int setFirst(set_t *set, ITEM_TYPE *item) -{ - if(set->alloc == -1) - return 0; - - *item = set->list[set->alloc].val; - set->trace = set->list[set->alloc].alloc_next; - - return 1; -} - -int setNext(set_t *set, ITEM_TYPE *item) -{ - if(set->trace == -1) - return 0; - - *item = set->list[set->trace].val; - set->trace = set->list[set->trace].alloc_next; - - return 1; -} - -int setDestroy(set_t *set) -{ - SD_FREE(set); - - return 1; -} - -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Keith Whitwell - * - * 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 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. - * - */ - -#define ISFREE(bptr) ((bptr)->free) - -#define PRINTF(fmt, arg...) do{}while(0) -#define fprintf(fmt, arg...) do{}while(0) - -static void *calloc(size_t nmemb, size_t size) -{ - void *addr; - addr = SD_MALLOC(nmemb*size); - memset(addr, 0, nmemb*size); - return addr; -} - -void mmDumpMemInfo( memHeap_t *heap ) -{ - TMemBlock *p; - - PRINTF ("Memory heap %p:\n", heap); - if (heap == 0) { - PRINTF (" heap == 0\n"); - } else { - p = (TMemBlock *)heap; - while (p) { - PRINTF (" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? '.':'U', - p->reserved ? 'R':'.'); - p = p->next; - } - } - PRINTF ("End of memory blocks\n"); -} - -memHeap_t *mmInit(int ofs, - int size) -{ - PMemBlock blocks; - - if (size <= 0) { - return 0; - } - blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock)); - if (blocks) { - blocks->ofs = ofs; - blocks->size = size; - blocks->free = 1; - return (memHeap_t *)blocks; - } else - return 0; -} - -/* Kludgey workaround for existing i810 server. Remove soon. - */ -memHeap_t *mmAddRange( memHeap_t *heap, - int ofs, - int size ) -{ - PMemBlock blocks; - blocks = (TMemBlock *) calloc(2,sizeof(TMemBlock)); - if (blocks) { - blocks[0].size = size; - blocks[0].free = 1; - blocks[0].ofs = ofs; - blocks[0].next = &blocks[1]; - - /* Discontinuity - stops JoinBlock from trying to join non-adjacent - * ranges. - */ - blocks[1].size = 0; - blocks[1].free = 0; - blocks[1].ofs = ofs+size; - blocks[1].next = (PMemBlock) heap; - return (memHeap_t *)blocks; - } - else - return heap; -} - -static TMemBlock* SliceBlock(TMemBlock *p, - int startofs, int size, - int reserved, int alignment) -{ - TMemBlock *newblock; - - /* break left */ - if (startofs > p->ofs) { - newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->next = p->next; - p->size -= newblock->size; - p->next = newblock; - p = newblock; - } - - /* break right */ - if (size < p->size) { - newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock)); - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->next = p->next; - p->size = size; - p->next = newblock; - } - - /* p = middle block */ - p->align = alignment; - p->free = 0; - p->reserved = reserved; - return p; -} - -PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch) -{ - int mask,startofs,endofs; - TMemBlock *p; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - mask = (1 << align2)-1; - startofs = 0; - p = (TMemBlock *)heap; - while (p) { - if (ISFREE(p)) { - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - p = p->next; - } - if (!p) - return NULL; - p = SliceBlock(p,startofs,size,0,mask+1); - p->heap = heap; - return p; -} - -static __inline__ int Join2Blocks(TMemBlock *p) -{ - if (p->free && p->next && p->next->free) { - TMemBlock *q = p->next; - p->size += q->size; - p->next = q->next; - SD_FREE(q); - return 1; - } - return 0; -} - -int mmFreeMem(PMemBlock b) -{ - TMemBlock *p,*prev; - - if (!b) - return 0; - if (!b->heap) { - fprintf(stderr, "no heap\n"); - return -1; - } - p = b->heap; - prev = NULL; - while (p && p != b) { - prev = p; - p = p->next; - } - if (!p || p->free || p->reserved) { - if (!p) - fprintf(stderr, "block not found in heap\n"); - else if (p->free) - fprintf(stderr, "block already free\n"); - else - fprintf(stderr, "block is reserved\n"); - return -1; - } - p->free = 1; - Join2Blocks(p); - if (prev) - Join2Blocks(prev); - return 0; -} - -int mmReserveMem(memHeap_t *heap, int offset,int size) -{ - int endofs; - TMemBlock *p; - - if (!heap || size <= 0) - return -1; - endofs = offset+size; - p = (TMemBlock *)heap; - while (p && p->ofs <= offset) { - if (ISFREE(p) && endofs <= (p->ofs+p->size)) { - SliceBlock(p,offset,size,1,1); - return 0; - } - p = p->next; - } - return -1; -} - -int mmFreeReserved(memHeap_t *heap, int offset) -{ - TMemBlock *p,*prev; - - if (!heap) - return -1; - p = (TMemBlock *)heap; - prev = NULL; - while (p && p->ofs != offset) { - prev = p; - p = p->next; - } - if (!p || !p->reserved) - return -1; - p->free = 1; - p->reserved = 0; - Join2Blocks(p); - if (prev) - Join2Blocks(prev); - return 0; -} - -void mmDestroy(memHeap_t *heap) -{ - TMemBlock *p,*q; - - if (!heap) - return; - p = (TMemBlock *)heap; - while (p) { - q = p->next; - SD_FREE(p); - p = q; - } -} diff --git a/bsd/sis/sis_ds.h b/bsd/sis/sis_ds.h deleted file mode 100644 index dbbd8ef5..00000000 --- a/bsd/sis/sis_ds.h +++ /dev/null @@ -1,163 +0,0 @@ -/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw - * - * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. - * 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: - * Sung-Ching Lin <sclin@sis.com.tw> - * - */ - -#ifndef _sis_ds_h_ -#define _sis_ds_h_ - -/* Set Data Structure */ - -#define SET_SIZE 5000 -#define SD_MALLOC(s) malloc( s, DRM(M_DRM), M_NOWAIT ) -#define SD_FREE(s) free( s, DRM(M_DRM) ) - -typedef unsigned int ITEM_TYPE; - -typedef struct { - ITEM_TYPE val; - int alloc_next, free_next; -} list_item_t; - -typedef struct { - int alloc; - int free; - int trace; - list_item_t list[SET_SIZE]; -} set_t; - -set_t *setInit(void); -int setAdd(set_t *set, ITEM_TYPE item); -int setDel(set_t *set, ITEM_TYPE item); -int setFirst(set_t *set, ITEM_TYPE *item); -int setNext(set_t *set, ITEM_TYPE *item); -int setDestroy(set_t *set); - -#endif - -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Keith Whitwell - * - * 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 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. - * - */ - -#ifndef MM_INC -#define MM_INC - -struct mem_block_t { - struct mem_block_t *next; - struct mem_block_t *heap; - int ofs,size; - int align; - int free:1; - int reserved:1; -}; -typedef struct mem_block_t TMemBlock; -typedef struct mem_block_t *PMemBlock; - -/* a heap is just the first block in a chain */ -typedef struct mem_block_t memHeap_t; - -static __inline__ int mmBlockSize(PMemBlock b) -{ return b->size; } - -static __inline__ int mmOffset(PMemBlock b) -{ return b->ofs; } - -static __inline__ void mmMarkReserved(PMemBlock b) -{ b->reserved = 1; } - -/* - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -memHeap_t *mmInit( int ofs, int size ); - - - -memHeap_t *mmAddRange( memHeap_t *heap, - int ofs, - int size ); - - -/* - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch ); - -/* - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -int mmFreeMem( PMemBlock b ); - -/* - * Reserve 'size' bytes block start at offset - * This is used to prevent allocation of memory already used - * by the X server for the front buffer, pixmaps, and cursor - * input: size, offset - * output: 0 if OK, -1 if error - */ -int mmReserveMem( memHeap_t *heap, int offset,int size ); -int mmFreeReserved( memHeap_t *heap, int offset ); - -/* - * destroy MM - */ -void mmDestroy( memHeap_t *mmInit ); - -/* For debuging purpose. */ -void mmDumpMemInfo( memHeap_t *mmInit ); - -#endif diff --git a/bsd/sis/sis_mm.c b/bsd/sis/sis_mm.c deleted file mode 100644 index c00aa7e5..00000000 --- a/bsd/sis/sis_mm.c +++ /dev/null @@ -1,300 +0,0 @@ -/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*- - * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw - * - * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. - * 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: - * Sung-Ching Lin <sclin@sis.com.tw> - * - */ - -#ifdef __linux -#define __NO_VERSION__ -#include <linux/sisfb.h> -#endif - -#include "sis.h" -#include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" -#include "sis_ds.h" - -#define MAX_CONTEXT 100 -#define VIDEO_TYPE 0 -#define AGP_TYPE 1 - -typedef struct { - int used; - int context; - set_t *sets[2]; /* 0 for video, 1 for AGP */ -} sis_context_t; - -static sis_context_t global_ppriv[MAX_CONTEXT]; - -static int add_alloc_set(int context, int type, unsigned int val) -{ - int i, retval = 0; - - for(i = 0; i < MAX_CONTEXT; i++) - if(global_ppriv[i].used && global_ppriv[i].context == context){ - retval = setAdd(global_ppriv[i].sets[type], val); - break; - } - return retval; -} - -static int del_alloc_set(int context, int type, unsigned int val) -{ - int i, retval = 0; - for(i = 0; i < MAX_CONTEXT; i++) - if(global_ppriv[i].used && global_ppriv[i].context == context){ - retval = setDel(global_ppriv[i].sets[type], val); - break; - } - return retval; -} - -/* fb management via fb device */ -#if 1 -int sis_fb_alloc( DRM_OS_IOCTL ) -{ - drm_sis_mem_t fb; - struct sis_memreq req; - int retval = 0; - - DRM_OS_KRNFROMUSR( fb, (drm_sis_mem_t *) data, sizeof(fb) ); - - req.size = fb.size; - sis_malloc(&req); - if(req.offset){ - /* TODO */ - fb.offset = req.offset; - fb.free = req.offset; - if(!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)){ - DRM_DEBUG("adding to allocation set fails"); - sis_free(req.offset); - retval = -1; - } - } - else{ - fb.offset = 0; - fb.size = 0; - fb.free = 0; - } - - DRM_OS_KRNTOUSR( (drm_sis_mem_t *) data, fb, sizeof(fb) ); - - DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); - - return retval; -} - -int sis_fb_free( DRM_OS_IOCTL ) -{ - drm_sis_mem_t fb; - int retval = 0; - - DRM_OS_KRNFROMUSR( fb, (drm_sis_mem_t *) data, sizeof(fb) ); - - if(!fb.free){ - return -1; - } - - sis_free(fb.free); - if(!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) - retval = -1; - - DRM_DEBUG("free fb, offset = %d\n", fb.free); - - return retval; -} - -#else - -int sis_fb_alloc( DRM_OS_IOCTL ) -{ - return -1; -} - -int sis_fb_free( DRM_OS_IOCTL ) -{ - return 0; -} - -#endif - -/* agp memory management */ -#if 1 - -static memHeap_t *AgpHeap = NULL; - -int sisp_agp_init( DRM_OS_IOCTL ) -{ - drm_sis_agp_t agp; - - DRM_OS_KRNFROMUSR( agp, (drm_sis_agp_t *) data, sizeof(agp) ); - - AgpHeap = mmInit(agp.offset, agp.size); - - DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size); - - return 0; -} - -int sisp_agp_alloc( DRM_OS_IOCTL ) -{ - drm_sis_mem_t agp; - PMemBlock block; - int retval = 0; - - if(!AgpHeap) - return -1; - - DRM_OS_KRNFROMUSR( agp, (drm_sis_mem_t *) data, sizeof(agp)); - - block = mmAllocMem(AgpHeap, agp.size, 0, 0); - if(block){ - /* TODO */ - agp.offset = block->ofs; - agp.free = (unsigned int)block; - if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){ - DRM_DEBUG("adding to allocation set fails"); - mmFreeMem((PMemBlock)agp.free); - retval = -1; - } - } - else{ - agp.offset = 0; - agp.size = 0; - agp.free = 0; - } - - DRM_OS_KRNTOUSR( (drm_sis_mem_t *) data, agp, sizeof(agp) ); - - DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset); - - return retval; -} - -int sisp_agp_free( DRM_OS_IOCTL ) -{ - drm_sis_mem_t agp; - int retval = 0; - - if(!AgpHeap) - return -1; - - DRM_OS_KRNFROMUSR( agp, (drm_sis_mem_t *) data, sizeof(agp)); - - if(!agp.free){ - return -1; - } - - mmFreeMem((PMemBlock)agp.free); - if(!del_alloc_set(agp.context, AGP_TYPE, agp.free)) - retval = -1; - - DRM_DEBUG("free agp, free = %d\n", agp.free); - - return retval; -} - -#endif - -int sis_init_context(int context) -{ - int i; - - for(i = 0; i < MAX_CONTEXT ; i++) - if(global_ppriv[i].used && (global_ppriv[i].context == context)) - break; - - if(i >= MAX_CONTEXT){ - for(i = 0; i < MAX_CONTEXT ; i++){ - if(!global_ppriv[i].used){ - global_ppriv[i].context = context; - global_ppriv[i].used = 1; - global_ppriv[i].sets[0] = setInit(); - global_ppriv[i].sets[1] = setInit(); - DRM_DEBUG("init allocation set, socket=%d, context = %d\n", - i, context); - break; - } - } - if((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) || - (global_ppriv[i].sets[1] == NULL)){ - return 0; - } - } - - return 1; -} - -int sis_final_context(int context) -{ - int i; - - for(i=0; i<MAX_CONTEXT; i++) - if(global_ppriv[i].used && (global_ppriv[i].context == context)) - break; - - if(i < MAX_CONTEXT){ - set_t *set; - unsigned int item; - int retval; - - DRM_DEBUG("find socket %d, context = %d\n", i, context); - - /* Video Memory */ - set = global_ppriv[i].sets[0]; - retval = setFirst(set, &item); - while(retval){ - DRM_DEBUG("free video memory 0x%x\n", item); -#if 0 - sis_free(item); -#endif - retval = setNext(set, &item); - } - setDestroy(set); - - /* AGP Memory */ - set = global_ppriv[i].sets[1]; - retval = setFirst(set, &item); - while(retval){ - DRM_DEBUG("free agp memory 0x%x\n", item); - mmFreeMem((PMemBlock)item); - retval = setNext(set, &item); - } - setDestroy(set); - - global_ppriv[i].used = 0; - } - - /* turn-off auto-flip */ - /* TODO */ -#if defined(SIS_STEREO) - flip_final(); -#endif - - return 1; -} diff --git a/bsd/sis_drm.h b/bsd/sis_drm.h index 21b66350..8b88c507 100644 --- a/bsd/sis_drm.h +++ b/bsd/sis_drm.h @@ -29,11 +29,11 @@ typedef struct { #if defined(__KERNEL__) || defined(_KERNEL) -int sis_fb_alloc(DRM_OS_IOCTL); -int sis_fb_free(DRM_OS_IOCTL); -int sisp_agp_init(DRM_OS_IOCTL); -int sisp_agp_alloc(DRM_OS_IOCTL); -int sisp_agp_free(DRM_OS_IOCTL); +int sis_fb_alloc(DRM_IOCTL_ARGS); +int sis_fb_free(DRM_IOCTL_ARGS); +int sisp_agp_init(DRM_IOCTL_ARGS); +int sisp_agp_alloc(DRM_IOCTL_ARGS); +int sisp_agp_free(DRM_IOCTL_ARGS); #endif diff --git a/bsd/tdfx/tdfx.h b/bsd/tdfx.h index 40aba8fb..40aba8fb 100644 --- a/bsd/tdfx/tdfx.h +++ b/bsd/tdfx.h diff --git a/bsd/tdfx/Makefile b/bsd/tdfx/Makefile index d177ff60..149e3112 100644 --- a/bsd/tdfx/Makefile +++ b/bsd/tdfx/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/.. KMOD= tdfx NOMAN= YES SRCS= tdfx_drv.c -SRCS+= device_if.h bus_if.h pci_if.h opt_drm_linux.h +SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h CFLAGS+= ${DEBUG_FLAGS} -I. -I.. @: @@ -12,14 +13,17 @@ CFLAGS+= ${DEBUG_FLAGS} -I. -I.. machine: ln -sf /sys/i386/include machine -.if ${MACHINE_ARCH} == "i386" -# This line enables linux ioctl handling -# If you want support for this uncomment this line -#TDFX_OPTS= "\#define DRM_LINUX" 1 +.if defined(DRM_DEBUG) +DRM_DEBUG_OPT= "\#define DRM_DEBUG 1" .endif -opt_drm_linux.h: - touch opt_drm_linux.h - echo $(TDFX_OPTS) >> opt_drm_linux.h +.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/tdfx_drv.c b/bsd/tdfx_drv.c new file mode 100644 index 00000000..8bc8c57d --- /dev/null +++ b/bsd/tdfx_drv.c @@ -0,0 +1,99 @@ +/* tdfx_drv.c -- tdfx driver -*- linux-c -*- + * Created: Thu Oct 7 10:38:32 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> + * Daryll Strauss <daryll@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + + +#include <sys/types.h> + +#include "tdfx.h" +#include "drmP.h" + +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "tdfx" +#define DRIVER_DESC "3dfx Banshee/Voodoo3+" +#define DRIVER_DATE "20010216" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#ifndef PCI_VENDOR_ID_3DFX +#define PCI_VENDOR_ID_3DFX 0x121A +#endif +#ifndef PCI_DEVICE_ID_3DFX_VOODOO5 +#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 +#endif +#ifndef PCI_DEVICE_ID_3DFX_VOODOO4 +#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007 +#endif +#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000 /* Voodoo3 3000 */ +#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005 +#endif +#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000 /* Voodoo3 3000 */ +#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004 +#endif +#ifndef PCI_DEVICE_ID_3DFX_BANSHEE +#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 +#endif + +/* 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)[] = { + {0x121a, 0x0003, 1, "3dfx Voodoo Banshee"}, + {0x121a, 0x0004, 1, "3dfx Voodoo3 2000"}, + {0x121a, 0x0005, 1, "3dfx Voodoo3 3000"}, + {0x121a, 0x0007, 1, "3dfx Voodoo4"}, + {0x121a, 0x0009, 1, "3dfx Voodoo5"}, + {0, 0, 0, NULL} +}; + + +#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_lock.h" +#include "drm_memory.h" +#include "drm_vm.h" +#include "drm_sysctl.h" + +#ifdef __FreeBSD__ +DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0); +#endif /* __FreeBSD__ */ diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 9cc83a27..b5375ee5 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -1381,7 +1381,8 @@ int drmCommandRead(int fd, unsigned long drmCommandIndex, { unsigned long request; - request = DRM_IOR( DRM_COMMAND_BASE + drmCommandIndex, size); + request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, + DRM_COMMAND_BASE + drmCommandIndex, size); if (ioctl(fd, request, data)) { return -errno; @@ -1394,7 +1395,8 @@ int drmCommandWrite(int fd, unsigned long drmCommandIndex, { unsigned long request; - request = DRM_IOW( DRM_COMMAND_BASE + drmCommandIndex, size); + request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, + DRM_COMMAND_BASE + drmCommandIndex, size); if (ioctl(fd, request, data)) { return -errno; @@ -1407,7 +1409,8 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, { unsigned long request; - request = DRM_IOWR( DRM_COMMAND_BASE + drmCommandIndex, size); + request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, + DRM_COMMAND_BASE + drmCommandIndex, size); if (ioctl(fd, request, data)) { return -errno; diff --git a/linux-core/drmP.h b/linux-core/drmP.h index ee6c3781..c00efb4c 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -71,6 +71,8 @@ #include <asm/pgalloc.h> #include "drm.h" +#include "drm_os_linux.h" + /* DRM template customization defaults */ #ifndef __HAVE_AGP @@ -101,7 +103,7 @@ #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) #define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR)) - +#define __REALLY_HAVE_SG (__HAVE_SG) /* Begin the DRM... */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index b124c422..af6858d7 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -127,6 +127,22 @@ static struct file_operations DRM(fops) = { \ } #endif +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ +/* Use an additional macro to avoid preprocessor troubles */ +#define DRM_OPTIONS_FUNC DRM(options) +static int __init DRM(options)( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC ); +#undef DRM_OPTIONS_FUNC +#endif /* * The default number of instances (minor numbers) to initialize. diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h new file mode 100644 index 00000000..8c073f0b --- /dev/null +++ b/linux-core/drm_os_linux.h @@ -0,0 +1,56 @@ +#define __NO_VERSION__ + +#include <linux/interrupt.h> /* For task queue support */ +#include <linux/delay.h> + +#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_DEVICE drm_file_t *priv = filp->private_data; \ + drm_device_t *dev = priv->dev + +/* For data going from/to the kernel through the ioctl argument */ +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_from_user(&arg1, arg2, arg3) ) \ + return -EFAULT +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_to_user(arg1, &arg2, arg3) ) \ + return -EFAULT +/* Other copying of data from/to kernel space */ +#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ + copy_from_user(arg1, arg2, arg3) +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ + copy_to_user(arg1, arg2, arg3) +/* Macros for copyfrom user, but checking readability only once */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + verify_area( VERIFY_READ, uaddr, size ) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + __copy_from_user(arg1, arg2, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + __get_user(val, uaddr) + + +/* malloc/free without the overhead of DRM(alloc) */ +#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) +#define DRM_FREE(x) kfree(x) + +#define DRM_GETSAREA() \ +do { \ + struct list_head *list; \ + list_for_each( list, &dev->maplist->head ) { \ + drm_map_list_t *entry = (drm_map_list_t *)list; \ + if ( entry->map && \ + entry->map->type == _DRM_SHM && \ + (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ + dev_priv->sarea = entry->map; \ + break; \ + } \ + } \ +} while (0) diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index d1a92e2a..439d7887 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -37,48 +37,6 @@ #include "i810_drm.h" #include "i810_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20020211" - -/* Interface history - * - * 1.1 - XFree86 4.1 - * 1.2 - XvMC interfaces - * - XFree86 4.2 - * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) - * - Remove requirement for interrupt (leave stubs again) - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } - - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -87,25 +45,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i810_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i810_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux-core/i830_drv.c b/linux-core/i830_drv.c index ad31d1ef..b5efcef3 100644 --- a/linux-core/i830_drv.c +++ b/linux-core/i830_drv.c @@ -38,34 +38,6 @@ #include "i830_drm.h" #include "i830_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i830" -#define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20011004" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#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_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 }, - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -74,25 +46,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i830_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i830_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index cc8d728e..f0d4935d 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -35,36 +35,6 @@ #include "drm.h" #include "mga_drm.h" #include "mga_drv.h" - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010321" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 2 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, - - -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -72,27 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init mga_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", mga_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index 32180a30..e2e42690 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -37,45 +37,6 @@ #include "r128_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010917" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -83,26 +44,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init r128_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", r128_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index e4af560b..df859360 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -35,49 +35,6 @@ #include "radeon_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20020611" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 -#define DRIVER_PATCHLEVEL 1 - -/* Interface history: - * - * 1.1 - ?? - * 1.2 - Add vertex2 ioctl (keith) - * - Add stencil capability to clear ioctl (gareth, keith) - * - Increase MAX_TEXTURE_LEVELS (brian) - * 1.3 - Add cmdbuf ioctl (keith) - * - Add support for new radeon packets (keith) - * - Add getparam ioctl (keith) - * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). - */ -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -85,26 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init radeon_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", radeon_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c index 2d9612f5..0c917bd4 100644 --- a/linux-core/sis_drv.c +++ b/linux-core/sis_drv.c @@ -31,31 +31,6 @@ #include "sis_drm.h" #include "sis_drv.h" -#define DRIVER_AUTHOR "SIS" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20010503" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ - /* AGP Memory Management */ \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } -#if 0 /* these don't appear to be defined */ - /* SIS Stereo */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } -#endif - -#define __HAVE_COUNTERS 5 - #include "drm_auth.h" #include "drm_agpsupport.h" #include "drm_bufs.h" diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c index 91499077..8b790188 100644 --- a/linux-core/tdfx_drv.c +++ b/linux-core/tdfx_drv.c @@ -82,25 +82,6 @@ static drm_pci_list_t DRM(idlist)[] = { #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init tdfx_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", tdfx_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/drm.h b/linux/drm.h index 6ab295c4..376568e0 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -38,10 +38,27 @@ #if defined(__linux__) #include <linux/config.h> #include <asm/ioctl.h> /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include <sys/ioccom.h> -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include <sys/ioccom.h> +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif #define XFREE86_VERSION(major,minor,patch,snap) \ @@ -367,10 +384,9 @@ typedef struct drm_scatter_gather { #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) diff --git a/linux/drmP.h b/linux/drmP.h index ee6c3781..c00efb4c 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -71,6 +71,8 @@ #include <asm/pgalloc.h> #include "drm.h" +#include "drm_os_linux.h" + /* DRM template customization defaults */ #ifndef __HAVE_AGP @@ -101,7 +103,7 @@ #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) #define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR)) - +#define __REALLY_HAVE_SG (__HAVE_SG) /* Begin the DRM... */ diff --git a/linux/drm_drv.h b/linux/drm_drv.h index b124c422..af6858d7 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -127,6 +127,22 @@ static struct file_operations DRM(fops) = { \ } #endif +#ifndef MODULE +/* DRM(options) is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ +/* Use an additional macro to avoid preprocessor troubles */ +#define DRM_OPTIONS_FUNC DRM(options) +static int __init DRM(options)( char *str ) +{ + DRM(parse_options)( str ); + return 1; +} + +__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC ); +#undef DRM_OPTIONS_FUNC +#endif /* * The default number of instances (minor numbers) to initialize. diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h new file mode 100644 index 00000000..8c073f0b --- /dev/null +++ b/linux/drm_os_linux.h @@ -0,0 +1,56 @@ +#define __NO_VERSION__ + +#include <linux/interrupt.h> /* For task queue support */ +#include <linux/delay.h> + +#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_DEVICE drm_file_t *priv = filp->private_data; \ + drm_device_t *dev = priv->dev + +/* For data going from/to the kernel through the ioctl argument */ +#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_from_user(&arg1, arg2, arg3) ) \ + return -EFAULT +#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ + if ( copy_to_user(arg1, &arg2, arg3) ) \ + return -EFAULT +/* Other copying of data from/to kernel space */ +#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ + copy_from_user(arg1, arg2, arg3) +#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ + copy_to_user(arg1, arg2, arg3) +/* Macros for copyfrom user, but checking readability only once */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + verify_area( VERIFY_READ, uaddr, size ) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + __copy_from_user(arg1, arg2, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + __get_user(val, uaddr) + + +/* malloc/free without the overhead of DRM(alloc) */ +#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) +#define DRM_FREE(x) kfree(x) + +#define DRM_GETSAREA() \ +do { \ + struct list_head *list; \ + list_for_each( list, &dev->maplist->head ) { \ + drm_map_list_t *entry = (drm_map_list_t *)list; \ + if ( entry->map && \ + entry->map->type == _DRM_SHM && \ + (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \ + dev_priv->sarea = entry->map; \ + break; \ + } \ + } \ +} while (0) diff --git a/linux/gamma.h b/linux/gamma.h index a38c3c28..44d8d5bc 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -38,6 +38,31 @@ */ #define __HAVE_MTRR 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "gamma" +#define DRIVER_DESC "3DLabs gamma" +#define DRIVER_DATE "20010624" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } + +#define IOCTL_TABLE_NAME DRM(ioctls) +#define IOCTL_FUNC_NAME DRM(ioctl) + +#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 + /* DMA customization: */ #define __HAVE_DMA 1 diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index 3d37a5fc..b41526bb 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -36,32 +36,6 @@ #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 "20010624" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } - -#define IOCTL_TABLE_NAME DRM(ioctls) -#define IOCTL_FUNC_NAME DRM(ioctl) - -#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_agpsupport.h" #include "drm_bufs.h" @@ -70,25 +44,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init gamma_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", gamma_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/i810.h b/linux/i810.h index 64309f59..ea1e7fe5 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -41,6 +41,47 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i810" +#define DRIVER_DESC "Intel i810" +#define DRIVER_DATE "20020211" + +/* Interface history + * + * 1.1 - XFree86 4.1 + * 1.2 - XvMC interfaces + * - XFree86 4.2 + * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) + * - Remove requirement for interrupt (leave stubs again) + */ +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 1 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } + + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 diff --git a/linux/i810_drv.c b/linux/i810_drv.c index d1a92e2a..439d7887 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -37,48 +37,6 @@ #include "i810_drm.h" #include "i810_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20020211" - -/* Interface history - * - * 1.1 - XFree86 4.1 - * 1.2 - XvMC interfaces - * - XFree86 4.2 - * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) - * - Remove requirement for interrupt (leave stubs again) - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 } - - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -87,25 +45,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i810_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i810_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/i830.h b/linux/i830.h index fb7a0b32..794588b2 100644 --- a/linux/i830.h +++ b/linux/i830.h @@ -41,6 +41,33 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "VA Linux Systems Inc." + +#define DRIVER_NAME "i830" +#define DRIVER_DESC "Intel 830M" +#define DRIVER_DATE "20011004" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + +#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_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 }, + +#define __HAVE_COUNTERS 4 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY +#define __HAVE_COUNTER9 _DRM_STAT_DMA + /* Driver customization: */ #define __HAVE_RELEASE 1 diff --git a/linux/i830_drv.c b/linux/i830_drv.c index ad31d1ef..b5efcef3 100644 --- a/linux/i830_drv.c +++ b/linux/i830_drv.c @@ -38,34 +38,6 @@ #include "i830_drm.h" #include "i830_drv.h" -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i830" -#define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20011004" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#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_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 }, - -#define __HAVE_COUNTERS 4 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_COUNTER9 _DRM_STAT_DMA - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -74,25 +46,6 @@ #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init i830_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", i830_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/mga_drv.c b/linux/mga_drv.c index cc8d728e..f0d4935d 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -35,36 +35,6 @@ #include "drm.h" #include "mga_drm.h" #include "mga_drv.h" - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010321" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 2 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, - - -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -72,27 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init mga_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", mga_options ); -#endif - - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/r128_drv.c b/linux/r128_drv.c index 32180a30..e2e42690 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -37,45 +37,6 @@ #include "r128_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010917" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, - - -#if 0 -/* GH: Count data sent to card via ring or vertex/indirect buffers. - */ -#define __HAVE_COUNTERS 3 -#define __HAVE_COUNTER6 _DRM_STAT_IRQ -#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY -#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#endif - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -83,26 +44,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init r128_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", r128_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/radeon.h b/linux/radeon.h deleted file mode 100644 index 0fdeb82a..00000000 --- a/linux/radeon.h +++ /dev/null @@ -1,81 +0,0 @@ -/* radeon.h -- ATI Radeon DRM template customization -*- linux-c -*- - * Created: Wed Feb 14 17:07:34 2001 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 - * VA LINUX SYSTEMS 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 __RADEON_H__ -#define __RADEON_H__ - -/* This remains constant for all DRM template files. - */ -#define DRM(x) radeon_##x - -/* General customization: - */ -#define __HAVE_AGP 1 -#define __MUST_HAVE_AGP 0 -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 1 -#define __HAVE_SG 1 -#define __HAVE_PCI_DMA 1 - -/* Driver customization: - */ -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - radeon_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ -} while (0) - -/* DMA customization: - */ -#define __HAVE_DMA 1 - -#if 0 -/* GH: Remove this for now... */ -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - return radeon_do_cp_idle( dev_priv ); \ -} while (0) -#endif - -/* Buffer customization: - */ -#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_radeon_private_t *)((dev)->dev_private))->buffers - -#endif diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index e4af560b..df859360 100644 --- a/linux/radeon_drv.c +++ b/linux/radeon_drv.c @@ -35,49 +35,6 @@ #include "radeon_drv.h" #include "ati_pcigart.h" -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20020611" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 -#define DRIVER_PATCHLEVEL 1 - -/* Interface history: - * - * 1.1 - ?? - * 1.2 - Add vertex2 ioctl (keith) - * - Add stencil capability to clear ioctl (gareth, keith) - * - Increase MAX_TEXTURE_LEVELS (brian) - * 1.3 - Add cmdbuf ioctl (keith) - * - Add support for new radeon packets (keith) - * - Add getparam ioctl (keith) - * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). - */ -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, - - #include "drm_agpsupport.h" #include "drm_auth.h" #include "drm_bufs.h" @@ -85,26 +42,6 @@ #include "drm_dma.h" #include "drm_drawable.h" #include "drm_drv.h" - -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init radeon_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", radeon_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/sis.h b/linux/sis.h index 02f03086..0bf3dfa9 100644 --- a/linux/sis.h +++ b/linux/sis.h @@ -42,6 +42,31 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "SIS" +#define DRIVER_NAME "sis" +#define DRIVER_DESC "SIS 300/630/540" +#define DRIVER_DATE "20010503" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ + /* AGP Memory Management */ \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ + [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } +#if 0 /* these don't appear to be defined */ + /* SIS Stereo */ + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, + [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } +#endif + +#define __HAVE_COUNTERS 5 + /* Buffer customization: */ #define DRIVER_AGP_BUFFERS_MAP( dev ) \ diff --git a/linux/sis_drv.c b/linux/sis_drv.c index 2d9612f5..0c917bd4 100644 --- a/linux/sis_drv.c +++ b/linux/sis_drv.c @@ -31,31 +31,6 @@ #include "sis_drm.h" #include "sis_drv.h" -#define DRIVER_AUTHOR "SIS" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20010503" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 0 }, \ - /* AGP Memory Management */ \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 0 }, \ - [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 0 } -#if 0 /* these don't appear to be defined */ - /* SIS Stereo */ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 }, - [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 } -#endif - -#define __HAVE_COUNTERS 5 - #include "drm_auth.h" #include "drm_agpsupport.h" #include "drm_bufs.h" diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index 91499077..8b790188 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -82,25 +82,6 @@ static drm_pci_list_t DRM(idlist)[] = { #include "drm_drawable.h" #include "drm_drv.h" -#ifndef MODULE -/* DRM(options) is called by the kernel to parse command-line options - * passed via the boot-loader (e.g., LILO). It calls the insmod option - * routine, drm_parse_drm. - */ - -/* JH- We have to hand expand the string ourselves because of the cpp. If - * anyone can think of a way that we can fit into the __setup macro without - * changing it, then please send the solution my way. - */ -static int __init tdfx_options( char *str ) -{ - DRM(parse_options)( str ); - return 1; -} - -__setup( DRIVER_NAME "=", tdfx_options ); -#endif - #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/shared-core/drm.h b/shared-core/drm.h index 6ab295c4..376568e0 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -38,10 +38,27 @@ #if defined(__linux__) #include <linux/config.h> #include <asm/ioctl.h> /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include <sys/ioccom.h> -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include <sys/ioccom.h> +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif #define XFREE86_VERSION(major,minor,patch,snap) \ @@ -367,10 +384,9 @@ typedef struct drm_scatter_gather { #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) diff --git a/linux/mga_dma.c b/shared-core/mga_dma.c index 525975a8..1d64e1ca 100644 --- a/linux/mga_dma.c +++ b/shared-core/mga_dma.c @@ -33,16 +33,12 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "mga.h" #include "drmP.h" #include "drm.h" #include "mga_drm.h" #include "mga_drv.h" -#include <linux/interrupt.h> /* For task queue support */ -#include <linux/delay.h> - #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 @@ -55,7 +51,7 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; @@ -63,32 +59,32 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) MGA_WRITE8( MGA_CRTC_INDEX, 0 ); return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed!\n" ); DRM_INFO( " status=0x%08x\n", status ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } int mga_do_dma_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed! status=0x%08x\n", status ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } int mga_do_dma_reset( drm_mga_private_t *dev_priv ) @@ -96,7 +92,7 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv ) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The primary DMA stream should look like new right about now. */ @@ -117,13 +113,13 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv ) int mga_do_engine_reset( drm_mga_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* Okay, so we've completely screwed up and locked the engine. * How about we clean up after ourselves? */ MGA_WRITE( MGA_RST, MGA_SOFTRESET ); - udelay( 15 ); /* Wait at least 10 usecs */ + DRM_UDELAY( 15 ); /* Wait at least 10 usecs */ MGA_WRITE( MGA_RST, 0 ); /* Initialize the registers that get clobbered by the soft @@ -162,7 +158,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( primary->tail == primary->last_flush ) { DRM_DEBUG( " bailing out...\n" ); @@ -201,7 +197,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) mga_flush_write_combine(); MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) @@ -209,7 +205,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA_WRAP(); @@ -244,7 +240,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); set_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) @@ -252,7 +248,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_wrap++; DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); @@ -261,7 +257,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); clear_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __FUNCTION__ ); + DRM_DEBUG( "done.\n" ); } @@ -301,13 +297,12 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; - DRM_DEBUG( "%s: count=%d\n", - __FUNCTION__, dma->buf_count ); + DRM_DEBUG( "count=%d\n", dma->buf_count ); dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); if ( dev_priv->head == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) ); SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 ); @@ -319,7 +314,7 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) entry = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); if ( entry == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( entry, 0, sizeof(drm_mga_freelist_t) ); @@ -348,7 +343,7 @@ static void mga_freelist_cleanup( drm_device_t *dev ) drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; drm_mga_freelist_t *next; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); entry = dev_priv->head; while ( entry ) { @@ -386,7 +381,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev ) drm_mga_freelist_t *prev; drm_mga_freelist_t *tail = dev_priv->tail; u32 head, wrap; - DRM_DEBUG( "%s:\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); head = MGA_READ( MGA_PRIMADDRESS ); wrap = dev_priv->sarea_priv->last_wrap; @@ -418,8 +413,7 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *head, *entry, *prev; - DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n", - __FUNCTION__, + DRM_DEBUG( "age=0x%06lx wrap=%d\n", buf_priv->list_entry->age.head - dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); @@ -452,13 +446,12 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) { drm_mga_private_t *dev_priv; - struct list_head *list; int ret; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER ); if ( !dev_priv ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_mga_private_t) ); @@ -488,21 +481,14 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->texture_offset = init->texture_offset[0]; dev_priv->texture_size = init->texture_size[0]; - list_for_each( list, &dev->maplist->head ) { - drm_map_list_t *entry = (drm_map_list_t *)list; - if ( entry->map && - entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK) ) { - dev_priv->sarea = entry->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR( "failed to find sarea!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); @@ -511,7 +497,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { @@ -519,7 +505,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->status, init->status_offset ); if(!dev_priv->status) { @@ -527,7 +513,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->warp, init->warp_offset ); @@ -536,7 +522,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->primary, init->primary_offset ); if(!dev_priv->primary) { @@ -544,7 +530,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if(!dev_priv->buffers) { @@ -552,7 +538,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->sarea_priv = @@ -570,7 +556,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } ret = mga_warp_install_microcode( dev_priv ); @@ -620,8 +606,6 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; - spin_lock_init( &dev_priv->prim.list_lock ); - dev_priv->prim.status[0] = dev_priv->primary->offset; dev_priv->prim.status[1] = 0; @@ -634,7 +618,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } /* Make dev_private visable to others. */ @@ -644,7 +628,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) int mga_do_cleanup_dma( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -665,15 +649,12 @@ int mga_do_cleanup_dma( drm_device_t *dev ) return 0; } -int mga_dma_init( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_init( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_init_t init; - if ( copy_from_user( &init, (drm_mga_init_t *)arg, sizeof(init) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t *)data, sizeof(init) ); switch ( init.func ) { case MGA_INIT_DMA: @@ -682,7 +663,7 @@ int mga_dma_init( struct inode *inode, struct file *filp, return mga_do_cleanup_dma( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } @@ -690,21 +671,17 @@ int mga_dma_init( struct inode *inode, struct file *filp, * Primary DMA stream management */ -int mga_dma_flush( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_flush( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_lock_t lock; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); - DRM_DEBUG( "%s: %s%s%s\n", - __FUNCTION__, + DRM_DEBUG( "%s%s%s\n", (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" ); @@ -719,7 +696,7 @@ int mga_dma_flush( struct inode *inode, struct file *filp, #if MGA_DMA_DEBUG int ret = mga_do_wait_for_idle( dev_priv ); if ( ret < 0 ) - DRM_INFO( __FUNCTION__": -EBUSY\n" ); + DRM_INFO( "%s: -EBUSY\n", __func__ ); return ret; #else return mga_do_wait_for_idle( dev_priv ); @@ -729,11 +706,9 @@ int mga_dma_flush( struct inode *inode, struct file *filp, } } -int mga_dma_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_reset( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; LOCK_TEST_WITH_RETURN( dev ); @@ -753,27 +728,25 @@ static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = mga_freelist_get( dev ); - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( copy_to_user( &d->request_indices[i], + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return -EFAULT; - if ( copy_to_user( &d->request_sizes[i], + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); d->granted_count++; } return 0; } -int mga_dma_buffers( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_buffers( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_dma_t d; @@ -781,23 +754,22 @@ int mga_dma_buffers( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); /* Please don't send us buffers. */ if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count ); - return -EINVAL; + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); } /* We'll send you buffers. */ if ( d.request_count < 0 || d.request_count > dma->buf_count ) { DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count ); - return -EINVAL; + DRM_CURRENTPID, d.request_count, dma->buf_count ); + return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); @@ -808,8 +780,7 @@ int mga_dma_buffers( struct inode *inode, struct file *filp, ret = mga_dma_get_buffers( dev, &d ); } - if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); return ret; } diff --git a/linux/mga_drm.h b/shared-core/mga_drm.h index 8f56beed..8f56beed 100644 --- a/linux/mga_drm.h +++ b/shared-core/mga_drm.h diff --git a/bsd/mga/mga_drv.h b/shared-core/mga_drv.h index be207e30..51bc706e 100644 --- a/bsd/mga/mga_drv.h +++ b/shared-core/mga_drv.h @@ -31,12 +31,6 @@ #ifndef __MGA_DRV_H__ #define __MGA_DRV_H__ -#ifndef u8 -#define u8 u_int8_t -#define u16 u_int16_t -#define u32 u_int32_t -#endif - typedef struct drm_mga_primary_buffer { u8 *start; u8 *end; @@ -44,7 +38,7 @@ typedef struct drm_mga_primary_buffer { u32 tail; int space; - volatile long wrapped; + int wrapped; volatile u32 *status; @@ -52,8 +46,6 @@ typedef struct drm_mga_primary_buffer { u32 last_wrap; u32 high_mark; - - spinlock_t list_lock; } drm_mga_primary_buffer_t; typedef struct drm_mga_freelist { @@ -109,10 +101,10 @@ typedef struct drm_mga_private { } drm_mga_private_t; /* mga_dma.c */ -extern int mga_dma_init( DRM_OS_IOCTL ); -extern int mga_dma_flush( DRM_OS_IOCTL ); -extern int mga_dma_reset( DRM_OS_IOCTL ); -extern int mga_dma_buffers( DRM_OS_IOCTL ); +extern int mga_dma_init( DRM_IOCTL_ARGS ); +extern int mga_dma_flush( DRM_IOCTL_ARGS ); +extern int mga_dma_reset( DRM_IOCTL_ARGS ); +extern int mga_dma_buffers( DRM_IOCTL_ARGS ); extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ); extern int mga_do_dma_idle( drm_mga_private_t *dev_priv ); @@ -127,18 +119,19 @@ extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ); extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); /* mga_state.c */ -extern int mga_dma_clear( DRM_OS_IOCTL ); -extern int mga_dma_swap( DRM_OS_IOCTL ); -extern int mga_dma_vertex( DRM_OS_IOCTL ); -extern int mga_dma_indices( DRM_OS_IOCTL ); -extern int mga_dma_iload( DRM_OS_IOCTL ); -extern int mga_dma_blit( DRM_OS_IOCTL ); +extern int mga_dma_clear( DRM_IOCTL_ARGS ); +extern int mga_dma_swap( DRM_IOCTL_ARGS ); +extern int mga_dma_vertex( DRM_IOCTL_ARGS ); +extern int mga_dma_indices( DRM_IOCTL_ARGS ); +extern int mga_dma_iload( DRM_IOCTL_ARGS ); +extern int mga_dma_blit( DRM_IOCTL_ARGS ); /* mga_warp.c */ 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_OS_READMEMORYBARRIER +#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() + #define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) #define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) @@ -148,12 +141,12 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv ); #ifdef __alpha__ #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { wmb(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { wmb(); MGA_DEREF8( reg ) = val; } while (0) +#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) static inline u32 _MGA_READ(u32 *addr) { - mb(); + DRM_READMEMORYBARRIER(); return *(volatile u32 *)addr; } @@ -193,10 +186,10 @@ do { \ #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_OS_CURRENTPID ) { \ + dev->lock.pid != DRM_CURRENTPID ) { \ DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - DRM_OS_RETURN( EINVAL ); \ + __func__ ); \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -208,8 +201,8 @@ do { \ } else if ( dev_priv->prim.space < \ dev_priv->prim.high_mark ) { \ if ( MGA_DMA_DEBUG ) \ - DRM_INFO( __FUNCTION__": wrap...\n" ); \ - DRM_OS_RETURN( EBUSY); \ + DRM_INFO( "%s: wrap...\n", __func__ ); \ + return DRM_ERR(EBUSY); \ } \ } \ } while (0) @@ -217,10 +210,10 @@ do { \ #define WRAP_WAIT_WITH_RETURN( dev_priv ) \ do { \ if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( mga_do_wait_for_idle( dev_priv ) ) { \ + if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ if ( MGA_DMA_DEBUG ) \ - DRM_INFO( __FUNCTION__": wrap...\n" ); \ - DRM_OS_RETURN( EBUSY); \ + DRM_INFO( "%s: wrap...\n", __func__ ); \ + return DRM_ERR(EBUSY); \ } \ mga_do_dma_wrap_end( dev_priv ); \ } \ @@ -241,7 +234,7 @@ do { \ do { \ if ( MGA_VERBOSE ) { \ DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \ - (n), __FUNCTION__ ); \ + (n), __func__ ); \ DRM_INFO( " space=0x%x req=0x%x\n", \ dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ } \ @@ -252,7 +245,7 @@ do { \ #define BEGIN_DMA_WRAP() \ do { \ if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ + DRM_INFO( "BEGIN_DMA() in %s\n", __func__ ); \ DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ } \ prim = dev_priv->prim.start; \ @@ -271,7 +264,7 @@ do { \ #define FLUSH_DMA() \ do { \ if ( 0 ) { \ - DRM_INFO( __FUNCTION__ ":\n" ); \ + DRM_INFO( "%s:\n", __func__ ); \ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ dev_priv->prim.tail, \ MGA_READ( MGA_PRIMADDRESS ) - \ diff --git a/linux/mga_state.c b/shared-core/mga_state.c index 17cbc855..adf67de3 100644 --- a/linux/mga_state.c +++ b/shared-core/mga_state.c @@ -32,7 +32,6 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "mga.h" #include "drmP.h" #include "drm.h" @@ -71,7 +70,7 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, ADVANCE_DMA(); } -static inline void mga_g200_emit_context( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -97,7 +96,7 @@ static inline void mga_g200_emit_context( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g400_emit_context( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -128,7 +127,7 @@ static inline void mga_g400_emit_context( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; @@ -159,7 +158,7 @@ static inline void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; @@ -203,7 +202,7 @@ static inline void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; @@ -244,7 +243,7 @@ static inline void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; @@ -274,7 +273,7 @@ static inline void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) ADVANCE_DMA(); } -static inline void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) +static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; @@ -422,7 +421,7 @@ static int mga_verify_context( drm_mga_private_t *dev_priv ) ctx->dstorg, dev_priv->front_offset, dev_priv->back_offset ); ctx->dstorg = 0; - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; @@ -442,7 +441,7 @@ static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit ); tex->texorg = 0; - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; @@ -484,13 +483,13 @@ static int mga_verify_iload( drm_mga_private_t *dev_priv, dstorg + length > (dev_priv->texture_offset + dev_priv->texture_size) ) { DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( length & MGA_ILOAD_MASK ) { DRM_ERROR( "*** bad iload length: 0x%x\n", length & MGA_ILOAD_MASK ); - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; @@ -503,7 +502,7 @@ static int mga_verify_blit( drm_mga_private_t *dev_priv, (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) { DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg ); - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; } @@ -523,7 +522,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( __FUNCTION__ ":\n" ); + DRM_DEBUG( "\n" ); BEGIN_DMA( 1 ); @@ -617,7 +616,7 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) int nbox = sarea_priv->nbox; int i; DMA_LOCALS; - DRM_DEBUG( __FUNCTION__ ":\n" ); + DRM_DEBUG( "\n" ); sarea_priv->last_frame.head = dev_priv->prim.tail; sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; @@ -663,7 +662,7 @@ static void mga_dma_dispatch_swap( drm_device_t *dev ) FLUSH_DMA(); - DRM_DEBUG( "%s... done.\n", __FUNCTION__ ); + DRM_DEBUG( "%s... done.\n", __func__ ); } static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) @@ -771,8 +770,7 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; u32 y2; DMA_LOCALS; - DRM_DEBUG( "%s: buf=%d used=%d\n", - __FUNCTION__, buf->idx, buf->used ); + DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); y2 = length / 64; @@ -826,7 +824,7 @@ static void mga_dma_dispatch_blit( drm_device_t *dev, int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; - DRM_DEBUG( __FUNCTION__ ":\n" ); + DRM_DEBUG( "\n" ); BEGIN_DMA( 4 + nbox ); @@ -883,19 +881,16 @@ static void mga_dma_dispatch_blit( drm_device_t *dev, * */ -int mga_dma_clear( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_clear( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &clear, (drm_mga_clear_t *) arg, sizeof(clear) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t *)data, sizeof(clear) ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -911,11 +906,9 @@ int mga_dma_clear( struct inode *inode, struct file *filp, return 0; } -int mga_dma_swap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_swap( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -935,11 +928,9 @@ int mga_dma_swap( struct inode *inode, struct file *filp, return 0; } -int mga_dma_vertex( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_vertex( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -948,12 +939,11 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &vertex, - (drm_mga_vertex_t *)arg, - sizeof(vertex) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( vertex, + (drm_mga_vertex_t *)data, + sizeof(vertex) ); - if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL; + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL); buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -967,7 +957,7 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, buf_priv->dispatched = 0; mga_freelist_put( dev, buf ); } - return -EINVAL; + return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); @@ -977,11 +967,9 @@ int mga_dma_vertex( struct inode *inode, struct file *filp, return 0; } -int mga_dma_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_indices( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -990,12 +978,11 @@ int mga_dma_indices( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &indices, - (drm_mga_indices_t *)arg, - sizeof(indices) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( indices, + (drm_mga_indices_t *)data, + sizeof(indices) ); - if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL; + if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL); buf = dma->buflist[indices.idx]; buf_priv = buf->dev_private; @@ -1009,7 +996,7 @@ int mga_dma_indices( struct inode *inode, struct file *filp, buf_priv->dispatched = 0; mga_freelist_put( dev, buf ); } - return -EINVAL; + return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); @@ -1019,38 +1006,35 @@ int mga_dma_indices( struct inode *inode, struct file *filp, return 0; } -int mga_dma_iload( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_iload( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_iload_t iload; - DRM_DEBUG( __FUNCTION__ ":\n" ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t *)data, sizeof(iload) ); #if 0 if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { if ( MGA_DMA_DEBUG ) - DRM_INFO( __FUNCTION__": -EBUSY\n" ); - return -EBUSY; + DRM_INFO( "%s: -EBUSY\n", __func__ ); + return DRM_ERR(EBUSY); } #endif - if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL; + if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL); buf = dma->buflist[iload.idx]; buf_priv = buf->dev_private; if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) { mga_freelist_put( dev, buf ); - return -EINVAL; + return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); @@ -1064,26 +1048,23 @@ int mga_dma_iload( struct inode *inode, struct file *filp, return 0; } -int mga_dma_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int mga_dma_blit( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_blit_t blit; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &blit, (drm_mga_blit_t *)arg, sizeof(blit) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t *)data, sizeof(blit) ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) ) - return -EINVAL; + return DRM_ERR(EINVAL); WRAP_TEST_WITH_RETURN( dev_priv ); diff --git a/bsd/mga/mga_ucode.h b/shared-core/mga_ucode.h index fa0f82ec..fa0f82ec 100644 --- a/bsd/mga/mga_ucode.h +++ b/shared-core/mga_ucode.h diff --git a/linux/mga_warp.c b/shared-core/mga_warp.c index 4dd998b3..ea7f53a6 100644 --- a/linux/mga_warp.c +++ b/shared-core/mga_warp.c @@ -107,7 +107,7 @@ static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) if ( size > dev_priv->warp->size ) { DRM_ERROR( "microcode too large! (%u > %lu)\n", size, dev_priv->warp->size ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } memset( dev_priv->warp_pipe_phys, 0, @@ -144,7 +144,7 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) if ( size > dev_priv->warp->size ) { DRM_ERROR( "microcode too large! (%u > %lu)\n", size, dev_priv->warp->size ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } memset( dev_priv->warp_pipe_phys, 0, @@ -170,7 +170,7 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) case MGA_CARD_TYPE_G200: return mga_warp_install_g200_microcode( dev_priv ); default: - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -195,7 +195,7 @@ int mga_warp_init( drm_mga_private_t *dev_priv ) MGA_WRITE( MGA_WVRTXSZ, 7 ); break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE | @@ -205,7 +205,7 @@ int mga_warp_init( drm_mga_private_t *dev_priv ) if ( wmisc != WMISC_EXPECTED ) { DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n", wmisc, WMISC_EXPECTED ); - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; diff --git a/linux/r128_cce.c b/shared-core/r128_cce.c index 72b8d767..f52b9a67 100644 --- a/linux/r128_cce.c +++ b/shared-core/r128_cce.c @@ -28,19 +28,14 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "r128.h" #include "drmP.h" #include "drm.h" #include "r128_drm.h" #include "r128_drv.h" -#include <linux/interrupt.h> /* For task queue support */ -#include <linux/delay.h> - #define R128_FIFO_DEBUG 0 - /* CCE microcode (from ATI) */ static u32 r128_cce_microcode[] = { 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, @@ -86,6 +81,7 @@ static u32 r128_cce_microcode[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ); int R128_READ_PLL(drm_device_t *dev, int addr) { @@ -130,13 +126,13 @@ static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv ) if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) { return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries ) @@ -146,13 +142,13 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries ) for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK; if ( slots >= entries ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) @@ -160,20 +156,20 @@ int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) int i, ret; ret = r128_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { r128_do_pixcache_flush( dev_priv ); return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if R128_FIFO_DEBUG - DRM_ERROR( "%s failed!\n", __FUNCTION__ ); + DRM_ERROR( "failed!\n" ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } @@ -186,7 +182,7 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv ) { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); r128_do_wait_for_idle( dev_priv ); @@ -227,14 +223,14 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv ) return r128_do_pixcache_flush( dev_priv ); } } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if R128_FIFO_DEBUG DRM_ERROR( "failed!\n" ); r128_status( dev_priv ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } /* Start the Concurrent Command Engine. @@ -322,7 +318,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev, u32 ring_start; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The manual (p. 2) says this address is in "VM space". This * means it's an offset from the start of AGP space. @@ -377,13 +373,12 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev, static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) { drm_r128_private_t *dev_priv; - struct list_head *list; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_r128_private_t) ); @@ -393,7 +388,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->usec_timeout = init->usec_timeout; @@ -402,7 +397,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_DEBUG( "TIMEOUT problem!\n" ); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->cce_mode = init->cce_mode; @@ -422,7 +417,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_DEBUG( "Bad cce_mode!\n" ); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } switch ( init->cce_mode ) { @@ -484,20 +479,13 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | (dev_priv->span_offset >> 5)); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); @@ -505,35 +493,35 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_ERROR("could not find framebuffer!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset ); if(!dev_priv->cce_ring) { DRM_ERROR("could not find cce ring region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); if(!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if(!dev_priv->buffers) { DRM_ERROR("could not find dma buffer region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( !dev_priv->is_pci ) { @@ -543,7 +531,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -561,7 +549,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) DRM_ERROR("Could not ioremap agp regions!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } } else { dev_priv->cce_ring->handle = @@ -599,16 +587,18 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) R128_WRITE( R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch ); +#if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart) ) { DRM_ERROR( "failed to init PCI GART!\n" ); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); } +#endif r128_cce_init_ring_buffer( dev, dev_priv ); r128_cce_load_microcode( dev_priv ); @@ -625,16 +615,20 @@ int r128_do_cleanup_cce( drm_device_t *dev ) if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; +#if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { +#endif DRM_IOREMAPFREE( dev_priv->cce_ring ); DRM_IOREMAPFREE( dev_priv->ring_rptr ); DRM_IOREMAPFREE( dev_priv->buffers ); +#if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); } +#endif DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); @@ -644,17 +638,14 @@ int r128_do_cleanup_cce( drm_device_t *dev ) return 0; } -int r128_cce_init( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_init( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_init_t init; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); - if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t *)data, sizeof(init) ); switch ( init.func ) { case R128_INIT_CCE: @@ -663,21 +654,19 @@ int r128_cce_init( struct inode *inode, struct file *filp, return r128_do_cleanup_cce( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } -int r128_cce_start( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_start( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { - DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ ); + DRM_DEBUG( "%s while CCE running\n", __func__ ); return 0; } @@ -689,20 +678,17 @@ int r128_cce_start( struct inode *inode, struct file *filp, /* Stop the CCE. The engine must have been idled before calling this * routine. */ -int r128_cce_stop( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_stop( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_cce_stop_t stop; int ret; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) ); /* Flush any pending CCE commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. @@ -716,7 +702,7 @@ int r128_cce_stop( struct inode *inode, struct file *filp, */ if ( stop.idle ) { ret = r128_do_cce_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CCE. If the engine isn't idle, @@ -733,19 +719,17 @@ int r128_cce_stop( struct inode *inode, struct file *filp, /* Just reset the CCE ring. Called as part of an X Server engine reset. */ -int r128_cce_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_reset( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); - return -EINVAL; + DRM_DEBUG( "%s called before init done\n", __func__ ); + return DRM_ERR(EINVAL); } r128_do_cce_reset( dev_priv ); @@ -756,13 +740,11 @@ int r128_cce_reset( struct inode *inode, struct file *filp, return 0; } -int r128_cce_idle( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_idle( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -773,12 +755,10 @@ int r128_cce_idle( struct inode *inode, struct file *filp, return r128_do_cce_idle( dev_priv ); } -int r128_engine_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_engine_reset( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEVICE; + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -793,7 +773,7 @@ int r128_engine_reset( struct inode *inode, struct file *filp, static int r128_do_init_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); @@ -811,7 +791,7 @@ static int r128_do_init_pageflip( drm_device_t *dev ) int r128_do_cleanup_pageflip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); @@ -822,17 +802,14 @@ int r128_do_cleanup_pageflip( drm_device_t *dev ) return 0; } -int r128_fullscreen( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_fullscreen( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_fullscreen_t fs; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); switch ( fs.func ) { case R128_INIT_FULLSCREEN: @@ -841,7 +818,7 @@ int r128_fullscreen( struct inode *inode, struct file *filp, return r128_do_cleanup_pageflip( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } @@ -864,7 +841,7 @@ static int r128_freelist_init( drm_device_t *dev ) dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER ); if ( dev_priv->head == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) ); dev_priv->head->age = R128_BUFFER_USED; @@ -875,7 +852,7 @@ static int r128_freelist_init( drm_device_t *dev ) entry = DRM(alloc)( sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER ); - if ( !entry ) return -ENOMEM; + if ( !entry ) return DRM_ERR(ENOMEM); entry->age = R128_BUFFER_FREE; entry->buf = buf; @@ -930,7 +907,7 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev ) return buf; } } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_ERROR( "returning NULL!\n" ); @@ -963,12 +940,12 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) r128_update_ring_snapshot( ring ); if ( ring->space >= n ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } /* FIXME: This is being ignored... */ DRM_ERROR( "failed!\n" ); - return -EBUSY; + return DRM_ERR(EBUSY); } static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) @@ -978,50 +955,47 @@ static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = r128_freelist_get( dev ); - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( copy_to_user( &d->request_indices[i], &buf->idx, + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return -EFAULT; - if ( copy_to_user( &d->request_sizes[i], &buf->total, + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); d->granted_count++; } return 0; } -int r128_cce_buffers( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_buffers( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; int ret = 0; drm_dma_t d; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *) data, sizeof(d) ); /* Please don't send us buffers. */ if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count ); - return -EINVAL; + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); } /* We'll send you buffers. */ if ( d.request_count < 0 || d.request_count > dma->buf_count ) { DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count ); - return -EINVAL; + DRM_CURRENTPID, d.request_count, dma->buf_count ); + return DRM_ERR(EINVAL); } d.granted_count = 0; @@ -1030,8 +1004,7 @@ int r128_cce_buffers( struct inode *inode, struct file *filp, ret = r128_cce_get_buffers( dev, &d ); } - if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d) ); return ret; } diff --git a/linux/r128_drm.h b/shared-core/r128_drm.h index a8d23008..a8d23008 100644 --- a/linux/r128_drm.h +++ b/shared-core/r128_drm.h diff --git a/bsd/r128/r128_drv.h b/shared-core/r128_drv.h index 743e48e5..04296590 100644 --- a/bsd/r128/r128_drv.h +++ b/shared-core/r128_drv.h @@ -31,20 +31,11 @@ * Michel Dänzer <daenzerm@student.ethz.ch> */ -#include <machine/endian.h> -#if BYTE_ORDER==LITTLE_ENDIAN -#define le32_to_cpu(x) x -#define cpu_to_le32(x) x -#else -#define le32_to_cpu(x) ntohl(x) -#define cpu_to_le32(x) htonl(x) -#endif - #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) -#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) +#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) ) typedef struct drm_r128_freelist { unsigned int age; @@ -81,9 +72,7 @@ typedef struct drm_r128_private { int usec_timeout; int is_pci; unsigned long phys_pci_gart; -#if __REALLY_HAVE_SG dma_addr_t bus_pci_gart; -#endif unsigned long cce_buffers_offset; atomic_t idle_count; @@ -127,14 +116,14 @@ typedef struct drm_r128_buf_priv { } drm_r128_buf_priv_t; /* r128_cce.c */ -extern int r128_cce_init( DRM_OS_IOCTL ); -extern int r128_cce_start( DRM_OS_IOCTL ); -extern int r128_cce_stop( DRM_OS_IOCTL ); -extern int r128_cce_reset( DRM_OS_IOCTL ); -extern int r128_cce_idle( DRM_OS_IOCTL ); -extern int r128_engine_reset( DRM_OS_IOCTL ); -extern int r128_fullscreen( DRM_OS_IOCTL ); -extern int r128_cce_buffers( DRM_OS_IOCTL ); +extern int r128_cce_init( DRM_IOCTL_ARGS ); +extern int r128_cce_start( DRM_IOCTL_ARGS ); +extern int r128_cce_stop( DRM_IOCTL_ARGS ); +extern int r128_cce_reset( DRM_IOCTL_ARGS ); +extern int r128_cce_idle( DRM_IOCTL_ARGS ); +extern int r128_engine_reset( DRM_IOCTL_ARGS ); +extern int r128_fullscreen( DRM_IOCTL_ARGS ); +extern int r128_cce_buffers( DRM_IOCTL_ARGS ); extern void r128_freelist_reset( drm_device_t *dev ); extern drm_buf_t *r128_freelist_get( drm_device_t *dev ); @@ -154,14 +143,14 @@ extern int r128_do_cleanup_cce( drm_device_t *dev ); extern int r128_do_cleanup_pageflip( drm_device_t *dev ); /* r128_state.c */ -extern int r128_cce_clear( DRM_OS_IOCTL ); -extern int r128_cce_swap( DRM_OS_IOCTL ); -extern int r128_cce_vertex( DRM_OS_IOCTL ); -extern int r128_cce_indices( DRM_OS_IOCTL ); -extern int r128_cce_blit( DRM_OS_IOCTL ); -extern int r128_cce_depth( DRM_OS_IOCTL ); -extern int r128_cce_stipple( DRM_OS_IOCTL ); -extern int r128_cce_indirect( DRM_OS_IOCTL ); +extern int r128_cce_clear( DRM_IOCTL_ARGS ); +extern int r128_cce_swap( DRM_IOCTL_ARGS ); +extern int r128_cce_vertex( DRM_IOCTL_ARGS ); +extern int r128_cce_indices( DRM_IOCTL_ARGS ); +extern int r128_cce_blit( DRM_IOCTL_ARGS ); +extern int r128_cce_depth( DRM_IOCTL_ARGS ); +extern int r128_cce_stipple( DRM_IOCTL_ARGS ); +extern int r128_cce_indirect( DRM_IOCTL_ARGS ); /* Register definitions, register access macros and drmAddMap constants @@ -379,44 +368,11 @@ extern int r128_cce_indirect( DRM_OS_IOCTL ); #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE( reg ) + reg) -#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg))) -static inline u32 _R128_READ(u32 *addr) -{ - DRM_OS_READMEMORYBARRIER; - return *(volatile u32 *)addr; -} -#define R128_WRITE(reg,val) \ -do { \ - DRM_OS_WRITEMEMORYBARRIER; \ - R128_DEREF(reg) = val; \ -} while (0) -#else -#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) ) -#define R128_WRITE(reg,val) \ -do { \ - R128_DEREF( reg ) = cpu_to_le32( val ); \ -} while (0) -#endif +#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_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg)) -static inline u8 _R128_READ8(u8 *addr) -{ - DRM_OS_READMEMORYBARRIER; - return *(volatile u8 *)addr; -} -#define R128_WRITE8(reg,val) \ -do { \ - DRM_OS_WRITEMEMORYBARRIER; \ - R128_DEREF8(reg) = val; \ -} while (0) -#else -#define R128_READ8(reg) R128_DEREF8( reg ) -#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0) -#endif +#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_WRITE_PLL(addr,val) \ do { \ @@ -444,10 +400,9 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != DRM_OS_CURRENTPID ) { \ - DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - DRM_OS_RETURN( EINVAL ); \ + dev->lock.pid != DRM_CURRENTPID ) { \ + DRM_ERROR( "%s called without lock held\n", __func__ ); \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -459,12 +414,13 @@ do { \ r128_update_ring_snapshot( ring ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - DRM_OS_DELAY( 1 ); \ + DRM_UDELAY(1); \ } \ DRM_ERROR( "ring space check failed!\n" ); \ - DRM_OS_RETURN( EBUSY ); \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ + ; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -472,7 +428,7 @@ do { \ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ int __ret = r128_do_cce_idle( dev_priv ); \ - if ( __ret < 0 ) return __ret; \ + if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ r128_freelist_reset( dev ); \ } \ @@ -488,7 +444,11 @@ do { \ * Ring control */ -#define r128_flush_write_combine() DRM_OS_READMEMORYBARRIER +#if defined(__powerpc__) +#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else +#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() +#endif #define R128_VERBOSE 0 @@ -499,7 +459,7 @@ do { \ #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - (n), __FUNCTION__ ); \ + (n), __func__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ diff --git a/linux/r128_state.c b/shared-core/r128_state.c index a5b925f5..a8ffd073 100644 --- a/linux/r128_state.c +++ b/shared-core/r128_state.c @@ -27,14 +27,11 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "r128.h" #include "drmP.h" #include "drm.h" #include "r128_drm.h" #include "r128_drv.h" -#include "drm.h" -#include <linux/delay.h> /* ================================================================ @@ -46,7 +43,7 @@ static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, { u32 aux_sc_cntl = 0x00000000; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 17 ); @@ -84,12 +81,12 @@ static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, ADVANCE_RING(); } -static inline void r128_emit_core( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 2 ); @@ -99,12 +96,12 @@ static inline void r128_emit_core( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_context( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 13 ); @@ -125,12 +122,12 @@ static inline void r128_emit_context( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_setup( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 3 ); @@ -141,12 +138,12 @@ static inline void r128_emit_setup( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_masks( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 5 ); @@ -160,12 +157,12 @@ static inline void r128_emit_masks( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_window( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 2 ); @@ -175,14 +172,14 @@ static inline void r128_emit_window( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_tex0( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; int i; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS ); @@ -202,13 +199,13 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_tex1( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; int i; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); + DRM_DEBUG( " %s\n", __func__ ); BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS ); @@ -226,12 +223,12 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv ) ADVANCE_RING(); } -static inline void r128_emit_state( drm_r128_private_t *dev_priv ) +static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv ) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; - DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + DRM_DEBUG( "%s: dirty=0x%08x\n", __func__, dirty ); if ( dirty & R128_UPLOAD_CORE ) { r128_emit_core( dev_priv ); @@ -372,7 +369,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, unsigned int flags = clear->flags; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __func__ ); if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; @@ -475,7 +472,7 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __func__ ); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -531,7 +528,7 @@ static void r128_cce_dispatch_flip( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -580,8 +577,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev, int prim = buf_priv->prim; int i = 0; RING_LOCALS; - DRM_DEBUG( "%s: buf=%d nbox=%d\n", - __FUNCTION__, buf->idx, sarea_priv->nbox ); + DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); if ( 0 ) r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); @@ -792,7 +788,7 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, u32 *data; int dword_shift, dwords; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll @@ -813,7 +809,7 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, break; default: DRM_ERROR( "invalid blit format %d\n", blit->format ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Flush the pixel cache, and mark the contents as Read Invalid. @@ -833,14 +829,14 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, buf = dma->buflist[blit->idx]; buf_priv = buf->dev_private; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", blit->idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf_priv->discard = 1; @@ -902,36 +898,36 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, u8 *mask; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); count = depth->n; - if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { - return -EFAULT; + if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + return DRM_ERR(EFAULT); } - if ( copy_from_user( &y, depth->y, sizeof(y) ) ) { - return -EFAULT; + if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + return DRM_ERR(EFAULT); } - buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL ); + buffer = DRM_MALLOC( depth->n * sizeof(u32) ); if ( buffer == NULL ) - return -ENOMEM; - if ( copy_from_user( buffer, depth->buffer, + return DRM_ERR(ENOMEM); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, depth->n * sizeof(u32) ) ) { - kfree( buffer ); - return -EFAULT; + DRM_FREE( buffer ); + return DRM_ERR(EFAULT); } if ( depth->mask ) { - mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL ); + mask = DRM_MALLOC( depth->n * sizeof(u8) ); if ( mask == NULL ) { - kfree( buffer ); - return -ENOMEM; + DRM_FREE( buffer ); + return DRM_ERR(ENOMEM); } - if ( copy_from_user( mask, depth->mask, + if ( DRM_COPY_FROM_USER( mask, depth->mask, depth->n * sizeof(u8) ) ) { - kfree( buffer ); - kfree( mask ); - return -EFAULT; + DRM_FREE( buffer ); + DRM_FREE( mask ); + return DRM_ERR(EFAULT); } for ( i = 0 ; i < count ; i++, x++ ) { @@ -957,7 +953,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - kfree( mask ); + DRM_FREE( mask ); } else { for ( i = 0 ; i < count ; i++, x++ ) { BEGIN_RING( 6 ); @@ -981,7 +977,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, } } - kfree( buffer ); + DRM_FREE( buffer ); return 0; } @@ -995,59 +991,59 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, u8 *mask; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); count = depth->n; - x = kmalloc( count * sizeof(*x), GFP_KERNEL ); + x = DRM_MALLOC( count * sizeof(*x) ); if ( x == NULL ) { - return -ENOMEM; + return DRM_ERR(ENOMEM); } - y = kmalloc( count * sizeof(*y), GFP_KERNEL ); + y = DRM_MALLOC( count * sizeof(*y) ); if ( y == NULL ) { - kfree( x ); - return -ENOMEM; + DRM_FREE( x ); + return DRM_ERR(ENOMEM); } - if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) { - kfree( x ); - kfree( y ); - return -EFAULT; + if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); } - if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) { - kfree( x ); - kfree( y ); - return -EFAULT; + if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); } - buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL ); + buffer = DRM_MALLOC( depth->n * sizeof(u32) ); if ( buffer == NULL ) { - kfree( x ); - kfree( y ); - return -ENOMEM; + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(ENOMEM); } - if ( copy_from_user( buffer, depth->buffer, + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, depth->n * sizeof(u32) ) ) { - kfree( x ); - kfree( y ); - kfree( buffer ); - return -EFAULT; + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); + return DRM_ERR(EFAULT); } if ( depth->mask ) { - mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL ); + mask = DRM_MALLOC( depth->n * sizeof(u8) ); if ( mask == NULL ) { - kfree( x ); - kfree( y ); - kfree( buffer ); - return -ENOMEM; + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); + return DRM_ERR(ENOMEM); } - if ( copy_from_user( mask, depth->mask, + if ( DRM_COPY_FROM_USER( mask, depth->mask, depth->n * sizeof(u8) ) ) { - kfree( x ); - kfree( y ); - kfree( buffer ); - kfree( mask ); - return -EFAULT; + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); + DRM_FREE( mask ); + return DRM_ERR(EFAULT); } for ( i = 0 ; i < count ; i++ ) { @@ -1073,7 +1069,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - kfree( mask ); + DRM_FREE( mask ); } else { for ( i = 0 ; i < count ; i++ ) { BEGIN_RING( 6 ); @@ -1097,9 +1093,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, } } - kfree( x ); - kfree( y ); - kfree( buffer ); + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); return 0; } @@ -1110,14 +1106,14 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev, drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); count = depth->n; - if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { - return -EFAULT; + if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + return DRM_ERR(EFAULT); } - if ( copy_from_user( &y, depth->y, sizeof(y) ) ) { - return -EFAULT; + if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + return DRM_ERR(EFAULT); } BEGIN_RING( 7 ); @@ -1152,31 +1148,31 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, int count, *x, *y; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __func__ ); count = depth->n; if ( count > dev_priv->depth_pitch ) { count = dev_priv->depth_pitch; } - x = kmalloc( count * sizeof(*x), GFP_KERNEL ); + x = DRM_MALLOC( count * sizeof(*x) ); if ( x == NULL ) { - return -ENOMEM; + return DRM_ERR(ENOMEM); } - y = kmalloc( count * sizeof(*y), GFP_KERNEL ); + y = DRM_MALLOC( count * sizeof(*y) ); if ( y == NULL ) { - kfree( x ); - return -ENOMEM; + DRM_FREE( x ); + return DRM_ERR(ENOMEM); } - if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) { - kfree( x ); - kfree( y ); - return -EFAULT; + if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); } - if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) { - kfree( x ); - kfree( y ); - return -EFAULT; + if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); } for ( i = 0 ; i < count ; i++ ) { @@ -1203,8 +1199,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, ADVANCE_RING(); } - kfree( x ); - kfree( y ); + DRM_FREE( x ); + DRM_FREE( y ); return 0; } @@ -1219,7 +1215,7 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) drm_r128_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __func__ ); BEGIN_RING( 33 ); @@ -1236,21 +1232,18 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) * IOCTL functions */ -int r128_cce_clear( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_clear( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_clear_t clear; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &clear, (drm_r128_clear_t *) arg, - sizeof(clear) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data, + sizeof(clear) ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1266,14 +1259,12 @@ int r128_cce_clear( struct inode *inode, struct file *filp, return 0; } -int r128_cce_swap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_swap( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "%s\n", __func__ ); LOCK_TEST_WITH_RETURN( dev ); @@ -1293,11 +1284,9 @@ int r128_cce_swap( struct inode *inode, struct file *filp, return 0; } -int r128_cce_vertex( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_vertex( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1307,27 +1296,26 @@ int r128_cce_vertex( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg, - sizeof(vertex) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data, + sizeof(vertex) ); - DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard ); if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", vertex.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( vertex.prim < 0 || vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1336,14 +1324,14 @@ int r128_cce_vertex( struct inode *inode, struct file *filp, buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf->used = vertex.count; @@ -1355,11 +1343,9 @@ int r128_cce_vertex( struct inode *inode, struct file *filp, return 0; } -int r128_cce_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_indices( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1370,27 +1356,25 @@ int r128_cce_indices( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &elts, (drm_r128_indices_t *)arg, - sizeof(elts) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data, + sizeof(elts) ); - DRM_DEBUG( "%s: pid=%d buf=%d s=%d e=%d d=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard ); if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", elts.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( elts.prim < 0 || elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { DRM_ERROR( "buffer prim %d\n", elts.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1399,14 +1383,14 @@ int r128_cce_indices( struct inode *inode, struct file *filp, buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", elts.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } count = (elts.end - elts.start) / sizeof(u16); @@ -1414,11 +1398,11 @@ int r128_cce_indices( struct inode *inode, struct file *filp, if ( elts.start & 0x7 ) { DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( elts.start < buf->used ) { DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf->used = elts.end; @@ -1430,28 +1414,24 @@ int r128_cce_indices( struct inode *inode, struct file *filp, return 0; } -int r128_cce_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_blit( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &blit, (drm_r128_blit_t *)arg, - sizeof(blit) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data, + sizeof(blit) ); - DRM_DEBUG( "%s: pid=%d index=%d\n", - __FUNCTION__, current->pid, blit.idx ); + DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx ); if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", blit.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1460,19 +1440,16 @@ int r128_cce_blit( struct inode *inode, struct file *filp, return r128_cce_dispatch_blit( dev, &blit ); } -int r128_cce_depth( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_depth( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &depth, (drm_r128_depth_t *)arg, - sizeof(depth) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data, + sizeof(depth) ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1487,27 +1464,24 @@ int r128_cce_depth( struct inode *inode, struct file *filp, return r128_cce_dispatch_read_pixels( dev, &depth ); } - return -EINVAL; + return DRM_ERR(EINVAL); } -int r128_cce_stipple( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_stipple( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_stipple_t stipple; u32 mask[32]; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg, - sizeof(stipple) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data, + sizeof(stipple) ); - if ( copy_from_user( &mask, stipple.mask, + if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) - return -EFAULT; + return DRM_ERR( EFAULT ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1516,11 +1490,9 @@ int r128_cce_stipple( struct inode *inode, struct file *filp, return 0; } -int r128_cce_indirect( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int r128_cce_indirect( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1533,13 +1505,12 @@ int r128_cce_indirect( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &indirect, (drm_r128_indirect_t *)arg, - sizeof(indirect) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data, + sizeof(indirect) ); DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", indirect.idx, indirect.start, @@ -1548,26 +1519,26 @@ int r128_cce_indirect( struct inode *inode, struct file *filp, if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", indirect.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf = dma->buflist[indirect.idx]; buf_priv = buf->dev_private; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( indirect.start < buf->used ) { DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", indirect.start, buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); diff --git a/linux/radeon_cp.c b/shared-core/radeon_cp.c index 5486f1c1..1ddbdced 100644 --- a/linux/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -28,16 +28,12 @@ * Gareth Hughes <gareth@valinux.com> */ -#define __NO_VERSION__ #include "radeon.h" #include "drmP.h" #include "drm.h" #include "radeon_drm.h" #include "radeon_drv.h" -#include <linux/interrupt.h> /* For task queue support */ -#include <linux/delay.h> - #define RADEON_FIFO_DEBUG 0 #if defined(__alpha__) || defined(__powerpc__) @@ -358,14 +354,14 @@ static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) & RADEON_RB2D_DC_BUSY) ) { return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if RADEON_FIFO_DEBUG DRM_ERROR( "failed!\n" ); radeon_status( dev_priv ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, @@ -377,14 +373,14 @@ 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_UDELAY( 1 ); } #if RADEON_FIFO_DEBUG DRM_ERROR( "failed!\n" ); radeon_status( dev_priv ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) @@ -392,7 +388,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) int i, ret; ret = radeon_do_wait_for_fifo( dev_priv, 64 ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(RADEON_READ( RADEON_RBBM_STATUS ) @@ -400,14 +396,14 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) radeon_do_pixcache_flush( dev_priv ); return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } #if RADEON_FIFO_DEBUG DRM_ERROR( "failed!\n" ); radeon_status( dev_priv ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } @@ -419,7 +415,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) { int i; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); @@ -438,7 +434,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) */ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); #if 0 u32 tmp; @@ -452,7 +448,7 @@ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 6 ); @@ -471,7 +467,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) { RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_wait_for_idle( dev_priv ); @@ -496,7 +492,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) { u32 cur_read_ptr; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); @@ -510,7 +506,7 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) */ static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); @@ -523,7 +519,7 @@ static int radeon_do_engine_reset( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); radeon_do_pixcache_flush( dev_priv ); @@ -656,13 +652,12 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - struct list_head *list; u32 tmp; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); @@ -675,7 +670,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } #endif @@ -683,7 +678,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_ERROR( "PCI GART memory not allocated!\n" ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->usec_timeout = init->usec_timeout; @@ -692,7 +687,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_DEBUG( "TIMEOUT problem!\n" ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->cp_mode = init->cp_mode; @@ -710,7 +705,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } switch ( init->fb_bpp ) { @@ -776,20 +771,13 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if(!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); @@ -797,35 +785,35 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_ERROR("could not find framebuffer!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); if(!dev_priv->cp_ring) { DRM_ERROR("could not find cp ring region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); if(!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if(!dev_priv->buffers) { DRM_ERROR("could not find dma buffer region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( !dev_priv->is_pci ) { @@ -835,7 +823,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -853,7 +841,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) DRM_ERROR("could not find ioremap agp regions!\n"); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } } else { dev_priv->cp_ring->handle = @@ -933,13 +921,14 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_WRITE( RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear ); +#if __REALLY_HAVE_SG if ( dev_priv->is_pci ) { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart)) { DRM_ERROR( "failed to init PCI GART!\n" ); dev->dev_private = (void *)dev_priv; radeon_do_cleanup_cp(dev); - return -ENOMEM; + return DRM_ERR(ENOMEM); } /* Turn on PCI GART */ @@ -962,12 +951,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ } else { +#endif /* __REALLY_HAVE_SG */ /* Turn off PCI GART */ tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN; RADEON_WRITE( RADEON_AIC_CNTL, tmp ); +#if __REALLY_HAVE_SG } +#endif /* __REALLY_HAVE_SG */ radeon_cp_load_microcode( dev_priv ); radeon_cp_init_ring_buffer( dev, dev_priv ); @@ -983,7 +975,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) int radeon_do_cleanup_cp( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -993,10 +985,12 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) DRM_IOREMAPFREE( dev_priv->ring_rptr ); DRM_IOREMAPFREE( dev_priv->buffers ); } else { +#if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, dev_priv->phys_pci_gart, dev_priv->bus_pci_gart )) DRM_ERROR( "failed to cleanup PCI GART!\n" ); +#endif /* __REALLY_HAVE_SG */ } DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), @@ -1007,15 +1001,12 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) return 0; } -int radeon_cp_init( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_init( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_init_t init; - if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) ); switch ( init.func ) { case RADEON_INIT_CP: @@ -1024,26 +1015,24 @@ int radeon_cp_init( struct inode *inode, struct file *filp, return radeon_do_cleanup_cp( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } -int radeon_cp_start( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_start( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); if ( dev_priv->cp_running ) { - DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); + DRM_DEBUG( "%s while CP running\n", __func__ ); return 0; } if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { DRM_DEBUG( "%s called with bogus CP mode (%d)\n", - __FUNCTION__, dev_priv->cp_mode ); + __func__, dev_priv->cp_mode ); return 0; } @@ -1055,20 +1044,17 @@ int radeon_cp_start( struct inode *inode, struct file *filp, /* Stop the CP. The engine must have been idled before calling this * routine. */ -int radeon_cp_stop( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_stop( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_cp_stop_t stop; int ret; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); /* Flush any pending CP commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. @@ -1082,7 +1068,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp, */ if ( stop.idle ) { ret = radeon_do_cp_idle( dev_priv ); - if ( ret < 0 ) return ret; + if ( ret ) return ret; } /* Finally, we can turn off the CP. If the engine isn't idle, @@ -1099,19 +1085,17 @@ int radeon_cp_stop( struct inode *inode, struct file *filp, /* Just reset the CP ring. Called as part of an X Server engine reset. */ -int radeon_cp_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_reset( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); - return -EINVAL; + DRM_DEBUG( "%s called before init done\n", __func__ ); + return DRM_ERR(EINVAL); } radeon_do_cp_reset( dev_priv ); @@ -1122,25 +1106,21 @@ int radeon_cp_reset( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_idle( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_idle( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); return radeon_do_cp_idle( dev_priv ); } -int radeon_engine_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_engine_reset( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEVICE; + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -1154,8 +1134,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp, /* KW: Deprecated to say the least: */ -int radeon_fullscreen( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_fullscreen( DRM_IOCTL_ARGS ) { return 0; } @@ -1200,7 +1179,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev ) } start = 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_ERROR( "returning NULL!\n" ); @@ -1235,7 +1214,7 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) radeon_update_ring_snapshot( ring ); if ( ring->space > n ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } /* FIXME: This return value is ignored in the BEGIN_RING macro! */ @@ -1243,7 +1222,7 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) radeon_status( dev_priv ); DRM_ERROR( "failed!\n" ); #endif - return -EBUSY; + return DRM_ERR(EBUSY); } static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) @@ -1253,50 +1232,47 @@ static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = radeon_freelist_get( dev ); - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( copy_to_user( &d->request_indices[i], &buf->idx, + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return -EFAULT; - if ( copy_to_user( &d->request_sizes[i], &buf->total, + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); d->granted_count++; } return 0; } -int radeon_cp_buffers( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_buffers( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; int ret = 0; drm_dma_t d; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); /* Please don't send us buffers. */ if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count ); - return -EINVAL; + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); } /* We'll send you buffers. */ if ( d.request_count < 0 || d.request_count > dma->buf_count ) { DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count ); - return -EINVAL; + DRM_CURRENTPID, d.request_count, dma->buf_count ); + return DRM_ERR(EINVAL); } d.granted_count = 0; @@ -1305,8 +1281,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp, ret = radeon_cp_get_buffers( dev, &d ); } - if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) ) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); return ret; } diff --git a/linux/radeon_drm.h b/shared-core/radeon_drm.h index dd24d429..dd24d429 100644 --- a/linux/radeon_drm.h +++ b/shared-core/radeon_drm.h diff --git a/linux/radeon_drv.h b/shared-core/radeon_drv.h index 457c183a..ae66f12e 100644 --- a/linux/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) readl( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) +#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head , (val)) typedef struct drm_radeon_freelist { unsigned int age; @@ -119,29 +119,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_IOCTL_ARGS ); +extern int radeon_cp_start( DRM_IOCTL_ARGS ); +extern int radeon_cp_stop( DRM_IOCTL_ARGS ); +extern int radeon_cp_reset( DRM_IOCTL_ARGS ); +extern int radeon_cp_idle( DRM_IOCTL_ARGS ); +extern int radeon_engine_reset( DRM_IOCTL_ARGS ); +extern int radeon_fullscreen( DRM_IOCTL_ARGS ); +extern int radeon_cp_buffers( DRM_IOCTL_ARGS ); 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 = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32); @@ -154,28 +146,17 @@ 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_vertex2( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int radeon_cp_getparam( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int radeon_cp_flip( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int radeon_cp_clear( DRM_IOCTL_ARGS ); +extern int radeon_cp_swap( DRM_IOCTL_ARGS ); +extern int radeon_cp_vertex( DRM_IOCTL_ARGS ); +extern int radeon_cp_indices( DRM_IOCTL_ARGS ); +extern int radeon_cp_texture( DRM_IOCTL_ARGS ); +extern int radeon_cp_stipple( DRM_IOCTL_ARGS ); +extern int radeon_cp_indirect( DRM_IOCTL_ARGS ); +extern int radeon_cp_vertex2( DRM_IOCTL_ARGS ); +extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ); +extern int radeon_cp_getparam( DRM_IOCTL_ARGS ); +extern int radeon_cp_flip( DRM_IOCTL_ARGS ); @@ -544,11 +525,11 @@ extern int radeon_cp_flip( struct inode *inode, struct file *filp, #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(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) readb( (volatile u8 *) RADEON_ADDR(reg) ) -#define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg) ) +#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_WRITE_PLL( addr, val ) \ do { \ @@ -628,10 +609,9 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); #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; \ + dev->lock.pid != DRM_CURRENTPID ) { \ + DRM_ERROR( "%s called without lock held\n", __func__ ); \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -643,7 +623,7 @@ do { \ radeon_update_ring_snapshot( ring ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - udelay( 1 ); \ + DRM_UDELAY( 1 ); \ } \ DRM_ERROR( "ring space check from memory failed, reading register...\n" ); \ /* If ring space check fails from RAM, try reading the \ @@ -655,9 +635,10 @@ do { \ goto __ring_space_done; \ \ DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ + ; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -665,7 +646,7 @@ do { \ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ - if ( __ret < 0 ) return __ret; \ + if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ radeon_freelist_reset( dev ); \ } \ @@ -694,18 +675,18 @@ do { \ #if defined(__powerpc__) #define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) #else -#define radeon_flush_write_combine() mb() +#define radeon_flush_write_combine() DRM_WRITEMEMORYBARRIER() #endif #define RADEON_VERBOSE 0 -#define RING_LOCALS int write, _nr; unsigned int mask; volatile u32 *ring; +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - n, __FUNCTION__ ); \ + n, __func__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ COMMIT_RING(); \ @@ -731,7 +712,7 @@ do { \ dev_priv->ring.tail = write; \ } while (0) -#define COMMIT_RING() do { \ +#define COMMIT_RING() do { \ radeon_flush_write_combine(); \ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ } while (0) @@ -757,17 +738,17 @@ do { \ \ if (write + _size > mask) { \ int i = (mask+1) - write; \ - if (__copy_from_user( (int *)(ring+write), \ + if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ _tab, i*4 )) \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ write = 0; \ _size -= i; \ _tab += i; \ } \ \ - if (_size && __copy_from_user( (int *)(ring+write), \ + if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ _tab, _size*4 )) \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ \ write += _size; \ write &= mask; \ diff --git a/linux/radeon_state.c b/shared-core/radeon_state.c index b4c5cc63..83fae493 100644 --- a/linux/radeon_state.c +++ b/shared-core/radeon_state.c @@ -27,20 +27,18 @@ * Kevin E. Martin <martin@valinux.com> */ -#define __NO_VERSION__ #include "radeon.h" #include "drmP.h" #include "drm.h" #include "radeon_drm.h" #include "radeon_drv.h" -#include <linux/delay.h> /* ================================================================ * CP hardware state programming functions */ -static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, +static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, drm_clip_rect_t *box ) { RING_LOCALS; @@ -65,7 +63,7 @@ static void radeon_emit_state( drm_radeon_private_t *dev_priv, unsigned int dirty ) { RING_LOCALS; - DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + DRM_DEBUG( "dirty=0x%08x\n", dirty ); if ( dirty & RADEON_UPLOAD_CONTEXT ) { BEGIN_RING( 14 ); @@ -329,7 +327,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev, u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; int i; RING_LOCALS; - DRM_DEBUG( __FUNCTION__": flags = 0x%x\n", flags ); + DRM_DEBUG( "flags = 0x%x\n", flags ); if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { unsigned int tmp = flags; @@ -507,7 +505,7 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev ) drm_clip_rect_t *pbox = sarea_priv->boxes; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); #if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -582,7 +580,7 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); #if RADEON_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -670,8 +668,7 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, int i = 0; RING_LOCALS; - DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", - __FUNCTION__, + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", prim->prim, prim->vc_format, prim->start, @@ -687,7 +684,7 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, do { /* Emit the next cliprect */ if ( i < nbox ) { - if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) return; radeon_emit_clip_rect( dev_priv, &box ); @@ -782,8 +779,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, int start = prim->start + RADEON_INDEX_PRIM_OFFSET; int count = (prim->finish - start) / sizeof(u16); - DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", - __FUNCTION__, + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", prim->prim, prim->vc_format, prim->start, @@ -821,7 +817,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, do { if ( i < nbox ) { - if (__copy_from_user( &box, &boxes[i], sizeof(box) )) + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) return; radeon_emit_clip_rect( dev_priv, &box ); @@ -846,7 +842,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, drm_buf_t *buf; u32 format; u32 *buffer; - u8 *data; + const u8 *data; int size, dwords, tex_width, blit_width; u32 y, height; int ret = 0, i; @@ -855,7 +851,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, /* FIXME: Be smarter about this... */ buf = radeon_freelist_get( dev ); - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", tex->offset >> 10, tex->pitch, tex->format, @@ -888,7 +884,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, break; default: DRM_ERROR( "invalid texture format %d\n", tex->format ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_DEBUG( " tex=%dx%d blit=%d\n", @@ -920,13 +916,13 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, */ y = image->y; height = image->height; - data = (u8 *)image->data; + data = (const u8 *)image->data; size = height * blit_width; if ( size > RADEON_MAX_TEXTURE_SIZE ) { /* Texture image is too large, do a multipass upload */ - ret = -EAGAIN; + ret = DRM_ERR(EAGAIN); /* Adjust the blit size to fit the indirect buffer */ height = RADEON_MAX_TEXTURE_SIZE / blit_width; @@ -935,11 +931,11 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, /* Update the input parameters for next time */ image->y += height; image->height -= height; - image->data = (char *)image->data + size; + image->data = (const char *)image->data + size; - if ( copy_to_user( tex->image, image, sizeof(*image) ) ) { + if ( DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ) ) { DRM_ERROR( "EFAULT on tex->image\n" ); - return -EFAULT; + return DRM_ERR(EFAULT); } } else if ( size < 4 && size > 0 ) { size = 4; @@ -974,9 +970,9 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, /* Texture image width is larger than the minimum, so we * can upload it directly. */ - if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) { + if ( DRM_COPY_FROM_USER( buffer, data, dwords * sizeof(u32) ) ) { DRM_ERROR( "EFAULT on data, %d dwords\n", dwords ); - return -EFAULT; + return DRM_ERR(EFAULT); } } else { /* Texture image width is less than the minimum, so we @@ -984,17 +980,17 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, * width. */ for ( i = 0 ; i < tex->height ; i++ ) { - if ( copy_from_user( buffer, data, tex_width ) ) { + if ( DRM_COPY_FROM_USER( buffer, data, tex_width ) ) { DRM_ERROR( "EFAULT on pad, %d bytes\n", tex_width ); - return -EFAULT; + return DRM_ERR(EFAULT); } buffer += 8; data += tex_width; } } - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; buf->used = (dwords + 8) * sizeof(u32); radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); @@ -1019,7 +1015,7 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) drm_radeon_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); BEGIN_RING( 35 ); @@ -1039,31 +1035,28 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) * IOCTL functions */ -int radeon_cp_clear( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_clear( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_clear_t clear; drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, - sizeof(clear) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, + sizeof(clear) ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if ( copy_from_user( &depth_boxes, clear.depth_boxes, + if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes, sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); @@ -1080,7 +1073,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); @@ -1090,7 +1083,6 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL ); ADVANCE_RING(); - dev_priv->page_flipping = 1; dev_priv->current_page = 0; dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; @@ -1101,7 +1093,7 @@ static int radeon_do_init_pageflip( drm_device_t *dev ) int radeon_do_cleanup_pageflip( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); if (dev_priv->current_page != 0) radeon_cp_dispatch_flip( dev ); @@ -1117,13 +1109,11 @@ int radeon_do_cleanup_pageflip( drm_device_t *dev ) /* Swapping and flipping are different operations, need different ioctls. * They can & should be intermixed to support multiple 3d windows. */ -int radeon_cp_flip( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_flip( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -1138,14 +1128,12 @@ int radeon_cp_flip( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_swap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_swap( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG( "%s\n", __FUNCTION__ ); + DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev ); @@ -1161,11 +1149,9 @@ int radeon_cp_swap( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_vertex( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_vertex( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; @@ -1176,27 +1162,26 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg, - sizeof(vertex) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data, + sizeof(vertex) ); - DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard ); if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", vertex.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( vertex.prim < 0 || vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1204,14 +1189,14 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, buf = dma->buflist[vertex.idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Build up a prim_t record: @@ -1250,11 +1235,9 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_indices( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; @@ -1266,27 +1249,26 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg, - sizeof(elts) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data, + sizeof(elts) ); - DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n", - __FUNCTION__, current->pid, + DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n", + DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard ); if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", elts.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( elts.prim < 0 || elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { DRM_ERROR( "buffer prim %d\n", elts.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1294,14 +1276,14 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, buf = dma->buflist[elts.idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", elts.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } count = (elts.end - elts.start) / sizeof(u16); @@ -1309,11 +1291,11 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, if ( elts.start & 0x7 ) { DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( elts.start < buf->used ) { DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf->used = elts.end; @@ -1351,11 +1333,9 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_texture( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_texture( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_texture_t tex; drm_radeon_tex_image_t image; @@ -1363,18 +1343,17 @@ int radeon_cp_texture( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); if ( tex.image == NULL ) { DRM_ERROR( "null texture image!\n" ); - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( copy_from_user( &image, + if ( DRM_COPY_FROM_USER( &image, (drm_radeon_tex_image_t *)tex.image, sizeof(image) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); @@ -1385,23 +1364,20 @@ int radeon_cp_texture( struct inode *inode, struct file *filp, return ret; } -int radeon_cp_stipple( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_stipple( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_stipple_t stipple; u32 mask[32]; LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg, - sizeof(stipple) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, + sizeof(stipple) ); - if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) ) - return -EFAULT; + if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) + return DRM_ERR(EFAULT); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1411,11 +1387,9 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_indirect( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_indirect( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1425,13 +1399,12 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg, - sizeof(indirect) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t *)data, + sizeof(indirect) ); DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", indirect.idx, indirect.start, @@ -1440,25 +1413,25 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", indirect.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf = dma->buflist[indirect.idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } if ( indirect.start < buf->used ) { DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", indirect.start, buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1489,11 +1462,9 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_vertex2( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_vertex2( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; @@ -1505,21 +1476,21 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg, - sizeof(vertex) ) ) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, + sizeof(vertex) ); - DRM_DEBUG( __FUNCTION__": pid=%d index=%d discard=%d\n", - current->pid, vertex.idx, vertex.discard ); + DRM_DEBUG( "pid=%d index=%d discard=%d\n", + DRM_CURRENTPID, + vertex.idx, vertex.discard ); if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", vertex.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1527,34 +1498,34 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp, buf = dma->buflist[vertex.idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - return -EINVAL; + return DRM_ERR(EINVAL); for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { drm_radeon_prim_t prim; drm_radeon_tcl_prim_t tclprim; - if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) ) - return -EFAULT; + if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) ) + return DRM_ERR(EFAULT); if ( prim.stateidx != laststate ) { drm_radeon_state_t state; - if ( copy_from_user( &state, + if ( DRM_COPY_FROM_USER( &state, &vertex.state[prim.stateidx], sizeof(state) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); radeon_emit_state2( dev_priv, &state ); @@ -1607,7 +1578,7 @@ static int radeon_emit_packets( RING_LOCALS; if (sz * sizeof(int) > cmdbuf->bufsz) - return -EINVAL; + return DRM_ERR(EINVAL); BEGIN_RING(sz+1); OUT_RING( CP_PACKET0( reg, (sz-1) ) ); @@ -1619,7 +1590,7 @@ static int radeon_emit_packets( return 0; } -static inline int radeon_emit_scalars( +static __inline__ int radeon_emit_scalars( drm_radeon_private_t *dev_priv, drm_radeon_cmd_header_t header, drm_radeon_cmd_buffer_t *cmdbuf ) @@ -1641,7 +1612,7 @@ static inline int radeon_emit_scalars( return 0; } -static inline int radeon_emit_vectors( +static __inline__ int radeon_emit_vectors( drm_radeon_private_t *dev_priv, drm_radeon_cmd_header_t header, drm_radeon_cmd_buffer_t *cmdbuf ) @@ -1674,16 +1645,16 @@ static int radeon_emit_packet3( drm_device_t *dev, RING_LOCALS; - DRM_DEBUG("%s\n", __FUNCTION__); + DRM_DEBUG("\n"); - if (__get_user( tmp, &cmd[0])) - return -EFAULT; + if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) + return DRM_ERR(EFAULT); cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || cmdsz * 4 > cmdbuf->bufsz) - return -EINVAL; + return DRM_ERR(EINVAL); BEGIN_RING( cmdsz ); OUT_RING_USER_TABLE( cmd, cmdsz ); @@ -1706,21 +1677,21 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, int i = 0; RING_LOCALS; - DRM_DEBUG("%s\n", __FUNCTION__); + DRM_DEBUG("\n"); - if (__get_user( tmp, &cmd[0])) - return -EFAULT; + if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) + return DRM_ERR(EFAULT); cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || cmdsz * 4 > cmdbuf->bufsz) - return -EINVAL; + return DRM_ERR(EINVAL); do { if ( i < cmdbuf->nbox ) { - if (__copy_from_user( &box, &boxes[i], sizeof(box) )) - return -EFAULT; + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) + return DRM_ERR(EFAULT); radeon_emit_clip_rect( dev_priv, &box ); } @@ -1740,11 +1711,9 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, -int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf = 0; @@ -1755,34 +1724,31 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, LOCK_TEST_WITH_RETURN( dev ); if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( &cmdbuf, (drm_radeon_cmd_buffer_t *)arg, - sizeof(cmdbuf) ) ) { - DRM_ERROR("copy_from_user\n"); - return -EFAULT; - } + DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, + sizeof(cmdbuf) ); - DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid ); + DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - if (verify_area( VERIFY_READ, cmdbuf.buf, cmdbuf.bufsz )) - return -EFAULT; + if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) + return DRM_ERR(EFAULT); if (cmdbuf.nbox && - verify_area( VERIFY_READ, cmdbuf.boxes, + DRM_VERIFYAREA_READ(cmdbuf.boxes, cmdbuf.nbox * sizeof(drm_clip_rect_t))) - return -EFAULT; + return DRM_ERR(EFAULT); while ( cmdbuf.bufsz >= sizeof(header) ) { - if (__get_user( header.i, (int *)cmdbuf.buf )) { + if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { DRM_ERROR("__get_user %p\n", cmdbuf.buf); - return -EFAULT; + return DRM_ERR(EFAULT); } cmdbuf.buf += sizeof(header); @@ -1792,21 +1758,21 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, case RADEON_CMD_PACKET: if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_packets failed\n"); - return -EINVAL; + return DRM_ERR(EINVAL); } break; case RADEON_CMD_SCALARS: if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_scalars failed\n"); - return -EINVAL; + return DRM_ERR(EINVAL); } break; case RADEON_CMD_VECTORS: if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_vectors failed\n"); - return -EINVAL; + return DRM_ERR(EINVAL); } break; @@ -1815,13 +1781,13 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != current->pid || buf->pending ) { + if ( buf->pid != DRM_CURRENTPID || buf->pending ) { DRM_ERROR( "bad buffer\n" ); - return -EINVAL; + return DRM_ERR(EINVAL); } radeon_cp_discard_buffer( dev, buf ); @@ -1830,14 +1796,14 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, case RADEON_CMD_PACKET3: if (radeon_emit_packet3( dev, &cmdbuf )) { DRM_ERROR("radeon_emit_packet3 failed\n"); - return -EINVAL; + return DRM_ERR(EINVAL); } break; case RADEON_CMD_PACKET3_CLIP: if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); - return -EINVAL; + return DRM_ERR(EINVAL); } break; @@ -1845,7 +1811,7 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, DRM_ERROR("bad cmd_type %d at %p\n", header.header.cmd_type, cmdbuf.buf - sizeof(header)); - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -1856,46 +1822,35 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, -int radeon_cp_getparam( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_getparam( DRM_IOCTL_ARGS ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_getparam_t param; int value; if ( !dev_priv ) { - DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); } - if ( copy_from_user( ¶m, (drm_radeon_getparam_t *)arg, - sizeof(param) ) ) { - DRM_ERROR("copy_from_user\n"); - return -EFAULT; - } + DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, + sizeof(param) ); - DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid ); + DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); switch( param.param ) { case RADEON_PARAM_AGP_BUFFER_OFFSET: value = dev_priv->agp_buffers_offset; break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( copy_to_user( param.value, &value, sizeof(int) ) ) { + if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { DRM_ERROR( "copy_to_user\n" ); - return -EFAULT; + return DRM_ERR(EFAULT); } return 0; } - - - - - - diff --git a/shared/drm.h b/shared/drm.h index 6ab295c4..376568e0 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -38,10 +38,27 @@ #if defined(__linux__) #include <linux/config.h> #include <asm/ioctl.h> /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#elif defined(__FreeBSD__) +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) && defined(XFree86Server) +/* Prevent name collision when including sys/ioccom.h */ +#undef ioctl #include <sys/ioccom.h> -#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#else +#include <sys/ioccom.h> +#endif /* __FreeBSD__ && xf86ioctl */ +#define DRM_IOCTL_NR(n) ((n) & 0xff) +#define DRM_IOC_VOID IOC_VOID +#define DRM_IOC_READ IOC_OUT +#define DRM_IOC_WRITE IOC_IN +#define DRM_IOC_READWRITE IOC_INOUT +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif #define XFREE86_VERSION(major,minor,patch,snap) \ @@ -367,10 +384,9 @@ typedef struct drm_scatter_gather { #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) #define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) #define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) diff --git a/bsd/mga/mga.h b/shared/mga.h index 277aa202..5380cb0d 100644 --- a/bsd/mga/mga.h +++ b/shared/mga.h @@ -41,6 +41,33 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "mga" +#define DRIVER_DESC "Matrox G200/G400" +#define DRIVER_DATE "20010321" + +#define DRIVER_MAJOR 3 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 2 + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + +#define __HAVE_COUNTERS 3 +#define __HAVE_COUNTER6 _DRM_STAT_IRQ +#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY +#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY + /* Driver customization: */ #define DRIVER_PRETAKEDOWN() do { \ diff --git a/shared/mga_dma.c b/shared/mga_dma.c new file mode 100644 index 00000000..1d64e1ca --- /dev/null +++ b/shared/mga_dma.c @@ -0,0 +1,786 @@ +/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*- + * Created: Mon Dec 13 01:50:01 1999 by jhartmann@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> + * Jeff Hartmann <jhartmann@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + * Rewritten by: + * Gareth Hughes <gareth@valinux.com> + */ + +#include "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" + +#define MGA_DEFAULT_USEC_TIMEOUT 10000 +#define MGA_FREELIST_DEBUG 0 + + +/* ================================================================ + * Engine control + */ + +int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) +{ + u32 status = 0; + int i; + DRM_DEBUG( "\n" ); + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; + if ( status == MGA_ENDPRDMASTS ) { + MGA_WRITE8( MGA_CRTC_INDEX, 0 ); + return 0; + } + DRM_UDELAY( 1 ); + } + +#if MGA_DMA_DEBUG + DRM_ERROR( "failed!\n" ); + DRM_INFO( " status=0x%08x\n", status ); +#endif + return DRM_ERR(EBUSY); +} + +int mga_do_dma_idle( drm_mga_private_t *dev_priv ) +{ + u32 status = 0; + int i; + DRM_DEBUG( "\n" ); + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; + if ( status == MGA_ENDPRDMASTS ) return 0; + DRM_UDELAY( 1 ); + } + +#if MGA_DMA_DEBUG + DRM_ERROR( "failed! status=0x%08x\n", status ); +#endif + return DRM_ERR(EBUSY); +} + +int mga_do_dma_reset( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_primary_buffer_t *primary = &dev_priv->prim; + + DRM_DEBUG( "\n" ); + + /* The primary DMA stream should look like new right about now. + */ + primary->tail = 0; + primary->space = primary->size; + primary->last_flush = 0; + + sarea_priv->last_wrap = 0; + + /* FIXME: Reset counters, buffer ages etc... + */ + + /* FIXME: What else do we need to reinitialize? WARP stuff? + */ + + return 0; +} + +int mga_do_engine_reset( drm_mga_private_t *dev_priv ) +{ + DRM_DEBUG( "\n" ); + + /* Okay, so we've completely screwed up and locked the engine. + * How about we clean up after ourselves? + */ + MGA_WRITE( MGA_RST, MGA_SOFTRESET ); + DRM_UDELAY( 15 ); /* Wait at least 10 usecs */ + MGA_WRITE( MGA_RST, 0 ); + + /* Initialize the registers that get clobbered by the soft + * reset. Many of the core register values survive a reset, + * but the drawing registers are basically all gone. + * + * 3D clients should probably die after calling this. The X + * server should reset the engine state to known values. + */ +#if 0 + MGA_WRITE( MGA_PRIMPTR, + virt_to_bus((void *)dev_priv->prim.status_page) | + MGA_PRIMPTREN0 | + MGA_PRIMPTREN1 ); +#endif + + MGA_WRITE( MGA_ICLEAR, MGA_SOFTRAPICLR ); + MGA_WRITE( MGA_IEN, MGA_SOFTRAPIEN ); + + /* The primary DMA stream should look like new right about now. + */ + mga_do_dma_reset( dev_priv ); + + /* This bad boy will never fail. + */ + return 0; +} + + +/* ================================================================ + * Primary DMA stream + */ + +void mga_do_dma_flush( drm_mga_private_t *dev_priv ) +{ + drm_mga_primary_buffer_t *primary = &dev_priv->prim; + u32 head, tail; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + if ( primary->tail == primary->last_flush ) { + DRM_DEBUG( " bailing out...\n" ); + return; + } + + tail = primary->tail + dev_priv->primary->offset; + + /* We need to pad the stream between flushes, as the card + * actually (partially?) reads the first of these commands. + * See page 4-16 in the G400 manual, middle of the page or so. + */ + BEGIN_DMA( 1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + ADVANCE_DMA(); + + primary->last_flush = primary->tail; + + head = MGA_READ( MGA_PRIMADDRESS ); + + if ( head <= tail ) { + primary->space = primary->size - primary->tail; + } else { + primary->space = head - tail; + } + + DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset ); + DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset ); + DRM_DEBUG( " space = 0x%06x\n", primary->space ); + + mga_flush_write_combine(); + MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); + + DRM_DEBUG( "done.\n" ); +} + +void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) +{ + drm_mga_primary_buffer_t *primary = &dev_priv->prim; + u32 head, tail; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + BEGIN_DMA_WRAP(); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + ADVANCE_DMA(); + + tail = primary->tail + dev_priv->primary->offset; + + primary->tail = 0; + primary->last_flush = 0; + primary->last_wrap++; + + head = MGA_READ( MGA_PRIMADDRESS ); + + if ( head == dev_priv->primary->offset ) { + primary->space = primary->size; + } else { + primary->space = head - dev_priv->primary->offset; + } + + DRM_DEBUG( " head = 0x%06lx\n", + head - dev_priv->primary->offset ); + DRM_DEBUG( " tail = 0x%06x\n", primary->tail ); + DRM_DEBUG( " wrap = %d\n", primary->last_wrap ); + DRM_DEBUG( " space = 0x%06x\n", primary->space ); + + mga_flush_write_combine(); + MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); + + set_bit( 0, &primary->wrapped ); + DRM_DEBUG( "done.\n" ); +} + +void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) +{ + drm_mga_primary_buffer_t *primary = &dev_priv->prim; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + u32 head = dev_priv->primary->offset; + DRM_DEBUG( "\n" ); + + sarea_priv->last_wrap++; + DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); + + mga_flush_write_combine(); + MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); + + clear_bit( 0, &primary->wrapped ); + DRM_DEBUG( "done.\n" ); +} + + +/* ================================================================ + * Freelist management + */ + +#define MGA_BUFFER_USED ~0 +#define MGA_BUFFER_FREE 0 + +#if MGA_FREELIST_DEBUG +static void mga_freelist_print( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_freelist_t *entry; + + DRM_INFO( "\n" ); + DRM_INFO( "current dispatch: last=0x%x done=0x%x\n", + dev_priv->sarea_priv->last_dispatch, + (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) - + dev_priv->primary->offset) ); + DRM_INFO( "current freelist:\n" ); + + for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) { + DRM_INFO( " %p idx=%2d age=0x%x 0x%06lx\n", + entry, entry->buf->idx, entry->age.head, + entry->age.head - dev_priv->primary->offset ); + } + DRM_INFO( "\n" ); +} +#endif + +static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) +{ + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_freelist_t *entry; + int i; + DRM_DEBUG( "count=%d\n", dma->buf_count ); + + dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t), + DRM_MEM_DRIVER ); + if ( dev_priv->head == NULL ) + return DRM_ERR(ENOMEM); + + memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) ); + SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 ); + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + + entry = DRM(alloc)( sizeof(drm_mga_freelist_t), + DRM_MEM_DRIVER ); + if ( entry == NULL ) + return DRM_ERR(ENOMEM); + + memset( entry, 0, sizeof(drm_mga_freelist_t) ); + + entry->next = dev_priv->head->next; + entry->prev = dev_priv->head; + SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 ); + entry->buf = buf; + + if ( dev_priv->head->next != NULL ) + dev_priv->head->next->prev = entry; + if ( entry->next == NULL ) + dev_priv->tail = entry; + + buf_priv->list_entry = entry; + buf_priv->discard = 0; + buf_priv->dispatched = 0; + + dev_priv->head->next = entry; + } + + return 0; +} + +static void mga_freelist_cleanup( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_freelist_t *entry; + drm_mga_freelist_t *next; + DRM_DEBUG( "\n" ); + + entry = dev_priv->head; + while ( entry ) { + next = entry->next; + DRM(free)( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); + entry = next; + } + + dev_priv->head = dev_priv->tail = NULL; +} + +#if 0 +/* FIXME: Still needed? + */ +static void mga_freelist_reset( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + int i; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + SET_AGE( &buf_priv->list_entry->age, + MGA_BUFFER_FREE, 0 ); + } +} +#endif + +static drm_buf_t *mga_freelist_get( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_freelist_t *next; + drm_mga_freelist_t *prev; + drm_mga_freelist_t *tail = dev_priv->tail; + u32 head, wrap; + DRM_DEBUG( "\n" ); + + head = MGA_READ( MGA_PRIMADDRESS ); + wrap = dev_priv->sarea_priv->last_wrap; + + DRM_DEBUG( " tail=0x%06lx %d\n", + tail->age.head ? + tail->age.head - dev_priv->primary->offset : 0, + tail->age.wrap ); + DRM_DEBUG( " head=0x%06lx %d\n", + head - dev_priv->primary->offset, wrap ); + + if ( TEST_AGE( &tail->age, head, wrap ) ) { + prev = dev_priv->tail->prev; + next = dev_priv->tail; + prev->next = NULL; + next->prev = next->next = NULL; + dev_priv->tail = prev; + SET_AGE( &next->age, MGA_BUFFER_USED, 0 ); + return next->buf; + } + + DRM_DEBUG( "returning NULL!\n" ); + return NULL; +} + +int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_freelist_t *head, *entry, *prev; + + DRM_DEBUG( "age=0x%06lx wrap=%d\n", + buf_priv->list_entry->age.head - + dev_priv->primary->offset, + buf_priv->list_entry->age.wrap ); + + entry = buf_priv->list_entry; + head = dev_priv->head; + + if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { + SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 ); + prev = dev_priv->tail; + prev->next = entry; + entry->prev = prev; + entry->next = NULL; + } else { + prev = head->next; + head->next = entry; + prev->prev = entry; + entry->prev = head; + entry->next = prev; + } + + return 0; +} + + +/* ================================================================ + * DMA initialization, cleanup + */ + +static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) +{ + drm_mga_private_t *dev_priv; + int ret; + DRM_DEBUG( "\n" ); + + dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER ); + if ( !dev_priv ) + return DRM_ERR(ENOMEM); + + memset( dev_priv, 0, sizeof(drm_mga_private_t) ); + + dev_priv->chipset = init->chipset; + + dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; + + if ( init->sgram ) { + dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; + } else { + dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; + } + dev_priv->maccess = init->maccess; + + dev_priv->fb_cpp = init->fb_cpp; + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + dev_priv->depth_cpp = init->depth_cpp; + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + + /* FIXME: Need to support AGP textures... + */ + dev_priv->texture_offset = init->texture_offset[0]; + dev_priv->texture_size = init->texture_size[0]; + + DRM_GETSAREA(); + + if(!dev_priv->sarea) { + DRM_ERROR( "failed to find sarea!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + if(!dev_priv->fb) { + DRM_ERROR( "failed to find framebuffer!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + if(!dev_priv->mmio) { + DRM_ERROR( "failed to find mmio region!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->status, init->status_offset ); + if(!dev_priv->status) { + DRM_ERROR( "failed to find status page!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + + DRM_FIND_MAP( dev_priv->warp, init->warp_offset ); + if(!dev_priv->warp) { + DRM_ERROR( "failed to find warp microcode region!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->primary, init->primary_offset ); + if(!dev_priv->primary) { + DRM_ERROR( "failed to find primary dma region!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + if(!dev_priv->buffers) { + DRM_ERROR( "failed to find dma buffer region!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(EINVAL); + } + + dev_priv->sarea_priv = + (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + DRM_IOREMAP( dev_priv->warp ); + DRM_IOREMAP( dev_priv->primary ); + DRM_IOREMAP( dev_priv->buffers ); + + if(!dev_priv->warp->handle || + !dev_priv->primary->handle || + !dev_priv->buffers->handle ) { + DRM_ERROR( "failed to ioremap agp regions!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(ENOMEM); + } + + ret = mga_warp_install_microcode( dev_priv ); + if ( ret < 0 ) { + DRM_ERROR( "failed to install WARP ucode!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return ret; + } + + ret = mga_warp_init( dev_priv ); + if ( ret < 0 ) { + DRM_ERROR( "failed to init WARP engine!\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return ret; + } + + dev_priv->prim.status = (u32 *)dev_priv->status->handle; + + mga_do_wait_for_idle( dev_priv ); + + /* Init the primary DMA registers. + */ + MGA_WRITE( MGA_PRIMADDRESS, + dev_priv->primary->offset | MGA_DMA_GENERAL ); +#if 0 + MGA_WRITE( MGA_PRIMPTR, + virt_to_bus((void *)dev_priv->prim.status) | + MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ + MGA_PRIMPTREN1 ); /* DWGSYNC */ +#endif + + dev_priv->prim.start = (u8 *)dev_priv->primary->handle; + dev_priv->prim.end = ((u8 *)dev_priv->primary->handle + + dev_priv->primary->size); + dev_priv->prim.size = dev_priv->primary->size; + + dev_priv->prim.tail = 0; + dev_priv->prim.space = dev_priv->prim.size; + dev_priv->prim.wrapped = 0; + + dev_priv->prim.last_flush = 0; + dev_priv->prim.last_wrap = 0; + + dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; + + dev_priv->prim.status[0] = dev_priv->primary->offset; + dev_priv->prim.status[1] = 0; + + dev_priv->sarea_priv->last_wrap = 0; + dev_priv->sarea_priv->last_frame.head = 0; + dev_priv->sarea_priv->last_frame.wrap = 0; + + if ( mga_freelist_init( dev, dev_priv ) < 0 ) { + DRM_ERROR( "could not initialize freelist\n" ); + /* Assign dev_private so we can do cleanup. */ + dev->dev_private = (void *)dev_priv; + mga_do_cleanup_dma( dev ); + return DRM_ERR(ENOMEM); + } + + /* Make dev_private visable to others. */ + dev->dev_private = (void *)dev_priv; + return 0; +} + +int mga_do_cleanup_dma( drm_device_t *dev ) +{ + DRM_DEBUG( "\n" ); + + if ( dev->dev_private ) { + drm_mga_private_t *dev_priv = dev->dev_private; + + DRM_IOREMAPFREE( dev_priv->warp ); + DRM_IOREMAPFREE( dev_priv->primary ); + DRM_IOREMAPFREE( dev_priv->buffers ); + + if ( dev_priv->head != NULL ) { + mga_freelist_cleanup( dev ); + } + + DRM(free)( dev->dev_private, sizeof(drm_mga_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int mga_dma_init( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_init_t init; + + DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t *)data, sizeof(init) ); + + switch ( init.func ) { + case MGA_INIT_DMA: + return mga_do_init_dma( dev, &init ); + case MGA_CLEANUP_DMA: + return mga_do_cleanup_dma( dev ); + } + + return DRM_ERR(EINVAL); +} + + +/* ================================================================ + * Primary DMA stream management + */ + +int mga_dma_flush( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_lock_t lock; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); + + DRM_DEBUG( "%s%s%s\n", + (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", + (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", + (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" ); + + WRAP_WAIT_WITH_RETURN( dev_priv ); + + if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) { + mga_do_dma_flush( dev_priv ); + } + + if ( lock.flags & _DRM_LOCK_QUIESCENT ) { +#if MGA_DMA_DEBUG + int ret = mga_do_wait_for_idle( dev_priv ); + if ( ret < 0 ) + DRM_INFO( "%s: -EBUSY\n", __func__ ); + return ret; +#else + return mga_do_wait_for_idle( dev_priv ); +#endif + } else { + return 0; + } +} + +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 ); + + return mga_do_dma_reset( dev_priv ); +} + + +/* ================================================================ + * DMA buffer management + */ + +static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) +{ + drm_buf_t *buf; + int i; + + for ( i = d->granted_count ; i < d->request_count ; i++ ) { + buf = mga_freelist_get( dev ); + if ( !buf ) return DRM_ERR(EAGAIN); + + buf->pid = DRM_CURRENTPID; + + if ( DRM_COPY_TO_USER( &d->request_indices[i], + &buf->idx, sizeof(buf->idx) ) ) + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], + &buf->total, sizeof(buf->total) ) ) + return DRM_ERR(EFAULT); + + d->granted_count++; + } + return 0; +} + +int mga_dma_buffers( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_dma_t d; + int ret = 0; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); + + /* Please don't send us buffers. + */ + if ( d.send_count != 0 ) { + DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); + } + + /* We'll send you buffers. + */ + 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); + } + + WRAP_TEST_WITH_RETURN( dev_priv ); + + d.granted_count = 0; + + if ( d.request_count ) { + ret = mga_dma_get_buffers( dev, &d ); + } + + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); + + return ret; +} diff --git a/shared/mga_drm.h b/shared/mga_drm.h new file mode 100644 index 00000000..8f56beed --- /dev/null +++ b/shared/mga_drm.h @@ -0,0 +1,325 @@ +/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- + * Created: Tue Jan 25 01:50:01 1999 by jhartmann@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 + * VA LINUX SYSTEMS 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: + * Jeff Hartmann <jhartmann@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + * Rewritten by: + * Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __MGA_DRM_H__ +#define __MGA_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (mga_sarea.h) + */ + +#ifndef __MGA_SAREA_DEFINES__ +#define __MGA_SAREA_DEFINES__ + +/* WARP pipe flags + */ +#define MGA_F 0x1 /* fog */ +#define MGA_A 0x2 /* alpha */ +#define MGA_S 0x4 /* specular */ +#define MGA_T2 0x8 /* multitexture */ + +#define MGA_WARP_TGZ 0 +#define MGA_WARP_TGZF (MGA_F) +#define MGA_WARP_TGZA (MGA_A) +#define MGA_WARP_TGZAF (MGA_F|MGA_A) +#define MGA_WARP_TGZS (MGA_S) +#define MGA_WARP_TGZSF (MGA_S|MGA_F) +#define MGA_WARP_TGZSA (MGA_S|MGA_A) +#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A) +#define MGA_WARP_T2GZ (MGA_T2) +#define MGA_WARP_T2GZF (MGA_T2|MGA_F) +#define MGA_WARP_T2GZA (MGA_T2|MGA_A) +#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F) +#define MGA_WARP_T2GZS (MGA_T2|MGA_S) +#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F) +#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) +#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) + +#define MGA_MAX_G200_PIPES 8 /* no multitex */ +#define MGA_MAX_G400_PIPES 16 +#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES +#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ + +#define MGA_CARD_TYPE_G200 1 +#define MGA_CARD_TYPE_G400 2 + + +#define MGA_FRONT 0x1 +#define MGA_BACK 0x2 +#define MGA_DEPTH 0x4 + +/* What needs to be changed for the current vertex dma buffer? + */ +#define MGA_UPLOAD_CONTEXT 0x1 +#define MGA_UPLOAD_TEX0 0x2 +#define MGA_UPLOAD_TEX1 0x4 +#define MGA_UPLOAD_PIPE 0x8 +#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ +#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ +#define MGA_UPLOAD_2D 0x40 +#define MGA_WAIT_AGE 0x80 /* handled client-side */ +#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ +#if 0 +#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock + quiescent */ +#endif + +/* 32 buffers of 64k each, total 2 meg. + */ +#define MGA_BUFFER_SIZE (1 << 16) +#define MGA_NUM_BUFFERS 128 + +/* Keep these small for testing. + */ +#define MGA_NR_SAREA_CLIPRECTS 8 + +/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 + * regions, subject to a minimum region size of (1<<16) == 64k. + * + * Clients may subdivide regions internally, but when sharing between + * clients, the region size is the minimum granularity. + */ + +#define MGA_CARD_HEAP 0 +#define MGA_AGP_HEAP 1 +#define MGA_NR_TEX_HEAPS 2 +#define MGA_NR_TEX_REGIONS 16 +#define MGA_LOG_MIN_TEX_REGION_SIZE 16 + +#endif /* __MGA_SAREA_DEFINES__ */ + + +/* Setup registers for 3D context + */ +typedef struct { + unsigned int dstorg; + unsigned int maccess; + unsigned int plnwt; + unsigned int dwgctl; + unsigned int alphactrl; + unsigned int fogcolor; + unsigned int wflag; + unsigned int tdualstage0; + unsigned int tdualstage1; + unsigned int fcol; + unsigned int stencil; + unsigned int stencilctl; +} drm_mga_context_regs_t; + +/* Setup registers for 2D, X server + */ +typedef struct { + unsigned int pitch; +} drm_mga_server_regs_t; + +/* Setup registers for each texture unit + */ +typedef struct { + unsigned int texctl; + unsigned int texctl2; + unsigned int texfilter; + unsigned int texbordercol; + unsigned int texorg; + unsigned int texwidth; + unsigned int texheight; + unsigned int texorg1; + unsigned int texorg2; + unsigned int texorg3; + unsigned int texorg4; +} drm_mga_texture_regs_t; + +/* General aging mechanism + */ +typedef struct { + unsigned int head; /* Position of head pointer */ + unsigned int wrap; /* Primary DMA wrap count */ +} drm_mga_age_t; + +typedef struct _drm_mga_sarea { + /* The channel for communication of state information to the kernel + * on firing a vertex dma buffer. + */ + drm_mga_context_regs_t context_state; + drm_mga_server_regs_t server_state; + drm_mga_texture_regs_t tex_state[2]; + unsigned int warp_pipe; + unsigned int dirty; + unsigned int vertsize; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Information about the most recently used 3d drawable. The + * client fills in the req_* fields, the server fills in the + * exported_ fields and puts the cliprects into boxes, above. + * + * The client clears the exported_drawable field before + * clobbering the boxes data. + */ + unsigned int req_drawable; /* the X drawable id */ + unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ + + unsigned int exported_drawable; + unsigned int exported_index; + unsigned int exported_stamp; + unsigned int exported_buffers; + unsigned int exported_nfront; + unsigned int exported_nback; + int exported_back_x, exported_front_x, exported_w; + int exported_back_y, exported_front_y, exported_h; + drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + + /* Counters for aging textures and for client-side throttling. + */ + unsigned int status[4]; + unsigned int last_wrap; + + drm_mga_age_t last_frame; + unsigned int last_enqueue; /* last time a buffer was enqueued */ + unsigned int last_dispatch; /* age of the most recently dispatched buffer */ + unsigned int last_quiescent; /* */ + + /* LRU lists for texture memory in agp space and on the card. + */ + drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; + unsigned int texAge[MGA_NR_TEX_HEAPS]; + + /* Mechanism to validate card state. + */ + int ctxOwner; +} drm_mga_sarea_t; + + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmMga.h) + */ + +/* MGA specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) +#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) +#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) + +typedef struct _drm_mga_warp_index { + int installed; + unsigned long phys_addr; + int size; +} drm_mga_warp_index_t; + +typedef struct drm_mga_init { + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 + } func; + + unsigned long sarea_priv_offset; + + int chipset; + int sgram; + + unsigned int maccess; + + unsigned int fb_cpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; + + unsigned int texture_offset[MGA_NR_TEX_HEAPS]; + unsigned int texture_size[MGA_NR_TEX_HEAPS]; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long status_offset; + unsigned long warp_offset; + unsigned long primary_offset; + unsigned long buffers_offset; +} drm_mga_init_t; + +typedef struct drm_mga_fullscreen { + enum { + MGA_INIT_FULLSCREEN = 0x01, + MGA_CLEANUP_FULLSCREEN = 0x02 + } func; +} drm_mga_fullscreen_t; + +typedef struct drm_mga_clear { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; +} drm_mga_clear_t; + +typedef struct drm_mga_vertex { + int idx; /* buffer to queue */ + int used; /* bytes in use */ + int discard; /* client finished with buffer? */ +} drm_mga_vertex_t; + +typedef struct drm_mga_indices { + int idx; /* buffer to queue */ + unsigned int start; + unsigned int end; + int discard; /* client finished with buffer? */ +} drm_mga_indices_t; + +typedef struct drm_mga_iload { + int idx; + unsigned int dstorg; + unsigned int length; +} drm_mga_iload_t; + +typedef struct _drm_mga_blit { + unsigned int planemask; + unsigned int srcorg; + unsigned int dstorg; + int src_pitch, dst_pitch; + int delta_sx, delta_sy; + int delta_dx, delta_dy; + int height, ydir; /* flip image vertically */ + int source_pitch, dest_pitch; +} drm_mga_blit_t; + +#endif diff --git a/linux/mga_drv.h b/shared/mga_drv.h index ba2602e7..51bc706e 100644 --- a/linux/mga_drv.h +++ b/shared/mga_drv.h @@ -38,7 +38,7 @@ typedef struct drm_mga_primary_buffer { u32 tail; int space; - volatile int wrapped; + int wrapped; volatile u32 *status; @@ -46,8 +46,6 @@ typedef struct drm_mga_primary_buffer { u32 last_wrap; u32 high_mark; - - spinlock_t list_lock; } drm_mga_primary_buffer_t; typedef struct drm_mga_freelist { @@ -103,14 +101,10 @@ typedef struct drm_mga_private { } drm_mga_private_t; /* mga_dma.c */ -extern int mga_dma_init( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_flush( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_buffers( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int mga_dma_init( DRM_IOCTL_ARGS ); +extern int mga_dma_flush( DRM_IOCTL_ARGS ); +extern int mga_dma_reset( DRM_IOCTL_ARGS ); +extern int mga_dma_buffers( DRM_IOCTL_ARGS ); extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ); extern int mga_do_dma_idle( drm_mga_private_t *dev_priv ); @@ -125,24 +119,18 @@ extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ); extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); /* mga_state.c */ -extern int mga_dma_clear( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_swap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_vertex( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_iload( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_dma_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int mga_dma_clear( DRM_IOCTL_ARGS ); +extern int mga_dma_swap( DRM_IOCTL_ARGS ); +extern int mga_dma_vertex( DRM_IOCTL_ARGS ); +extern int mga_dma_indices( DRM_IOCTL_ARGS ); +extern int mga_dma_iload( DRM_IOCTL_ARGS ); +extern int mga_dma_blit( DRM_IOCTL_ARGS ); /* mga_warp.c */ 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() mb() +#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() #define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) @@ -153,12 +141,12 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv ); #ifdef __alpha__ #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { wmb(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { wmb(); MGA_DEREF8( reg ) = val; } while (0) +#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) static inline u32 _MGA_READ(u32 *addr) { - mb(); + DRM_READMEMORYBARRIER(); return *(volatile u32 *)addr; } @@ -198,10 +186,10 @@ do { \ #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != current->pid ) { \ + dev->lock.pid != DRM_CURRENTPID ) { \ DRM_ERROR( "%s called without lock held\n", \ - __FUNCTION__ ); \ - return -EINVAL; \ + __func__ ); \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -213,8 +201,8 @@ do { \ } else if ( dev_priv->prim.space < \ dev_priv->prim.high_mark ) { \ if ( MGA_DMA_DEBUG ) \ - DRM_INFO( __FUNCTION__": wrap...\n" ); \ - return -EBUSY; \ + DRM_INFO( "%s: wrap...\n", __func__ ); \ + return DRM_ERR(EBUSY); \ } \ } \ } while (0) @@ -224,8 +212,8 @@ do { \ if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ if ( MGA_DMA_DEBUG ) \ - DRM_INFO( __FUNCTION__": wrap...\n" ); \ - return -EBUSY; \ + DRM_INFO( "%s: wrap...\n", __func__ ); \ + return DRM_ERR(EBUSY); \ } \ mga_do_dma_wrap_end( dev_priv ); \ } \ @@ -246,7 +234,7 @@ do { \ do { \ if ( MGA_VERBOSE ) { \ DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \ - (n), __FUNCTION__ ); \ + (n), __func__ ); \ DRM_INFO( " space=0x%x req=0x%x\n", \ dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ } \ @@ -257,7 +245,7 @@ do { \ #define BEGIN_DMA_WRAP() \ do { \ if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \ + DRM_INFO( "BEGIN_DMA() in %s\n", __func__ ); \ DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ } \ prim = dev_priv->prim.start; \ @@ -276,7 +264,7 @@ do { \ #define FLUSH_DMA() \ do { \ if ( 0 ) { \ - DRM_INFO( __FUNCTION__ ":\n" ); \ + DRM_INFO( "%s:\n", __func__ ); \ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ dev_priv->prim.tail, \ MGA_READ( MGA_PRIMADDRESS ) - \ @@ -634,7 +622,7 @@ do { \ /* Simple idle test. */ -static inline int mga_is_idle( drm_mga_private_t *dev_priv ) +static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv ) { u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; return ( status == MGA_ENDPRDMASTS ); diff --git a/shared/mga_state.c b/shared/mga_state.c new file mode 100644 index 00000000..adf67de3 --- /dev/null +++ b/shared/mga_state.c @@ -0,0 +1,1078 @@ +/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- + * Created: Thu Jan 27 02:53:43 2000 by jhartmann@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 + * VA LINUX SYSTEMS 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: + * Jeff Hartmann <jhartmann@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + * Rewritten by: + * Gareth Hughes <gareth@valinux.com> + */ + +#include "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" +#include "drm.h" + + +/* ================================================================ + * DMA hardware state programming functions + */ + +static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, + drm_clip_rect_t *box ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + unsigned int pitch = dev_priv->front_pitch; + DMA_LOCALS; + + BEGIN_DMA( 2 ); + + /* Force reset of DWGCTL on G400 (eliminates clip disable bit). + */ + if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { + DMA_BLOCK( MGA_DWGCTL, ctx->dwgctl, + MGA_LEN + MGA_EXEC, 0x80000000, + MGA_DWGCTL, ctx->dwgctl, + MGA_LEN + MGA_EXEC, 0x80000000 ); + } + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_CXBNDRY, (box->x2 << 16) | box->x1, + MGA_YTOP, box->y1 * pitch, + MGA_YBOT, box->y2 * pitch ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + DMA_LOCALS; + + BEGIN_DMA( 3 ); + + DMA_BLOCK( MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); + + DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, + MGA_ZORG, dev_priv->depth_offset ); + + DMA_BLOCK( MGA_FCOL, ctx->fcol, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + DMA_LOCALS; + + BEGIN_DMA( 4 ); + + DMA_BLOCK( MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); + + DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, + MGA_ZORG, dev_priv->depth_offset ); + + DMA_BLOCK( MGA_WFLAG1, ctx->wflag, + MGA_TDUALSTAGE0, ctx->tdualstage0, + MGA_TDUALSTAGE1, ctx->tdualstage1, + MGA_FCOL, ctx->fcol ); + + DMA_BLOCK( MGA_STENCIL, ctx->stencil, + MGA_STENCILCTL, ctx->stencilctl, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; + DMA_LOCALS; + + BEGIN_DMA( 4 ); + + DMA_BLOCK( MGA_TEXCTL2, tex->texctl2, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); + + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); + + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR24, tex->texwidth ); + + DMA_BLOCK( MGA_WR34, tex->texheight, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, + MGA_DMAPAD, 0x00000000 ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; + DMA_LOCALS; + +/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */ +/* tex->texctl, tex->texctl2); */ + + BEGIN_DMA( 6 ); + + DMA_BLOCK( MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); + + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); + + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR49, 0x00000000 ); + + DMA_BLOCK( MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, + MGA_WR52, MGA_G400_WR_MAGIC ); + + DMA_BLOCK( MGA_WR60, MGA_G400_WR_MAGIC, + MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, + MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; + DMA_LOCALS; + +/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */ +/* tex->texctl, tex->texctl2); */ + + BEGIN_DMA( 5 ); + + DMA_BLOCK( MGA_TEXCTL2, (tex->texctl2 | + MGA_MAP1_ENABLE | + MGA_G400_TC2_MAGIC), + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); + + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); + + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR49, 0x00000000 ); + + DMA_BLOCK( MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, + MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC ); + + DMA_BLOCK( MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, + MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int pipe = sarea_priv->warp_pipe; + DMA_LOCALS; + + BEGIN_DMA( 3 ); + + DMA_BLOCK( MGA_WIADDR, MGA_WMODE_SUSPEND, + MGA_WVRTXSZ, 0x00000007, + MGA_WFLAG, 0x00000000, + MGA_WR24, 0x00000000 ); + + DMA_BLOCK( MGA_WR25, 0x00000100, + MGA_WR34, 0x00000000, + MGA_WR42, 0x0000ffff, + MGA_WR60, 0x0000ffff ); + + /* Padding required to to hardware bug. + */ + DMA_BLOCK( MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | + MGA_WMODE_START | + MGA_WAGP_ENABLE) ); + + ADVANCE_DMA(); +} + +static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int pipe = sarea_priv->warp_pipe; + DMA_LOCALS; + +/* printk("mga_g400_emit_pipe %x\n", pipe); */ + + BEGIN_DMA( 10 ); + + DMA_BLOCK( MGA_WIADDR2, MGA_WMODE_SUSPEND, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + if ( pipe & MGA_T2 ) { + DMA_BLOCK( MGA_WVRTXSZ, 0x00001e09, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x1e000000 ); + } else { + if ( dev_priv->warp_pipe & MGA_T2 ) { + /* Flush the WARP pipe */ + DMA_BLOCK( MGA_YDST, 0x00000000, + MGA_FXLEFT, 0x00000000, + MGA_FXRIGHT, 0x00000001, + MGA_DWGCTL, MGA_DWGCTL_FLUSH ); + + DMA_BLOCK( MGA_LEN + MGA_EXEC, 0x00000001, + MGA_DWGSYNC, 0x00007000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_LEN + MGA_EXEC, 0x00000000 ); + + DMA_BLOCK( MGA_TEXCTL2, (MGA_DUALTEX | + MGA_G400_TC2_MAGIC), + MGA_LEN + MGA_EXEC, 0x00000000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_DMAPAD, 0x00000000 ); + } + + DMA_BLOCK( MGA_WVRTXSZ, 0x00001807, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x18000000 ); + } + + DMA_BLOCK( MGA_WFLAG, 0x00000000, + MGA_WFLAG1, 0x00000000, + MGA_WR56, MGA_G400_WR56_MAGIC, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_WR49, 0x00000000, /* tex0 */ + MGA_WR57, 0x00000000, /* tex0 */ + MGA_WR53, 0x00000000, /* tex1 */ + MGA_WR61, 0x00000000 ); /* tex1 */ + + DMA_BLOCK( MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ + MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ + MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ + MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ + + /* Padding required to to hardware bug */ + DMA_BLOCK( MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | + MGA_WMODE_START | + MGA_WAGP_ENABLE) ); + + ADVANCE_DMA(); +} + +static void mga_g200_emit_state( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + + if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { + mga_g200_emit_pipe( dev_priv ); + dev_priv->warp_pipe = sarea_priv->warp_pipe; + } + + if ( dirty & MGA_UPLOAD_CONTEXT ) { + mga_g200_emit_context( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; + } + + if ( dirty & MGA_UPLOAD_TEX0 ) { + mga_g200_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } +} + +static void mga_g400_emit_state( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + int multitex = sarea_priv->warp_pipe & MGA_T2; + + if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { + mga_g400_emit_pipe( dev_priv ); + dev_priv->warp_pipe = sarea_priv->warp_pipe; + } + + if ( dirty & MGA_UPLOAD_CONTEXT ) { + mga_g400_emit_context( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; + } + + if ( dirty & MGA_UPLOAD_TEX0 ) { + mga_g400_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } + + if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) { + mga_g400_emit_tex1( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; + } +} + + +/* ================================================================ + * SAREA state verification + */ + +/* Disallow all write destinations except the front and backbuffer. + */ +static int mga_verify_context( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + + if ( ctx->dstorg != dev_priv->front_offset && + ctx->dstorg != dev_priv->back_offset ) { + DRM_ERROR( "*** bad DSTORG: %x (front %x, back %x)\n\n", + ctx->dstorg, dev_priv->front_offset, + dev_priv->back_offset ); + ctx->dstorg = 0; + return DRM_ERR(EINVAL); + } + + return 0; +} + +/* Disallow texture reads from PCI space. + */ +static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; + unsigned int org; + + org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); + + if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) { + DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n", + tex->texorg, unit ); + tex->texorg = 0; + return DRM_ERR(EINVAL); + } + + return 0; +} + +static int mga_verify_state( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + int ret = 0; + + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + if ( dirty & MGA_UPLOAD_CONTEXT ) + ret |= mga_verify_context( dev_priv ); + + if ( dirty & MGA_UPLOAD_TEX0 ) + ret |= mga_verify_tex( dev_priv, 0 ); + + if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { + if ( dirty & MGA_UPLOAD_TEX1 ) + ret |= mga_verify_tex( dev_priv, 1 ); + + if ( dirty & MGA_UPLOAD_PIPE ) + ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); + } else { + if ( dirty & MGA_UPLOAD_PIPE ) + ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES ); + } + + return ( ret == 0 ); +} + +static int mga_verify_iload( drm_mga_private_t *dev_priv, + unsigned int dstorg, unsigned int length ) +{ + if ( dstorg < dev_priv->texture_offset || + dstorg + length > (dev_priv->texture_offset + + dev_priv->texture_size) ) { + DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg ); + return DRM_ERR(EINVAL); + } + + if ( length & MGA_ILOAD_MASK ) { + DRM_ERROR( "*** bad iload length: 0x%x\n", + length & MGA_ILOAD_MASK ); + return DRM_ERR(EINVAL); + } + + return 0; +} + +static int mga_verify_blit( drm_mga_private_t *dev_priv, + unsigned int srcorg, unsigned int dstorg ) +{ + if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || + (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) { + DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n", + srcorg, dstorg ); + return DRM_ERR(EINVAL); + } + return 0; +} + + +/* ================================================================ + * + */ + +static void mga_dma_dispatch_clear( drm_device_t *dev, + drm_mga_clear_t *clear ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + int i; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + BEGIN_DMA( 1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + ADVANCE_DMA(); + + for ( i = 0 ; i < nbox ; i++ ) { + drm_clip_rect_t *box = &pbox[i]; + u32 height = box->y2 - box->y1; + + DRM_DEBUG( " from=%d,%d to=%d,%d\n", + box->x1, box->y1, box->x2, box->y2 ); + + if ( clear->flags & MGA_FRONT ) { + BEGIN_DMA( 2 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->front_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); + + ADVANCE_DMA(); + } + + + if ( clear->flags & MGA_BACK ) { + BEGIN_DMA( 2 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->back_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); + + ADVANCE_DMA(); + } + + if ( clear->flags & MGA_DEPTH ) { + BEGIN_DMA( 2 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->depth_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_depth, + MGA_DSTORG, dev_priv->depth_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); + + ADVANCE_DMA(); + } + + } + + BEGIN_DMA( 1 ); + + /* Force reset of DWGCTL */ + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); + + ADVANCE_DMA(); + + FLUSH_DMA(); +} + +static void mga_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + int i; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + sarea_priv->last_frame.head = dev_priv->prim.tail; + sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; + + BEGIN_DMA( 4 + nbox ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset, + MGA_MACCESS, dev_priv->maccess, + MGA_SRCORG, dev_priv->back_offset, + MGA_AR5, dev_priv->front_pitch ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, 0xffffffff, + MGA_DWGCTL, MGA_DWGCTL_COPY ); + + for ( i = 0 ; i < nbox ; i++ ) { + drm_clip_rect_t *box = &pbox[i]; + u32 height = box->y2 - box->y1; + u32 start = box->y1 * dev_priv->front_pitch; + + DRM_DEBUG( " from=%d,%d to=%d,%d\n", + box->x1, box->y1, box->x2, box->y2 ); + + DMA_BLOCK( MGA_AR0, start + box->x2 - 1, + MGA_AR3, start + box->x1, + MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, + MGA_YDSTLEN + MGA_EXEC, + (box->y1 << 16) | height ); + } + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, + MGA_DWGCTL, ctx->dwgctl ); + + ADVANCE_DMA(); + + FLUSH_DMA(); + + DRM_DEBUG( "%s... done.\n", __func__ ); +} + +static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + u32 address = (u32) buf->bus_address; + u32 length = (u32) buf->used; + int i = 0; + DMA_LOCALS; + DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used ); + + if ( buf->used ) { + buf_priv->dispatched = 1; + + MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); + + do { + if ( i < sarea_priv->nbox ) { + mga_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + } + + BEGIN_DMA( 1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SECADDRESS, (address | + MGA_DMA_VERTEX), + MGA_SECEND, ((address + length) | + MGA_PAGPXFER) ); + + ADVANCE_DMA(); + } while ( ++i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + AGE_BUFFER( buf_priv ); + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; + + mga_freelist_put( dev, buf ); + } + + FLUSH_DMA(); +} + +static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, + unsigned int start, unsigned int end ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + u32 address = (u32) buf->bus_address; + int i = 0; + DMA_LOCALS; + DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end ); + + if ( start != end ) { + buf_priv->dispatched = 1; + + MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); + + do { + if ( i < sarea_priv->nbox ) { + mga_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + } + + BEGIN_DMA( 1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SETUPADDRESS, address + start, + MGA_SETUPEND, ((address + end) | + MGA_PAGPXFER) ); + + ADVANCE_DMA(); + } while ( ++i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + AGE_BUFFER( buf_priv ); + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; + + mga_freelist_put( dev, buf ); + } + + FLUSH_DMA(); +} + +/* This copies a 64 byte aligned agp region to the frambuffer with a + * standard blit, the ioctl needs to do checking. + */ +static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, + unsigned int dstorg, unsigned int length ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; + u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; + u32 y2; + DMA_LOCALS; + DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); + + y2 = length / 64; + + BEGIN_DMA( 5 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + DMA_BLOCK( MGA_DSTORG, dstorg, + MGA_MACCESS, 0x00000000, + MGA_SRCORG, srcorg, + MGA_AR5, 64 ); + + DMA_BLOCK( MGA_PITCH, 64, + MGA_PLNWT, 0xffffffff, + MGA_DMAPAD, 0x00000000, + MGA_DWGCTL, MGA_DWGCTL_COPY ); + + DMA_BLOCK( MGA_AR0, 63, + MGA_AR3, 0, + MGA_FXBNDRY, (63 << 16) | 0, + MGA_YDSTLEN + MGA_EXEC, y2 ); + + DMA_BLOCK( MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, + MGA_PITCH, dev_priv->front_pitch, + MGA_DWGSYNC, 0x00007000 ); + + ADVANCE_DMA(); + + AGE_BUFFER( buf_priv ); + + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; + + mga_freelist_put( dev, buf ); + + FLUSH_DMA(); +} + +static void mga_dma_dispatch_blit( drm_device_t *dev, + drm_mga_blit_t *blit ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + u32 scandir = 0, i; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + BEGIN_DMA( 4 + nbox ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + DMA_BLOCK( MGA_DWGCTL, MGA_DWGCTL_COPY, + MGA_PLNWT, blit->planemask, + MGA_SRCORG, blit->srcorg, + MGA_DSTORG, blit->dstorg ); + + DMA_BLOCK( MGA_SGN, scandir, + MGA_MACCESS, dev_priv->maccess, + MGA_AR5, blit->ydir * blit->src_pitch, + MGA_PITCH, blit->dst_pitch ); + + for ( i = 0 ; i < nbox ; i++ ) { + int srcx = pbox[i].x1 + blit->delta_sx; + int srcy = pbox[i].y1 + blit->delta_sy; + int dstx = pbox[i].x1 + blit->delta_dx; + int dsty = pbox[i].y1 + blit->delta_dy; + int h = pbox[i].y2 - pbox[i].y1; + int w = pbox[i].x2 - pbox[i].x1 - 1; + int start; + + if ( blit->ydir == -1 ) { + srcy = blit->height - srcy - 1; + } + + start = srcy * blit->src_pitch + srcx; + + DMA_BLOCK( MGA_AR0, start + w, + MGA_AR3, start, + MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), + MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h ); + } + + /* Do something to flush AGP? + */ + + /* Force reset of DWGCTL */ + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_PITCH, dev_priv->front_pitch, + MGA_DWGCTL, ctx->dwgctl ); + + ADVANCE_DMA(); +} + + +/* ================================================================ + * + */ + +int mga_dma_clear( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_clear_t clear; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t *)data, sizeof(clear) ); + + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_clear( dev, &clear ); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; + + return 0; +} + +int mga_dma_swap( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_swap( dev ); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; + + return 0; +} + +int mga_dma_vertex( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_vertex_t vertex; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( vertex, + (drm_mga_vertex_t *)data, + sizeof(vertex) ); + + if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL); + buf = dma->buflist[vertex.idx]; + buf_priv = buf->dev_private; + + buf->used = vertex.used; + buf_priv->discard = vertex.discard; + + if ( !mga_verify_state( dev_priv ) ) { + if ( vertex.discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); + buf_priv->dispatched = 0; + mga_freelist_put( dev, buf ); + } + return DRM_ERR(EINVAL); + } + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_vertex( dev, buf ); + + return 0; +} + +int mga_dma_indices( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_indices_t indices; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( indices, + (drm_mga_indices_t *)data, + sizeof(indices) ); + + if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL); + + buf = dma->buflist[indices.idx]; + buf_priv = buf->dev_private; + + buf_priv->discard = indices.discard; + + if ( !mga_verify_state( dev_priv ) ) { + if ( indices.discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); + buf_priv->dispatched = 0; + mga_freelist_put( dev, buf ); + } + return DRM_ERR(EINVAL); + } + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_indices( dev, buf, indices.start, indices.end ); + + return 0; +} + +int mga_dma_iload( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_buf_t *buf; + drm_mga_buf_priv_t *buf_priv; + drm_mga_iload_t iload; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t *)data, sizeof(iload) ); + +#if 0 + if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { + if ( MGA_DMA_DEBUG ) + DRM_INFO( "%s: -EBUSY\n", __func__ ); + return DRM_ERR(EBUSY); + } +#endif + if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL); + + buf = dma->buflist[iload.idx]; + buf_priv = buf->dev_private; + + if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) { + mga_freelist_put( dev, buf ); + return DRM_ERR(EINVAL); + } + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length ); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; + + return 0; +} + +int mga_dma_blit( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_blit_t blit; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t *)data, sizeof(blit) ); + + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) ) + return DRM_ERR(EINVAL); + + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_blit( dev, &blit ); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; + + return 0; +} diff --git a/linux/mga_ucode.h b/shared/mga_ucode.h index fa0f82ec..fa0f82ec 100644 --- a/linux/mga_ucode.h +++ b/shared/mga_ucode.h diff --git a/shared/mga_warp.c b/shared/mga_warp.c new file mode 100644 index 00000000..ea7f53a6 --- /dev/null +++ b/shared/mga_warp.c @@ -0,0 +1,212 @@ +/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- + * Created: Thu Jan 11 21:29:32 2001 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 + * VA LINUX SYSTEMS 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> + */ + +#define __NO_VERSION__ +#include "mga.h" +#include "drmP.h" +#include "drm.h" +#include "mga_drm.h" +#include "mga_drv.h" +#include "mga_ucode.h" + + +#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ + +#define WARP_UCODE_SIZE( which ) \ + ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) + +#define WARP_UCODE_INSTALL( which, where ) \ +do { \ + DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ + dev_priv->warp_pipe_phys[where] = pcbase; \ + memcpy( vcbase, which, sizeof(which) ); \ + pcbase += WARP_UCODE_SIZE( which ); \ + vcbase += WARP_UCODE_SIZE( which ); \ +} while (0) + + +static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv ) +{ + unsigned int size; + + size = ( WARP_UCODE_SIZE( warp_g400_tgz ) + + WARP_UCODE_SIZE( warp_g400_tgza ) + + WARP_UCODE_SIZE( warp_g400_tgzaf ) + + WARP_UCODE_SIZE( warp_g400_tgzf ) + + WARP_UCODE_SIZE( warp_g400_tgzs ) + + WARP_UCODE_SIZE( warp_g400_tgzsa ) + + WARP_UCODE_SIZE( warp_g400_tgzsaf ) + + WARP_UCODE_SIZE( warp_g400_tgzsf ) + + WARP_UCODE_SIZE( warp_g400_t2gz ) + + WARP_UCODE_SIZE( warp_g400_t2gza ) + + WARP_UCODE_SIZE( warp_g400_t2gzaf ) + + WARP_UCODE_SIZE( warp_g400_t2gzf ) + + WARP_UCODE_SIZE( warp_g400_t2gzs ) + + WARP_UCODE_SIZE( warp_g400_t2gzsa ) + + WARP_UCODE_SIZE( warp_g400_t2gzsaf ) + + WARP_UCODE_SIZE( warp_g400_t2gzsf ) ); + + size = PAGE_ALIGN( size ); + + DRM_DEBUG( "G400 ucode size = %d bytes\n", size ); + return size; +} + +static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv ) +{ + unsigned int size; + + size = ( WARP_UCODE_SIZE( warp_g200_tgz ) + + WARP_UCODE_SIZE( warp_g200_tgza ) + + WARP_UCODE_SIZE( warp_g200_tgzaf ) + + WARP_UCODE_SIZE( warp_g200_tgzf ) + + WARP_UCODE_SIZE( warp_g200_tgzs ) + + WARP_UCODE_SIZE( warp_g200_tgzsa ) + + WARP_UCODE_SIZE( warp_g200_tgzsaf ) + + WARP_UCODE_SIZE( warp_g200_tgzsf ) ); + + size = PAGE_ALIGN( size ); + + DRM_DEBUG( "G200 ucode size = %d bytes\n", size ); + return size; +} + +static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) +{ + unsigned char *vcbase = dev_priv->warp->handle; + unsigned long pcbase = dev_priv->warp->offset; + unsigned int size; + + size = mga_warp_g400_microcode_size( dev_priv ); + if ( size > dev_priv->warp->size ) { + DRM_ERROR( "microcode too large! (%u > %lu)\n", + size, dev_priv->warp->size ); + return DRM_ERR(ENOMEM); + } + + memset( dev_priv->warp_pipe_phys, 0, + sizeof(dev_priv->warp_pipe_phys) ); + + WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ ); + WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF ); + WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA ); + WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF ); + WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS ); + WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF ); + WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA ); + WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF ); + + WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ ); + WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF ); + WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA ); + WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF ); + WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS ); + WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF ); + WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA ); + WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF ); + + return 0; +} + +static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) +{ + unsigned char *vcbase = dev_priv->warp->handle; + unsigned long pcbase = dev_priv->warp->offset; + unsigned int size; + + size = mga_warp_g200_microcode_size( dev_priv ); + if ( size > dev_priv->warp->size ) { + DRM_ERROR( "microcode too large! (%u > %lu)\n", + size, dev_priv->warp->size ); + return DRM_ERR(ENOMEM); + } + + memset( dev_priv->warp_pipe_phys, 0, + sizeof(dev_priv->warp_pipe_phys) ); + + WARP_UCODE_INSTALL( warp_g200_tgz, MGA_WARP_TGZ ); + WARP_UCODE_INSTALL( warp_g200_tgzf, MGA_WARP_TGZF ); + WARP_UCODE_INSTALL( warp_g200_tgza, MGA_WARP_TGZA ); + WARP_UCODE_INSTALL( warp_g200_tgzaf, MGA_WARP_TGZAF ); + WARP_UCODE_INSTALL( warp_g200_tgzs, MGA_WARP_TGZS ); + WARP_UCODE_INSTALL( warp_g200_tgzsf, MGA_WARP_TGZSF ); + WARP_UCODE_INSTALL( warp_g200_tgzsa, MGA_WARP_TGZSA ); + WARP_UCODE_INSTALL( warp_g200_tgzsaf, MGA_WARP_TGZSAF ); + + return 0; +} + +int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) +{ + switch ( dev_priv->chipset ) { + case MGA_CARD_TYPE_G400: + return mga_warp_install_g400_microcode( dev_priv ); + case MGA_CARD_TYPE_G200: + return mga_warp_install_g200_microcode( dev_priv ); + default: + return DRM_ERR(EINVAL); + } +} + +#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) + +int mga_warp_init( drm_mga_private_t *dev_priv ) +{ + u32 wmisc; + + /* FIXME: Get rid of these damned magic numbers... + */ + switch ( dev_priv->chipset ) { + case MGA_CARD_TYPE_G400: + MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND ); + MGA_WRITE( MGA_WGETMSB, 0x00000E00 ); + MGA_WRITE( MGA_WVRTXSZ, 0x00001807 ); + MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 ); + break; + case MGA_CARD_TYPE_G200: + MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND ); + MGA_WRITE( MGA_WGETMSB, 0x1606 ); + MGA_WRITE( MGA_WVRTXSZ, 7 ); + break; + default: + return DRM_ERR(EINVAL); + } + + MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE | + MGA_WMASTER_ENABLE | + MGA_WCACHEFLUSH_ENABLE) ); + wmisc = MGA_READ( MGA_WMISC ); + if ( wmisc != WMISC_EXPECTED ) { + DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n", + wmisc, WMISC_EXPECTED ); + return DRM_ERR(EINVAL); + } + + return 0; +} diff --git a/linux/r128.h b/shared/r128.h index 926b4bfd..472a8014 100644 --- a/linux/r128.h +++ b/shared/r128.h @@ -43,6 +43,35 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "r128" +#define DRIVER_DESC "ATI Rage 128" +#define DRIVER_DATE "20010917" + +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 0 + + +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ diff --git a/shared/r128_cce.c b/shared/r128_cce.c new file mode 100644 index 00000000..f52b9a67 --- /dev/null +++ b/shared/r128_cce.c @@ -0,0 +1,1010 @@ +/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- + * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com + * + * Copyright 2000 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: + * Gareth Hughes <gareth@valinux.com> + */ + +#include "r128.h" +#include "drmP.h" +#include "drm.h" +#include "r128_drm.h" +#include "r128_drv.h" + +#define R128_FIFO_DEBUG 0 + +/* CCE microcode (from ATI) */ +static u32 r128_cce_microcode[] = { + 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, + 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, + 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1, + 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11, + 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28, + 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, + 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, + 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, + 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071, + 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2, + 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1, + 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, + 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, + 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, + 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1, + 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82, + 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729, + 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008, + 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, + 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, + 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, + 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0, + 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370, + 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1, + 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793, + 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, + 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, + 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1, + 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1, + 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894, + 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14, + 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1, + 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, + 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, + 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ); + +int R128_READ_PLL(drm_device_t *dev, int addr) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + + R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return R128_READ(R128_CLOCK_CNTL_DATA); +} + +#if R128_FIFO_DEBUG +static void r128_status( drm_r128_private_t *dev_priv ) +{ + printk( "GUI_STAT = 0x%08x\n", + (unsigned int)R128_READ( R128_GUI_STAT ) ); + printk( "PM4_STAT = 0x%08x\n", + (unsigned int)R128_READ( R128_PM4_STAT ) ); + printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n", + (unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) ); + printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n", + (unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) ); + printk( "PM4_MICRO_CNTL = 0x%08x\n", + (unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) ); + printk( "PM4_BUFFER_CNTL = 0x%08x\n", + (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) ); +} +#endif + + +/* ================================================================ + * Engine, FIFO control + */ + +static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv ) +{ + u32 tmp; + int i; + + tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL; + R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp ); + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) { + return 0; + } + DRM_UDELAY( 1 ); + } + +#if R128_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); +#endif + return DRM_ERR(EBUSY); +} + +static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries ) +{ + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK; + if ( slots >= entries ) return 0; + DRM_UDELAY( 1 ); + } + +#if R128_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); +#endif + return DRM_ERR(EBUSY); +} + +int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) +{ + int i, ret; + + ret = r128_do_wait_for_fifo( dev_priv, 64 ); + if ( ret ) return ret; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { + r128_do_pixcache_flush( dev_priv ); + return 0; + } + DRM_UDELAY( 1 ); + } + +#if R128_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); +#endif + return DRM_ERR(EBUSY); +} + + +/* ================================================================ + * CCE control, initialization + */ + +/* Load the microcode for the CCE */ +static void r128_cce_load_microcode( drm_r128_private_t *dev_priv ) +{ + int i; + + DRM_DEBUG( "\n" ); + + r128_do_wait_for_idle( dev_priv ); + + R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 ); + for ( i = 0 ; i < 256 ; i++ ) { + R128_WRITE( R128_PM4_MICROCODE_DATAH, + r128_cce_microcode[i * 2] ); + R128_WRITE( R128_PM4_MICROCODE_DATAL, + r128_cce_microcode[i * 2 + 1] ); + } +} + +/* Flush any pending commands to the CCE. This should only be used just + * prior to a wait for idle, as it informs the engine that the command + * stream is ending. + */ +static void r128_do_cce_flush( drm_r128_private_t *dev_priv ) +{ + u32 tmp; + + tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE; + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp ); +} + +/* Wait for the CCE to go idle. + */ +int r128_do_cce_idle( drm_r128_private_t *dev_priv ) +{ + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { + int pm4stat = R128_READ( R128_PM4_STAT ); + if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= + dev_priv->cce_fifo_size ) && + !(pm4stat & (R128_PM4_BUSY | + R128_PM4_GUI_ACTIVE)) ) { + return r128_do_pixcache_flush( dev_priv ); + } + } + DRM_UDELAY( 1 ); + } + +#if R128_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + r128_status( dev_priv ); +#endif + return DRM_ERR(EBUSY); +} + +/* Start the Concurrent Command Engine. + */ +static void r128_do_cce_start( drm_r128_private_t *dev_priv ) +{ + r128_do_wait_for_idle( dev_priv ); + + R128_WRITE( R128_PM4_BUFFER_CNTL, + dev_priv->cce_mode | dev_priv->ring.size_l2qw ); + R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */ + R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN ); + + dev_priv->cce_running = 1; +} + +/* Reset the Concurrent Command Engine. This will not flush any pending + * commands, so you must wait for the CCE command stream to complete + * before calling this routine. + */ +static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) +{ + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); + R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + SET_RING_HEAD( &dev_priv->ring, 0 ); + dev_priv->ring.tail = 0; +} + +/* Stop the Concurrent Command Engine. This will not flush any pending + * commands, so you must flush the command stream and wait for the CCE + * to go idle before calling this routine. + */ +static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) +{ + R128_WRITE( R128_PM4_MICRO_CNTL, 0 ); + R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 ); + + dev_priv->cce_running = 0; +} + +/* Reset the engine. This will stop the CCE if it is running. + */ +static int r128_do_engine_reset( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; + + r128_do_pixcache_flush( dev_priv ); + + clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX ); + mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL ); + + R128_WRITE_PLL( R128_MCLK_CNTL, + mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP ); + + gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL ); + + /* Taken from the sample code - do not change */ + R128_WRITE( R128_GEN_RESET_CNTL, + gen_reset_cntl | R128_SOFT_RESET_GUI ); + R128_READ( R128_GEN_RESET_CNTL ); + R128_WRITE( R128_GEN_RESET_CNTL, + gen_reset_cntl & ~R128_SOFT_RESET_GUI ); + R128_READ( R128_GEN_RESET_CNTL ); + + R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl ); + R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index ); + R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl ); + + /* Reset the CCE ring */ + r128_do_cce_reset( dev_priv ); + + /* The CCE is no longer running after an engine reset */ + dev_priv->cce_running = 0; + + /* Reset any pending vertex, indirect buffers */ + r128_freelist_reset( dev ); + + return 0; +} + +static void r128_cce_init_ring_buffer( drm_device_t *dev, + drm_r128_private_t *dev_priv ) +{ + u32 ring_start; + u32 tmp; + + DRM_DEBUG( "\n" ); + + /* The manual (p. 2) says this address is in "VM space". This + * means it's an offset from the start of AGP space. + */ +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) + ring_start = dev_priv->cce_ring->offset - dev->agp->base; + else +#endif + ring_start = dev_priv->cce_ring->offset - dev->sg->handle; + + R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET ); + + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); + R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + + /* DL_RPTR_ADDR is a physical address in AGP space. */ + SET_RING_HEAD( &dev_priv->ring, 0 ); + + if ( !dev_priv->is_pci ) { + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, + dev_priv->ring_rptr->offset ); + } else { + drm_sg_mem_t *entry = dev->sg; + unsigned long tmp_ofs, page_ofs; + + tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; + page_ofs = tmp_ofs >> PAGE_SHIFT; + + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, + entry->busaddr[page_ofs]); + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], + entry->handle + tmp_ofs ); + } + + /* Set watermark control */ + R128_WRITE( R128_PM4_BUFFER_WM_CNTL, + ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) + | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT) + | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT) + | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) ); + + /* Force read. Why? Because it's in the examples... */ + R128_READ( R128_PM4_BUFFER_ADDR ); + + /* Turn on bus mastering */ + tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS; + R128_WRITE( R128_BUS_CNTL, tmp ); +} + +static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) +{ + drm_r128_private_t *dev_priv; + + DRM_DEBUG( "\n" ); + + dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); + if ( dev_priv == NULL ) + return DRM_ERR(ENOMEM); + + memset( dev_priv, 0, sizeof(drm_r128_private_t) ); + + dev_priv->is_pci = init->is_pci; + + if ( dev_priv->is_pci && !dev->sg ) { + DRM_ERROR( "PCI GART memory not allocated!\n" ); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + + dev_priv->usec_timeout = init->usec_timeout; + if ( dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) { + DRM_DEBUG( "TIMEOUT problem!\n" ); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + + dev_priv->cce_mode = init->cce_mode; + + /* GH: Simple idle check. + */ + atomic_set( &dev_priv->idle_count, 0 ); + + /* We don't support anything other than bus-mastering ring mode, + * but the ring can be in either AGP or PCI space for the ring + * read pointer. + */ + if ( ( init->cce_mode != R128_PM4_192BM ) && + ( init->cce_mode != R128_PM4_128BM_64INDBM ) && + ( init->cce_mode != R128_PM4_64BM_128INDBM ) && + ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) { + DRM_DEBUG( "Bad cce_mode!\n" ); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + + switch ( init->cce_mode ) { + case R128_PM4_NONPM4: + dev_priv->cce_fifo_size = 0; + break; + case R128_PM4_192PIO: + case R128_PM4_192BM: + dev_priv->cce_fifo_size = 192; + break; + case R128_PM4_128PIO_64INDBM: + case R128_PM4_128BM_64INDBM: + dev_priv->cce_fifo_size = 128; + break; + case R128_PM4_64PIO_128INDBM: + case R128_PM4_64BM_128INDBM: + case R128_PM4_64PIO_64VCBM_64INDBM: + case R128_PM4_64BM_64VCBM_64INDBM: + case R128_PM4_64PIO_64VCPIO_64INDPIO: + dev_priv->cce_fifo_size = 64; + break; + } + + switch ( init->fb_bpp ) { + case 16: + dev_priv->color_fmt = R128_DATATYPE_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = R128_DATATYPE_ARGB8888; + break; + } + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + switch ( init->depth_bpp ) { + case 16: + dev_priv->depth_fmt = R128_DATATYPE_RGB565; + break; + case 24: + case 32: + default: + dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; + break; + } + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + dev_priv->span_offset = init->span_offset; + + dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) | + (dev_priv->front_offset >> 5)); + dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) | + (dev_priv->back_offset >> 5)); + dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + (dev_priv->depth_offset >> 5) | + R128_DST_TILE); + dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | + (dev_priv->span_offset >> 5)); + + DRM_GETSAREA(); + + if(!dev_priv->sarea) { + DRM_ERROR("could not find sarea!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + if(!dev_priv->fb) { + DRM_ERROR("could not find framebuffer!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + if(!dev_priv->mmio) { + DRM_ERROR("could not find mmio region!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset ); + if(!dev_priv->cce_ring) { + DRM_ERROR("could not find cce ring region!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + if(!dev_priv->ring_rptr) { + DRM_ERROR("could not find ring read pointer!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + if(!dev_priv->buffers) { + DRM_ERROR("could not find dma buffer region!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + + if ( !dev_priv->is_pci ) { + DRM_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); + if(!dev_priv->agp_textures) { + DRM_ERROR("could not find agp texture region!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(EINVAL); + } + } + + dev_priv->sarea_priv = + (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if ( !dev_priv->is_pci ) { + DRM_IOREMAP( dev_priv->cce_ring ); + DRM_IOREMAP( dev_priv->ring_rptr ); + DRM_IOREMAP( dev_priv->buffers ); + if(!dev_priv->cce_ring->handle || + !dev_priv->ring_rptr->handle || + !dev_priv->buffers->handle) { + DRM_ERROR("Could not ioremap agp regions!\n"); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(ENOMEM); + } + } else { + dev_priv->cce_ring->handle = + (void *)dev_priv->cce_ring->offset; + dev_priv->ring_rptr->handle = + (void *)dev_priv->ring_rptr->offset; + dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; + } + +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) + dev_priv->cce_buffers_offset = dev->agp->base; + else +#endif + dev_priv->cce_buffers_offset = dev->sg->handle; + + dev_priv->ring.head = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle); + + dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; + dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle + + init->ring_size / sizeof(u32)); + dev_priv->ring.size = init->ring_size; + dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); + + dev_priv->ring.tail_mask = + (dev_priv->ring.size / sizeof(u32)) - 1; + + dev_priv->ring.high_mark = 128; + + dev_priv->sarea_priv->last_frame = 0; + R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); + + dev_priv->sarea_priv->last_dispatch = 0; + R128_WRITE( R128_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch ); + +#if __REALLY_HAVE_SG + if ( dev_priv->is_pci ) { + if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, + &dev_priv->bus_pci_gart) ) { + DRM_ERROR( "failed to init PCI GART!\n" ); + dev->dev_private = (void *)dev_priv; + r128_do_cleanup_cce( dev ); + return DRM_ERR(ENOMEM); + } + R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); + } +#endif + + r128_cce_init_ring_buffer( dev, dev_priv ); + r128_cce_load_microcode( dev_priv ); + + dev->dev_private = (void *)dev_priv; + + r128_do_engine_reset( dev ); + + return 0; +} + +int r128_do_cleanup_cce( drm_device_t *dev ) +{ + if ( dev->dev_private ) { + drm_r128_private_t *dev_priv = dev->dev_private; + +#if __REALLY_HAVE_SG + if ( !dev_priv->is_pci ) { +#endif + DRM_IOREMAPFREE( dev_priv->cce_ring ); + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + DRM_IOREMAPFREE( dev_priv->buffers ); +#if __REALLY_HAVE_SG + } else { + if (!DRM(ati_pcigart_cleanup)( dev, + dev_priv->phys_pci_gart, + dev_priv->bus_pci_gart )) + DRM_ERROR( "failed to cleanup PCI GART!\n" ); + } +#endif + + DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int r128_cce_init( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_init_t init; + + DRM_DEBUG( "\n" ); + + DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t *)data, sizeof(init) ); + + switch ( init.func ) { + case R128_INIT_CCE: + return r128_do_init_cce( dev, &init ); + case R128_CLEANUP_CCE: + return r128_do_cleanup_cce( dev ); + } + + return DRM_ERR(EINVAL); +} + +int r128_cce_start( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) { + DRM_DEBUG( "%s while CCE running\n", __func__ ); + return 0; + } + + r128_do_cce_start( dev_priv ); + + return 0; +} + +/* Stop the CCE. The engine must have been idled before calling this + * routine. + */ +int r128_cce_stop( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_cce_stop_t stop; + int ret; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) ); + + /* Flush any pending CCE commands. This ensures any outstanding + * commands are exectuted by the engine before we turn it off. + */ + if ( stop.flush ) { + r128_do_cce_flush( dev_priv ); + } + + /* If we fail to make the engine go idle, we return an error + * code so that the DRM ioctl wrapper can try again. + */ + if ( stop.idle ) { + ret = r128_do_cce_idle( dev_priv ); + if ( ret ) return ret; + } + + /* Finally, we can turn off the CCE. If the engine isn't idle, + * we will get some dropped triangles as they won't be fully + * rendered before the CCE is shut down. + */ + r128_do_cce_stop( dev_priv ); + + /* Reset the engine */ + r128_do_engine_reset( dev ); + + return 0; +} + +/* Just reset the CCE ring. Called as part of an X Server engine reset. + */ +int r128_cce_reset( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_DEBUG( "%s called before init done\n", __func__ ); + return DRM_ERR(EINVAL); + } + + r128_do_cce_reset( dev_priv ); + + /* The CCE is no longer running after an engine reset */ + dev_priv->cce_running = 0; + + return 0; +} + +int r128_cce_idle( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( dev_priv->cce_running ) { + r128_do_cce_flush( dev_priv ); + } + + return r128_do_cce_idle( dev_priv ); +} + +int r128_engine_reset( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + return r128_do_engine_reset( dev ); +} + + +/* ================================================================ + * Fullscreen mode + */ + +static int r128_do_init_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); + dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, + dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + + return 0; +} + +int r128_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); + + dev_priv->page_flipping = 0; + dev_priv->current_page = 0; + + return 0; +} + +int r128_fullscreen( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_fullscreen_t fs; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); + + switch ( fs.func ) { + case R128_INIT_FULLSCREEN: + return r128_do_init_pageflip( dev ); + case R128_CLEANUP_FULLSCREEN: + return r128_do_cleanup_pageflip( dev ); + } + + return DRM_ERR(EINVAL); +} + + +/* ================================================================ + * Freelist management + */ +#define R128_BUFFER_USED 0xffffffff +#define R128_BUFFER_FREE 0 + +#if 0 +static int r128_freelist_init( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_freelist_t *entry; + int i; + + dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t), + DRM_MEM_DRIVER ); + if ( dev_priv->head == NULL ) + return DRM_ERR(ENOMEM); + + memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) ); + dev_priv->head->age = R128_BUFFER_USED; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + + entry = DRM(alloc)( sizeof(drm_r128_freelist_t), + DRM_MEM_DRIVER ); + if ( !entry ) return DRM_ERR(ENOMEM); + + entry->age = R128_BUFFER_FREE; + entry->buf = buf; + entry->prev = dev_priv->head; + entry->next = dev_priv->head->next; + if ( !entry->next ) + dev_priv->tail = entry; + + buf_priv->discard = 0; + buf_priv->dispatched = 0; + buf_priv->list_entry = entry; + + dev_priv->head->next = entry; + + if ( dev_priv->head->next ) + dev_priv->head->next->prev = entry; + } + + return 0; + +} +#endif + +drm_buf_t *r128_freelist_get( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_buf_priv_t *buf_priv; + drm_buf_t *buf; + int i, t; + + /* FIXME: Optimize -- use freelist code */ + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 ) + return buf; + } + + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { + u32 done_age = R128_READ( R128_LAST_DISPATCH_REG ); + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pending && buf_priv->age <= done_age ) { + /* The buffer has been processed, so it + * can now be used. + */ + buf->pending = 0; + return buf; + } + } + DRM_UDELAY( 1 ); + } + + DRM_ERROR( "returning NULL!\n" ); + return NULL; +} + +void r128_freelist_reset( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + drm_buf_t *buf = dma->buflist[i]; + drm_r128_buf_priv_t *buf_priv = buf->dev_private; + buf_priv->age = 0; + } +} + + +/* ================================================================ + * CCE command submission + */ + +int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) +{ + drm_r128_ring_buffer_t *ring = &dev_priv->ring; + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + r128_update_ring_snapshot( ring ); + if ( ring->space >= n ) + return 0; + DRM_UDELAY( 1 ); + } + + /* FIXME: This is being ignored... */ + DRM_ERROR( "failed!\n" ); + return DRM_ERR(EBUSY); +} + +static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) +{ + int i; + drm_buf_t *buf; + + for ( i = d->granted_count ; i < d->request_count ; i++ ) { + buf = r128_freelist_get( dev ); + if ( !buf ) return DRM_ERR(EAGAIN); + + buf->pid = DRM_CURRENTPID; + + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, + sizeof(buf->idx) ) ) + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, + sizeof(buf->total) ) ) + return DRM_ERR(EFAULT); + + d->granted_count++; + } + return 0; +} + +int r128_cce_buffers( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + int ret = 0; + drm_dma_t d; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *) data, sizeof(d) ); + + /* Please don't send us buffers. + */ + if ( d.send_count != 0 ) { + DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); + } + + /* We'll send you buffers. + */ + 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); + } + + d.granted_count = 0; + + if ( d.request_count ) { + ret = r128_cce_get_buffers( dev, &d ); + } + + DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d) ); + + return ret; +} diff --git a/shared/r128_drm.h b/shared/r128_drm.h new file mode 100644 index 00000000..a8d23008 --- /dev/null +++ b/shared/r128_drm.h @@ -0,0 +1,308 @@ +/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- + * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com + * + * Copyright 2000 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: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + */ + +#ifndef __R128_DRM_H__ +#define __R128_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (r128_sarea.h) + */ +#ifndef __R128_SAREA_DEFINES__ +#define __R128_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? + */ +#define R128_UPLOAD_CONTEXT 0x001 +#define R128_UPLOAD_SETUP 0x002 +#define R128_UPLOAD_TEX0 0x004 +#define R128_UPLOAD_TEX1 0x008 +#define R128_UPLOAD_TEX0IMAGES 0x010 +#define R128_UPLOAD_TEX1IMAGES 0x020 +#define R128_UPLOAD_CORE 0x040 +#define R128_UPLOAD_MASKS 0x080 +#define R128_UPLOAD_WINDOW 0x100 +#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ +#define R128_REQUIRE_QUIESCENCE 0x400 +#define R128_UPLOAD_ALL 0x7ff + +#define R128_FRONT 0x1 +#define R128_BACK 0x2 +#define R128_DEPTH 0x4 + +/* Primitive types + */ +#define R128_POINTS 0x1 +#define R128_LINES 0x2 +#define R128_LINE_STRIP 0x3 +#define R128_TRIANGLES 0x4 +#define R128_TRIANGLE_FAN 0x5 +#define R128_TRIANGLE_STRIP 0x6 + +/* Vertex/indirect buffer size + */ +#define R128_BUFFER_SIZE 16384 + +/* Byte offsets for indirect buffer data + */ +#define R128_INDEX_PRIM_OFFSET 20 +#define R128_HOSTDATA_BLIT_OFFSET 32 + +/* Keep these small for testing. + */ +#define R128_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define R128_LOCAL_TEX_HEAP 0 +#define R128_AGP_TEX_HEAP 1 +#define R128_NR_TEX_HEAPS 2 +#define R128_NR_TEX_REGIONS 64 +#define R128_LOG_TEX_GRANULARITY 16 + +#define R128_NR_CONTEXT_REGS 12 + +#define R128_MAX_TEXTURE_LEVELS 11 +#define R128_MAX_TEXTURE_UNITS 2 + +#endif /* __R128_SAREA_DEFINES__ */ + +typedef struct { + /* Context state - can be written in one large chunk */ + unsigned int dst_pitch_offset_c; + unsigned int dp_gui_master_cntl_c; + unsigned int sc_top_left_c; + unsigned int sc_bottom_right_c; + unsigned int z_offset_c; + unsigned int z_pitch_c; + unsigned int z_sten_cntl_c; + unsigned int tex_cntl_c; + unsigned int misc_3d_state_cntl_reg; + unsigned int texture_clr_cmp_clr_c; + unsigned int texture_clr_cmp_msk_c; + unsigned int fog_color_c; + + /* Texture state */ + unsigned int tex_size_pitch_c; + unsigned int constant_color_c; + + /* Setup state */ + unsigned int pm4_vc_fpu_setup; + unsigned int setup_cntl; + + /* Mask state */ + unsigned int dp_write_mask; + unsigned int sten_ref_mask_c; + unsigned int plane_3d_mask_c; + + /* Window state */ + unsigned int window_xy_offset; + + /* Core state */ + unsigned int scale_3d_cntl; +} drm_r128_context_regs_t; + +/* Setup registers for each texture unit + */ +typedef struct { + unsigned int tex_cntl; + unsigned int tex_combine_cntl; + unsigned int tex_size_pitch; + unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS]; + unsigned int tex_border_color; +} drm_r128_texture_regs_t; + + +typedef struct drm_r128_sarea { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + drm_r128_context_regs_t context_state; + drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[R128_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for client-side throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + + drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + int tex_age[R128_NR_TEX_HEAPS]; + int ctx_owner; +} drm_r128_sarea_t; + + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmR128.h) + */ + +/* Rage 128 specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t) + +typedef struct drm_r128_init { + enum { + R128_INIT_CCE = 0x01, + R128_CLEANUP_CCE = 0x02 + } func; +#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) + int sarea_priv_offset; +#else + unsigned long sarea_priv_offset; +#endif + int is_pci; + int cce_mode; + int cce_secure; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + unsigned int span_offset; + +#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) + unsigned int fb_offset; + unsigned int mmio_offset; + unsigned int ring_offset; + unsigned int ring_rptr_offset; + unsigned int buffers_offset; + unsigned int agp_textures_offset; +#else + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +#endif +} drm_r128_init_t; + +typedef struct drm_r128_cce_stop { + int flush; + int idle; +} drm_r128_cce_stop_t; + +typedef struct drm_r128_clear { + unsigned int flags; +#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) + int x, y, w, h; +#endif + unsigned int clear_color; + unsigned int clear_depth; +#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0) + unsigned int color_mask; + unsigned int depth_mask; +#endif +} drm_r128_clear_t; + +typedef struct drm_r128_vertex { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drm_r128_vertex_t; + +typedef struct drm_r128_indices { + int prim; + int idx; + int start; + int end; + int discard; /* Client finished with buffer? */ +} drm_r128_indices_t; + +typedef struct drm_r128_blit { + int idx; + int pitch; + int offset; + int format; + unsigned short x, y; + unsigned short width, height; +} drm_r128_blit_t; + +typedef struct drm_r128_depth { + enum { + R128_WRITE_SPAN = 0x01, + R128_WRITE_PIXELS = 0x02, + R128_READ_SPAN = 0x03, + R128_READ_PIXELS = 0x04 + } func; + int n; + int *x; + int *y; + unsigned int *buffer; + unsigned char *mask; +} drm_r128_depth_t; + +typedef struct drm_r128_stipple { + unsigned int *mask; +} drm_r128_stipple_t; + +typedef struct drm_r128_indirect { + int idx; + int start; + int end; + int discard; +} drm_r128_indirect_t; + +typedef struct drm_r128_fullscreen { + enum { + R128_INIT_FULLSCREEN = 0x01, + R128_CLEANUP_FULLSCREEN = 0x02 + } func; +} drm_r128_fullscreen_t; + +#endif diff --git a/linux/r128_drv.h b/shared/r128_drv.h index 0485deda..04296590 100644 --- a/linux/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) readl( (volatile u32 *) (ring)->head ) -#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) +#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) ) typedef struct drm_r128_freelist { unsigned int age; @@ -116,29 +116,21 @@ typedef struct drm_r128_buf_priv { } drm_r128_buf_priv_t; /* r128_cce.c */ -extern int r128_cce_init( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_start( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_stop( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_idle( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_engine_reset( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_fullscreen( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_buffers( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int r128_cce_init( DRM_IOCTL_ARGS ); +extern int r128_cce_start( DRM_IOCTL_ARGS ); +extern int r128_cce_stop( DRM_IOCTL_ARGS ); +extern int r128_cce_reset( DRM_IOCTL_ARGS ); +extern int r128_cce_idle( DRM_IOCTL_ARGS ); +extern int r128_engine_reset( DRM_IOCTL_ARGS ); +extern int r128_fullscreen( DRM_IOCTL_ARGS ); +extern int r128_cce_buffers( DRM_IOCTL_ARGS ); extern void r128_freelist_reset( drm_device_t *dev ); extern drm_buf_t *r128_freelist_get( drm_device_t *dev ); extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n ); -static inline void +static __inline__ void r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring ) { ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32); @@ -151,22 +143,14 @@ extern int r128_do_cleanup_cce( drm_device_t *dev ); extern int r128_do_cleanup_pageflip( drm_device_t *dev ); /* r128_state.c */ -extern int r128_cce_clear( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_swap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_vertex( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_indices( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_depth( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_stipple( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int r128_cce_indirect( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int r128_cce_clear( DRM_IOCTL_ARGS ); +extern int r128_cce_swap( DRM_IOCTL_ARGS ); +extern int r128_cce_vertex( DRM_IOCTL_ARGS ); +extern int r128_cce_indices( DRM_IOCTL_ARGS ); +extern int r128_cce_blit( DRM_IOCTL_ARGS ); +extern int r128_cce_depth( DRM_IOCTL_ARGS ); +extern int r128_cce_stipple( DRM_IOCTL_ARGS ); +extern int r128_cce_indirect( DRM_IOCTL_ARGS ); /* Register definitions, register access macros and drmAddMap constants @@ -384,11 +368,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp, #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE( reg ) + reg) -#define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) ) -#define R128_WRITE(reg,val) writel( (val), (volatile u32 *) R128_ADDR(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) readb( (volatile u8 *) R128_ADDR(reg) ) -#define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) ) +#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_WRITE_PLL(addr,val) \ do { \ @@ -416,10 +400,9 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); #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; \ + dev->lock.pid != DRM_CURRENTPID ) { \ + DRM_ERROR( "%s called without lock held\n", __func__ ); \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -431,12 +414,13 @@ do { \ r128_update_ring_snapshot( ring ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - udelay( 1 ); \ + DRM_UDELAY(1); \ } \ DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ + ; \ } while (0) #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ @@ -444,7 +428,7 @@ do { \ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ int __ret = r128_do_cce_idle( dev_priv ); \ - if ( __ret < 0 ) return __ret; \ + if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ r128_freelist_reset( dev ); \ } \ @@ -463,7 +447,7 @@ do { \ #if defined(__powerpc__) #define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) #else -#define r128_flush_write_combine() mb() +#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() #endif @@ -475,7 +459,7 @@ do { \ #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - (n), __FUNCTION__ ); \ + (n), __func__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ diff --git a/shared/r128_state.c b/shared/r128_state.c new file mode 100644 index 00000000..a8ffd073 --- /dev/null +++ b/shared/r128_state.c @@ -0,0 +1,1566 @@ +/* r128_state.c -- State support for r128 -*- linux-c -*- + * Created: Thu Jan 27 02:53:43 2000 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> + */ + +#include "r128.h" +#include "drmP.h" +#include "drm.h" +#include "r128_drm.h" +#include "r128_drv.h" + + +/* ================================================================ + * CCE hardware state programming functions + */ + +static void r128_emit_clip_rects( drm_r128_private_t *dev_priv, + drm_clip_rect_t *boxes, int count ) +{ + u32 aux_sc_cntl = 0x00000000; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 17 ); + + if ( count >= 1 ) { + OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) ); + OUT_RING( boxes[0].x1 ); + OUT_RING( boxes[0].x2 - 1 ); + OUT_RING( boxes[0].y1 ); + OUT_RING( boxes[0].y2 - 1 ); + + aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); + } + if ( count >= 2 ) { + OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) ); + OUT_RING( boxes[1].x1 ); + OUT_RING( boxes[1].x2 - 1 ); + OUT_RING( boxes[1].y1 ); + OUT_RING( boxes[1].y2 - 1 ); + + aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); + } + if ( count >= 3 ) { + OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) ); + OUT_RING( boxes[2].x1 ); + OUT_RING( boxes[2].x2 - 1 ); + OUT_RING( boxes[2].y1 ); + OUT_RING( boxes[2].y2 - 1 ); + + aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); + } + + OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) ); + OUT_RING( aux_sc_cntl ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) ); + OUT_RING( ctx->scale_3d_cntl ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 13 ); + + OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) ); + OUT_RING( ctx->dst_pitch_offset_c ); + OUT_RING( ctx->dp_gui_master_cntl_c ); + OUT_RING( ctx->sc_top_left_c ); + OUT_RING( ctx->sc_bottom_right_c ); + OUT_RING( ctx->z_offset_c ); + OUT_RING( ctx->z_pitch_c ); + OUT_RING( ctx->z_sten_cntl_c ); + OUT_RING( ctx->tex_cntl_c ); + OUT_RING( ctx->misc_3d_state_cntl_reg ); + OUT_RING( ctx->texture_clr_cmp_clr_c ); + OUT_RING( ctx->texture_clr_cmp_msk_c ); + OUT_RING( ctx->fog_color_c ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 3 ); + + OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) ); + OUT_RING( ctx->setup_cntl ); + OUT_RING( ctx->pm4_vc_fpu_setup ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 5 ); + + OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); + OUT_RING( ctx->dp_write_mask ); + + OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) ); + OUT_RING( ctx->sten_ref_mask_c ); + OUT_RING( ctx->plane_3d_mask_c ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) ); + OUT_RING( ctx->window_xy_offset ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_context_regs_t *ctx = &sarea_priv->context_state; + drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; + int i; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS ); + + OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C, + 2 + R128_MAX_TEXTURE_LEVELS ) ); + OUT_RING( tex->tex_cntl ); + OUT_RING( tex->tex_combine_cntl ); + OUT_RING( ctx->tex_size_pitch_c ); + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { + OUT_RING( tex->tex_offset[i] ); + } + + OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) ); + OUT_RING( ctx->constant_color_c ); + OUT_RING( tex->tex_border_color ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; + int i; + RING_LOCALS; + DRM_DEBUG( " %s\n", __func__ ); + + BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS ); + + OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C, + 1 + R128_MAX_TEXTURE_LEVELS ) ); + OUT_RING( tex->tex_cntl ); + OUT_RING( tex->tex_combine_cntl ); + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { + OUT_RING( tex->tex_offset[i] ); + } + + OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) ); + OUT_RING( tex->tex_border_color ); + + ADVANCE_RING(); +} + +static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv ) +{ + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + + DRM_DEBUG( "%s: dirty=0x%08x\n", __func__, dirty ); + + if ( dirty & R128_UPLOAD_CORE ) { + r128_emit_core( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_CORE; + } + + if ( dirty & R128_UPLOAD_CONTEXT ) { + r128_emit_context( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; + } + + if ( dirty & R128_UPLOAD_SETUP ) { + r128_emit_setup( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_SETUP; + } + + if ( dirty & R128_UPLOAD_MASKS ) { + r128_emit_masks( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_MASKS; + } + + if ( dirty & R128_UPLOAD_WINDOW ) { + r128_emit_window( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; + } + + if ( dirty & R128_UPLOAD_TEX0 ) { + r128_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_TEX0; + } + + if ( dirty & R128_UPLOAD_TEX1 ) { + r128_emit_tex1( dev_priv ); + sarea_priv->dirty &= ~R128_UPLOAD_TEX1; + } + + /* Turn off the texture cache flushing */ + sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + + sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; +} + + +#if R128_PERFORMANCE_BOXES +/* ================================================================ + * Performance monitoring functions + */ + +static void r128_clear_box( drm_r128_private_t *dev_priv, + int x, int y, int w, int h, + int r, int g, int b ) +{ + u32 pitch, offset; + u32 fb_bpp, color; + RING_LOCALS; + + switch ( dev_priv->fb_bpp ) { + case 16: + fb_bpp = R128_GMC_DST_16BPP; + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + break; + case 24: + fb_bpp = R128_GMC_DST_24BPP; + color = ((r << 16) | (g << 8) | b); + break; + case 32: + fb_bpp = R128_GMC_DST_32BPP; + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + break; + default: + return; + } + + offset = dev_priv->back_offset; + pitch = dev_priv->back_pitch >> 3; + + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); + + OUT_RING( (pitch << 21) | (offset >> 5) ); + OUT_RING( color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); +} + +static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv ) +{ + if ( atomic_read( &dev_priv->idle_count ) == 0 ) { + r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + } else { + atomic_set( &dev_priv->idle_count, 0 ); + } +} + +#endif + + +/* ================================================================ + * CCE command dispatch functions + */ + +static void r128_print_dirty( const char *msg, unsigned int flags ) +{ + DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & R128_UPLOAD_CORE) ? "core, " : "", + (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", + (flags & R128_UPLOAD_SETUP) ? "setup, " : "", + (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", + (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", + (flags & R128_UPLOAD_MASKS) ? "masks, " : "", + (flags & R128_UPLOAD_WINDOW) ? "window, " : "", + (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); +} + +static void r128_cce_dispatch_clear( drm_device_t *dev, + drm_r128_clear_t *clear ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + unsigned int flags = clear->flags; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __func__ ); + + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(R128_FRONT | R128_BACK); + if ( tmp & R128_FRONT ) flags |= R128_BACK; + if ( tmp & R128_BACK ) flags |= R128_FRONT; + } + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", + pbox[i].x1, pbox[i].y1, pbox[i].x2, + pbox[i].y2, flags ); + + if ( flags & (R128_FRONT | R128_BACK) ) { + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) ); + OUT_RING( clear->color_mask ); + + ADVANCE_RING(); + } + + if ( flags & R128_FRONT ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); + + OUT_RING( dev_priv->front_pitch_offset_c ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & R128_BACK ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); + + OUT_RING( dev_priv->back_pitch_offset_c ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & R128_DEPTH ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( clear->clear_depth ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + } +} + +static void r128_cce_dispatch_swap( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __func__ ); + +#if R128_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + r128_cce_performance_boxes( dev_priv ); +#endif + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + BEGIN_RING( 7 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->color_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->back_pitch_offset_c ); + OUT_RING( dev_priv->front_pitch_offset_c ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); + OUT_RING( dev_priv->sarea_priv->last_frame ); + + ADVANCE_RING(); +} + +static void r128_cce_dispatch_flip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); + +#if R128_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + r128_cce_performance_boxes( dev_priv ); +#endif + + BEGIN_RING( 4 ); + + R128_WAIT_UNTIL_PAGE_FLIPPED(); + OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 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; + } + + ADVANCE_RING(); + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); + OUT_RING( dev_priv->sarea_priv->last_frame ); + + ADVANCE_RING(); +} + +static void r128_cce_dispatch_vertex( drm_device_t *dev, + drm_buf_t *buf ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_buf_priv_t *buf_priv = buf->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + int format = sarea_priv->vc_format; + int offset = buf->bus_address; + int size = buf->used; + int prim = buf_priv->prim; + int i = 0; + RING_LOCALS; + DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox ); + + if ( 0 ) + r128_print_dirty( "dispatch_vertex", sarea_priv->dirty ); + + if ( buf->used ) { + buf_priv->dispatched = 1; + + if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128_emit_state( dev_priv ); + } + + do { + /* Emit the next set of up to three cliprects */ + if ( i < sarea_priv->nbox ) { + r128_emit_clip_rects( dev_priv, + &sarea_priv->boxes[i], + sarea_priv->nbox - i ); + } + + /* Emit the vertex buffer rendering commands */ + BEGIN_RING( 5 ); + + OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) ); + OUT_RING( offset ); + OUT_RING( size ); + OUT_RING( format ); + OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | + (size << R128_CCE_VC_CNTL_NUM_SHIFT) ); + + ADVANCE_RING(); + + i += 3; + } while ( i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); + OUT_RING( buf_priv->age ); + + ADVANCE_RING(); + + buf->pending = 1; + buf->used = 0; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; + + sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; + sarea_priv->nbox = 0; +} + +static void r128_cce_dispatch_indirect( drm_device_t *dev, + drm_buf_t *buf, + int start, int end ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_buf_priv_t *buf_priv = buf->dev_private; + RING_LOCALS; + DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", + buf->idx, start, end ); + + if ( start != end ) { + int offset = buf->bus_address + start; + int dwords = (end - start + 3) / sizeof(u32); + + /* Indirect buffer data must be an even number of + * dwords, so if we've been given an odd number we must + * pad the data with a Type-2 CCE packet. + */ + if ( dwords & 1 ) { + u32 *data = (u32 *) + ((char *)dev_priv->buffers->handle + + buf->offset + start); + data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 ); + } + + buf_priv->dispatched = 1; + + /* Fire off the indirect buffer */ + BEGIN_RING( 3 ); + + OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) ); + OUT_RING( offset ); + OUT_RING( dwords ); + + ADVANCE_RING(); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the indirect buffer age */ + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); + OUT_RING( buf_priv->age ); + + ADVANCE_RING(); + + buf->pending = 1; + buf->used = 0; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; +} + +static void r128_cce_dispatch_indices( drm_device_t *dev, + drm_buf_t *buf, + int start, int end, + int count ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_buf_priv_t *buf_priv = buf->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + int format = sarea_priv->vc_format; + int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset; + int prim = buf_priv->prim; + u32 *data; + int dwords; + int i = 0; + RING_LOCALS; + DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); + + if ( 0 ) + r128_print_dirty( "dispatch_indices", sarea_priv->dirty ); + + if ( start != end ) { + buf_priv->dispatched = 1; + + if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128_emit_state( dev_priv ); + } + + dwords = (end - start + 3) / sizeof(u32); + + data = (u32 *)((char *)dev_priv->buffers->handle + + buf->offset + start); + + data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, + dwords-2 ) ); + + data[1] = cpu_to_le32( offset ); + data[2] = cpu_to_le32( R128_MAX_VB_VERTS ); + data[3] = cpu_to_le32( format ); + data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | + (count << 16)) ); + + if ( count & 0x1 ) { +#ifdef __LITTLE_ENDIAN + data[dwords-1] &= 0x0000ffff; +#else + data[dwords-1] &= 0xffff0000; +#endif + } + + do { + /* Emit the next set of up to three cliprects */ + if ( i < sarea_priv->nbox ) { + r128_emit_clip_rects( dev_priv, + &sarea_priv->boxes[i], + sarea_priv->nbox - i ); + } + + r128_cce_dispatch_indirect( dev, buf, start, end ); + + i += 3; + } while ( i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) ); + OUT_RING( buf_priv->age ); + + ADVANCE_RING(); + + buf->pending = 1; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; + + sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; + sarea_priv->nbox = 0; +} + +static int r128_cce_dispatch_blit( drm_device_t *dev, + drm_r128_blit_t *blit ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + u32 *data; + int dword_shift, dwords; + RING_LOCALS; + DRM_DEBUG( "\n" ); + + /* The compiler won't optimize away a division by a variable, + * even if the only legal values are powers of two. Thus, we'll + * use a shift instead. + */ + switch ( blit->format ) { + case R128_DATATYPE_ARGB8888: + dword_shift = 0; + break; + case R128_DATATYPE_ARGB1555: + case R128_DATATYPE_RGB565: + case R128_DATATYPE_ARGB4444: + dword_shift = 1; + break; + case R128_DATATYPE_CI8: + case R128_DATATYPE_RGB8: + dword_shift = 2; + break; + default: + DRM_ERROR( "invalid blit format %d\n", blit->format ); + return DRM_ERR(EINVAL); + } + + /* Flush the pixel cache, and mark the contents as Read Invalid. + * This ensures no pixel data gets mixed up with the texture + * data from the host data blit, otherwise part of the texture + * image may be corrupted. + */ + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); + OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI ); + + ADVANCE_RING(); + + /* Dispatch the indirect buffer. + */ + 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 ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", blit->idx ); + return DRM_ERR(EINVAL); + } + + buf_priv->discard = 1; + + dwords = (blit->width * blit->height) >> dword_shift; + + data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); + + data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) ); + data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (blit->format << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_HOST_DATA | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS) ); + + data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) ); + data[3] = cpu_to_le32( 0xffffffff ); + data[4] = cpu_to_le32( 0xffffffff ); + data[5] = cpu_to_le32( (blit->y << 16) | blit->x ); + data[6] = cpu_to_le32( (blit->height << 16) | blit->width ); + data[7] = cpu_to_le32( dwords ); + + buf->used = (dwords + 8) * sizeof(u32); + + r128_cce_dispatch_indirect( dev, buf, 0, buf->used ); + + /* Flush the pixel cache after the blit completes. This ensures + * the texture data is written out to memory before rendering + * continues. + */ + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) ); + OUT_RING( R128_PC_FLUSH_GUI ); + + ADVANCE_RING(); + + return 0; +} + + +/* ================================================================ + * Tiled depth buffer management + * + * FIXME: These should all set the destination write mask for when we + * have hardware stencil support. + */ + +static int r128_cce_dispatch_write_span( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int count, x, y; + u32 *buffer; + u8 *mask; + int i; + RING_LOCALS; + DRM_DEBUG( "\n" ); + + count = depth->n; + if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + return DRM_ERR(EFAULT); + } + if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + return DRM_ERR(EFAULT); + } + + buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + if ( buffer == NULL ) + return DRM_ERR(ENOMEM); + if ( DRM_COPY_FROM_USER( buffer, depth->buffer, + depth->n * sizeof(u32) ) ) { + DRM_FREE( buffer ); + return DRM_ERR(EFAULT); + } + + if ( depth->mask ) { + mask = DRM_MALLOC( depth->n * sizeof(u8) ); + if ( mask == NULL ) { + DRM_FREE( buffer ); + return DRM_ERR(ENOMEM); + } + if ( DRM_COPY_FROM_USER( mask, depth->mask, + depth->n * sizeof(u8) ) ) { + DRM_FREE( buffer ); + DRM_FREE( mask ); + return DRM_ERR(EFAULT); + } + + for ( i = 0 ; i < count ; i++, x++ ) { + if ( mask[i] ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + DRM_FREE( mask ); + } else { + for ( i = 0 ; i < count ; i++, x++ ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + DRM_FREE( buffer ); + + return 0; +} + +static int r128_cce_dispatch_write_pixels( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int count, *x, *y; + u32 *buffer; + u8 *mask; + int i; + RING_LOCALS; + DRM_DEBUG( "\n" ); + + count = depth->n; + + x = DRM_MALLOC( count * sizeof(*x) ); + if ( x == NULL ) { + return DRM_ERR(ENOMEM); + } + y = DRM_MALLOC( count * sizeof(*y) ); + if ( y == NULL ) { + DRM_FREE( x ); + return DRM_ERR(ENOMEM); + } + if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); + } + if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); + } + + buffer = DRM_MALLOC( depth->n * sizeof(u32) ); + if ( buffer == NULL ) { + DRM_FREE( x ); + DRM_FREE( y ); + 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 ); + return DRM_ERR(EFAULT); + } + + if ( depth->mask ) { + mask = DRM_MALLOC( depth->n * sizeof(u8) ); + if ( mask == NULL ) { + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); + 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 ); + return DRM_ERR(EFAULT); + } + + for ( i = 0 ; i < count ; i++ ) { + if ( mask[i] ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + DRM_FREE( mask ); + } else { + for ( i = 0 ; i < count ; i++ ) { + BEGIN_RING( 6 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( buffer[i] ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + } + + DRM_FREE( x ); + DRM_FREE( y ); + DRM_FREE( buffer ); + + return 0; +} + +static int r128_cce_dispatch_read_span( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int count, x, y; + RING_LOCALS; + DRM_DEBUG( "\n" ); + + count = depth->n; + if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) { + return DRM_ERR(EFAULT); + } + if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) { + return DRM_ERR(EFAULT); + } + + BEGIN_RING( 7 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( dev_priv->span_pitch_offset_c ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (0 << 16) | 0 ); + OUT_RING( (count << 16) | 1 ); + + ADVANCE_RING(); + + return 0; +} + +static int r128_cce_dispatch_read_pixels( drm_device_t *dev, + drm_r128_depth_t *depth ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int count, *x, *y; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __func__ ); + + count = depth->n; + if ( count > dev_priv->depth_pitch ) { + count = dev_priv->depth_pitch; + } + + x = DRM_MALLOC( count * sizeof(*x) ); + if ( x == NULL ) { + return DRM_ERR(ENOMEM); + } + y = DRM_MALLOC( count * sizeof(*y) ); + if ( y == NULL ) { + DRM_FREE( x ); + return DRM_ERR(ENOMEM); + } + if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); + } + if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { + DRM_FREE( x ); + DRM_FREE( y ); + return DRM_ERR(EFAULT); + } + + for ( i = 0 ; i < count ; i++ ) { + BEGIN_RING( 7 ); + + OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (dev_priv->depth_fmt << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->depth_pitch_offset_c ); + OUT_RING( dev_priv->span_pitch_offset_c ); + + OUT_RING( (x[i] << 16) | y[i] ); + OUT_RING( (i << 16) | 0 ); + OUT_RING( (1 << 16) | 1 ); + + ADVANCE_RING(); + } + + DRM_FREE( x ); + DRM_FREE( y ); + + return 0; +} + + +/* ================================================================ + * Polygon stipple + */ + +static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __func__ ); + + BEGIN_RING( 33 ); + + OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); + for ( i = 0 ; i < 32 ; i++ ) { + OUT_RING( stipple[i] ); + } + + ADVANCE_RING(); +} + + +/* ================================================================ + * IOCTL functions + */ + +int r128_cce_clear( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_r128_clear_t clear; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data, + sizeof(clear) ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; + + r128_cce_dispatch_clear( dev, &clear ); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + + return 0; +} + +int r128_cce_swap( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; + DRM_DEBUG( "%s\n", __func__ ); + + LOCK_TEST_WITH_RETURN( dev ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; + + if ( !dev_priv->page_flipping ) { + r128_cce_dispatch_swap( dev ); + dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS); + } else { + r128_cce_dispatch_flip( dev ); + } + + return 0; +} + +int r128_cce_vertex( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_vertex_t vertex; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data, + sizeof(vertex) ); + + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, + vertex.idx, vertex.count, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + if ( vertex.prim < 0 || + vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { + DRM_ERROR( "buffer prim %d\n", vertex.prim ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + 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 ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return DRM_ERR(EINVAL); + } + + buf->used = vertex.count; + buf_priv->prim = vertex.prim; + buf_priv->discard = vertex.discard; + + r128_cce_dispatch_vertex( dev, buf ); + + return 0; +} + +int r128_cce_indices( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_indices_t elts; + int count; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data, + sizeof(elts) ); + + DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, + elts.idx, elts.start, elts.end, elts.discard ); + + if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + elts.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + if ( elts.prim < 0 || + elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { + DRM_ERROR( "buffer prim %d\n", elts.prim ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + 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 ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", elts.idx ); + return DRM_ERR(EINVAL); + } + + count = (elts.end - elts.start) / sizeof(u16); + elts.start -= R128_INDEX_PRIM_OFFSET; + + if ( elts.start & 0x7 ) { + DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + return DRM_ERR(EINVAL); + } + if ( elts.start < buf->used ) { + DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); + return DRM_ERR(EINVAL); + } + + buf->used = elts.end; + buf_priv->prim = elts.prim; + buf_priv->discard = elts.discard; + + r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); + + return 0; +} + +int r128_cce_blit( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_blit_t blit; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data, + sizeof(blit) ); + + DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx ); + + if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + blit.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + return r128_cce_dispatch_blit( dev, &blit ); +} + +int r128_cce_depth( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_depth_t depth; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data, + sizeof(depth) ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + switch ( depth.func ) { + case R128_WRITE_SPAN: + return r128_cce_dispatch_write_span( dev, &depth ); + case R128_WRITE_PIXELS: + return r128_cce_dispatch_write_pixels( dev, &depth ); + case R128_READ_SPAN: + return r128_cce_dispatch_read_span( dev, &depth ); + case R128_READ_PIXELS: + return r128_cce_dispatch_read_pixels( dev, &depth ); + } + + return DRM_ERR(EINVAL); +} + +int r128_cce_stipple( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_r128_stipple_t stipple; + u32 mask[32]; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data, + sizeof(stipple) ); + + if ( DRM_COPY_FROM_USER( &mask, stipple.mask, + 32 * sizeof(u32) ) ) + return DRM_ERR( EFAULT ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + r128_cce_dispatch_stipple( dev, mask ); + + return 0; +} + +int r128_cce_indirect( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_r128_buf_priv_t *buf_priv; + drm_r128_indirect_t indirect; +#if 0 + RING_LOCALS; +#endif + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data, + sizeof(indirect) ); + + DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, + indirect.end, indirect.discard ); + + if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + + 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 ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + return DRM_ERR(EINVAL); + } + + if ( indirect.start < buf->used ) { + DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf->used = indirect.end; + buf_priv->discard = indirect.discard; + +#if 0 + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING( 2 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); +#endif + + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ + r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + + return 0; +} diff --git a/bsd/radeon/radeon.h b/shared/radeon.h index 0fdeb82a..503df68b 100644 --- a/bsd/radeon/radeon.h +++ b/shared/radeon.h @@ -43,6 +43,48 @@ #define __HAVE_SG 1 #define __HAVE_PCI_DMA 1 +#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." + +#define DRIVER_NAME "radeon" +#define DRIVER_DESC "ATI Radeon" +#define DRIVER_DATE "20020611" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 3 +#define DRIVER_PATCHLEVEL 1 + +/* Interface history: + * + * 1.1 - ?? + * 1.2 - Add vertex2 ioctl (keith) + * - Add stencil capability to clear ioctl (gareth, keith) + * - Increase MAX_TEXTURE_LEVELS (brian) + * 1.3 - Add cmdbuf ioctl (keith) + * - Add support for new radeon packets (keith) + * - Add getparam ioctl (keith) + * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). + */ +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c new file mode 100644 index 00000000..1ddbdced --- /dev/null +++ b/shared/radeon_cp.c @@ -0,0 +1,1287 @@ +/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, 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: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" + +#define RADEON_FIFO_DEBUG 0 + +#if defined(__alpha__) || defined(__powerpc__) +# define PCIGART_ENABLED +#else +# undef PCIGART_ENABLED +#endif + + +/* CP microcode (from ATI) */ +static u32 radeon_cp_microcode[][2] = { + { 0x21007000, 0000000000 }, + { 0x20007000, 0000000000 }, + { 0x000000b4, 0x00000004 }, + { 0x000000b8, 0x00000004 }, + { 0x6f5b4d4c, 0000000000 }, + { 0x4c4c427f, 0000000000 }, + { 0x5b568a92, 0000000000 }, + { 0x4ca09c6d, 0000000000 }, + { 0xad4c4c4c, 0000000000 }, + { 0x4ce1af3d, 0000000000 }, + { 0xd8afafaf, 0000000000 }, + { 0xd64c4cdc, 0000000000 }, + { 0x4cd10d10, 0000000000 }, + { 0x000f0000, 0x00000016 }, + { 0x362f242d, 0000000000 }, + { 0x00000012, 0x00000004 }, + { 0x000f0000, 0x00000016 }, + { 0x362f282d, 0000000000 }, + { 0x000380e7, 0x00000002 }, + { 0x04002c97, 0x00000002 }, + { 0x000f0001, 0x00000016 }, + { 0x333a3730, 0000000000 }, + { 0x000077ef, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00000017, 0x00000004 }, + { 0x0003802b, 0x00000002 }, + { 0x040067e0, 0x00000002 }, + { 0x00000017, 0x00000004 }, + { 0x000077e0, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x000037e1, 0x00000002 }, + { 0x040067e1, 0x00000006 }, + { 0x000077e0, 0x00000002 }, + { 0x000077e1, 0x00000002 }, + { 0x000077e1, 0x00000006 }, + { 0xffffffff, 0000000000 }, + { 0x10000000, 0000000000 }, + { 0x0003802b, 0x00000002 }, + { 0x040067e0, 0x00000006 }, + { 0x00007675, 0x00000002 }, + { 0x00007676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0003802c, 0x00000002 }, + { 0x04002676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0000002f, 0x00000018 }, + { 0x0000002f, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x00000030, 0x00000018 }, + { 0x00000030, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x01605000, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00098000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x64c0603e, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00080000, 0x00000016 }, + { 0000000000, 0000000000 }, + { 0x0400251d, 0x00000002 }, + { 0x00007580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x04002580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x00000049, 0x00000004 }, + { 0x00005000, 0000000000 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x00019000, 0x00000002 }, + { 0x00011055, 0x00000014 }, + { 0x00000055, 0x00000012 }, + { 0x0400250f, 0x00000002 }, + { 0x0000504f, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007565, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000058, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x01e655b4, 0x00000002 }, + { 0x4401b0e4, 0x00000002 }, + { 0x01c110e4, 0x00000002 }, + { 0x26667066, 0x00000018 }, + { 0x040c2565, 0x00000002 }, + { 0x00000066, 0x00000018 }, + { 0x04002564, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x0000005d, 0x00000004 }, + { 0x00401069, 0x00000008 }, + { 0x00101000, 0x00000002 }, + { 0x000d80ff, 0x00000002 }, + { 0x0080006c, 0x00000008 }, + { 0x000f9000, 0x00000002 }, + { 0x000e00ff, 0x00000002 }, + { 0000000000, 0x00000006 }, + { 0x0000008f, 0x00000018 }, + { 0x0000005b, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007576, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00009000, 0x00000002 }, + { 0x00041000, 0x00000002 }, + { 0x0c00350e, 0x00000002 }, + { 0x00049000, 0x00000002 }, + { 0x00051000, 0x00000002 }, + { 0x01e785f8, 0x00000002 }, + { 0x00200000, 0x00000002 }, + { 0x0060007e, 0x0000000c }, + { 0x00007563, 0x00000002 }, + { 0x006075f0, 0x00000021 }, + { 0x20007073, 0x00000004 }, + { 0x00005073, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007576, 0x00000002 }, + { 0x00007577, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x0000750f, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00600083, 0x0000000c }, + { 0x006075f0, 0x00000021 }, + { 0x000075f8, 0x00000002 }, + { 0x00000083, 0x00000004 }, + { 0x000a750e, 0x00000002 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x0020750f, 0x00000002 }, + { 0x00600086, 0x00000004 }, + { 0x00007570, 0x00000002 }, + { 0x00007571, 0x00000002 }, + { 0x00007572, 0x00000006 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00005000, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00007568, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000095, 0x0000000c }, + { 0x00058000, 0x00000002 }, + { 0x0c607562, 0x00000002 }, + { 0x00000097, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00600096, 0x00000004 }, + { 0x400070e5, 0000000000 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x000380e5, 0x00000002 }, + { 0x000000a8, 0x0000001c }, + { 0x000650aa, 0x00000018 }, + { 0x040025bb, 0x00000002 }, + { 0x000610ab, 0x00000018 }, + { 0x040075bc, 0000000000 }, + { 0x000075bb, 0x00000002 }, + { 0x000075bc, 0000000000 }, + { 0x00090000, 0x00000006 }, + { 0x00090000, 0x00000002 }, + { 0x000d8002, 0x00000006 }, + { 0x00007832, 0x00000002 }, + { 0x00005000, 0x00000002 }, + { 0x000380e7, 0x00000002 }, + { 0x04002c97, 0x00000002 }, + { 0x00007820, 0x00000002 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x01200000, 0x00000002 }, + { 0x20077000, 0x00000002 }, + { 0x01200000, 0x00000002 }, + { 0x20007000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x0120751b, 0x00000002 }, + { 0x8040750a, 0x00000002 }, + { 0x8040750b, 0x00000002 }, + { 0x00110000, 0x00000002 }, + { 0x000380e5, 0x00000002 }, + { 0x000000c6, 0x0000001c }, + { 0x000610ab, 0x00000018 }, + { 0x844075bd, 0x00000002 }, + { 0x000610aa, 0x00000018 }, + { 0x840075bb, 0x00000002 }, + { 0x000610ab, 0x00000018 }, + { 0x844075bc, 0x00000002 }, + { 0x000000c9, 0x00000004 }, + { 0x804075bd, 0x00000002 }, + { 0x800075bb, 0x00000002 }, + { 0x804075bc, 0x00000002 }, + { 0x00108000, 0x00000002 }, + { 0x01400000, 0x00000002 }, + { 0x006000cd, 0x0000000c }, + { 0x20c07000, 0x00000020 }, + { 0x000000cf, 0x00000012 }, + { 0x00800000, 0x00000006 }, + { 0x0080751d, 0x00000006 }, + { 0000000000, 0000000000 }, + { 0x0000775c, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460275d, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x01e00830, 0x00000002 }, + { 0x21007000, 0000000000 }, + { 0x6464614d, 0000000000 }, + { 0x69687420, 0000000000 }, + { 0x00000073, 0000000000 }, + { 0000000000, 0000000000 }, + { 0x00005000, 0x00000002 }, + { 0x000380d0, 0x00000002 }, + { 0x040025e0, 0x00000002 }, + { 0x000075e1, 0000000000 }, + { 0x00000001, 0000000000 }, + { 0x000380e0, 0x00000002 }, + { 0x04002394, 0x00000002 }, + { 0x00005000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0x00000008, 0000000000 }, + { 0x00000004, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, +}; + + +int RADEON_READ_PLL(drm_device_t *dev, int addr) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); + return RADEON_READ(RADEON_CLOCK_CNTL_DATA); +} + +#if RADEON_FIFO_DEBUG +static void radeon_status( drm_radeon_private_t *dev_priv ) +{ + printk( "%s:\n", __FUNCTION__ ); + printk( "RBBM_STATUS = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) ); + printk( "CP_RB_RTPR = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) ); + printk( "CP_RB_WTPR = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) ); + printk( "AIC_CNTL = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) ); + printk( "AIC_STAT = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_AIC_STAT ) ); + printk( "AIC_PT_BASE = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) ); + printk( "TLB_ADDR = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) ); + printk( "TLB_DATA = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) ); +} +#endif + + +/* ================================================================ + * Engine, FIFO control + */ + +static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) +{ + u32 tmp; + int i; + + tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); + tmp |= RADEON_RB2D_DC_FLUSH_ALL; + RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ) + & RADEON_RB2D_DC_BUSY) ) { + return 0; + } + DRM_UDELAY( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return DRM_ERR(EBUSY); +} + +static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, + int entries ) +{ + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) + & RADEON_RBBM_FIFOCNT_MASK ); + if ( slots >= entries ) return 0; + DRM_UDELAY( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return DRM_ERR(EBUSY); +} + +static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) +{ + int i, ret; + + ret = radeon_do_wait_for_fifo( dev_priv, 64 ); + if ( ret ) return ret; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(RADEON_READ( RADEON_RBBM_STATUS ) + & RADEON_RBBM_ACTIVE) ) { + radeon_do_pixcache_flush( dev_priv ); + return 0; + } + DRM_UDELAY( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return DRM_ERR(EBUSY); +} + + +/* ================================================================ + * CP control, initialization + */ + +/* Load the microcode for the CP */ +static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) +{ + int i; + DRM_DEBUG( "\n" ); + + radeon_do_wait_for_idle( dev_priv ); + + RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); + for ( i = 0 ; i < 256 ; i++ ) { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + radeon_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + radeon_cp_microcode[i][0] ); + } +} + +/* Flush any pending commands to the CP. This should only be used just + * prior to a wait for idle, as it informs the engine that the command + * stream is ending. + */ +static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) +{ + DRM_DEBUG( "\n" ); +#if 0 + u32 tmp; + + tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31); + RADEON_WRITE( RADEON_CP_RB_WPTR, tmp ); +#endif +} + +/* Wait for the CP to go idle. + */ +int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) +{ + RING_LOCALS; + DRM_DEBUG( "\n" ); + + BEGIN_RING( 6 ); + + RADEON_PURGE_CACHE(); + RADEON_PURGE_ZCACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); + COMMIT_RING(); + + return radeon_do_wait_for_idle( dev_priv ); +} + +/* Start the Command Processor. + */ +static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) +{ + RING_LOCALS; + DRM_DEBUG( "\n" ); + + radeon_do_wait_for_idle( dev_priv ); + + RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode ); + + dev_priv->cp_running = 1; + + BEGIN_RING( 6 ); + + RADEON_PURGE_CACHE(); + RADEON_PURGE_ZCACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); + COMMIT_RING(); +} + +/* Reset the Command Processor. This will not flush any pending + * commands, so you must wait for the CP command stream to complete + * before calling this routine. + */ +static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) +{ + u32 cur_read_ptr; + DRM_DEBUG( "\n" ); + + cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); + RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; + dev_priv->ring.tail = cur_read_ptr; +} + +/* Stop the Command Processor. This will not flush any pending + * commands, so you must flush the command stream and wait for the CP + * to go idle before calling this routine. + */ +static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) +{ + DRM_DEBUG( "\n" ); + + RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); + + dev_priv->cp_running = 0; +} + +/* Reset the engine. This will stop the CP if it is running. + */ +static int radeon_do_engine_reset( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; + DRM_DEBUG( "\n" ); + + radeon_do_pixcache_flush( dev_priv ); + + clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX ); + mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL ); + + RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl | + RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB | + RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC | + RADEON_FORCEON_AIC ) ); + + rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET ); + + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB ) ); + RADEON_READ( RADEON_RBBM_SOFT_RESET ); + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset & + ~( RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB ) ) ); + RADEON_READ( RADEON_RBBM_SOFT_RESET ); + + + RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl ); + RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index ); + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset ); + + /* Reset the CP ring */ + radeon_do_cp_reset( dev_priv ); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; + + /* Reset any pending vertex, indirect buffers */ + radeon_freelist_reset( dev ); + + return 0; +} + +static void radeon_cp_init_ring_buffer( drm_device_t *dev, + drm_radeon_private_t *dev_priv ) +{ + u32 ring_start, cur_read_ptr; + u32 tmp; + + /* Initialize the memory controller */ + RADEON_WRITE( RADEON_MC_FB_LOCATION, + (dev_priv->agp_vm_start - 1) & 0xffff0000 ); + + if ( !dev_priv->is_pci ) { + RADEON_WRITE( RADEON_MC_AGP_LOCATION, + (((dev_priv->agp_vm_start - 1 + + dev_priv->agp_size) & 0xffff0000) | + (dev_priv->agp_vm_start >> 16)) ); + } + +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) + ring_start = (dev_priv->cp_ring->offset + - dev->agp->base + + dev_priv->agp_vm_start); + else +#endif + ring_start = (dev_priv->cp_ring->offset + - dev->sg->handle + + dev_priv->agp_vm_start); + + RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); + + /* Set the write pointer delay */ + RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); + + /* Initialize the ring buffer's read and write pointers */ + cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); + RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; + dev_priv->ring.tail = cur_read_ptr; + + if ( !dev_priv->is_pci ) { + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, + dev_priv->ring_rptr->offset ); + } else { + drm_sg_mem_t *entry = dev->sg; + unsigned long tmp_ofs, page_ofs; + + tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; + page_ofs = tmp_ofs >> PAGE_SHIFT; + + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, + entry->busaddr[page_ofs]); + DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", + entry->busaddr[page_ofs], + entry->handle + tmp_ofs ); + } + + /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); +#else + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); +#endif + + radeon_do_wait_for_idle( dev_priv ); + + /* Turn on bus mastering */ + tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE( RADEON_BUS_CNTL, tmp ); + + /* Sync everything up */ + RADEON_WRITE( RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); +} + +static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) +{ + drm_radeon_private_t *dev_priv; + u32 tmp; + DRM_DEBUG( "\n" ); + + dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); + if ( dev_priv == NULL ) + return DRM_ERR(ENOMEM); + + memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); + + dev_priv->is_pci = init->is_pci; + +#if !defined(PCIGART_ENABLED) + /* PCI support is not 100% working, so we disable it here. + */ + if ( dev_priv->is_pci ) { + DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } +#endif + + if ( dev_priv->is_pci && !dev->sg ) { + DRM_ERROR( "PCI GART memory not allocated!\n" ); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + + dev_priv->usec_timeout = init->usec_timeout; + if ( dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { + DRM_DEBUG( "TIMEOUT problem!\n" ); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + + dev_priv->cp_mode = init->cp_mode; + + /* Simple idle check. + */ + atomic_set( &dev_priv->idle_count, 0 ); + + /* We don't support anything other than bus-mastering ring mode, + * but the ring can be in either AGP or PCI space for the ring + * read pointer. + */ + if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && + ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { + DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + + switch ( init->fb_bpp ) { + case 16: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + } + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + switch ( init->depth_bpp ) { + case 16: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 32: + default: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + break; + } + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + + dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | + (dev_priv->front_offset >> 10)); + dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | + (dev_priv->back_offset >> 10)); + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | + (dev_priv->depth_offset >> 10)); + + /* Hardware state for depth clears. Remove this if/when we no + * longer clear the depth buffer with a 3D rectangle. Hard-code + * all values to prevent unwanted 3D state from slipping through + * and screwing with the clear operation. + */ + dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + (dev_priv->color_fmt << 10) | + (1<<15)); + + dev_priv->depth_clear.rb3d_zstencilcntl = + (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_REPLACE | + RADEON_STENCIL_ZPASS_REPLACE | + RADEON_STENCIL_ZFAIL_REPLACE | + RADEON_Z_WRITE_ENABLE); + + dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_FLAT | + RADEON_ALPHA_SHADE_FLAT | + RADEON_SPECULAR_SHADE_FLAT | + RADEON_FOG_SHADE_FLAT | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + DRM_GETSAREA(); + + if(!dev_priv->sarea) { + DRM_ERROR("could not find sarea!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + if(!dev_priv->fb) { + DRM_ERROR("could not find framebuffer!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + if(!dev_priv->mmio) { + DRM_ERROR("could not find mmio region!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); + if(!dev_priv->cp_ring) { + DRM_ERROR("could not find cp ring region!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + if(!dev_priv->ring_rptr) { + DRM_ERROR("could not find ring read pointer!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + if(!dev_priv->buffers) { + DRM_ERROR("could not find dma buffer region!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + + if ( !dev_priv->is_pci ) { + DRM_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); + if(!dev_priv->agp_textures) { + DRM_ERROR("could not find agp texture region!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + } + + dev_priv->sarea_priv = + (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if ( !dev_priv->is_pci ) { + DRM_IOREMAP( dev_priv->cp_ring ); + DRM_IOREMAP( dev_priv->ring_rptr ); + DRM_IOREMAP( dev_priv->buffers ); + if(!dev_priv->cp_ring->handle || + !dev_priv->ring_rptr->handle || + !dev_priv->buffers->handle) { + DRM_ERROR("could not find ioremap agp regions!\n"); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(EINVAL); + } + } else { + dev_priv->cp_ring->handle = + (void *)dev_priv->cp_ring->offset; + dev_priv->ring_rptr->handle = + (void *)dev_priv->ring_rptr->offset; + dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; + + DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", + dev_priv->cp_ring->handle ); + DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", + dev_priv->ring_rptr->handle ); + DRM_DEBUG( "dev_priv->buffers->handle %p\n", + dev_priv->buffers->handle ); + } + + + dev_priv->agp_size = init->agp_size; + dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) + dev_priv->agp_buffers_offset = (dev_priv->buffers->offset + - dev->agp->base + + dev_priv->agp_vm_start); + else +#endif + dev_priv->agp_buffers_offset = (dev_priv->buffers->offset + - dev->sg->handle + + dev_priv->agp_vm_start); + + DRM_DEBUG( "dev_priv->agp_size %d\n", + dev_priv->agp_size ); + DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n", + dev_priv->agp_vm_start ); + DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", + dev_priv->agp_buffers_offset ); + + dev_priv->ring.head = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle); + + dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; + dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle + + init->ring_size / sizeof(u32)); + dev_priv->ring.size = init->ring_size; + dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); + + dev_priv->ring.tail_mask = + (dev_priv->ring.size / sizeof(u32)) - 1; + + dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + +#if 0 + /* Initialize the scratch register pointer. This will cause + * the scratch register values to be written out to memory + * whenever they are updated. + * FIXME: This doesn't quite work yet, so we're disabling it + * for the release. + */ + RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset + + RADEON_SCRATCH_REG_OFFSET) ); + RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); +#endif + + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + + dev_priv->sarea_priv->last_frame = 0; + RADEON_WRITE( RADEON_LAST_FRAME_REG, + dev_priv->sarea_priv->last_frame ); + + dev_priv->sarea_priv->last_dispatch = 0; + RADEON_WRITE( RADEON_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch ); + + dev_priv->sarea_priv->last_clear = 0; + RADEON_WRITE( RADEON_LAST_CLEAR_REG, + dev_priv->sarea_priv->last_clear ); + +#if __REALLY_HAVE_SG + if ( dev_priv->is_pci ) { + if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, + &dev_priv->bus_pci_gart)) { + DRM_ERROR( "failed to init PCI GART!\n" ); + dev->dev_private = (void *)dev_priv; + radeon_do_cleanup_cp(dev); + return DRM_ERR(ENOMEM); + } + /* Turn on PCI GART + */ + tmp = RADEON_READ( RADEON_AIC_CNTL ) + | RADEON_PCIGART_TRANSLATE_EN; + RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + + /* set PCI GART page-table base address + */ + RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); + + /* set address range for PCI address translate + */ + RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); + RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start + + dev_priv->agp_size - 1); + + /* Turn off AGP aperture -- is this required for PCIGART? + */ + RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ + RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + } else { +#endif /* __REALLY_HAVE_SG */ + /* Turn off PCI GART + */ + tmp = RADEON_READ( RADEON_AIC_CNTL ) + & ~RADEON_PCIGART_TRANSLATE_EN; + RADEON_WRITE( RADEON_AIC_CNTL, tmp ); +#if __REALLY_HAVE_SG + } +#endif /* __REALLY_HAVE_SG */ + + radeon_cp_load_microcode( dev_priv ); + radeon_cp_init_ring_buffer( dev, dev_priv ); + + dev_priv->last_buf = 0; + + dev->dev_private = (void *)dev_priv; + + radeon_do_engine_reset( dev ); + + return 0; +} + +int radeon_do_cleanup_cp( drm_device_t *dev ) +{ + DRM_DEBUG( "\n" ); + + if ( dev->dev_private ) { + drm_radeon_private_t *dev_priv = dev->dev_private; + + if ( !dev_priv->is_pci ) { + DRM_IOREMAPFREE( dev_priv->cp_ring ); + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + DRM_IOREMAPFREE( dev_priv->buffers ); + } else { +#if __REALLY_HAVE_SG + if (!DRM(ati_pcigart_cleanup)( dev, + dev_priv->phys_pci_gart, + dev_priv->bus_pci_gart )) + DRM_ERROR( "failed to cleanup PCI GART!\n" ); +#endif /* __REALLY_HAVE_SG */ + } + + DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int radeon_cp_init( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_init_t init; + + DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) ); + + switch ( init.func ) { + case RADEON_INIT_CP: + return radeon_do_init_cp( dev, &init ); + case RADEON_CLEANUP_CP: + return radeon_do_cleanup_cp( dev ); + } + + return DRM_ERR(EINVAL); +} + +int radeon_cp_start( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( dev_priv->cp_running ) { + DRM_DEBUG( "%s while CP running\n", __func__ ); + return 0; + } + if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { + DRM_DEBUG( "%s called with bogus CP mode (%d)\n", + __func__, dev_priv->cp_mode ); + return 0; + } + + radeon_do_cp_start( dev_priv ); + + return 0; +} + +/* Stop the CP. The engine must have been idled before calling this + * routine. + */ +int radeon_cp_stop( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_cp_stop_t stop; + int ret; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); + + /* Flush any pending CP commands. This ensures any outstanding + * commands are exectuted by the engine before we turn it off. + */ + if ( stop.flush ) { + radeon_do_cp_flush( dev_priv ); + } + + /* If we fail to make the engine go idle, we return an error + * code so that the DRM ioctl wrapper can try again. + */ + if ( stop.idle ) { + ret = radeon_do_cp_idle( dev_priv ); + if ( ret ) return ret; + } + + /* Finally, we can turn off the CP. If the engine isn't idle, + * we will get some dropped triangles as they won't be fully + * rendered before the CP is shut down. + */ + radeon_do_cp_stop( dev_priv ); + + /* Reset the engine */ + radeon_do_engine_reset( dev ); + + return 0; +} + +/* Just reset the CP ring. Called as part of an X Server engine reset. + */ +int radeon_cp_reset( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_DEBUG( "%s called before init done\n", __func__ ); + return DRM_ERR(EINVAL); + } + + radeon_do_cp_reset( dev_priv ); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; + + return 0; +} + +int radeon_cp_idle( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + return radeon_do_cp_idle( dev_priv ); +} + +int radeon_engine_reset( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + return radeon_do_engine_reset( dev ); +} + + +/* ================================================================ + * Fullscreen mode + */ + +/* KW: Deprecated to say the least: + */ +int radeon_fullscreen( DRM_IOCTL_ARGS ) +{ + return 0; +} + + +/* ================================================================ + * Freelist management + */ + +/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through + * bufs until freelist code is used. Note this hides a problem with + * the scratch register * (used to keep track of last buffer + * completed) being written to before * the last buffer has actually + * completed rendering. + * + * KW: It's also a good way to find free buffers quickly. + */ + +drm_buf_t *radeon_freelist_get( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv; + drm_buf_t *buf; + int i, t; + int start; + + if ( ++dev_priv->last_buf >= dma->buf_count ) + dev_priv->last_buf = 0; + + start = dev_priv->last_buf; + + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { + u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG ); + for ( i = start ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + buf->pending = 0; + return buf; + } + start = 0; + } + DRM_UDELAY( 1 ); + } + + DRM_ERROR( "returning NULL!\n" ); + return NULL; +} + +void radeon_freelist_reset( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_radeon_private_t *dev_priv = dev->dev_private; + int i; + + dev_priv->last_buf = 0; + for ( i = 0 ; i < dma->buf_count ; i++ ) { + drm_buf_t *buf = dma->buflist[i]; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + buf_priv->age = 0; + } +} + + +/* ================================================================ + * CP command submission + */ + +int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) +{ + drm_radeon_ring_buffer_t *ring = &dev_priv->ring; + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + radeon_update_ring_snapshot( ring ); + if ( ring->space > n ) + return 0; + DRM_UDELAY( 1 ); + } + + /* FIXME: This return value is ignored in the BEGIN_RING macro! */ +#if RADEON_FIFO_DEBUG + radeon_status( dev_priv ); + DRM_ERROR( "failed!\n" ); +#endif + return DRM_ERR(EBUSY); +} + +static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) +{ + int i; + drm_buf_t *buf; + + for ( i = d->granted_count ; i < d->request_count ; i++ ) { + buf = radeon_freelist_get( dev ); + if ( !buf ) return DRM_ERR(EAGAIN); + + buf->pid = DRM_CURRENTPID; + + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, + sizeof(buf->idx) ) ) + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, + sizeof(buf->total) ) ) + return DRM_ERR(EFAULT); + + d->granted_count++; + } + return 0; +} + +int radeon_cp_buffers( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + int ret = 0; + drm_dma_t d; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); + + /* Please don't send us buffers. + */ + if ( d.send_count != 0 ) { + DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); + } + + /* We'll send you buffers. + */ + 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); + } + + d.granted_count = 0; + + if ( d.request_count ) { + ret = radeon_cp_get_buffers( dev, &d ); + } + + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); + + return ret; +} diff --git a/shared/radeon_drm.h b/shared/radeon_drm.h new file mode 100644 index 00000000..dd24d429 --- /dev/null +++ b/shared/radeon_drm.h @@ -0,0 +1,467 @@ +/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith_whitwell@yahoo.com> + */ + +#ifndef __RADEON_DRM_H__ +#define __RADEON_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (radeon_sarea.h) + */ +#ifndef __RADEON_SAREA_DEFINES__ +#define __RADEON_SAREA_DEFINES__ + +/* Old style state flags, required for sarea interface (1.1 and 1.2 + * clears) and 1.2 drm_vertex2 ioctl. + */ +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ +#define RADEON_UPLOAD_ALL 0x003effff +#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff + + +/* New style per-packet identifiers for use in cmd_buffer ioctl with + * the RADEON_EMIT_PACKET command. Comments relate new packets to old + * state bits and the packet size: + */ +#define RADEON_EMIT_PP_MISC 0 /* context/7 */ +#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ +#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ +#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ +#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ +#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ +#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ +#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ +#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ +#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ +#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ +#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ +#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ +#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ +#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ +#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ +#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ +#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ +#define RADEON_MAX_STATE_PACKETS 21 + + +/* Commands understood by cmd_buffer ioctl. More can be added but + * obviously these can't be removed or changed: + */ +#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ +#define RADEON_CMD_SCALARS 2 /* emit scalar data */ +#define RADEON_CMD_VECTORS 3 /* emit vector data */ +#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ +#define RADEON_CMD_PACKET3 5 /* emit hw packet */ +#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ + + +typedef union { + int i; + struct { + char cmd_type, pad0, pad1, pad2; + } header; + struct { + char cmd_type, packet_id, pad0, pad1; + } packet; + struct { + char cmd_type, offset, stride, count; + } scalars; + struct { + char cmd_type, offset, stride, count; + } vectors; + struct { + char cmd_type, buf_idx, pad0, pad1; + } dma; +} drm_radeon_cmd_header_t; + + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 + +/* Primitive types + */ +#define RADEON_POINTS 0x1 +#define RADEON_LINES 0x2 +#define RADEON_LINE_STRIP 0x3 +#define RADEON_TRIANGLES 0x4 +#define RADEON_TRIANGLE_FAN 0x5 +#define RADEON_TRIANGLE_STRIP 0x6 + +/* Vertex/indirect buffer size + */ +#define RADEON_BUFFER_SIZE 65536 + +/* Byte offsets for indirect buffer data + */ +#define RADEON_INDEX_PRIM_OFFSET 20 + +#define RADEON_SCRATCH_REG_OFFSET 32 + +#define RADEON_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define RADEON_LOCAL_TEX_HEAP 0 +#define RADEON_AGP_TEX_HEAP 1 +#define RADEON_NR_TEX_HEAPS 2 +#define RADEON_NR_TEX_REGIONS 64 +#define RADEON_LOG_TEX_GRANULARITY 16 + +#define RADEON_MAX_TEXTURE_LEVELS 12 +#define RADEON_MAX_TEXTURE_UNITS 3 + +#endif /* __RADEON_SAREA_DEFINES__ */ + +typedef struct { + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; + +typedef struct { + /* Context state */ + unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; /* 0x1c38 */ + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; /* 0x1c50 */ + + /* Line state */ + unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_state; + + unsigned int se_line_width; /* 0x1db8 */ + + /* Bumpmap state */ + unsigned int pp_lum_matrix; /* 0x1d00 */ + + unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_1; + + /* Mask state */ + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + + /* Setup state */ + unsigned int se_cntl_status; /* 0x2140 */ + + /* Misc state */ + unsigned int re_top_left; /* 0x26c0 */ + unsigned int re_misc; +} drm_radeon_context_regs_t; + +typedef struct { + /* Zbias state */ + unsigned int se_zbias_factor; /* 0x1dac */ + unsigned int se_zbias_constant; +} drm_radeon_context2_regs_t; + + +/* Setup registers for each texture unit + */ +typedef struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + unsigned int pp_border_color; +} drm_radeon_texture_regs_t; + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim:8; + unsigned int stateidx:8; + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; /* vertex format */ +} drm_radeon_prim_t; + + +typedef struct { + drm_radeon_context_regs_t context; + drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; + drm_radeon_context2_regs_t context2; + unsigned int dirty; +} drm_radeon_state_t; + + +typedef struct { + unsigned char next, prev; + unsigned char in_use; + int age; +} drm_radeon_tex_region_t; + +typedef struct { + /* The channel for communication of state information to the + * kernel on firing a vertex buffer with either of the + * obsoleted vertex/index ioctls. + */ + drm_radeon_context_regs_t context_state; + drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[RADEON_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for client-side throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + unsigned int last_clear; + + drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; + int tex_age[RADEON_NR_TEX_HEAPS]; + int ctx_owner; + int pfState; /* number of 3d windows (0,1,2ormore) */ + int pfCurrentPage; /* which buffer is being displayed? */ +} drm_radeon_sarea_t; + + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmRadeon.h) + * + * KW: actually it's illegal to change any of this (backwards compatibility). + */ + +/* Radeon specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) +#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t) +#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t) +#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52) + +typedef struct drm_radeon_init { + enum { + RADEON_INIT_CP = 0x01, + RADEON_CLEANUP_CP = 0x02 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cp_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drm_radeon_init_t; + +typedef struct drm_radeon_cp_stop { + int flush; + int idle; +} drm_radeon_cp_stop_t; + +typedef struct drm_radeon_fullscreen { + enum { + RADEON_INIT_FULLSCREEN = 0x01, + RADEON_CLEANUP_FULLSCREEN = 0x02 + } func; +} drm_radeon_fullscreen_t; + +#define CLEAR_X1 0 +#define CLEAR_Y1 1 +#define CLEAR_X2 2 +#define CLEAR_Y2 3 +#define CLEAR_DEPTH 4 + +typedef union drm_radeon_clear_rect { + float f[5]; + unsigned int ui[5]; +} drm_radeon_clear_rect_t; + +typedef struct drm_radeon_clear { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; /* misnamed field: should be stencil */ + drm_radeon_clear_rect_t *depth_boxes; +} drm_radeon_clear_t; + +typedef struct drm_radeon_vertex { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drm_radeon_vertex_t; + +typedef struct drm_radeon_indices { + int prim; + int idx; + int start; + int end; + int discard; /* Client finished with buffer? */ +} drm_radeon_indices_t; + +/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices + * - allows multiple primitives and state changes in a single ioctl + * - supports driver change to emit native primitives + */ +typedef struct drm_radeon_vertex2 { + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ + int nr_states; + drm_radeon_state_t *state; + int nr_prims; + drm_radeon_prim_t *prim; +} drm_radeon_vertex2_t; + +/* v1.3 - obsoletes drm_radeon_vertex2 + * - allows arbitarily large cliprect list + * - allows updating of tcl packet, vector and scalar state + * - allows memory-efficient description of state updates + * - allows state to be emitted without a primitive + * (for clears, ctx switches) + * - allows more than one dma buffer to be referenced per ioctl + * - supports tcl driver + * - may be extended in future versions with new cmd types, packets + */ +typedef struct drm_radeon_cmd_buffer { + int bufsz; + char *buf; + int nbox; + drm_clip_rect_t *boxes; +} drm_radeon_cmd_buffer_t; + +typedef struct drm_radeon_tex_image { + unsigned int x, y; /* Blit coordinates */ + unsigned int width, height; + const void *data; +} drm_radeon_tex_image_t; + +typedef struct drm_radeon_texture { + int offset; + int pitch; + int format; + int width; /* Texture image coordinates */ + int height; + drm_radeon_tex_image_t *image; +} drm_radeon_texture_t; + +typedef struct drm_radeon_stipple { + unsigned int *mask; +} drm_radeon_stipple_t; + +typedef struct drm_radeon_indirect { + int idx; + int start; + int end; + int discard; +} drm_radeon_indirect_t; + + +/* 1.3: An ioctl to get parameters that aren't available to the 3d + * client any other way. + */ +#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1 + +typedef struct drm_radeon_getparam { + int param; + int *value; +} drm_radeon_getparam_t; + +#endif diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h new file mode 100644 index 00000000..ae66f12e --- /dev/null +++ b/shared/radeon_drv.h @@ -0,0 +1,760 @@ +/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, 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: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#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)) + +typedef struct drm_radeon_freelist { + unsigned int age; + drm_buf_t *buf; + struct drm_radeon_freelist *next; + struct drm_radeon_freelist *prev; +} drm_radeon_freelist_t; + +typedef struct drm_radeon_ring_buffer { + u32 *start; + u32 *end; + int size; + int size_l2qw; + + volatile u32 *head; + u32 tail; + u32 tail_mask; + int space; + + int high_mark; +} drm_radeon_ring_buffer_t; + +typedef struct drm_radeon_depth_clear_t { + u32 rb3d_cntl; + u32 rb3d_zstencilcntl; + u32 se_cntl; +} drm_radeon_depth_clear_t; + +typedef struct drm_radeon_private { + drm_radeon_ring_buffer_t ring; + drm_radeon_sarea_t *sarea_priv; + + int agp_size; + u32 agp_vm_start; + unsigned long agp_buffers_offset; + + int cp_mode; + int cp_running; + + drm_radeon_freelist_t *head; + drm_radeon_freelist_t *tail; + int last_buf; + volatile u32 *scratch; + + int usec_timeout; + int is_pci; + unsigned long phys_pci_gart; + dma_addr_t bus_pci_gart; + + atomic_t idle_count; + + int page_flipping; + int current_page; + u32 crtc_offset; + u32 crtc_offset_cntl; + + u32 color_fmt; + unsigned int front_offset; + unsigned int front_pitch; + unsigned int back_offset; + unsigned int back_pitch; + + u32 depth_fmt; + unsigned int depth_offset; + unsigned int depth_pitch; + + u32 front_pitch_offset; + u32 back_pitch_offset; + u32 depth_pitch_offset; + + 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_radeon_private_t; + +typedef struct drm_radeon_buf_priv { + u32 age; +} drm_radeon_buf_priv_t; + + /* radeon_cp.c */ +extern int radeon_cp_init( DRM_IOCTL_ARGS ); +extern int radeon_cp_start( DRM_IOCTL_ARGS ); +extern int radeon_cp_stop( DRM_IOCTL_ARGS ); +extern int radeon_cp_reset( DRM_IOCTL_ARGS ); +extern int radeon_cp_idle( DRM_IOCTL_ARGS ); +extern int radeon_engine_reset( DRM_IOCTL_ARGS ); +extern int radeon_fullscreen( DRM_IOCTL_ARGS ); +extern int radeon_cp_buffers( DRM_IOCTL_ARGS ); + +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 +radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) +{ + ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32); + if ( ring->space <= 0 ) + ring->space += ring->size; +} + +extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); +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( DRM_IOCTL_ARGS ); +extern int radeon_cp_swap( DRM_IOCTL_ARGS ); +extern int radeon_cp_vertex( DRM_IOCTL_ARGS ); +extern int radeon_cp_indices( DRM_IOCTL_ARGS ); +extern int radeon_cp_texture( DRM_IOCTL_ARGS ); +extern int radeon_cp_stipple( DRM_IOCTL_ARGS ); +extern int radeon_cp_indirect( DRM_IOCTL_ARGS ); +extern int radeon_cp_vertex2( DRM_IOCTL_ARGS ); +extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ); +extern int radeon_cp_getparam( DRM_IOCTL_ARGS ); +extern int radeon_cp_flip( DRM_IOCTL_ARGS ); + + + +/* Register definitions, register access macros and drmAddMap constants + * for Radeon kernel driver. + */ + +#define RADEON_AGP_COMMAND 0x0f60 +#define RADEON_AUX_SCISSOR_CNTL 0x26f0 +# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) +# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) +# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26) +# define RADEON_SCISSOR_0_ENABLE (1 << 28) +# define RADEON_SCISSOR_1_ENABLE (1 << 29) +# define RADEON_SCISSOR_2_ENABLE (1 << 30) + +#define RADEON_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) + +#define RADEON_CLOCK_CNTL_DATA 0x000c +# define RADEON_PLL_WR_EN (1 << 7) +#define RADEON_CLOCK_CNTL_INDEX 0x0008 +#define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CRTC_OFFSET 0x0224 +#define RADEON_CRTC_OFFSET_CNTL 0x0228 +# define RADEON_CRTC_TILE_EN (1 << 15) +# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) + +#define RADEON_RB3D_COLORPITCH 0x1c48 + +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define RADEON_GMC_BRUSH_NONE (15 << 4) +# define RADEON_GMC_DST_16BPP (4 << 8) +# define RADEON_GMC_DST_24BPP (5 << 8) +# define RADEON_GMC_DST_32BPP (6 << 8) +# define RADEON_GMC_DST_DATATYPE_SHIFT 8 +# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define RADEON_GMC_WR_MSK_DIS (1 << 30) +# define RADEON_ROP3_S 0x00cc0000 +# define RADEON_ROP3_P 0x00f00000 +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_DST_PITCH_OFFSET_C 0x1c80 +# define RADEON_DST_TILE_LINEAR (0 << 30) +# define RADEON_DST_TILE_MACRO (1 << 30) +# define RADEON_DST_TILE_MICRO (2 << 30) +# define RADEON_DST_TILE_BOTH (3 << 30) + +#define RADEON_SCRATCH_REG0 0x15e0 +#define RADEON_SCRATCH_REG1 0x15e4 +#define RADEON_SCRATCH_REG2 0x15e8 +#define RADEON_SCRATCH_REG3 0x15ec +#define RADEON_SCRATCH_REG4 0x15f0 +#define RADEON_SCRATCH_REG5 0x15f4 +#define RADEON_SCRATCH_UMSK 0x0770 +#define RADEON_SCRATCH_ADDR 0x0774 + +#define RADEON_HOST_PATH_CNTL 0x0130 +# define RADEON_HDP_SOFT_RESET (1 << 26) +# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) +# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) + +#define RADEON_ISYNC_CNTL 0x1724 +# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) +# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) +# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) +# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) +# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) +# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) + +#define RADEON_RBBM_GUICNTL 0x172c +# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) +# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) +# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) +# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) + +#define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_FB_LOCATION 0x0148 +#define RADEON_MCLK_CNTL 0x0012 +# define RADEON_FORCEON_MCLKA (1 << 16) +# define RADEON_FORCEON_MCLKB (1 << 17) +# define RADEON_FORCEON_YCLKA (1 << 18) +# define RADEON_FORCEON_YCLKB (1 << 19) +# define RADEON_FORCEON_MC (1 << 20) +# define RADEON_FORCEON_AIC (1 << 21) + +#define RADEON_PP_BORDER_COLOR_0 0x1d40 +#define RADEON_PP_BORDER_COLOR_1 0x1d44 +#define RADEON_PP_BORDER_COLOR_2 0x1d48 +#define RADEON_PP_CNTL 0x1c38 +# define RADEON_SCISSOR_ENABLE (1 << 1) +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +#define RADEON_PP_ROT_MATRIX_0 0x1d58 +#define RADEON_PP_TXFILTER_0 0x1c54 +#define RADEON_PP_TXFILTER_1 0x1c6c +#define RADEON_PP_TXFILTER_2 0x1c84 + +#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH (3 << 0) +# define RADEON_RB2D_DC_FREE (3 << 2) +# define RADEON_RB2D_DC_FLUSH_ALL 0xf +# define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_DITHER_ENABLE (1 << 2) +# define RADEON_ROUND_ENABLE (1 << 3) +# define RADEON_SCALE_DITHER_ENABLE (1 << 4) +# define RADEON_DITHER_INIT (1 << 5) +# define RADEON_ROP_ENABLE (1 << 6) +# define RADEON_STENCIL_ENABLE (1 << 7) +# define RADEON_Z_ENABLE (1 << 8) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +#define RADEON_RB3D_ZCACHE_MODE 0x3250 +#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 +# define RADEON_RB3D_ZC_FLUSH (1 << 0) +# define RADEON_RB3D_ZC_FREE (1 << 2) +# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 +# define RADEON_RB3D_ZC_BUSY (1 << 31) +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) +# define RADEON_Z_WRITE_ENABLE (1 << 30) +#define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) +#define RADEON_RBBM_STATUS 0x0e40 +# define RADEON_RBBM_FIFOCNT_MASK 0x007f +# define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_RE_LINE_PATTERN 0x1cd0 +#define RADEON_RE_MISC 0x26c4 +#define RADEON_RE_TOP_LEFT 0x26c0 +#define RADEON_RE_WIDTH_HEIGHT 0x1c44 +#define RADEON_RE_STIPPLE_ADDR 0x1cc8 +#define RADEON_RE_STIPPLE_DATA 0x1ccc + +#define RADEON_SCISSOR_TL_0 0x1cd8 +#define RADEON_SCISSOR_BR_0 0x1cdc +#define RADEON_SCISSOR_TL_1 0x1ce0 +#define RADEON_SCISSOR_BR_1 0x1ce4 +#define RADEON_SCISSOR_TL_2 0x1ce8 +#define RADEON_SCISSOR_BR_2 0x1cec +#define RADEON_SE_COORD_FMT 0x1c50 +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_FFACE_CULL_CW (0 << 0) +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) +# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) +# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) +# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_FOG_SHADE_FLAT (1 << 14) +# define RADEON_FOG_SHADE_GOURAUD (2 << 14) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) +# define RADEON_ROUND_MODE_TRUNC (0 << 28) +# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) +#define RADEON_SE_CNTL_STATUS 0x2140 +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_ZBIAS_FACTOR 0x1db0 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200 +# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 +# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 +#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204 +#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208 +# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 +#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C +#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 +#define RADEON_SURFACE_ACCESS_CLR 0x0bfc +#define RADEON_SURFACE_CNTL 0x0b00 +# define RADEON_SURF_TRANSLATION_DIS (1 << 8) +# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20) +# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20) +# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20) +# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20) +# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22) +# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22) +# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22) +# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22) +#define RADEON_SURFACE0_INFO 0x0b0c +# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0) +# define RADEON_SURF_TILE_MODE_MASK (3 << 16) +# define RADEON_SURF_TILE_MODE_MACRO (0 << 16) +# define RADEON_SURF_TILE_MODE_MICRO (1 << 16) +# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16) +# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16) +#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 +#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 +#define RADEON_SURFACE1_INFO 0x0b1c +#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 +#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 +#define RADEON_SURFACE2_INFO 0x0b2c +#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 +#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 +#define RADEON_SURFACE3_INFO 0x0b3c +#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 +#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SURFACE4_INFO 0x0b4c +#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 +#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 +#define RADEON_SURFACE5_INFO 0x0b5c +#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 +#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 +#define RADEON_SURFACE6_INFO 0x0b6c +#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 +#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 +#define RADEON_SURFACE7_INFO 0x0b7c +#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 +#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 +#define RADEON_SW_SEMAPHORE 0x013c + +#define RADEON_WAIT_UNTIL 0x1720 +# define RADEON_WAIT_CRTC_PFLIP (1 << 0) +# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) +# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) +# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) + +#define RADEON_RB3D_ZMASKOFFSET 0x1c34 +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) + + +/* CP registers */ +#define RADEON_CP_ME_RAM_ADDR 0x07d4 +#define RADEON_CP_ME_RAM_RADDR 0x07d8 +#define RADEON_CP_ME_RAM_DATAH 0x07dc +#define RADEON_CP_ME_RAM_DATAL 0x07e0 + +#define RADEON_CP_RB_BASE 0x0700 +#define RADEON_CP_RB_CNTL 0x0704 +# define RADEON_BUF_SWAP_32BIT (2 << 16) +#define RADEON_CP_RB_RPTR_ADDR 0x070c +#define RADEON_CP_RB_RPTR 0x0710 +#define RADEON_CP_RB_WPTR 0x0714 + +#define RADEON_CP_RB_WPTR_DELAY 0x0718 +# define RADEON_PRE_WRITE_TIMER_SHIFT 0 +# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + +#define RADEON_CP_IB_BASE 0x0738 + +#define RADEON_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) + +#define RADEON_AIC_CNTL 0x01d0 +# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) +#define RADEON_AIC_STAT 0x01d4 +#define RADEON_AIC_PT_BASE 0x01d8 +#define RADEON_AIC_LO_ADDR 0x01dc +#define RADEON_AIC_HI_ADDR 0x01e0 +#define RADEON_AIC_TLB_ADDR 0x01e4 +#define RADEON_AIC_TLB_DATA 0x01e8 + +/* CP command packets */ +#define RADEON_CP_PACKET0 0x00000000 +# define RADEON_ONE_REG_WR (1 << 15) +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 +#define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 +# define RADEON_WAIT_FOR_IDLE 0x00002600 +# define RADEON_3D_DRAW_VBUF 0x00002800 +# define RADEON_3D_DRAW_IMMD 0x00002900 +# define RADEON_3D_DRAW_INDX 0x00002A00 +# define RADEON_3D_LOAD_VBPNTR 0x00002F00 +# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 +# define RADEON_CNTL_PAINT_MULTI 0x00009A00 +# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 +# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 + +#define RADEON_CP_PACKET_MASK 0xC0000000 +#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 +#define RADEON_CP_PACKET0_REG_MASK 0x000007ff +#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff +#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_VTX_Z_PRESENT (1 << 31) +#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3) + +#define RADEON_PRIM_TYPE_NONE (0 << 0) +#define RADEON_PRIM_TYPE_POINT (1 << 0) +#define RADEON_PRIM_TYPE_LINE (2 << 0) +#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0) +#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0) +#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0) +#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0) +#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0) +#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) +#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) +#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) +#define RADEON_PRIM_TYPE_MASK 0xf +#define RADEON_PRIM_WALK_IND (1 << 4) +#define RADEON_PRIM_WALK_LIST (2 << 4) +#define RADEON_PRIM_WALK_RING (3 << 4) +#define RADEON_COLOR_ORDER_BGRA (0 << 6) +#define RADEON_COLOR_ORDER_RGBA (1 << 6) +#define RADEON_MAOS_ENABLE (1 << 7) +#define RADEON_VTX_FMT_R128_MODE (0 << 8) +#define RADEON_VTX_FMT_RADEON_MODE (1 << 8) +#define RADEON_NUM_VERTICES_SHIFT 16 + +#define RADEON_COLOR_FORMAT_CI8 2 +#define RADEON_COLOR_FORMAT_ARGB1555 3 +#define RADEON_COLOR_FORMAT_RGB565 4 +#define RADEON_COLOR_FORMAT_ARGB8888 6 +#define RADEON_COLOR_FORMAT_RGB332 7 +#define RADEON_COLOR_FORMAT_RGB8 9 +#define RADEON_COLOR_FORMAT_ARGB4444 15 + +#define RADEON_TXFORMAT_I8 0 +#define RADEON_TXFORMAT_AI88 1 +#define RADEON_TXFORMAT_RGB332 2 +#define RADEON_TXFORMAT_ARGB1555 3 +#define RADEON_TXFORMAT_RGB565 4 +#define RADEON_TXFORMAT_ARGB4444 5 +#define RADEON_TXFORMAT_ARGB8888 6 +#define RADEON_TXFORMAT_RGBA8888 7 + +/* Constants */ +#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ + +#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 +#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 +#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 +#define RADEON_LAST_DISPATCH 1 + +#define RADEON_MAX_VB_AGE 0x7fffffff +#define RADEON_MAX_VB_VERTS (0xffff) + +#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_WRITE_PLL( addr, val ) \ +do { \ + RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \ + ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ + RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ +} while (0) + +extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); + + +#define CP_PACKET0( reg, n ) \ + (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET0_TABLE( reg, n ) \ + (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET1( reg0, reg1 ) \ + (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2)) +#define CP_PACKET2() \ + (RADEON_CP_PACKET2) +#define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + + +/* ================================================================ + * Engine control helper macros + */ + +#define RADEON_WAIT_UNTIL_2D_IDLE() do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_3D_IDLE() do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_IDLE() do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ +} while (0) + +#define RADEON_FLUSH_CACHE() do { \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH ); \ +} while (0) + +#define RADEON_PURGE_CACHE() do { \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ +} while (0) + +#define RADEON_FLUSH_ZCACHE() do { \ + OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ +} while (0) + +#define RADEON_PURGE_ZCACHE() do { \ + OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ +} while (0) + + +/* ================================================================ + * 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", __func__ ); \ + return DRM_ERR(EINVAL); \ + } \ +} while (0) + +#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \ + if ( ring->space < ring->high_mark ) { \ + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ + radeon_update_ring_snapshot( ring ); \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + DRM_UDELAY( 1 ); \ + } \ + DRM_ERROR( "ring space check from memory failed, reading register...\n" ); \ + /* If ring space check fails from RAM, try reading the \ + register directly */ \ + ring->space = 4 * ( RADEON_READ( RADEON_CP_RB_RPTR ) - ring->tail ); \ + if ( ring->space <= 0 ) \ + ring->space += ring->size; \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + \ + DRM_ERROR( "ring space check failed!\n" ); \ + return DRM_ERR(EBUSY); \ + } \ + __ring_space_done: \ + ; \ +} while (0) + +#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ + if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ + int __ret = radeon_do_cp_idle( dev_priv ); \ + if ( __ret ) return __ret; \ + sarea_priv->last_dispatch = 0; \ + radeon_freelist_reset( dev ); \ + } \ +} while (0) + +#define RADEON_DISPATCH_AGE( age ) do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + +#define RADEON_FRAME_AGE( age ) do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + +#define RADEON_CLEAR_AGE( age ) do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + + +/* ================================================================ + * Ring control + */ + +#if defined(__powerpc__) +#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else +#define radeon_flush_write_combine() DRM_WRITEMEMORYBARRIER() +#endif + + +#define RADEON_VERBOSE 0 + +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; + +#define BEGIN_RING( n ) do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ + n, __func__ ); \ + } \ + if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + COMMIT_RING(); \ + radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ + } \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ + ring = dev_priv->ring.start; \ + write = dev_priv->ring.tail; \ + mask = dev_priv->ring.tail_mask; \ +} while (0) + +#define ADVANCE_RING() do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ + write, dev_priv->ring.tail ); \ + } \ + if (((dev_priv->ring.tail + _nr) & mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x\n", \ + ((dev_priv->ring.tail + _nr) & mask), \ + write); \ + } else \ + dev_priv->ring.tail = write; \ +} while (0) + +#define COMMIT_RING() do { \ + radeon_flush_write_combine(); \ + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ +} while (0) + +#define OUT_RING( x ) do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ + (unsigned int)(x), write ); \ + } \ + ring[write++] = (x); \ + write &= mask; \ +} while (0) + +#define OUT_RING_REG( reg, val ) do { \ + OUT_RING( CP_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + + +#define OUT_RING_USER_TABLE( tab, sz ) do { \ + int _size = (sz); \ + int *_tab = (tab); \ + \ + if (write + _size > mask) { \ + int i = (mask+1) - write; \ + if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ + _tab, i*4 )) \ + return DRM_ERR(EFAULT); \ + write = 0; \ + _size -= i; \ + _tab += i; \ + } \ + \ + if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ + _tab, _size*4 )) \ + return DRM_ERR(EFAULT); \ + \ + write += _size; \ + write &= mask; \ +} while (0) + + +#define RADEON_PERFORMANCE_BOXES 0 + +#endif /* __RADEON_DRV_H__ */ diff --git a/shared/radeon_state.c b/shared/radeon_state.c new file mode 100644 index 00000000..83fae493 --- /dev/null +++ b/shared/radeon_state.c @@ -0,0 +1,1856 @@ +/* radeon_state.c -- State support for Radeon -*- linux-c -*- + * + * Copyright 2000 VA Linux Systems, Inc., Fremont, 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> + * Kevin E. Martin <martin@valinux.com> + */ + +#include "radeon.h" +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" + + +/* ================================================================ + * CP hardware state programming functions + */ + +static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, + drm_clip_rect_t *box ) +{ + RING_LOCALS; + + DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", + box->x1, box->y1, box->x2, box->y2 ); + + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); + OUT_RING( (box->y1 << 16) | box->x1 ); + OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); +/* OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );*/ + OUT_RING( (box->y2 << 16) | box->x2 ); + ADVANCE_RING(); +} + +/* Emit 1.1 state + */ +static void radeon_emit_state( drm_radeon_private_t *dev_priv, + drm_radeon_context_regs_t *ctx, + drm_radeon_texture_regs_t *tex, + unsigned int dirty ) +{ + RING_LOCALS; + DRM_DEBUG( "dirty=0x%08x\n", dirty ); + + if ( dirty & RADEON_UPLOAD_CONTEXT ) { + BEGIN_RING( 14 ); + OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); + OUT_RING( ctx->pp_misc ); + OUT_RING( ctx->pp_fog_color ); + OUT_RING( ctx->re_solid_color ); + OUT_RING( ctx->rb3d_blendcntl ); + OUT_RING( ctx->rb3d_depthoffset ); + OUT_RING( ctx->rb3d_depthpitch ); + OUT_RING( ctx->rb3d_zstencilcntl ); + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); + OUT_RING( ctx->pp_cntl ); + OUT_RING( ctx->rb3d_cntl ); + OUT_RING( ctx->rb3d_coloroffset ); + OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); + OUT_RING( ctx->rb3d_colorpitch ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_VERTFMT ) { + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); + OUT_RING( ctx->se_coord_fmt ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_LINE ) { + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); + OUT_RING( ctx->re_line_pattern ); + OUT_RING( ctx->re_line_state ); + OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); + OUT_RING( ctx->se_line_width ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_BUMPMAP ) { + BEGIN_RING( 5 ); + OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); + OUT_RING( ctx->pp_lum_matrix ); + OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); + OUT_RING( ctx->pp_rot_matrix_0 ); + OUT_RING( ctx->pp_rot_matrix_1 ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_MASKS ) { + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); + OUT_RING( ctx->rb3d_stencilrefmask ); + OUT_RING( ctx->rb3d_ropcntl ); + OUT_RING( ctx->rb3d_planemask ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_VIEWPORT ) { + BEGIN_RING( 7 ); + OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); + OUT_RING( ctx->se_vport_xscale ); + OUT_RING( ctx->se_vport_xoffset ); + OUT_RING( ctx->se_vport_yscale ); + OUT_RING( ctx->se_vport_yoffset ); + OUT_RING( ctx->se_vport_zscale ); + OUT_RING( ctx->se_vport_zoffset ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_SETUP ) { + BEGIN_RING( 4 ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); + OUT_RING( ctx->se_cntl_status ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_MISC ) { + BEGIN_RING( 2 ); + OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); + OUT_RING( ctx->re_misc ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_TEX0 ) { + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); + OUT_RING( tex[0].pp_txfilter ); + OUT_RING( tex[0].pp_txformat ); + OUT_RING( tex[0].pp_txoffset ); + OUT_RING( tex[0].pp_txcblend ); + OUT_RING( tex[0].pp_txablend ); + OUT_RING( tex[0].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); + OUT_RING( tex[0].pp_border_color ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_TEX1 ) { + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); + OUT_RING( tex[1].pp_txfilter ); + OUT_RING( tex[1].pp_txformat ); + OUT_RING( tex[1].pp_txoffset ); + OUT_RING( tex[1].pp_txcblend ); + OUT_RING( tex[1].pp_txablend ); + OUT_RING( tex[1].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); + OUT_RING( tex[1].pp_border_color ); + ADVANCE_RING(); + } + + if ( dirty & RADEON_UPLOAD_TEX2 ) { + BEGIN_RING( 9 ); + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); + OUT_RING( tex[2].pp_txfilter ); + OUT_RING( tex[2].pp_txformat ); + OUT_RING( tex[2].pp_txoffset ); + OUT_RING( tex[2].pp_txcblend ); + OUT_RING( tex[2].pp_txablend ); + OUT_RING( tex[2].pp_tfactor ); + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); + OUT_RING( tex[2].pp_border_color ); + ADVANCE_RING(); + } +} + +/* Emit 1.2 state + */ +static void radeon_emit_state2( drm_radeon_private_t *dev_priv, + drm_radeon_state_t *state ) +{ + RING_LOCALS; + + if (state->dirty & RADEON_UPLOAD_ZBIAS) { + BEGIN_RING( 3 ); + OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) ); + OUT_RING( state->context2.se_zbias_factor ); + OUT_RING( state->context2.se_zbias_constant ); + ADVANCE_RING(); + } + + radeon_emit_state( dev_priv, &state->context, + state->tex, state->dirty ); +} + +/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in + * 1.3 cmdbuffers allow all previous state to be updated as well as + * the tcl scalar and vector areas. + */ +static struct { + int start; + int len; + const char *name; +} packet[RADEON_MAX_STATE_PACKETS] = { + { RADEON_PP_MISC,7,"RADEON_PP_MISC" }, + { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" }, + { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" }, + { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" }, + { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" }, + { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" }, + { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" }, + { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" }, + { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" }, + { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" }, + { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" }, + { RADEON_RE_MISC,1,"RADEON_RE_MISC" }, + { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" }, + { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" }, + { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" }, + { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" }, + { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" }, + { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" }, + { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" }, + { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" }, + { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" }, +}; + + + + + + + + + + +#if RADEON_PERFORMANCE_BOXES +/* ================================================================ + * Performance monitoring functions + */ + +static void radeon_clear_box( drm_radeon_private_t *dev_priv, + int x, int y, int w, int h, + int r, int g, int b ) +{ + u32 pitch, offset; + u32 color; + RING_LOCALS; + + switch ( dev_priv->color_fmt ) { + case RADEON_COLOR_FORMAT_RGB565: + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + break; + case RADEON_COLOR_FORMAT_ARGB8888: + default: + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + break; + } + + offset = dev_priv->back_offset; + pitch = dev_priv->back_pitch >> 3; + + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( (pitch << 22) | (offset >> 5) ); + OUT_RING( color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); +} + +static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) +{ + if ( atomic_read( &dev_priv->idle_count ) == 0 ) { + radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + } else { + atomic_set( &dev_priv->idle_count, 0 ); + } +} + +#endif + + +/* ================================================================ + * CP command dispatch functions + */ + +static void radeon_cp_dispatch_clear( drm_device_t *dev, + drm_radeon_clear_t *clear, + drm_radeon_clear_rect_t *depth_boxes ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + unsigned int flags = clear->flags; + u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0; + int i; + RING_LOCALS; + DRM_DEBUG( "flags = 0x%x\n", flags ); + + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(RADEON_FRONT | RADEON_BACK); + if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; + if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; + } + + /* We have to clear the depth and/or stencil buffers by + * rendering a quad into just those buffers. Thus, we have to + * make sure the 3D engine is configured correctly. + */ + if ( flags & (RADEON_DEPTH | RADEON_STENCIL) ) { + rb3d_cntl = depth_clear->rb3d_cntl; + + if ( flags & RADEON_DEPTH ) { + rb3d_cntl |= RADEON_Z_ENABLE; + } else { + rb3d_cntl &= ~RADEON_Z_ENABLE; + } + + if ( flags & RADEON_STENCIL ) { + rb3d_cntl |= RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ + } else { + rb3d_cntl &= ~RADEON_STENCIL_ENABLE; + rb3d_stencilrefmask = 0x00000000; + } + } + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", + x, y, w, h, flags ); + + if ( flags & (RADEON_FRONT | RADEON_BACK) ) { + BEGIN_RING( 4 ); + + /* Ensure the 3D stream is idle before doing a + * 2D fill to clear the front or back buffer. + */ + RADEON_WAIT_UNTIL_3D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( clear->color_mask ); + + ADVANCE_RING(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; + } + + if ( flags & RADEON_FRONT ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & RADEON_BACK ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & (RADEON_DEPTH | RADEON_STENCIL) ) { + + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + + BEGIN_RING( 28 ); + + RADEON_WAIT_UNTIL_2D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); + OUT_RING( 0x00000000 ); + OUT_RING( rb3d_cntl ); + + OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL, + depth_clear->rb3d_zstencilcntl ); + OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, + rb3d_stencilrefmask ); + OUT_RING_REG( RADEON_RB3D_PLANEMASK, + 0x00000000 ); + OUT_RING_REG( RADEON_SE_CNTL, + depth_clear->se_cntl ); + + /* Radeon 7500 doesn't like vertices without + * color. + */ + OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) ); + OUT_RING( RADEON_VTX_Z_PRESENT | + RADEON_VTX_PKCOLOR_PRESENT); + OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + RADEON_MAOS_ENABLE | + RADEON_VTX_FMT_RADEON_MODE | + (3 << RADEON_NUM_VERTICES_SHIFT)) ); + + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); + + OUT_RING( depth_boxes[i].ui[CLEAR_X1] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); + + OUT_RING( depth_boxes[i].ui[CLEAR_X2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_Y2] ); + OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] ); + OUT_RING( 0x0 ); + + ADVANCE_RING(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->ctx_owner = 0; + } + } + + /* Increment the clear counter. The client-side 3D driver must + * wait on this value before performing the clear ioctl. We + * need this because the card's so damned fast... + */ + dev_priv->sarea_priv->last_clear++; + + BEGIN_RING( 4 ); + + RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); +} + +static void radeon_cp_dispatch_swap( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int i; + RING_LOCALS; + DRM_DEBUG( "\n" ); + +#if RADEON_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + radeon_cp_performance_boxes( dev_priv ); +#endif + + /* Wait for the 3D stream to idle before dispatching the bitblt. + * This will prevent data corruption between the two streams. + */ + BEGIN_RING( 2 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); + + ADVANCE_RING(); + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n", + x, y, w, h ); + + BEGIN_RING( 7 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); + OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS ); + + /* Make this work even if front & back are flipped: + */ + if (dev_priv->current_page == 0) { + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( dev_priv->front_pitch_offset ); + } + else { + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( dev_priv->back_pitch_offset ); + } + + OUT_RING( (x << 16) | y ); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 4 ); + + RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + RADEON_WAIT_UNTIL_2D_IDLE(); + + ADVANCE_RING(); +} + +static void radeon_cp_dispatch_flip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG( "page=%d\n", dev_priv->current_page ); + +#if RADEON_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + radeon_cp_performance_boxes( dev_priv ); +#endif + + BEGIN_RING( 4 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); +/* + RADEON_WAIT_UNTIL_PAGE_FLIPPED(); +*/ + OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 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; + } + + ADVANCE_RING(); + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; + + BEGIN_RING( 2 ); + + RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + + ADVANCE_RING(); +} + +static int bad_prim_vertex_nr( int primitive, int nr ) +{ + switch (primitive & RADEON_PRIM_TYPE_MASK) { + case RADEON_PRIM_TYPE_NONE: + case RADEON_PRIM_TYPE_POINT: + return nr < 1; + case RADEON_PRIM_TYPE_LINE: + return (nr & 1) || nr == 0; + case RADEON_PRIM_TYPE_LINE_STRIP: + return nr < 2; + case RADEON_PRIM_TYPE_TRI_LIST: + case RADEON_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_PRIM_TYPE_RECT_LIST: + return nr % 3 || nr == 0; + case RADEON_PRIM_TYPE_TRI_FAN: + case RADEON_PRIM_TYPE_TRI_STRIP: + return nr < 3; + default: + return 1; + } +} + + + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim; + unsigned int numverts; + unsigned int offset; + unsigned int vc_format; +} drm_radeon_tcl_prim_t; + +static void radeon_cp_dispatch_vertex( drm_device_t *dev, + drm_buf_t *buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) + +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start; + int numverts = (int)prim->numverts; + int i = 0; + RING_LOCALS; + + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, prim->numverts )) { + DRM_ERROR( "bad prim %x numverts %d\n", + prim->prim, prim->numverts ); + return; + } + + do { + /* Emit the next cliprect */ + if ( i < nbox ) { + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) + return; + + radeon_emit_clip_rect( dev_priv, &box ); + } + + /* Emit the vertex buffer rendering commands */ + BEGIN_RING( 5 ); + + OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); + OUT_RING( offset ); + OUT_RING( numverts ); + OUT_RING( prim->vc_format ); + OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (numverts << RADEON_NUM_VERTICES_SHIFT) ); + + ADVANCE_RING(); + + i++; + } while ( i < nbox ); +} + + + +static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + RING_LOCALS; + + buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); + + buf->pending = 1; + buf->used = 0; +} + +static void radeon_cp_dispatch_indirect( drm_device_t *dev, + drm_buf_t *buf, + int start, int end ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", + buf->idx, start, end ); + + if ( start != end ) { + int offset = (dev_priv->agp_buffers_offset + + buf->offset + start); + int dwords = (end - start + 3) / sizeof(u32); + + /* Indirect buffer data must be an even number of + * dwords, so if we've been given an odd number we must + * pad the data with a Type-2 CP packet. + */ + if ( dwords & 1 ) { + u32 *data = (u32 *) + ((char *)dev_priv->buffers->handle + + buf->offset + start); + data[dwords++] = RADEON_CP_PACKET2; + } + + /* Fire off the indirect buffer */ + BEGIN_RING( 3 ); + + OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) ); + OUT_RING( offset ); + OUT_RING( dwords ); + + ADVANCE_RING(); + } +} + + +static void radeon_cp_dispatch_indices( drm_device_t *dev, + drm_buf_t *elt_buf, + drm_radeon_tcl_prim_t *prim, + drm_clip_rect_t *boxes, + int nbox ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_clip_rect_t box; + int offset = dev_priv->agp_buffers_offset + prim->offset; + u32 *data; + int dwords; + int i = 0; + int start = prim->start + RADEON_INDEX_PRIM_OFFSET; + int count = (prim->finish - start) / sizeof(u16); + + DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", + prim->prim, + prim->vc_format, + prim->start, + prim->finish, + prim->offset, + prim->numverts); + + if (bad_prim_vertex_nr( prim->prim, count )) { + DRM_ERROR( "bad prim %x count %d\n", + prim->prim, count ); + return; + } + + + if ( start >= prim->finish || + (prim->start & 0x7) ) { + DRM_ERROR( "buffer prim %d\n", prim->prim ); + return; + } + + dwords = (prim->finish - prim->start + 3) / sizeof(u32); + + data = (u32 *)((char *)dev_priv->buffers->handle + + elt_buf->offset + prim->start); + + data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); + data[1] = offset; + data[2] = prim->numverts; + data[3] = prim->vc_format; + data[4] = (prim->prim | + RADEON_PRIM_WALK_IND | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (count << RADEON_NUM_VERTICES_SHIFT) ); + + do { + if ( i < nbox ) { + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) + return; + + radeon_emit_clip_rect( dev_priv, &box ); + } + + radeon_cp_dispatch_indirect( dev, elt_buf, + prim->start, + prim->finish ); + + i++; + } while ( i < nbox ); + +} + +#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) + +static int radeon_cp_dispatch_texture( drm_device_t *dev, + drm_radeon_texture_t *tex, + drm_radeon_tex_image_t *image ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_buf_t *buf; + u32 format; + u32 *buffer; + const u8 *data; + int size, dwords, tex_width, blit_width; + u32 y, height; + int ret = 0, i; + RING_LOCALS; + + /* FIXME: Be smarter about this... + */ + buf = radeon_freelist_get( dev ); + if ( !buf ) return DRM_ERR(EAGAIN); + + DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + tex->offset >> 10, tex->pitch, tex->format, + image->x, image->y, image->width, image->height ); + + /* The compiler won't optimize away a division by a variable, + * even if the only legal values are powers of two. Thus, we'll + * use a shift instead. + */ + switch ( tex->format ) { + case RADEON_TXFORMAT_ARGB8888: + case RADEON_TXFORMAT_RGBA8888: + format = RADEON_COLOR_FORMAT_ARGB8888; + tex_width = tex->width * 4; + blit_width = image->width * 4; + break; + case RADEON_TXFORMAT_AI88: + case RADEON_TXFORMAT_ARGB1555: + case RADEON_TXFORMAT_RGB565: + case RADEON_TXFORMAT_ARGB4444: + format = RADEON_COLOR_FORMAT_RGB565; + tex_width = tex->width * 2; + blit_width = image->width * 2; + break; + case RADEON_TXFORMAT_I8: + case RADEON_TXFORMAT_RGB332: + format = RADEON_COLOR_FORMAT_CI8; + tex_width = tex->width * 1; + blit_width = image->width * 1; + break; + default: + DRM_ERROR( "invalid texture format %d\n", tex->format ); + return DRM_ERR(EINVAL); + } + + DRM_DEBUG( " tex=%dx%d blit=%d\n", + tex_width, tex->height, blit_width ); + + /* Flush the pixel cache. This ensures no pixel data gets mixed + * up with the texture data from the host data blit, otherwise + * part of the texture image may be corrupted. + */ + BEGIN_RING( 4 ); + + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); + +#ifdef __BIG_ENDIAN + /* The Mesa texture functions provide the data in little endian as the + * chip wants it, but we need to compensate for the fact that the CP + * ring gets byte-swapped + */ + BEGIN_RING( 2 ); + OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); + ADVANCE_RING(); +#endif + + /* Make a copy of the parameters in case we have to update them + * for a multi-pass texture blit. + */ + y = image->y; + height = image->height; + data = (const u8 *)image->data; + + size = height * blit_width; + + if ( size > RADEON_MAX_TEXTURE_SIZE ) { + /* Texture image is too large, do a multipass upload */ + ret = DRM_ERR(EAGAIN); + + /* Adjust the blit size to fit the indirect buffer */ + height = RADEON_MAX_TEXTURE_SIZE / blit_width; + size = height * blit_width; + + /* Update the input parameters for next time */ + image->y += height; + image->height -= height; + image->data = (const char *)image->data + size; + + if ( DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ) ) { + DRM_ERROR( "EFAULT on tex->image\n" ); + return DRM_ERR(EFAULT); + } + } else if ( size < 4 && size > 0 ) { + size = 4; + } + + dwords = size / 4; + + /* Dispatch the indirect buffer. + */ + buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); + + buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); + buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (format << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_HOST_DATA | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS); + + buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); + buffer[3] = 0xffffffff; + buffer[4] = 0xffffffff; + buffer[5] = (y << 16) | image->x; + buffer[6] = (height << 16) | image->width; + buffer[7] = dwords; + + buffer += 8; + + if ( tex_width >= 32 ) { + /* Texture image width is larger than the minimum, so we + * can upload it directly. + */ + if ( DRM_COPY_FROM_USER( buffer, data, dwords * sizeof(u32) ) ) { + DRM_ERROR( "EFAULT on data, %d dwords\n", dwords ); + return DRM_ERR(EFAULT); + } + } else { + /* Texture image width is less than the minimum, so we + * need to pad out each image scanline to the minimum + * width. + */ + for ( i = 0 ; i < tex->height ; i++ ) { + if ( DRM_COPY_FROM_USER( buffer, data, tex_width ) ) { + DRM_ERROR( "EFAULT on pad, %d bytes\n", + tex_width ); + return DRM_ERR(EFAULT); + } + buffer += 8; + data += tex_width; + } + } + + buf->pid = DRM_CURRENTPID; + buf->used = (dwords + 8) * sizeof(u32); + + radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + radeon_cp_discard_buffer( dev, buf ); + + /* Flush the pixel cache after the blit completes. This ensures + * the texture data is written out to memory before rendering + * continues. + */ + BEGIN_RING( 4 ); + + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_2D_IDLE(); + + ADVANCE_RING(); + + return ret; +} + +static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + DRM_DEBUG( "\n" ); + + BEGIN_RING( 35 ); + + OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) ); + OUT_RING( 0x00000000 ); + + OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) ); + for ( i = 0 ; i < 32 ; i++ ) { + OUT_RING( stipple[i] ); + } + + ADVANCE_RING(); +} + + +/* ================================================================ + * IOCTL functions + */ + +int radeon_cp_clear( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_clear_t clear; + drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data, + sizeof(clear) ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes, + sarea_priv->nbox * sizeof(depth_boxes[0]) ) ) + return DRM_ERR(EFAULT); + + radeon_cp_dispatch_clear( dev, &clear, depth_boxes ); + + COMMIT_RING(); + return 0; +} + + + +/* Not sure why this isn't set all the time: + */ +static int radeon_do_init_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + DRM_DEBUG( "\n" ); + + dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); + + BEGIN_RING( 4 ); + RADEON_WAIT_UNTIL_3D_IDLE(); + OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) ); + OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL ); + ADVANCE_RING(); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; + + return 0; +} + +int radeon_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + if (dev_priv->current_page != 0) + radeon_cp_dispatch_flip( dev ); + + /* FIXME: If the X server changes screen resolution, it + * clobbers the value of RADEON_CRTC_OFFSET_CNTL, above, + * leading to a flashing efect. + */ + dev_priv->page_flipping = 0; + return 0; +} + +/* Swapping and flipping are different operations, need different ioctls. + * They can & should be intermixed to support multiple 3d windows. + */ +int radeon_cp_flip( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if (!dev_priv->page_flipping) + radeon_do_init_pageflip( dev ); + + radeon_cp_dispatch_flip( dev ); + + COMMIT_RING(); + return 0; +} + +int radeon_cp_swap( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + DRM_DEBUG( "\n" ); + + LOCK_TEST_WITH_RETURN( dev ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + radeon_cp_dispatch_swap( dev ); + dev_priv->sarea_priv->ctx_owner = 0; + + COMMIT_RING(); + return 0; +} + +int radeon_cp_vertex( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_vertex_t vertex; + drm_radeon_tcl_prim_t prim; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data, + sizeof(vertex) ); + + DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n", + DRM_CURRENTPID, + vertex.idx, vertex.count, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + if ( vertex.prim < 0 || + vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + DRM_ERROR( "buffer prim %d\n", vertex.prim ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf = dma->buflist[vertex.idx]; + + if ( buf->pid != DRM_CURRENTPID ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return DRM_ERR(EINVAL); + } + + /* Build up a prim_t record: + */ + if (vertex.count) { + buf->used = vertex.count; /* not used? */ + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + prim.start = 0; + prim.finish = vertex.count; /* unused */ + prim.prim = vertex.prim; + prim.numverts = vertex.count; + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_vertex( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + } + + if (vertex.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + + COMMIT_RING(); + return 0; +} + +int radeon_cp_indices( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_indices_t elts; + drm_radeon_tcl_prim_t prim; + int count; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data, + sizeof(elts) ); + + DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n", + DRM_CURRENTPID, + elts.idx, elts.start, elts.end, elts.discard ); + + if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + elts.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + if ( elts.prim < 0 || + elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + DRM_ERROR( "buffer prim %d\n", elts.prim ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf = dma->buflist[elts.idx]; + + if ( buf->pid != DRM_CURRENTPID ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", elts.idx ); + return DRM_ERR(EINVAL); + } + + count = (elts.end - elts.start) / sizeof(u16); + elts.start -= RADEON_INDEX_PRIM_OFFSET; + + if ( elts.start & 0x7 ) { + DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + return DRM_ERR(EINVAL); + } + if ( elts.start < buf->used ) { + DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); + return DRM_ERR(EINVAL); + } + + buf->used = elts.end; + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } + + + /* Build up a prim_t record: + */ + prim.start = elts.start; + prim.finish = elts.end; + prim.prim = elts.prim; + prim.offset = 0; /* offset from start of dma buffers */ + prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + prim.vc_format = dev_priv->sarea_priv->vc_format; + + radeon_cp_dispatch_indices( dev, buf, &prim, + dev_priv->sarea_priv->boxes, + dev_priv->sarea_priv->nbox ); + if (elts.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + + COMMIT_RING(); + return 0; +} + +int radeon_cp_texture( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_texture_t tex; + drm_radeon_tex_image_t image; + int ret; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) ); + + if ( tex.image == NULL ) { + DRM_ERROR( "null texture image!\n" ); + return DRM_ERR(EINVAL); + } + + if ( DRM_COPY_FROM_USER( &image, + (drm_radeon_tex_image_t *)tex.image, + sizeof(image) ) ) + return DRM_ERR(EFAULT); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + ret = radeon_cp_dispatch_texture( dev, &tex, &image ); + + COMMIT_RING(); + return ret; +} + +int radeon_cp_stipple( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_stipple_t stipple; + u32 mask[32]; + + LOCK_TEST_WITH_RETURN( dev ); + + DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data, + sizeof(stipple) ); + + if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) ) + return DRM_ERR(EFAULT); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + radeon_cp_dispatch_stipple( dev, mask ); + + COMMIT_RING(); + return 0; +} + +int radeon_cp_indirect( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_indirect_t indirect; + RING_LOCALS; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t *)data, + sizeof(indirect) ); + + DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, + indirect.end, indirect.discard ); + + if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + + buf = dma->buflist[indirect.idx]; + + if ( buf->pid != DRM_CURRENTPID ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + return DRM_ERR(EINVAL); + } + + if ( indirect.start < buf->used ) { + DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf->used = indirect.end; + + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING( 2 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); + + ADVANCE_RING(); + + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ + radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + if (indirect.discard) { + radeon_cp_discard_buffer( dev, buf ); + } + + + COMMIT_RING(); + return 0; +} + +int radeon_cp_vertex2( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_vertex2_t vertex; + int i; + unsigned char laststate; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, + sizeof(vertex) ); + + DRM_DEBUG( "pid=%d index=%d discard=%d\n", + DRM_CURRENTPID, + vertex.idx, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + buf = dma->buflist[vertex.idx]; + + if ( buf->pid != DRM_CURRENTPID ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); + } + + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return DRM_ERR(EINVAL); + } + + if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) + return DRM_ERR(EINVAL); + + for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { + drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t tclprim; + + if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) ) + return DRM_ERR(EFAULT); + + if ( prim.stateidx != laststate ) { + drm_radeon_state_t state; + + if ( DRM_COPY_FROM_USER( &state, + &vertex.state[prim.stateidx], + sizeof(state) ) ) + return DRM_ERR(EFAULT); + + radeon_emit_state2( dev_priv, &state ); + + laststate = prim.stateidx; + } + + tclprim.start = prim.start; + tclprim.finish = prim.finish; + tclprim.prim = prim.prim; + tclprim.vc_format = prim.vc_format; + + if ( prim.prim & RADEON_PRIM_WALK_IND ) { + tclprim.offset = prim.numverts * 64; + tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ + + radeon_cp_dispatch_indices( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } else { + tclprim.numverts = prim.numverts; + tclprim.offset = 0; /* not used */ + + radeon_cp_dispatch_vertex( dev, buf, &tclprim, + sarea_priv->boxes, + sarea_priv->nbox); + } + + if (sarea_priv->nbox == 1) + sarea_priv->nbox = 0; + } + + if ( vertex.discard ) { + radeon_cp_discard_buffer( dev, buf ); + } + + COMMIT_RING(); + return 0; +} + + +static int radeon_emit_packets( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int id = (int)header.packet.packet_id; + int sz = packet[id].len; + int reg = packet[id].start; + int *data = (int *)cmdbuf->buf; + RING_LOCALS; + + if (sz * sizeof(int) > cmdbuf->bufsz) + return DRM_ERR(EINVAL); + + BEGIN_RING(sz+1); + OUT_RING( CP_PACKET0( reg, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_scalars( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.scalars.count; + int *data = (int *)cmdbuf->buf; + int start = header.scalars.offset; + int stride = header.scalars.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + +static __inline__ int radeon_emit_vectors( + drm_radeon_private_t *dev_priv, + drm_radeon_cmd_header_t header, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + int sz = header.vectors.count; + int *data = (int *)cmdbuf->buf; + int start = header.vectors.offset; + int stride = header.vectors.stride; + RING_LOCALS; + + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); + OUT_RING_USER_TABLE( data, sz ); + ADVANCE_RING(); + + cmdbuf->buf += sz * sizeof(int); + cmdbuf->bufsz -= sz * sizeof(int); + return 0; +} + + +static int radeon_emit_packet3( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + RING_LOCALS; + + + DRM_DEBUG("\n"); + + if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) + return DRM_ERR(EFAULT); + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return DRM_ERR(EINVAL); + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + +static int radeon_emit_packet3_cliprect( drm_device_t *dev, + drm_radeon_cmd_buffer_t *cmdbuf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_clip_rect_t box; + int cmdsz, tmp; + int *cmd = (int *)cmdbuf->buf; + drm_clip_rect_t *boxes = cmdbuf->boxes; + int i = 0; + RING_LOCALS; + + DRM_DEBUG("\n"); + + if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) + return DRM_ERR(EFAULT); + + cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); + + if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || + cmdsz * 4 > cmdbuf->bufsz) + return DRM_ERR(EINVAL); + + do { + if ( i < cmdbuf->nbox ) { + if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) + return DRM_ERR(EFAULT); + radeon_emit_clip_rect( dev_priv, &box ); + } + + BEGIN_RING( cmdsz ); + OUT_RING_USER_TABLE( cmd, cmdsz ); + ADVANCE_RING(); + + } while ( ++i < cmdbuf->nbox ); + + if (cmdbuf->nbox == 1) + cmdbuf->nbox = 0; + + cmdbuf->buf += cmdsz * 4; + cmdbuf->bufsz -= cmdsz * 4; + return 0; +} + + + +int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf = 0; + int idx; + drm_radeon_cmd_buffer_t cmdbuf; + drm_radeon_cmd_header_t header; + + LOCK_TEST_WITH_RETURN( dev ); + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, + sizeof(cmdbuf) ); + + DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + VB_AGE_TEST_WITH_RETURN( dev_priv ); + + + if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) + return DRM_ERR(EFAULT); + + if (cmdbuf.nbox && + DRM_VERIFYAREA_READ(cmdbuf.boxes, + cmdbuf.nbox * sizeof(drm_clip_rect_t))) + return DRM_ERR(EFAULT); + + while ( cmdbuf.bufsz >= sizeof(header) ) { + + if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { + DRM_ERROR("__get_user %p\n", cmdbuf.buf); + return DRM_ERR(EFAULT); + } + + cmdbuf.buf += sizeof(header); + cmdbuf.bufsz -= sizeof(header); + + switch (header.header.cmd_type) { + case RADEON_CMD_PACKET: + if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_packets failed\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CMD_SCALARS: + if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_scalars failed\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CMD_VECTORS: + if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { + DRM_ERROR("radeon_emit_vectors failed\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CMD_DMA_DISCARD: + idx = header.dma.buf_idx; + if ( idx < 0 || idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + idx, dma->buf_count - 1 ); + return DRM_ERR(EINVAL); + } + + buf = dma->buflist[idx]; + if ( buf->pid != DRM_CURRENTPID || buf->pending ) { + DRM_ERROR( "bad buffer\n" ); + return DRM_ERR(EINVAL); + } + + radeon_cp_discard_buffer( dev, buf ); + break; + + case RADEON_CMD_PACKET3: + if (radeon_emit_packet3( dev, &cmdbuf )) { + DRM_ERROR("radeon_emit_packet3 failed\n"); + return DRM_ERR(EINVAL); + } + break; + + case RADEON_CMD_PACKET3_CLIP: + if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) { + DRM_ERROR("radeon_emit_packet3_clip failed\n"); + return DRM_ERR(EINVAL); + } + break; + + default: + DRM_ERROR("bad cmd_type %d at %p\n", + header.header.cmd_type, + cmdbuf.buf - sizeof(header)); + return DRM_ERR(EINVAL); + } + } + + + COMMIT_RING(); + return 0; +} + + + +int radeon_cp_getparam( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_getparam_t param; + int value; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __func__ ); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data, + sizeof(param) ); + + DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); + + switch( param.param ) { + case RADEON_PARAM_AGP_BUFFER_OFFSET: + value = dev_priv->agp_buffers_offset; + break; + default: + return DRM_ERR(EINVAL); + } + + if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return DRM_ERR(EFAULT); + } + + return 0; +} |