mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 05:48:04 +02:00
First audit of PCI GART code. Implementation appears to be solid on x86
platforms, still need to fix PPC?
This commit is contained in:
parent
c11d39c2e1
commit
967a589abd
11 changed files with 136 additions and 203 deletions
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define R128_NAME "r128"
|
||||
#define R128_DESC "ATI Rage 128"
|
||||
#define R128_DATE "20010101"
|
||||
#define R128_DATE "20010123"
|
||||
#define R128_MAJOR 2
|
||||
#define R128_MINOR 1
|
||||
#define R128_PATCHLEVEL 4
|
||||
|
|
@ -312,7 +312,7 @@ static int r128_takedown(drm_device_t *dev)
|
|||
handled in the AGP/GART driver. */
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if(dev->sg) {
|
||||
if (dev->sg) {
|
||||
drm_sg_cleanup(dev->sg);
|
||||
dev->sg = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
# ***** NOTE NOTE NOTE NOTE NOTE *****
|
||||
# To override the automatic Linux source tree determination, pass the
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
# **** End of SMP/MODVERSIONS detection
|
||||
CC= gcc
|
||||
MODS= gamma.o tdfx.o
|
||||
MODS= gamma.o tdfx.o r128.o
|
||||
LIBS= libdrm.a
|
||||
|
||||
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
|
|
@ -129,7 +129,7 @@ endif
|
|||
ifeq ($(AGP),1)
|
||||
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
|
||||
DRMOBJS += agpsupport.o
|
||||
MODS += mga.o r128.o radeon.o
|
||||
MODS += mga.o radeon.o
|
||||
ifeq ($(MACHINE),i386)
|
||||
MODS += i810.o
|
||||
endif
|
||||
|
|
|
|||
41
linux/bufs.c
41
linux/bufs.c
|
|
@ -11,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,7 +23,7 @@
|
|||
* 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>
|
||||
*
|
||||
|
|
@ -51,7 +51,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map;
|
||||
|
||||
|
||||
if (!(filp->f_mode & 3)) return -EACCES; /* Require read/write */
|
||||
|
||||
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
|
||||
|
|
@ -89,7 +89,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
map->handle = drm_ioremap(map->offset, map->size);
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case _DRM_SHM:
|
||||
map->handle = (void *)drm_alloc_pages(drm_order(map->size)
|
||||
|
|
@ -112,7 +112,10 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
break;
|
||||
#endif
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if(!dev->sg) return -EINVAL;
|
||||
if (!dev->sg) {
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
map->offset = map->offset + dev->sg->handle;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -144,7 +147,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
&map->offset,
|
||||
sizeof(map->offset)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +182,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
count = request.count;
|
||||
order = drm_order(request.size);
|
||||
size = 1 << order;
|
||||
|
||||
|
||||
DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
|
||||
request.count, request.size, size, order, dev->queue_count);
|
||||
|
||||
|
|
@ -197,7 +200,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
atomic_inc(&dev->buf_alloc);
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
|
||||
down(&dev->struct_sem);
|
||||
entry = &dma->bufs[order];
|
||||
if (entry->buf_count) {
|
||||
|
|
@ -205,7 +208,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM; /* May only call once for each order */
|
||||
}
|
||||
|
||||
|
||||
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
if (!entry->buflist) {
|
||||
|
|
@ -289,12 +292,12 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
dma->seg_count += entry->seg_count;
|
||||
dma->page_count += entry->seg_count << page_order;
|
||||
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
|
||||
|
||||
|
||||
drm_freelist_create(&entry->freelist, entry->buf_count);
|
||||
for (i = 0; i < entry->buf_count; i++) {
|
||||
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
|
||||
}
|
||||
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.count = entry->buf_count;
|
||||
|
|
@ -304,7 +307,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
&request,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -337,9 +340,9 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
|
||||
if (dma->bufs[i].buf_count) ++count;
|
||||
}
|
||||
|
||||
|
||||
DRM_DEBUG("count = %d\n", count);
|
||||
|
||||
|
||||
if (request.count >= count) {
|
||||
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
|
||||
if (dma->bufs[i].buf_count) {
|
||||
|
|
@ -379,7 +382,7 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
&request,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +416,7 @@ int drm_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
entry->freelist.low_mark = request.low_mark;
|
||||
entry->freelist.high_mark = request.high_mark;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -454,7 +457,7 @@ int drm_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
drm_free_buffer(dev, buf);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -472,7 +475,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
int i;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
spin_lock(&dev->count_lock);
|
||||
|
|
|
|||
|
|
@ -351,16 +351,16 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return -EINVAL;
|
||||
if (!dev_priv->is_pci && (request.flags & _DRM_SG_BUFFER))
|
||||
return -EINVAL;
|
||||
if (request.flags & _DRM_AGP_BUFFER)
|
||||
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
if (request.flags & _DRM_AGP_BUFFER)
|
||||
return r128_addbufs_agp(inode, filp, cmd, arg);
|
||||
#else
|
||||
printk("WARNING: trying to use AGP without kernel support!\n");
|
||||
#endif
|
||||
if (request.flags & _DRM_SG_BUFFER)
|
||||
if (request.flags & _DRM_SG_BUFFER) {
|
||||
return r128_addbufs_sg(inode, filp, cmd, arg);
|
||||
else
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
|
|
|
|||
|
|
@ -342,15 +342,13 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
|
|||
/* The manual (p. 2) says this address is in "VM space". This
|
||||
* means it's an offset from the start of AGP space.
|
||||
*/
|
||||
if ( !dev_priv->is_pci ) {
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
if ( !dev_priv->is_pci )
|
||||
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
|
||||
#else
|
||||
printk("WARNING: Trying to use AGP without kernel support!\n");
|
||||
else
|
||||
#endif
|
||||
} else {
|
||||
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 );
|
||||
|
|
@ -405,12 +403,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
|
||||
dev_priv->is_pci = init->is_pci;
|
||||
|
||||
/* GH: We don't support PCI cards until PCI GART is implemented.
|
||||
* Fail here so we can remove all checks for PCI cards around
|
||||
* the CCE ring code.
|
||||
*/
|
||||
|
||||
if ( dev_priv->is_pci && !dev->sg) {
|
||||
if ( dev_priv->is_pci && !dev->sg ) {
|
||||
DRM_ERROR( "PCI GART memory not allocated!\n" );
|
||||
drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -511,21 +505,25 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
if(dev_priv->is_pci) {
|
||||
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;
|
||||
} else {
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DO_IOREMAP( dev_priv->cce_ring );
|
||||
DO_IOREMAP( dev_priv->ring_rptr );
|
||||
DO_IOREMAP( dev_priv->buffers );
|
||||
} 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 ( !dev_priv->is_pci ) {
|
||||
DO_IOREMAP( dev_priv->agp_textures );
|
||||
}
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
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);
|
||||
|
|
@ -546,10 +544,9 @@ 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 ( dev_priv->is_pci && r128_pcigart_init( dev ) < 0) {
|
||||
DRM_ERROR( "failed to init PCIGART!\n" );
|
||||
drm_free( dev_priv, sizeof(*dev_priv),
|
||||
DRM_MEM_DRIVER );
|
||||
if ( dev_priv->is_pci && r128_pcigart_init( dev ) < 0 ) {
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -611,10 +608,10 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
r128_do_engine_reset( dev );
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -623,15 +620,14 @@ static int r128_do_cleanup_cce( drm_device_t *dev )
|
|||
if ( dev->dev_private ) {
|
||||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if(!dev_priv->is_pci) {
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DO_IOREMAPFREE( dev_priv->cce_ring );
|
||||
DO_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DO_IOREMAPFREE( dev_priv->buffers );
|
||||
DO_IOREMAPFREE( dev_priv->agp_textures );
|
||||
} else {
|
||||
r128_pcigart_cleanup( dev );
|
||||
}
|
||||
|
||||
r128_pcigart_cleanup(dev);
|
||||
|
||||
drm_free( dev->dev_private, sizeof(drm_r128_private_t),
|
||||
DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define R128_NAME "r128"
|
||||
#define R128_DESC "ATI Rage 128"
|
||||
#define R128_DATE "20010101"
|
||||
#define R128_DATE "20010123"
|
||||
#define R128_MAJOR 2
|
||||
#define R128_MINOR 1
|
||||
#define R128_PATCHLEVEL 4
|
||||
|
|
@ -312,7 +312,7 @@ static int r128_takedown(drm_device_t *dev)
|
|||
handled in the AGP/GART driver. */
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if(dev->sg) {
|
||||
if (dev->sg) {
|
||||
drm_sg_cleanup(dev->sg);
|
||||
dev->sg = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ typedef struct drm_r128_private {
|
|||
int cce_fifo_size;
|
||||
int cce_secure;
|
||||
int cce_running;
|
||||
u32 cce_buffers_offset;
|
||||
|
||||
drm_r128_freelist_t *head;
|
||||
drm_r128_freelist_t *tail;
|
||||
|
|
@ -92,8 +93,7 @@ typedef struct drm_r128_private {
|
|||
u32 depth_pitch_offset_c;
|
||||
u32 span_pitch_offset_c;
|
||||
|
||||
void *pci_gart_page;
|
||||
unsigned long phys_pci_gart_page;
|
||||
unsigned long phys_pci_gart;
|
||||
|
||||
drm_map_t *sarea;
|
||||
drm_map_t *fb;
|
||||
|
|
@ -404,14 +404,17 @@ extern int r128_pcigart_init(drm_device_t *dev);
|
|||
#define R128_WATERMARK_N 8
|
||||
#define R128_WATERMARK_K 128
|
||||
|
||||
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
|
||||
#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
|
||||
#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
|
||||
#define R128_MAX_VB_AGE 0x7fffffff
|
||||
|
||||
#define R128_MAX_VB_VERTS (0xffff)
|
||||
|
||||
#define R128_PCIGART_TABLE_ORDER 3
|
||||
#define R128_PCIGART_TABLE_PAGES (1 << 3)
|
||||
#define R128_MAX_PCIGART_PAGES 8192 /* 32 MB aperture */
|
||||
|
||||
|
||||
#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
|
||||
#define R128_ADDR(reg) (R128_BASE(reg) + reg)
|
||||
|
|
|
|||
|
|
@ -25,36 +25,28 @@
|
|||
*
|
||||
* Authors:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
#include "r128_drv.h"
|
||||
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
|
||||
|
||||
static unsigned long r128_alloc_pages( void )
|
||||
static unsigned long r128_alloc_pcigart_table( void )
|
||||
{
|
||||
unsigned long address;
|
||||
unsigned long addr_end;
|
||||
struct page *page;
|
||||
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
address = __get_free_pages( GFP_KERNEL, 3 );
|
||||
address = __get_free_pages( GFP_KERNEL, R128_PCIGART_TABLE_ORDER );
|
||||
if ( address == 0UL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_end = address + ((PAGE_SIZE * (1 << 3)) - 1);
|
||||
for (page = virt_to_page(address);
|
||||
page <= virt_to_page(addr_end);
|
||||
page++) {
|
||||
page = virt_to_page( address );
|
||||
|
||||
for ( i = 0 ; i <= R128_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
atomic_inc( &page->count );
|
||||
SetPageReserved( page );
|
||||
}
|
||||
|
|
@ -63,24 +55,22 @@ static unsigned long r128_alloc_pages( void )
|
|||
return address;
|
||||
}
|
||||
|
||||
static void r128_free_pages( unsigned long address )
|
||||
static void r128_free_pcigart_table( unsigned long address )
|
||||
{
|
||||
unsigned long addr_end;
|
||||
struct page *page;
|
||||
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !address ) return;
|
||||
|
||||
addr_end = address + ((PAGE_SIZE * (1 << 3)) - 1);
|
||||
page = virt_to_page( address );
|
||||
|
||||
for (page = virt_to_page(address);
|
||||
page <= virt_to_page(addr_end);
|
||||
page++) {
|
||||
for ( i = 0 ; i <= R128_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
atomic_dec( &page->count );
|
||||
ClearPageReserved( page );
|
||||
}
|
||||
|
||||
free_pages( address , 3 );
|
||||
free_pages( address, R128_PCIGART_TABLE_ORDER );
|
||||
}
|
||||
|
||||
int r128_pcigart_init( drm_device_t *dev )
|
||||
|
|
@ -89,50 +79,36 @@ int r128_pcigart_init( drm_device_t *dev )
|
|||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long address;
|
||||
unsigned long pages;
|
||||
unsigned long *pci_gart;
|
||||
u32 *pci_gart;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
#if 0
|
||||
dev_priv->phys_pci_gart_page = 0;
|
||||
dev_priv->pci_gart_page = NULL;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* 32 MB aperture is the largest size */
|
||||
pages = ( entry->pages <= 8192 )
|
||||
? entry->pages : 8192;
|
||||
|
||||
address = r128_alloc_pages();
|
||||
|
||||
|
||||
address = r128_alloc_pcigart_table();
|
||||
if ( !address ) {
|
||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev_priv->phys_pci_gart_page = address;
|
||||
dev_priv->pci_gart_page = (unsigned long *)address;
|
||||
dev_priv->phys_pci_gart = address;
|
||||
|
||||
DRM_DEBUG( "%s: phys=0x%08lx virt=%p\n",
|
||||
__FUNCTION__, dev_priv->phys_pci_gart_page,
|
||||
dev_priv->pci_gart_page );
|
||||
pci_gart = (u32 *)dev_priv->phys_pci_gart;
|
||||
|
||||
pci_gart = (unsigned long *)dev_priv->pci_gart_page;
|
||||
pages = ( entry->pages <= R128_MAX_PCIGART_PAGES )
|
||||
? entry->pages : R128_MAX_PCIGART_PAGES;
|
||||
|
||||
memset( pci_gart, 0, R128_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||
|
||||
for ( i = 0; i < 8192 ; i++) pci_gart[i] = 0;
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
pci_gart[i] = virt_to_bus( entry->pagelist[i]->virtual );
|
||||
pci_gart[i] = (u32) virt_to_bus( entry->pagelist[i]->virtual );
|
||||
}
|
||||
|
||||
DRM_DEBUG( "%s: writing PCI_GART_PAGE...\n", __FUNCTION__ );
|
||||
R128_WRITE( R128_PCI_GART_PAGE, virt_to_bus((void *)address) );
|
||||
R128_WRITE( R128_PCI_GART_PAGE, virt_to_bus( (void *)address ) );
|
||||
DRM_DEBUG( "%s: writing PCI_GART_PAGE... done.\n", __FUNCTION__ );
|
||||
|
||||
#if __i386__
|
||||
|
|
@ -149,10 +125,9 @@ int r128_pcigart_cleanup( drm_device_t *dev )
|
|||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( dev_priv->phys_pci_gart_page ) {
|
||||
r128_free_pages( dev_priv->phys_pci_gart_page );
|
||||
if ( dev_priv->phys_pci_gart ) {
|
||||
r128_free_pcigart_table( dev_priv->phys_pci_gart );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -616,9 +616,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
|
|||
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
int format = sarea_priv->vc_format;
|
||||
int offset = buf->bus_address;
|
||||
/*
|
||||
int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
|
||||
*/
|
||||
int size = buf->used;
|
||||
int prim = buf_priv->prim;
|
||||
int i = 0;
|
||||
|
|
@ -685,9 +682,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
|
|||
sarea_priv->nbox = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void r128_cce_dispatch_indirect( drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
int start, int end )
|
||||
|
|
@ -752,12 +746,11 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
|
|||
int start, int end,
|
||||
int count )
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
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;
|
||||
int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
|
||||
int prim = buf_priv->prim;
|
||||
u32 *data;
|
||||
int dwords;
|
||||
|
|
@ -765,15 +758,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
|
|||
RING_LOCALS;
|
||||
DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
|
||||
|
||||
if(dma->flags == _DRM_DMA_USE_SG)
|
||||
offset = dev_priv->buffers->offset - dev->sg->handle;
|
||||
else
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
offset = dev_priv->buffers->offset - dev->agp->base;
|
||||
#else
|
||||
printk("WARNING: trying to use AGP without kernel support!\n");
|
||||
#endif
|
||||
|
||||
r128_update_ring_snapshot( dev_priv );
|
||||
|
||||
if ( 0 )
|
||||
|
|
@ -1436,10 +1420,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
|
|||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
|
||||
if ( !dev_priv )
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg,
|
||||
sizeof(vertex) ) )
|
||||
|
|
@ -1501,10 +1483,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
|
|||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
|
||||
if ( !dev_priv )
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_from_user( &elts, (drm_r128_indices_t *)arg,
|
||||
sizeof(elts) ) )
|
||||
|
|
|
|||
|
|
@ -24,24 +24,25 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include <linux/config.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "drmP.h"
|
||||
#include <linux/wrapper.h>
|
||||
|
||||
#define DEBUG_SCATTER 0
|
||||
|
||||
void drm_sg_cleanup( drm_sg_mem_t *entry )
|
||||
{
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < entry->pages ; i++ ) {
|
||||
ClearPageReserved( entry->pagelist[i] );
|
||||
page = entry->pagelist[i];
|
||||
if ( page )
|
||||
ClearPageReserved( page );
|
||||
}
|
||||
|
||||
vfree( entry->virtual );
|
||||
|
|
@ -54,15 +55,6 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
|
|||
DRM_MEM_SGLISTS );
|
||||
}
|
||||
|
||||
static inline long usec( void )
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
do_gettimeofday( &tv );
|
||||
|
||||
return (tv.tv_sec & 0x7ff) * 1000000 + tv.tv_usec;
|
||||
}
|
||||
|
||||
int drm_sg_alloc( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
|
|
@ -77,7 +69,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( dev->sg ) return -EINVAL;
|
||||
if ( dev->sg )
|
||||
return -EINVAL;
|
||||
|
||||
if ( copy_from_user( &request,
|
||||
(drm_scatter_gather_t *)arg,
|
||||
|
|
@ -85,7 +78,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
|
||||
if ( !entry ) return -ENOMEM;
|
||||
if ( !entry )
|
||||
return -ENOMEM;
|
||||
|
||||
memset( entry, 0, sizeof(*entry) );
|
||||
|
||||
|
|
@ -100,11 +94,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* FIXME: We should really have a kernel call for this...
|
||||
*/
|
||||
entry->virtual = __vmalloc( (pages << PAGE_SHIFT),
|
||||
GFP_KERNEL,
|
||||
PAGE_KERNEL);
|
||||
entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
|
||||
if ( !entry->virtual ) {
|
||||
drm_free( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
|
|
@ -127,30 +117,20 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
|
||||
for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
|
||||
pgd = pgd_offset_k( i );
|
||||
if ( !pgd_present( *pgd ) )
|
||||
goto failed;
|
||||
|
||||
if ( pgd_present( *pgd ) && ( pmd = pmd_offset( pgd, i ) )
|
||||
&& pmd_present( *pmd ) && ( pte = pte_offset( pmd, i ) )
|
||||
&& pte_present( *pte ) )
|
||||
entry->pagelist[j] = pte_page( *pte );
|
||||
else
|
||||
{
|
||||
vfree( entry->virtual );
|
||||
drm_free( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
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] );
|
||||
|
||||
if ( j < 16 ) {
|
||||
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n",
|
||||
i, j,
|
||||
(unsigned long)entry->pagelist[j]->virtual);
|
||||
}
|
||||
}
|
||||
|
||||
request.handle = entry->handle;
|
||||
|
|
@ -165,7 +145,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
dev->sg = entry;
|
||||
|
||||
#if DEBUG_SCATTER
|
||||
/* Verify that each page points to its virtual address, and vice
|
||||
/* Verify that each page points to its virtual address, and vice
|
||||
* versa.
|
||||
*/
|
||||
{
|
||||
|
|
@ -178,7 +158,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
for(j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) {
|
||||
*tmp = 0xcafebabe;
|
||||
}
|
||||
tmp = (unsigned long *)((u8 *)entry->virtual +
|
||||
tmp = (unsigned long *)((u8 *)entry->virtual +
|
||||
(PAGE_SIZE * i));
|
||||
for(j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) {
|
||||
if(*tmp != 0xcafebabe && error == 0) {
|
||||
|
|
@ -197,6 +177,10 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
drm_sg_cleanup( entry );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int drm_sg_free( struct inode *inode, struct file *filp,
|
||||
|
|
@ -215,7 +199,8 @@ int drm_sg_free( struct inode *inode, struct file *filp,
|
|||
entry = dev->sg;
|
||||
dev->sg = NULL;
|
||||
|
||||
if ( !entry || entry->handle != request.handle ) return -EINVAL;
|
||||
if ( !entry || entry->handle != request.handle )
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
|
||||
|
||||
|
|
|
|||
33
linux/vm.c
33
linux/vm.c
|
|
@ -11,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,7 +23,7 @@
|
|||
* 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>
|
||||
*
|
||||
|
|
@ -213,7 +213,6 @@ struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
|
|||
page = entry->pagelist[page_offset];
|
||||
atomic_inc(&page->count); /* Dec. by kernel */
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return (unsigned long)virt_to_phys(page->virtual);
|
||||
#else
|
||||
|
|
@ -289,7 +288,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_device_t *dev;
|
||||
drm_device_dma_t *dma;
|
||||
unsigned long length = vma->vm_end - vma->vm_start;
|
||||
|
||||
|
||||
lock_kernel();
|
||||
dev = priv->dev;
|
||||
dma = dev->dma;
|
||||
|
|
@ -305,7 +304,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
|
|||
|
||||
vma->vm_ops = &drm_vm_dma_ops;
|
||||
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
|
||||
/* In Linux 2.2.3 and above, this is
|
||||
handled in do_mmap() in mm/mmap.c. */
|
||||
|
|
@ -322,7 +321,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
int i;
|
||||
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
||||
|
|
@ -339,14 +338,14 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
map = dev->maplist[i];
|
||||
if (map->offset == VM_OFFSET(vma)) break;
|
||||
}
|
||||
|
||||
|
||||
if (i >= dev->map_count) return -EINVAL;
|
||||
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
|
||||
return -EPERM;
|
||||
|
||||
/* Check for valid size. */
|
||||
if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
|
||||
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
|
||||
vma->vm_flags &= VM_MAYWRITE;
|
||||
#if defined(__i386__)
|
||||
|
|
@ -360,12 +359,6 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (map->type == _DRM_SCATTER_GATHER) {
|
||||
DRM_DEBUG("%s: scatter/gather\n", __FUNCTION__);
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
}
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_FRAME_BUFFER:
|
||||
case _DRM_REGISTERS:
|
||||
|
|
@ -377,10 +370,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
|
||||
pgprot_val(vma->vm_page_prot) |=
|
||||
_PAGE_NO_CACHE | _PAGE_GUARDED;
|
||||
#elif defined(__ia64__)
|
||||
if (map->type != _DRM_AGP)
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
vma->vm_page_prot =
|
||||
pgprot_writecombine(vma->vm_page_prot);
|
||||
#endif
|
||||
vma->vm_flags |= VM_IO; /* not in core dump */
|
||||
}
|
||||
|
|
@ -432,9 +427,5 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
#endif
|
||||
vma->vm_file = filp; /* Needed for drm_vm_open() */
|
||||
drm_vm_open(vma);
|
||||
|
||||
if(map->type == _DRM_SCATTER_GATHER) {
|
||||
DRM_DEBUG("%s: scatter/gather done.\n", __FUNCTION__);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue