summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkem <kem>2001-04-05 22:16:10 +0000
committerkem <kem>2001-04-05 22:16:10 +0000
commit812f595f5377a4698f12ad6bf4afee8dda10d880 (patch)
tree1519b0b6901a178b3cd64c45851f64b3ed7e0ecf
parent352c29556210dc11197518614e337313033e500f (diff)
Merged ati-pcigart-1-0-0ati-pcigart-1-0-0-20010405-merge
-rw-r--r--xc/config/cf/host.def5
-rwxr-xr-xxc/extras/ogl-sample/main/doc/man/manglu/standard/beginpolygon.gl2
-rw-r--r--xc/lib/GL/glx/glxext.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/Imakefile2
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.h18
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.c28
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c12
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c20
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.h17
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.c11
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.h103
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c26
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c14
-rw-r--r--xc/programs/Xserver/hw/xfree86/common/compiler.h1300
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c260
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c18
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c211
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c4
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/xf86sym.c1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c221
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux39
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ati_pcigart.h138
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h21
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h182
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_init.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h21
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_scatter.h218
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h74
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h42
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c63
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c176
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c6
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c12
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c32
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c749
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h14
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h14
59 files changed, 3245 insertions, 1245 deletions
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def
index 0db224799..3c6c69c89 100644
--- a/xc/config/cf/host.def
+++ b/xc/config/cf/host.def
@@ -1,11 +1,16 @@
#define DefaultGcc2AxpOpt -O2 -mcpu=ev6
+#define DefaultGcc2AxpOpt -O2 -mcpu=750
#define DefaultGcc2i386Opt -O2
#ifdef AlphaArchitecture
#define LibraryCDebugFlags -O2 -mcpu=ev6
#else
+#ifdef PpcArchitecture
+#define LibraryCDebugFlags -O2 -mcpu=750
+#else
#define LibraryCDebugFlags -O2
#endif
+#endif
#define BuildServersOnly YES
/*
* Turn this on to build xf86cfg and xf86config. It has the side-effect of
diff --git a/xc/extras/ogl-sample/main/doc/man/manglu/standard/beginpolygon.gl b/xc/extras/ogl-sample/main/doc/man/manglu/standard/beginpolygon.gl
index bf14e2a34..05ee80683 100755
--- a/xc/extras/ogl-sample/main/doc/man/manglu/standard/beginpolygon.gl
+++ b/xc/extras/ogl-sample/main/doc/man/manglu/standard/beginpolygon.gl
@@ -30,7 +30,7 @@ _C_ was created using the OpenGL(R) version 1.2.1 Sample Implementation
_C_ published by SGI, but has not been independently verified as being
_C_ compliant with the OpenGL(R) version 1.2.1 Specification.
_C_
-_C_ $Date: 2001/03/19 17:45:27 $ $Revision: 1.1 $
+_C_ $Date: 2001/04/05 22:16:10 $ $Revision: 1.2 $
_C_ The first character in this file must be an '_'!
_C_ Anything on a line after _C_ is ignored
_define(_filters,eqn)_C_
diff --git a/xc/lib/GL/glx/glxext.c b/xc/lib/GL/glx/glxext.c
index 141999150..fed1ce01f 100644
--- a/xc/lib/GL/glx/glxext.c
+++ b/xc/lib/GL/glx/glxext.c
@@ -33,8 +33,8 @@
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
-** $Date: 2001/03/30 17:03:54 $ $Revision: 1.18 $
-** $Header: /home/ajax/dri-backup/xc/xc/lib/GL/glx/glxext.c,v 1.18 2001/03/30 17:03:54 dawes Exp $
+** $Date: 2001/04/05 22:16:10 $ $Revision: 1.19 $
+** $Header: /home/ajax/dri-backup/xc/xc/lib/GL/glx/glxext.c,v 1.19 2001/04/05 22:16:10 kem Exp $
*/
/* <
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile
index 6639512c2..dcd78c5e8 100644
--- a/xc/lib/GL/mesa/src/drv/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/Imakefile
@@ -52,7 +52,7 @@ SUBDIRS += sis
SUBDIRS += tdfx
#endif
-#elif defined(AlphaArchitecture)
+#elif defined(AlphaArchitecture) || defined(PpcArchitecture)
SUBDIRS += common
SUBDIRS += gamma
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
index a2400c199..f0ea2a14e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
@@ -255,6 +255,24 @@ extern r128ContextPtr r128MakeCurrent( r128ContextPtr oldCtx,
r128ContextPtr newCtx,
__DRIdrawablePrivate *dPriv );
+/* ================================================================
+ * Byte ordering
+ */
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LE32_OUT( x, y ) do { x = y; } while (0)
+#define LE32_OUT_FLOAT( x, y ) do { *(GLfloat *)&(x) = y; } while (0)
+#else
+#include <byteswap.h>
+#define LE32_OUT( x, y ) do { x = bswap_32( y ); } while (0)
+#define LE32_OUT_FLOAT( x, y ) \
+do { \
+ GLuint __tmp; \
+ *(GLfloat *)&__tmp = y; \
+ x = bswap_32( __tmp ); \
+} while (0)
+#endif
/* ================================================================
* Debugging:
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
index 1aecb5034..5b595120e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
@@ -45,7 +45,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "X86/common_x86_asm.h"
#endif
-#define R128_DATE "20010321"
+#define R128_DATE "20010405"
/* Return the width and height of the current color buffer.
@@ -84,18 +84,22 @@ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name )
strncat( buffer, " M3", 3 );
}
- /* Append any AGP-specific information.
+ /* Append any AGP/PCI-specific information.
*/
- switch ( rmesa->r128Screen->AGPMode ) {
- case 1:
- strncat( (pointer)buffer, " AGP 1x", 7 );
- break;
- case 2:
- strncat( (pointer)buffer, " AGP 2x", 7 );
- break;
- case 4:
- strncat( (pointer)buffer, " AGP 4x", 7 );
- break;
+ if ( rmesa->r128Screen->IsPCI ) {
+ strncat( (pointer)buffer, " PCI", 4 );
+ } else {
+ switch ( rmesa->r128Screen->AGPMode ) {
+ case 1:
+ strncat( (pointer)buffer, " AGP 1x", 7 );
+ break;
+ case 2:
+ strncat( (pointer)buffer, " AGP 2x", 7 );
+ break;
+ case 4:
+ strncat( (pointer)buffer, " AGP 4x", 7 );
+ break;
+ }
}
/* Append any CPU-specific information.
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c
index 371223644..426425583 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c
@@ -308,7 +308,19 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa )
int wait = 0;
while ( 1 ) {
+#if defined(__alpha__)
+ /* necessary to preserve the Alpha paradigm */
+ /* NOTE: this will not work on SPARSE machines */
+ mem_barrier();
+ frame = *(volatile CARD32 *)(void *)(R128MMIO + R128_LAST_FRAME_REG);
+#else
frame = INREG( R128_LAST_FRAME_REG );
+#endif
+
+ if ( 0 )
+ fprintf( stderr, " last=0x%08x frame=0x%08x\n",
+ rmesa->sarea->last_frame, frame );
+
if ( rmesa->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) {
break;
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
index 8bd2c23f9..efdd025f4 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
@@ -30,6 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Gareth Hughes <gareth@valinux.com>
* Kevin E. Martin <martin@valinux.com>
+ * Michel Dänzer <michdaen@iiic.ethz.ch>
*
*/
@@ -572,8 +573,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst,
for ( i = 0 ; i < height ; i++ ) {
src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((R128PACKCOLOR4444( src[0], src[1], src[2], src[3] )) |
- (R128PACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16));
+ *dst++ = R128PACKCOLORS4444( src[0], src[1], src[2], src[3],
+ src[4], src[5], src[6], src[7] );
src += 8;
}
}
@@ -583,8 +584,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst,
for ( i = 0 ; i < height ; i++ ) {
src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((R128PACKCOLOR565( src[0], src[1], src[2] )) |
- (R128PACKCOLOR565( src[3], src[4], src[5] ) << 16));
+ *dst++ = R128PACKCOLORS565( src[0], src[1], src[2],
+ src[3], src[4], src[5] );
src += 6;
}
}
@@ -594,8 +595,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst,
for ( i = 0 ; i < height ; i++ ) {
src = (CARD8 *)image->Data + ((y + i) * pitch + x);
for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) |
- (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16));
+ *dst++ = R128PACKCOLORS4444( 0xff, 0xff, 0xff, src[0],
+ 0xff, 0xff, 0xff, src[1] );
src += 2;
}
}
@@ -605,8 +606,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst,
for ( i = 0 ; i < height ; i++ ) {
src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
for ( j = width >> 1 ; j ; j-- ) {
- *dst++ = ((R128PACKCOLOR4444( src[0], src[0], src[0], src[1] )) |
- (R128PACKCOLOR4444( src[2], src[2], src[2], src[3] ) << 16));
+ *dst++ = R128PACKCOLORS4444( src[0], src[0], src[0], src[1],
+ src[2], src[2], src[2], src[3] );
src += 4;
}
}
@@ -877,7 +878,8 @@ int r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t )
t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 );
/* Try AGP before kicking anything out of local mem */
- if ( !t->memBlock && heap == R128_CARD_HEAP ) {
+ if ( !rmesa->r128Screen->IsPCI &&
+ !t->memBlock && heap == R128_CARD_HEAP ) {
t->memBlock = mmAllocMem( rmesa->texHeap[R128_AGP_HEAP],
t->totalSize, 12, 0 );
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
index e1f67a56d..a0090f389 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
@@ -74,6 +74,23 @@ extern void r128DDInitTextureFuncs( GLcontext *ctx );
#define R128PACKCOLOR4444( r, g, b, a ) \
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define R128PACKCOLORS565( r0, g0, b0, r1, g1, b1 ) \
+ ((R128PACKCOLOR565( r0, g0, b0 )) | \
+ (R128PACKCOLOR565( r1, g1, b1 ) << 16))
+#define R128PACKCOLORS4444( r0, g0, b0, a0, r1, g1, b1, a1 ) \
+ ((R128PACKCOLOR4444( r0, g0, b0, a0 )) | \
+ (R128PACKCOLOR4444( r1, g1, b1, a1 ) << 16))
+#else
+#define R128PACKCOLORS565( r0, g0, b0, r1, g1, b1 ) \
+ ((R128PACKCOLOR565( r1, g1, b1 )) | \
+ (R128PACKCOLOR565( r0, g0, b0 ) << 16))
+#define R128PACKCOLORS4444( r0, g0, b0, a0, r1, g1, b1, a1 ) \
+ ((R128PACKCOLOR4444( r1, g1, b1, a1 )) | \
+ (R128PACKCOLOR4444( r0, g0, b0, a0 ) << 16))
+
+#endif
+
static __inline__ CARD32 r128PackColor( GLuint cpp,
GLubyte r, GLubyte g,
GLubyte b, GLubyte a )
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
index 4d83e27e0..52d1ad032 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
@@ -30,6 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Gareth Hughes <gareth@valinux.com>
* Kevin E. Martin <martin@valinux.com>
+ * Michel Dänzer <michdaen@iiic.ethz.ch>
*
*/
@@ -49,6 +50,7 @@ static struct {
quad_func quad;
} rast_tab[R128_MAX_TRIFUNC];
+#if __BYTE_ORDER == __LITTLE_ENDIAN
#define R128_COLOR( to, from ) \
do { \
(to)[0] = (from)[2]; \
@@ -56,6 +58,15 @@ do { \
(to)[2] = (from)[0]; \
(to)[3] = (from)[3]; \
} while (0)
+#else
+#define R128_COLOR( to, from ) \
+do { \
+ (to)[0] = (from)[3]; \
+ (to)[1] = (from)[0]; \
+ (to)[2] = (from)[1]; \
+ (to)[3] = (from)[2]; \
+} while (0)
+#endif
static void r128_null_quad( GLcontext *ctx, GLuint v0,
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
index 99c816dec..320ace740 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
@@ -56,7 +56,7 @@ static __inline void r128_draw_triangle( r128ContextPtr rmesa,
r128VertexPtr v1,
r128VertexPtr v2 )
{
- int vertsize = rmesa->vertsize;
+ GLuint vertsize = rmesa->vertsize;
CARD32 *vb = r128AllocVerticesInline( rmesa, 3 );
int j;
@@ -80,15 +80,15 @@ static __inline void r128_draw_triangle( r128ContextPtr rmesa,
: "memory" );
#else
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v0->ui[j];
+ LE32_OUT( vb[j], v0->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v1->ui[j];
+ LE32_OUT( vb[j], v1->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v2->ui[j];
+ LE32_OUT( vb[j], v2->ui[j] );
#endif
}
@@ -98,7 +98,7 @@ static __inline void r128_draw_quad( r128ContextPtr rmesa,
r128VertexPtr v2,
r128VertexPtr v3 )
{
- int vertsize = rmesa->vertsize;
+ GLuint vertsize = rmesa->vertsize;
CARD32 *vb = r128AllocVerticesInline( rmesa, 6 );
int j;
@@ -134,37 +134,37 @@ static __inline void r128_draw_quad( r128ContextPtr rmesa,
: "memory" );
#else
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v0->ui[j];
+ LE32_OUT( vb[j], v0->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v1->ui[j];
+ LE32_OUT( vb[j], v1->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v3->ui[j];
+ LE32_OUT( vb[j], v3->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v1->ui[j];
+ LE32_OUT( vb[j], v1->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v2->ui[j];
+ LE32_OUT( vb[j], v2->ui[j] );
vb += vertsize;
for ( j = 0 ; j < vertsize ; j++ )
- vb[j] = v3->ui[j];
+ LE32_OUT( vb[j], v3->ui[j] );
#endif
}
static __inline void r128_draw_line( r128ContextPtr rmesa,
r128VertexPtr tmp0,
r128VertexPtr tmp1,
- float width )
+ GLfloat width )
{
#if 1
- int vertsize = rmesa->vertsize;
+ GLuint vertsize = rmesa->vertsize;
CARD32 *vb = r128AllocVerticesInline( rmesa, 6 );
GLfloat hw, dx, dy, ix, iy;
GLuint j;
@@ -204,40 +204,40 @@ static __inline void r128_draw_line( r128ContextPtr rmesa,
x1 += 0.5F;
}
- *(float *)&vb[0] = x0 - ix;
- *(float *)&vb[1] = y0 - iy;
+ LE32_OUT_FLOAT( vb[0], x0 - ix );
+ LE32_OUT_FLOAT( vb[1], y0 - iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp0->ui[j];
+ LE32_OUT( vb[j], tmp0->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x1 + ix;
- *(float *)&vb[1] = y1 + iy;
+ LE32_OUT_FLOAT( vb[0], x1 + ix );
+ LE32_OUT_FLOAT( vb[1], y1 + iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp1->ui[j];
+ LE32_OUT( vb[j], tmp1->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x0 + ix;
- *(float *)&vb[1] = y0 + iy;
+ LE32_OUT_FLOAT( vb[0], x0 + ix );
+ LE32_OUT_FLOAT( vb[1], y0 + iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp0->ui[j];
+ LE32_OUT( vb[j], tmp0->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x0 - ix;
- *(float *)&vb[1] = y0 - iy;
+ LE32_OUT_FLOAT( vb[0], x0 - ix );
+ LE32_OUT_FLOAT( vb[1], y0 - iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp0->ui[j];
+ LE32_OUT( vb[j], tmp0->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x1 - ix;
- *(float *)&vb[1] = y1 - iy;
+ LE32_OUT_FLOAT( vb[0], x1 - ix );
+ LE32_OUT_FLOAT( vb[1], y1 - iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp1->ui[j];
+ LE32_OUT( vb[j], tmp1->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x1 + ix;
- *(float *)&vb[1] = y1 + iy;
+ LE32_OUT_FLOAT( vb[0], x1 + ix );
+ LE32_OUT_FLOAT( vb[1], y1 + iy );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp1->ui[j];
+ LE32_OUT( vb[j], tmp1->ui[j] );
#else
@@ -271,49 +271,50 @@ static __inline void r128_draw_line( r128ContextPtr rmesa,
}
static __inline void r128_draw_point( r128ContextPtr rmesa,
- r128VertexPtr tmp, float sz )
+ r128VertexPtr tmp, GLfloat sz )
{
#if 1
- int vertsize = rmesa->vertsize;
+ GLuint vertsize = rmesa->vertsize;
CARD32 *vb = r128AllocVerticesInline( rmesa, 6 );
int j;
const float x = tmp->v.x + PNT_X_OFFSET;
const float y = tmp->v.y + PNT_Y_OFFSET;
- *(float *)&vb[0] = x - sz;
- *(float *)&vb[1] = y - sz;
+ LE32_OUT_FLOAT( vb[0], x - sz );
+ LE32_OUT_FLOAT( vb[1], y - sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x + sz;
- *(float *)&vb[1] = y - sz;
+ LE32_OUT_FLOAT( vb[0], x + sz );
+ LE32_OUT_FLOAT( vb[1], y - sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x + sz;
- *(float *)&vb[1] = y + sz;
+ LE32_OUT_FLOAT( vb[0], x + sz );
+ LE32_OUT_FLOAT( vb[1], y + sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x + sz;
- *(float *)&vb[1] = y + sz;
+ LE32_OUT_FLOAT( vb[0], x + sz );
+ LE32_OUT_FLOAT( vb[1], y + sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x - sz;
- *(float *)&vb[1] = y + sz;
+ LE32_OUT_FLOAT( vb[0], x - sz );
+ LE32_OUT_FLOAT( vb[1], y + sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
vb += vertsize;
- *(float *)&vb[0] = x - sz;
- *(float *)&vb[1] = y - sz;
+ LE32_OUT_FLOAT( vb[0], x - sz );
+ LE32_OUT_FLOAT( vb[1], y - sz );
for (j = 2 ; j < vertsize ; j++)
- vb[j] = tmp->ui[j];
+ LE32_OUT( vb[j], tmp->ui[j] );
+
#else
int vertsize = rmesa->vertsize;
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
index 1a00d9eea..7bb314692 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
@@ -30,6 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Gareth Hughes <gareth@valinux.com>
* Kevin E. Martin <martin@valinux.com>
+ * Michel Dänzer <michdaen@iiic.ethz.ch>
*
*/
@@ -38,13 +39,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
-/* FIXME: This is endian-specific */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
typedef struct {
GLubyte blue;
GLubyte green;
GLubyte red;
GLubyte alpha;
} r128_color_t;
+#else
+typedef struct {
+ GLubyte alpha;
+ GLubyte red;
+ GLubyte green;
+ GLubyte blue;
+} r128_color_t;
+#endif
/* The vertex structure. The final tu1/tv1 values are only used in
* multitexture modes, and the rhw2 value is currently never used.
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
index 246734fc3..85bb9bab5 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
@@ -79,18 +79,22 @@ static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name )
/* Append any chipset-specific information. None yet.
*/
- /* Append any AGP-specific information.
+ /* Append any AGP/PCI-specific information.
*/
- switch ( rmesa->radeonScreen->AGPMode ) {
- case 1:
- strncat( buffer, " AGP 1x", 7 );
- break;
- case 2:
- strncat( buffer, " AGP 2x", 7 );
- break;
- case 4:
- strncat( buffer, " AGP 4x", 7 );
- break;
+ if ( rmesa->radeonScreen->IsPCI ) {
+ strncat( buffer, " PCI", 4 );
+ } else {
+ switch ( rmesa->radeonScreen->AGPMode ) {
+ case 1:
+ strncat( buffer, " AGP 1x", 7 );
+ break;
+ case 2:
+ strncat( buffer, " AGP 2x", 7 );
+ break;
+ case 4:
+ strncat( buffer, " AGP 4x", 7 );
+ break;
+ }
}
/* Append any CPU-specific information.
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
index c0137d0bd..fd16449d7 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
@@ -386,7 +386,14 @@ static int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
int i;
while ( 1 ) {
+#if defined(__alpha__)
+ /* necessary to preserve the Alpha paradigm */
+ /* NOTE: this will not work on SPARSE machines */
+ mem_barrier();
+ frame = *(volatile CARD32 *)(void *)(RADEONMMIO + RADEON_LAST_FRAME_REG);
+#else
frame = INREG( RADEON_LAST_FRAME_REG );
+#endif
if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) {
break;
}
@@ -609,7 +616,14 @@ static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask,
}
#else
while ( 1 ) {
+#if defined(__alpha__)
+ /* necessary to preserve the Alpha paradigm */
+ /* NOTE: this will not work on SPARSE machines */
+ mem_barrier();
+ clear = *(volatile CARD32 *)(void *)(RADEONMMIO + RADEON_LAST_CLEAR_REG);
+#else
clear = INREG( RADEON_LAST_CLEAR_REG );
+#endif
if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
break;
}
diff --git a/xc/programs/Xserver/hw/xfree86/common/compiler.h b/xc/programs/Xserver/hw/xfree86/common/compiler.h
index 61c487d68..404e5ffe4 100644
--- a/xc/programs/Xserver/hw/xfree86/common/compiler.h
+++ b/xc/programs/Xserver/hw/xfree86/common/compiler.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/compiler.h,v 3.43 1999/06/14 12:02:08 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/compiler.h,v 3.77 2001/01/06 21:29:04 tsi Exp $ */
/*
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
*
@@ -24,6 +24,11 @@
/* $XConsortium: compiler.h /main/16 1996/10/25 15:38:34 kaleb $ */
#ifndef _COMPILER_H
+
+#if !defined(_XF86_ANSIC_H) && defined(XFree86Module)
+# error missing #include "xf86_ansic.h" before #include "compiler.h"
+#endif
+
#define _COMPILER_H
#ifndef __STDC__
@@ -40,14 +45,8 @@
# ifdef __GNUC__
# define volatile __volatile__
# define const __const__
-# ifdef PC98
-# undef NO_INLINE
-# endif
# else
# define const /**/
-# ifdef PC98
-# define __inline__ /**/
-# endif
# ifdef __HIGHC__
# define __inline__ _Inline
# endif
@@ -63,6 +62,31 @@
#define inl RealInl
#endif
+#if defined(QNX4) /* Do this for now to keep Watcom happy */
+#define outb outp
+#define outw outpw
+#define outl outpd
+#define inb inp
+#define inw inpw
+#define inl inpd
+
+/* Define the ffs function for inlining */
+extern int ffs(unsigned long);
+#pragma aux ffs_ = \
+ "bsf edx, eax" \
+ "jnz bits_set" \
+ "xor eax, eax" \
+ "jmp exit1" \
+ "bits_set:" \
+ "mov eax, edx" \
+ "inc eax" \
+ "exit1:" \
+ __parm [eax] \
+ __modify [eax edx] \
+ __value [eax] \
+ ;
+#endif
+
#if defined(NO_INLINE) || defined(DO_PROTOTYPES)
#if !defined(__sparc__)
@@ -110,7 +134,9 @@ extern int testinx(unsigned short, unsigned char);
#ifdef __GNUC__
-#if defined(linux) && defined(__alpha__)
+#if (defined(linux) || defined(__FreeBSD__)) && defined(__alpha__)
+
+#ifdef linux
/* for Linux on Alpha, we use the LIBC _inx/_outx routines */
/* note that the appropriate setup via "ioperm" needs to be done */
/* *before* any inx/outx is done. */
@@ -157,6 +183,22 @@ inl(unsigned short port)
return _inl(port);
}
+#endif /* linux */
+
+#if defined(__FreeBSD__) && !defined(DO_PROTOTYPES)
+
+/* for FreeBSD on Alpha, we use the libio inx/outx routines */
+/* note that the appropriate setup via "ioperm" needs to be done */
+/* *before* any inx/outx is done. */
+
+extern void outb(unsigned int port, unsigned char val);
+extern void outw(unsigned int port, unsigned short val);
+extern void outl(unsigned int port, unsigned int val);
+extern unsigned char inb(unsigned int port);
+extern unsigned short inw(unsigned int port);
+extern unsigned int inl(unsigned int port);
+
+#endif /* __FreeBSD__ && !DO_PROTOTYPES */
/*
* inline functions to do unaligned accesses
@@ -313,6 +355,10 @@ static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
#endif
}
+/* to flush the I-cache before jumping to code which just got loaded */
+#define PAL_imb 134
+#define istream_mem_barrier() \
+ __asm__ __volatile__("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
#define mem_barrier() __asm__ __volatile__("mb" : : : "memory")
#ifdef __ELF__
#define write_mem_barrier() __asm__ __volatile__("wmb" : : : "memory")
@@ -320,6 +366,77 @@ static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
#define write_mem_barrier() mem_barrier()
#endif
+
+#elif defined(linux) && defined(__ia64__)
+
+#include <inttypes.h>
+
+#include <sys/io.h>
+
+struct __una_u64 { uint64_t x __attribute__((packed)); };
+struct __una_u32 { uint32_t x __attribute__((packed)); };
+struct __una_u16 { uint16_t x __attribute__((packed)); };
+
+extern __inline__ unsigned long
+__uldq (const unsigned long * r11)
+{
+ const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+ return ptr->x;
+}
+
+extern __inline__ unsigned long
+__uldl (const unsigned int * r11)
+{
+ const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+ return ptr->x;
+}
+
+extern __inline__ unsigned long
+__uldw (const unsigned short * r11)
+{
+ const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+ return ptr->x;
+}
+
+extern __inline__ void
+__ustq (unsigned long r5, unsigned long * r11)
+{
+ struct __una_u64 *ptr = (struct __una_u64 *) r11;
+ ptr->x = r5;
+}
+
+extern __inline__ void
+__ustl (unsigned long r5, unsigned int * r11)
+{
+ struct __una_u32 *ptr = (struct __una_u32 *) r11;
+ ptr->x = r5;
+}
+
+extern __inline__ void
+__ustw (unsigned long r5, unsigned short * r11)
+{
+ struct __una_u16 *ptr = (struct __una_u16 *) r11;
+ ptr->x = r5;
+}
+
+#define ldq_u(p) __uldq(p)
+#define ldl_u(p) __uldl(p)
+#define ldw_u(p) __uldw(p)
+#define stq_u(v,p) __ustq(v,p)
+#define stl_u(v,p) __ustl(v,p)
+#define stw_u(v,p) __ustw(v,p)
+
+#define mem_barrier() __asm__ __volatile__ ("mf" ::: "memory")
+#define write_mem_barrier() __asm__ __volatile__ ("mf" ::: "memory")
+
+#undef outb
+#undef outw
+#undef outl
+
+#define outb(a,b) _outb(b,a)
+#define outw(a,b) _outw(b,a)
+#define outl(a,b) _outl(b,a)
+
#elif (defined(linux) || defined(Lynx)) && defined(__sparc__)
#if !defined(Lynx)
@@ -327,19 +444,24 @@ static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
#define ASI_PL 0x88
#endif
+#define barrier() __asm__ __volatile__(".word 0x8143e00a": : :"memory")
+
static __inline__ void outb(unsigned long port, unsigned char val)
{
__asm__ __volatile__("stba %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
}
static __inline__ void outw(unsigned long port, unsigned short val)
{
__asm__ __volatile__("stha %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
}
static __inline__ void outl(unsigned long port, unsigned int val)
{
__asm__ __volatile__("sta %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
}
static __inline__ unsigned int inb(unsigned long port)
@@ -363,47 +485,244 @@ static __inline__ unsigned int inl(unsigned long port)
return ret;
}
+static __inline__ unsigned char xf86ReadMmio8(void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned char ret;
+
+ __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned short xf86ReadMmio16Be(void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned short ret;
+
+ __asm__ __volatile__("lduh [%1], %0" : "=r" (ret) : "r" (addr));
+ return ret;
+}
+
+static __inline__ unsigned short xf86ReadMmio16Le(void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned short ret;
+
+ __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int xf86ReadMmio32Be(void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned int ret;
+
+ __asm__ __volatile__("ld [%1], %0" : "=r" (ret) : "r" (addr));
+ return ret;
+}
+
+static __inline__ unsigned int xf86ReadMmio32Le(void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned int ret;
+
+ __asm__ __volatile__("lda [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ void xf86WriteMmio8(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stba %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void xf86WriteMmio16Be(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sth %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+ barrier();
+}
+
+static __inline__ void xf86WriteMmio16Le(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stha %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void xf86WriteMmio32Be(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("st %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+ barrier();
+}
+
+static __inline__ void xf86WriteMmio32Le(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sta %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void xf86WriteMmio8NB(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stba %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
+static __inline__ void xf86WriteMmio16BeNB(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sth %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+}
+
+static __inline__ void xf86WriteMmio16LeNB(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stha %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
+static __inline__ void xf86WriteMmio32BeNB(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("st %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+}
+
+static __inline__ void xf86WriteMmio32LeNB(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sta %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
#endif /* !Lynx */
-#include <string.h>
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads. Define some
+ * packed structures to talk about such things with.
+ */
+
+#if defined(__arch64__) || defined(__sparcv9)
+struct __una_u64 { unsigned long x __attribute__((packed)); };
+#endif
+struct __una_u32 { unsigned int x __attribute__((packed)); };
+struct __una_u16 { unsigned short x __attribute__((packed)); };
static __inline__ unsigned long ldq_u(unsigned long *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+#if defined(__arch64__) || defined(__sparcv9)
+ const struct __una_u64 *ptr = (const struct __una_u64 *) p;
+#else
+ const struct __una_u32 *ptr = (const struct __una_u32 *) p;
+#endif
+ return ptr->x;
+#else
unsigned long ret;
memmove(&ret, p, sizeof(*p));
return ret;
+#endif
}
static __inline__ unsigned long ldl_u(unsigned int *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+ const struct __una_u32 *ptr = (const struct __una_u32 *) p;
+ return ptr->x;
+#else
unsigned int ret;
memmove(&ret, p, sizeof(*p));
return ret;
+#endif
}
static __inline__ unsigned long ldw_u(unsigned short *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+ const struct __una_u16 *ptr = (const struct __una_u16 *) p;
+ return ptr->x;
+#else
unsigned short ret;
memmove(&ret, p, sizeof(*p));
return ret;
+#endif
}
static __inline__ void stq_u(unsigned long val, unsigned long *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+#if defined(__arch64__) || defined(__sparcv9)
+ struct __una_u64 *ptr = (struct __una_u64 *) p;
+#else
+ struct __una_u32 *ptr = (struct __una_u32 *) p;
+#endif
+ ptr->x = val;
+#else
unsigned long tmp = val;
memmove(p, &tmp, sizeof(*p));
+#endif
}
static __inline__ void stl_u(unsigned long val, unsigned int *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+ struct __una_u32 *ptr = (struct __una_u32 *) p;
+ ptr->x = val;
+#else
unsigned int tmp = val;
memmove(p, &tmp, sizeof(*p));
+#endif
}
static __inline__ void stw_u(unsigned long val, unsigned short *p)
{
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+ struct __una_u16 *ptr = (struct __una_u16 *) p;
+ ptr->x = val;
+#else
unsigned short tmp = val;
memmove(p, &tmp, sizeof(*p));
+#endif
}
#define mem_barrier() /* XXX: nop for now */
@@ -428,7 +747,7 @@ outw(unsigned short port, unsigned short val)
static __inline__ void
outl(unsigned short port, unsigned int val)
{
- *(volatile unsigned long*)(((unsigned short)(port))+IOPortBase) = val;
+ *(volatile unsigned int*)(((unsigned short)(port))+IOPortBase) = val;
}
static __inline__ unsigned int
@@ -446,7 +765,7 @@ inw(unsigned short port)
static __inline__ unsigned int
inl(unsigned short port)
{
- return(*(volatile unsigned long*)(((unsigned short)(port))+IOPortBase));
+ return(*(volatile unsigned int*)(((unsigned short)(port))+IOPortBase));
}
@@ -488,13 +807,13 @@ static __inline__ unsigned long ldw_u(unsigned short * r11)
}
#define stq_u(v,p) stl_u(v,p)
-#define stl_u(v,p) ((unsigned char *)(p)) = (v); \
- ((unsigned char *)(p)+1) = ((v) >> 8); \
- ((unsigned char *)(p)+2) = ((v) >> 16); \
- ((unsigned char *)(p)+3) = ((v) >> 24)
+#define stl_u(v,p) (*(unsigned char *)(p)) = (v); \
+ (*(unsigned char *)(p)+1) = ((v) >> 8); \
+ (*(unsigned char *)(p)+2) = ((v) >> 16); \
+ (*(unsigned char *)(p)+3) = ((v) >> 24)
-#define stw_u(v,p) ((unsigned char *)(p)) = (v); \
- ((unsigned char *)(p)+1) = ((v) >> 8)
+#define stw_u(v,p) (*(unsigned char *)(p)) = (v); \
+ (*(unsigned char *)(p)+1) = ((v) >> 8)
#define mem_barrier() /* NOP */
#endif /* __mips__ */
@@ -503,361 +822,285 @@ static __inline__ unsigned long ldw_u(unsigned short * r11)
#define ldq_u(p) (*((unsigned long *)(p)))
#define ldl_u(p) (*((unsigned int *)(p)))
#define ldw_u(p) (*((unsigned short *)(p)))
-#define stq_u(v,p) ((unsigned long *)(p)) = (v)
-#define stl_u(v,p) ((unsigned int *)(p)) = (v)
-#define stw_u(v,p) ((unsigned short *)(p)) = (v)
+#define stq_u(v,p) (*(unsigned long *)(p)) = (v)
+#define stl_u(v,p) (*(unsigned int *)(p)) = (v)
+#define stw_u(v,p) (*(unsigned short *)(p)) = (v)
#define mem_barrier() /* NOP */
#define write_mem_barrier() /* NOP */
#endif /* __arm32__ */
-#elif (defined(Lynx) || defined(linux)) && defined(__powerpc__)
+#elif (defined(Lynx) || defined(linux) || defined(__OpenBSD__)) && defined(__powerpc__)
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
extern volatile unsigned char *ioBase;
#define eieio() __asm__ __volatile__ ("eieio")
-static __inline__ void
-outb(unsigned short port, unsigned char value)
+static __inline__ unsigned char
+xf86ReadMmio8(void *base, const unsigned long offset)
{
- *((volatile unsigned char *)(ioBase + port)) = value; eieio();
+ register unsigned char val;
+ __asm__ __volatile__(
+ "lbzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return(val);
}
-static __inline__ void
-outw(unsigned short port, unsigned short value)
+static __inline__ unsigned short
+xf86ReadMmio16Be(void *base, const unsigned long offset)
{
- __asm__ __volatile__ (
- "sthbrx %0,%1,%2\n\t"
- "eieio"
- :
- : "r" (value), "r" (ioBase), "r" (port)
- : "memory"
- );
+ register unsigned short val;
+ __asm__ __volatile__(
+ "lhzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return(val);
}
-static __inline__ void
-outl(unsigned short port, unsigned int value)
+static __inline__ unsigned short
+xf86ReadMmio16Le(void *base, const unsigned long offset)
{
- __asm__ __volatile__ (
- "stwbrx %0,%1,%2\n\t"
- "eieio"
- :
- : "r" (value), "r" (ioBase), "r" (port)
- : "memory"
- );
+ register unsigned short val;
+ __asm__ __volatile__(
+ "lhbrx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return(val);
}
static __inline__ unsigned int
-inb(unsigned short port)
+xf86ReadMmio32Be(void *base, const unsigned long offset)
{
- unsigned char val;
-
- val = *((volatile unsigned char *)(ioBase + port));
- eieio();
- return(val);
+ register unsigned int val;
+ __asm__ __volatile__(
+ "lwzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return(val);
}
static __inline__ unsigned int
-inw(unsigned short port)
+xf86ReadMmio32Le(void *base, const unsigned long offset)
{
- register unsigned short val;
-
- __asm__ ("lhbrx %0,%1,%2\n\t"
- "eieio"
- : "=r" (val)
- : "r" (ioBase), "r" (port)
- );
- return(val);
+ register unsigned int val;
+ __asm__ __volatile__(
+ "lwbrx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return(val);
}
-static __inline__ unsigned int
-inl(unsigned short port)
+static __inline__ void
+xf86WriteMmioNB8(void *base, const unsigned long offset,
+ const unsigned char val)
{
- register unsigned long val;
-
- __asm__ ("lwbrx %0,%1,%2\n\t"
- "eieio"
- : "=r" (val)
- : "r" (ioBase), "r" (port)
- );
- return(val);
+ __asm__ __volatile__(
+ "stbx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
}
-#define ldq_u(p) ldl_u(p)
-#define ldl_u(p) ((*(unsigned char *)(p)) | \
- (*((unsigned char *)(p)+1)<<8) | \
- (*((unsigned char *)(p)+2)<<16) | \
- (*((unsigned char *)(p)+3)<<24))
-#define ldw_u(p) ((*(unsigned char *)(p)) | \
- (*((unsigned char *)(p)+1)<<8))
-
-#define stq_u(v,p) stl_u(v,p)
-#define stl_u(v,p) (*(unsigned char *)(p)) = (v); \
- (*((unsigned char *)(p)+1)) = ((v) >> 8); \
- (*((unsigned char *)(p)+2)) = ((v) >> 16); \
- (*((unsigned char *)(p)+3)) = ((v) >> 24)
-#define stw_u(v,p) (*(unsigned char *)(p)) = (v); \
- (*((unsigned char *)(p)+1)) = ((v) >> 8)
-
-#define mem_barrier() eieio()
-#define write_mem_barrier() eieio()
-
-#else /* ix86 */
-
-#define ldq_u(p) (*((unsigned long *)(p)))
-#define ldl_u(p) (*((unsigned int *)(p)))
-#define ldw_u(p) (*((unsigned short *)(p)))
-#define stq_u(v,p) ((unsigned long *)(p)) = (v)
-#define stl_u(v,p) ((unsigned int *)(p)) = (v)
-#define stw_u(v,p) ((unsigned short *)(p)) = (v)
-#define mem_barrier() /* NOP */
-#define write_mem_barrier() /* NOP */
-
-#if !defined(FAKEIT) && !defined(__mc68000__)
-#ifdef GCCUSESGAS
+static __inline__ void
+xf86WriteMmioNB16Le(void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ __asm__ __volatile__(
+ "sthbrx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
-/*
- * If gcc uses gas rather than the native assembler, the syntax of these
- * inlines has to be different. DHD
- */
-#ifndef PC98
+static __inline__ void
+xf86WriteMmioNB16Be(void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ __asm__ __volatile__(
+ "sthx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
static __inline__ void
-outb(unsigned short port, unsigned char val)
+xf86WriteMmioNB32Le(void *base, const unsigned long offset,
+ const unsigned int val)
{
- __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+ __asm__ __volatile__(
+ "stwbrx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
}
+static __inline__ void
+xf86WriteMmioNB32Be(void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ __asm__ __volatile__(
+ "stwx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
static __inline__ void
-outw(unsigned short port, unsigned short val)
+xf86WriteMmio8(void *base, const unsigned long offset,
+ const unsigned char val)
{
- __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+ xf86WriteMmioNB8(base,offset,val);
+ eieio();
}
static __inline__ void
-outl(unsigned short port, unsigned int val)
+xf86WriteMmio16Le(void *base, const unsigned long offset,
+ const unsigned short val)
{
- __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+ xf86WriteMmioNB16Le(base,offset,val);
+ eieio();
}
-static __inline__ unsigned int
-inb(unsigned short port)
+static __inline__ void
+xf86WriteMmio16Be(void *base, const unsigned long offset,
+ const unsigned short val)
{
- unsigned char ret;
- __asm__ __volatile__("inb %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ xf86WriteMmioNB16Be(base,offset,val);
+ eieio();
}
-static __inline__ unsigned int
-inw(unsigned short port)
+static __inline__ void
+xf86WriteMmio32Le(void *base, const unsigned long offset,
+ const unsigned int val)
{
- unsigned short ret;
- __asm__ __volatile__("inw %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ xf86WriteMmioNB32Le(base,offset,val);
+ eieio();
}
-static __inline__ unsigned int
-inl(unsigned short port)
+static __inline__ void
+xf86WriteMmio32Be(void *base, const unsigned long offset,
+ const unsigned int val)
{
- unsigned int ret;
- __asm__ __volatile__("inl %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ xf86WriteMmioNB32Be(base,offset,val);
+ eieio();
}
-#else /* PC98 */
static __inline__ void
-_outb(unsigned short port, unsigned char val)
+outb(unsigned short port, unsigned char value)
{
- __asm__ __volatile__("outb %0,%1" ::"a" (val), "d" (port));
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio8((void *)ioBase,port,value);
}
static __inline__ void
-_outw(unsigned short port, unsigned short val)
+outw(unsigned short port, unsigned short value)
{
- __asm__ __volatile__("outw %0,%1" ::"a" (val), "d" (port));
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio16Le((void *)ioBase,port,value);
}
-
+
static __inline__ void
-_outl(unsigned short port, unsigned int val)
+outl(unsigned short port, unsigned int value)
{
- __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio32Le((void *)ioBase,port,value);
}
-
static __inline__ unsigned int
-_inb(unsigned short port)
+inb(unsigned short port)
{
- unsigned char ret;
- __asm__ __volatile__("inb %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ if(ioBase == MAP_FAILED) return(0);
+ return(xf86ReadMmio8((void *)ioBase, port));
}
static __inline__ unsigned int
-_inw(unsigned short port)
+inw(unsigned short port)
{
- unsigned char ret;
- __asm__ __volatile__("inw %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ if(ioBase == MAP_FAILED) return(0);
+ return(xf86ReadMmio16Le((void *)ioBase, port));
}
static __inline__ unsigned int
-_inl(unsigned short port)
+inl(unsigned short port)
{
- unsigned int ret;
- __asm__ __volatile__("inl %1,%0" :
- "=a" (ret) :
- "d" (port));
- return ret;
+ if(ioBase == MAP_FAILED) return(0);
+ return(xf86ReadMmio32Le((void *)ioBase, port));
}
+#define ldq_u(p) ldl_u(p)
+#define ldl_u(p) ((*(unsigned char *)(p)) | \
+ (*((unsigned char *)(p)+1)<<8) | \
+ (*((unsigned char *)(p)+2)<<16) | \
+ (*((unsigned char *)(p)+3)<<24))
+#define ldw_u(p) ((*(unsigned char *)(p)) | \
+ (*((unsigned char *)(p)+1)<<8))
-#if defined(PC98_PW) || defined(PC98_XKB) || defined(PC98_NEC) || defined(PC98_PWLB) || defined(PC98_GA968)
-#define PW_PORT 0x600
-extern short chipID;
-extern void *mmioBase;
-extern unsigned short _port_tbl[];
-#define port_convert(x) _port_tbl[(unsigned short)x]
-#endif
+#define stq_u(v,p) stl_u(v,p)
+#define stl_u(v,p) (*(unsigned char *)(p)) = (v); \
+ (*((unsigned char *)(p)+1)) = ((v) >> 8); \
+ (*((unsigned char *)(p)+2)) = ((v) >> 16); \
+ (*((unsigned char *)(p)+3)) = ((v) >> 24)
+#define stw_u(v,p) (*(unsigned char *)(p)) = (v); \
+ (*((unsigned char *)(p)+1)) = ((v) >> 8)
-#if defined(PC98_WAB) || defined(PC98_GANB_WAP)
-static __inline__ unsigned short
-port_convert(unsigned short port)
-{
- port <<= 8;
- port &= 0x7f00; /* Mask 0111 1111 0000 0000 */
- port |= 0xE0;
- return port;
-}
-#endif /* PC98_WAB || PC98_GANB_WAP */
-
-#if defined(PC98_WABEP)
-static __inline__ unsigned short
-port_convert(unsigned short port)
-{
- port &= 0x7f; /* Mask 0000 0000 0111 1111 */
- port |= 0x0f00;
- return port;
-}
-#endif /* PC98_WABEP */
+#define mem_barrier() eieio()
+#define write_mem_barrier() eieio()
-#ifdef PC98_WSNA
-static __inline__ unsigned short
-port_convert(unsigned short port)
-{
- port <<= 8;
- port &= 0x7f00; /* Mask 0111 1111 0000 0000 */
- port |= 0xE2;
- return port;
-}
-#endif /* PC98_WSNA */
+#else /* ix86 */
-#ifdef PC98_NKVNEC
-#ifdef PC98_NEC_CIRRUS2
-static __inline__ unsigned short
-port_convert(unsigned short port)
-{
- port = (port & 0xf) + ((port & 0xf0) << 4) + 0x0050;
- return port;
-}
-#else
-static __inline__ unsigned short
-port_convert(unsigned short port)
-{
- port = (port & 0xf) + ((port & 0xf0) << 4) + 0x00a0;
- return port;
-}
-#endif /* PC98_NEC_CIRRUS2 */
-#endif /* PC98_NKVNEC */
+#define ldq_u(p) (*((unsigned long *)(p)))
+#define ldl_u(p) (*((unsigned int *)(p)))
+#define ldw_u(p) (*((unsigned short *)(p)))
+#define stq_u(v,p) (*(unsigned long *)(p)) = (v)
+#define stl_u(v,p) (*(unsigned int *)(p)) = (v)
+#define stw_u(v,p) (*(unsigned short *)(p)) = (v)
+#define mem_barrier() /* NOP */
+#define write_mem_barrier() /* NOP */
-#if defined(PC98_TGUI)
-extern void *mmioBase;
-#endif
+#if !defined(FAKEIT) && !defined(__mc68000__)
+#ifdef GCCUSESGAS
+
+/*
+ * If gcc uses gas rather than the native assembler, the syntax of these
+ * inlines has to be different. DHD
+ */
static __inline__ void
outb(unsigned short port, unsigned char val)
{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- *(volatile unsigned char *)((char *)mmioBase+(port)) = (unsigned char)(val);
-#else
__asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
-#endif
}
+
static __inline__ void
outw(unsigned short port, unsigned short val)
{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- *(volatile unsigned short *)((char *)mmioBase+(port)) = (unsigned short)(val);
-#else
__asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
-#endif
}
static __inline__ void
outl(unsigned short port, unsigned int val)
{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- *(volatile unsigned int *)((char *)mmioBase+(port)) = (unsigned int)(val);
-#else
__asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
-#endif
}
static __inline__ unsigned int
inb(unsigned short port)
{
unsigned char ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- ret =*(volatile unsigned char *)((char *)mmioBase+(port));
-#else
__asm__ __volatile__("inb %1,%0" :
"=a" (ret) :
"d" (port));
-#endif
return ret;
}
@@ -865,22 +1108,9 @@ static __inline__ unsigned int
inw(unsigned short port)
{
unsigned short ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- ret =*(volatile unsigned short *)((char *)mmioBase+(port));
-#else
__asm__ __volatile__("inw %1,%0" :
"=a" (ret) :
"d" (port));
-#endif
return ret;
}
@@ -888,27 +1118,12 @@ static __inline__ unsigned int
inl(unsigned short port)
{
unsigned int ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)||defined(PC98_TGUI)
- ret =*(volatile unsigned int *)((char *)mmioBase+(port));
-#else
__asm__ __volatile__("inl %1,%0" :
"=a" (ret) :
"d" (port));
-#endif
return ret;
}
-#endif /* PC98 */
-
#else /* GCCUSESGAS */
static __inline__ void
@@ -1023,9 +1238,9 @@ inl(unsigned short port)
#define ldq_u(p) (*((unsigned long long *)(p)))
#define ldl_u(p) (*((unsigned long *)(p)))
#define ldw_u(p) (*((unsigned short *)(p)))
-#define stq_u(v,p) ((unsigned long long *)(p)) = (v)
-#define stl_u(v,p) ((unsigned long *)(p)) = (v)
-#define stw_u(v,p) ((unsigned short *)(p)) = (v)
+#define stq_u(v,p) (*(unsigned long long *)(p)) = (v)
+#define stl_u(v,p) (*(unsigned long *)(p)) = (v)
+#define stw_u(v,p) (*(unsigned short *)(p)) = (v)
#define mem_barrier() eieio()
#define write_mem_barrier() eieio()
@@ -1046,10 +1261,10 @@ extern volatile unsigned char *ioBase;
extern void debug_outb(unsigned int a, unsigned char b, int line, char *file);
extern void debug_outw(unsigned int a, unsigned short w, int line, char *file);
-extern void debug_outl(unsigned int a, unsigned long l, int line, char *file);
+extern void debug_outl(unsigned int a, unsigned int l, int line, char *file);
extern unsigned char debug_inb(unsigned int a, int line, char *file);
extern unsigned short debug_inw(unsigned int a, int line, char *file);
-extern unsigned long debug_inl(unsigned int a, int line, char *file);
+extern unsigned int debug_inl(unsigned int a, int line, char *file);
#define outb(a,b) debug_outb(a,b, __LINE__, __FILE__)
#define outw(a,w) debug_outw(a,w, __LINE__, __FILE__)
@@ -1062,7 +1277,7 @@ extern unsigned long debug_inl(unsigned int a, int line, char *file);
extern unsigned char inb(unsigned int a);
extern unsigned short inw(unsigned int a);
-extern unsigned long inl(unsigned int a);
+extern unsigned int inl(unsigned int a);
# if PPCIO_INLINE
@@ -1073,15 +1288,15 @@ extern unsigned long inl(unsigned int a);
# else /* !PPCIO_INLINE */
extern void outb(unsigned int a, unsigned char b);
-extern void outw(unsigned int a, unsigned char w);
-extern void outl(unsigned int a, unsigned char l);
+extern void outw(unsigned int a, unsigned short w);
+extern void outl(unsigned int a, unsigned int l);
# endif /* PPCIO_INLINE */
#endif /* !PPCIO_DEBUG */
#else /* !GNUC && !PPC */
-#if !defined(AMOEBA) && !defined(MINIX)
+#if !defined(AMOEBA) && !defined(MINIX) && !defined(QNX4)
# if defined(__STDC__) && (__STDC__ == 1)
# ifndef asm
# define asm __asm
@@ -1097,284 +1312,25 @@ extern void outl(unsigned int a, unsigned char l);
# endif
# endif
# endif
-# ifndef PC98
# ifndef SCO325
+# if defined(USL)
+# if defined(IN_MODULE)
+# /* avoid including <sys/types.h> for <sys/inline.h> on UnixWare */
+# define ushort unsigned short
+# define ushort_t unsigned short
+# define ulong unsigned long
+# define ulong_t unsigned long
+# define uint_t unsigned int
+# define uchar_t unsigned char
+# else
+# include <sys/types.h>
+# endif /* IN_MODULE */
+# endif /* USL */
# include <sys/inline.h>
# else
# include "scoasm.h"
# endif
-# else
-#if defined(PC98_PW) || defined(PC98_XKB) || defined(PC98_NEC) || defined(PC98_PWLB) || defined(PC98_GA968)
-#define PW_PORT 0x600
-extern short chipID;
-extern void *mmioBase;
-extern unsigned short _port_tbl[];
-#define port_convert(x) _port_tbl[(unsigned short)x]
-#endif
-
-asm void _outl(port,val)
-{
-%reg port,val;
- movl port, %edx
- movl val, %eax
- outl (%dx)
-%reg port; mem val;
- movl port, %edx
- movl val, %eax
- outl (%dx)
-%mem port; reg val;
- movw port, %dx
- movl val, %eax
- outl (%dx)
-%mem port,val;
- movw port, %dx
- movl val, %eax
- outl (%dx)
-}
-
-asm void _outw(port,val)
-{
-%reg port,val;
- movl port, %edx
- movl val, %eax
- data16
- outl (%dx)
-%reg port; mem val;
- movl port, %edx
- movw val, %ax
- data16
- outl (%dx)
-%mem port; reg val;
- movw port, %dx
- movl val, %eax
- data16
- outl (%dx)
-%mem port,val;
- movw port, %dx
- movw val, %ax
- data16
- outl (%dx)
-}
-
-asm void _outb(port,val)
-{
-%reg port,val;
- movl port, %edx
- movl val, %eax
- outb (%dx)
-%reg port; mem val;
- movl port, %edx
- movb val, %al
- outb (%dx)
-%mem port; reg val;
- movw port, %dx
- movl val, %eax
- outb (%dx)
-%mem port,val;
- movw port, %dx
- movb val, %al
- outb (%dx)
-}
-
-asm int _inl(port)
-{
-%reg port;
- movl port, %edx
- inl (%dx)
-%mem port;
- movw port, %dx
- inl (%dx)
-}
-
-asm int _inw(port)
-{
-%reg port;
- subl %eax, %eax
- movl port, %edx
- data16
- inl (%dx)
-%mem port;
- subl %eax, %eax
- movw port, %dx
- data16
- inl (%dx)
-}
-
-asm int _inb(port)
-{
-%reg port;
- subl %eax, %eax
- movl port, %edx
- inb (%dx)
-%mem port;
- subl %eax, %eax
- movw port, %dx
- inb (%dx)
-}
-
-#if defined(PC98_WAB) || defined(PC98_GANB_WAP)
-static unsigned short
-port_convert(unsigned short port)
-{
- port <<= 8;
- port &= 0x7f00; /* Mask 0111 1111 0000 0000 */
- port |= 0xE0;
- return port;
-}
-#endif /* PC98_WAB || PC98_GANB_WAP */
-
-#if defined(PC98_WABEP)
-static unsigned short
-port_convert(unsigned short port)
-{
- port &= 0x7f; /* Mask 0000 0000 0111 1111 */
- port |= 0x0f00;
- return port;
-}
-#endif /* PC98_WABEP */
-
-#ifdef PC98_WSNA
-static unsigned short
-port_convert(unsigned short port)
-{
- port <<= 8;
- port &= 0x7f00; /* Mask 0111 1111 0000 0000 */
- port |= 0xE2;
- return port;
-}
-#endif /* PC98_WSNA */
-
-#ifdef PC98_NKVNEC
-#ifdef PC98_NEC_CIRRUS2
-static unsigned short
-port_convert(unsigned short port)
-{
- port = (port & 0xf) + ((port & 0xf0) << 4) + 0x0050;
- return port;
-}
-#else
-static unsigned short
-port_convert(unsigned short port)
-{
- port = (port & 0xf) + ((port & 0xf0) << 4) + 0x00a0;
- return port;
-}
-#endif /* PC98_NEC_CIRRUS2 */
-#endif /* PC98_NKVNEC */
-
-static void outl(port,val)
-{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- *(volatile unsigned int *)((char *)mmioBase+(port)) = (unsigned int)(val);
-#else
- _outl(port,val);
-#endif
-}
-
-static void outw(port,val)
-{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- *(volatile unsigned short *)((char *)mmioBase+(port)) = (unsigned short)(val);
-#else
- _outw(port,val);
-#endif
-}
-
-static void outb(port,val)
-{
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- *(volatile unsigned char *)((char *)mmioBase+(port)) = (unsigned char)(val);
-#else
- _outb(port,val);
-#endif
-}
-
-static int inl(port)
-{
- unsigned int ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- ret =*(volatile unsigned int *)((char *)mmioBase+(port));
-#else
- ret = _inl(port);
-#endif
- return ret;
-}
-
-static int inw(port)
-{
- unsigned short ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- ret =*(volatile unsigned short *)((char *)mmioBase+(port));
-#else
- ret = _inw(port);
-#endif
- return ret;
-}
-
-static int inb(port)
-{
- unsigned char ret;
-
-#if defined(PC98_GANB_WAP) || defined(PC98_NKVNEC) || defined(PC98_WAB) || \
- defined(PC98_WABEP) || defined(PC98_WSNA) || defined(PC98_PW) || \
- defined(PC98_XKB) || defined(PC98_NEC)
- unsigned short tmp;
- tmp=port_convert(port);
- port=tmp;
-#endif
-
-#if defined(PC98_NEC)||defined(PC98_PWLB)
- ret =*(volatile unsigned char *)((char *)mmioBase+(port));
-#else
- ret = _inb(port);
-#endif
- return ret;
-}
-
-
-# endif /* PC98 */
# if !defined(__HIGHC__) && !defined(SCO325)
# pragma asm partial_optimization outl
# pragma asm partial_optimization outw
@@ -1387,13 +1343,34 @@ static int inb(port)
#define ldq_u(p) (*((unsigned long *)(p)))
#define ldl_u(p) (*((unsigned int *)(p)))
#define ldw_u(p) (*((unsigned short *)(p)))
-#define stq_u(v,p) ((unsigned long *)(p)) = (v)
-#define stl_u(v,p) ((unsigned int *)(p)) = (v)
-#define stw_u(v,p) ((unsigned short *)(p)) = (v)
+#define stq_u(v,p) (*(unsigned long *)(p)) = (v)
+#define stl_u(v,p) (*(unsigned int *)(p)) = (v)
+#define stw_u(v,p) (*(unsigned short *)(p)) = (v)
#define mem_barrier() /* NOP */
#define write_mem_barrier() /* NOP */
#endif /* __GNUC__ */
+#if defined(QNX4)
+#include <sys/types.h>
+extern unsigned inb(unsigned port);
+extern unsigned inw(unsigned port);
+extern unsigned inl(unsigned port);
+extern void outb(unsigned port, unsigned val);
+extern void outw(unsigned port, unsigned val);
+extern void outl(unsigned port, unsigned val);
+#define ldq_u(p) (*((unsigned long *)(p)))
+#define ldl_u(p) (*((unsigned int *)(p)))
+#define ldw_u(p) (*((unsigned short *)(p)))
+#undef stq_u
+#define stq_u(v,p) ((unsigned long *)(p)) = (v)
+#undef stl_u
+#define stl_u(v,p) ((unsigned int *)(p)) = (v)
+#undef stw_u
+#define stw_u(v,p) ((unsigned short *)(p)) = (v)
+#define mem_barrier() /* NOP */
+#define write_mem_barrier() /* NOP */
+#endif /* QNX4 */
+
#if defined(IODEBUG) && defined(__GNUC__)
#undef inb
#undef inw
@@ -1403,7 +1380,7 @@ static int inb(port)
#undef outl
#define inb(a) __extension__ ({unsigned char __c=RealInb(a); ErrorF("inb(0x%03x) = 0x%02x\t@ line %4d, file %s\n", a, __c, __LINE__, __FILE__);__c;})
#define inw(a) __extension__ ({unsigned short __c=RealInw(a); ErrorF("inw(0x%03x) = 0x%04x\t@ line %4d, file %s\n", a, __c, __LINE__, __FILE__);__c;})
-#define inl(a) __extension__ ({unsigned long __c=RealInl(a); ErrorF("inl(0x%03x) = 0x%08x\t@ line %4d, file %s\n", a, __c, __LINE__, __FILE__);__c;})
+#define inl(a) __extension__ ({unsigned int __c=RealInl(a); ErrorF("inl(0x%03x) = 0x%08x\t@ line %4d, file %s\n", a, __c, __LINE__, __FILE__);__c;})
#define outb(a,b) (ErrorF("outb(0x%03x, 0x%02x)\t@ line %4d, file %s\n", a, b, __LINE__, __FILE__),RealOutb(a,b))
#define outw(a,b) (ErrorF("outw(0x%03x, 0x%04x)\t@ line %4d, file %s\n", a, b, __LINE__, __FILE__),RealOutw(a,b))
@@ -1411,13 +1388,13 @@ static int inb(port)
#endif
/*
- * This header sometimes gets included where is isn't needed, and on some
- * OSs this causes problems because the following functions generate
- * references to inb() and outb() which can't be resolved. Defining
- * NO_COMPILER_H_EXTRAS avoids this problem.
+ * This header sometimes gets included where is isn't needed, and on some OSs
+ * this causes problems because the following functions generate references to
+ * inx() and outx() which can't be resolved. If you need the extra definitions
+ * below, #define COMPILER_H_EXTRAS.
*/
-#ifndef NO_COMPILER_H_EXTRAS
+#ifdef COMPILER_H_EXTRAS
/*
*-----------------------------------------------------------------------
* Port manipulation convenience functions
@@ -1514,7 +1491,164 @@ testinx(unsigned short port, unsigned char ind)
{
return(testinx2(port, ind, 0xFF));
}
-#endif /* NO_COMPILER_H_EXTRAS */
+#endif /* COMPILER_H_EXTRAS */
#endif /* NO_INLINE */
+
+#ifdef __alpha__
+/* entry points for Mmio memory access routines */
+extern int (*xf86ReadMmio8)(void *, unsigned long);
+extern int (*xf86ReadMmio16)(void *, unsigned long);
+extern int (*xf86ReadMmio32)(void *, unsigned long);
+extern void (*xf86WriteMmio8)(int, void *, unsigned long);
+extern void (*xf86WriteMmio16)(int, void *, unsigned long);
+extern void (*xf86WriteMmio32)(int, void *, unsigned long);
+extern void (*xf86WriteMmioNB8)(int, void *, unsigned long);
+extern void (*xf86WriteMmioNB16)(int, void *, unsigned long);
+extern void (*xf86WriteMmioNB32)(int, void *, unsigned long);
+extern void xf86JensenMemToBus(char *, long, long, int);
+extern void xf86JensenBusToMem(char *, char *, unsigned long, int);
+extern void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int);
+extern void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
+/* Some macros to hide the system dependencies for MMIO accesses */
+/* Changed to kill noise generated by gcc's -Wcast-align */
+#define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset)
+#define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset)
+#define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset)
+# if defined (JENSEN_SUPPORT)
+#define MMIO_OUT32(base, offset, val) \
+ (*xf86WriteMmio32)((CARD32)(val), base, offset)
+#define MMIO_ONB32(base, offset, val) \
+ (*xf86WriteMmioNB32)((CARD32)(val), base, offset)
+# else
+#define MMIO_INB32(base, offset) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
+#define MMIO_OUT32(base, offset, val) \
+ do { \
+ write_mem_barrier(); \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \
+ } while (0)
+#define MMIO_ONB32(base, offset, val) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+# endif
+#define MMIO_OUT8(base, offset, val) \
+ (*xf86WriteMmio8)((CARD8)(val), base, offset)
+#define MMIO_OUT16(base, offset, val) \
+ (*xf86WriteMmio16)((CARD16)(val), base, offset)
+#define MMIO_ONB8(base, offset, val) \
+ (*xf86WriteMmioNB8)((CARD8)(val), base, offset)
+#define MMIO_ONB16(base, offset, val) \
+ (*xf86WriteMmioNB16)((CARD16)(val), base, offset)
+#elif defined(__powerpc__)
+ /*
+ * we provide byteswapping and no byteswapping functions here
+ * with byteswapping as default,
+ * drivers that don't need byteswapping should define PPC_MMIO_IS_BE
+ */
+# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
+# define MMIO_OUT8(base, offset, val) \
+ xf86WriteMmio8(base, offset, (CARD8)(val))
+# define MMIO_ONB8(base, offset, val) \
+ xf86WriteMmioNB8(base, offset, (CARD8)(val))
+# if defined(PPC_MMIO_IS_BE) /* No byteswapping */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Be(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmioNB16Be(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmioNB32Be(base, offset, (CARD32)(val))
+# else /* byteswapping is the default */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Le(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Le(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmioNB16Le(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmioNB32Le(base, offset, (CARD32)(val))
+# endif
+static __inline__ void ppc_flush_icache(char *addr)
+{
+ __asm__ volatile (
+ "dcbf 0,%0;"
+ "sync;"
+ "icbi 0,%0;"
+ "sync;"
+ "isync;"
+ : : "r"(addr) : "memory");
+}
+
+#elif defined(__sparc__)
+ /*
+ * Like powerpc, we provide byteswapping and no byteswapping functions
+ * here with byteswapping as default, drivers that don't need byteswapping
+ * should define SPARC_MMIO_IS_BE (perhaps create a generic macro so that we
+ * do not need to use PPC_MMIO_IS_BE and the sparc one in all the same places
+ * of drivers?).
+ */
+# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
+# define MMIO_OUT8(base, offset, val) \
+ xf86WriteMmio8(base, offset, (CARD8)(val))
+# define MMIO_ONB8(base, offset, val) \
+ xf86WriteMmio8NB(base, offset, (CARD8)(val))
+# if defined(SPARC_MMIO_IS_BE) /* No byteswapping */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Be(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmio16BeNB(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmio32BeNB(base, offset, (CARD32)(val))
+# else /* byteswapping is the default */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Le(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Le(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmio16LeNB(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmio32LeNB(base, offset, (CARD32)(val))
+# endif
+#else /* !__alpha__ && !__powerpc__ && !__sparc__ */
+#define MMIO_IN8(base, offset) \
+ *(volatile CARD8 *)(((CARD8*)(base)) + (offset))
+#define MMIO_IN16(base, offset) \
+ *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset))
+#define MMIO_IN32(base, offset) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
+#define MMIO_OUT8(base, offset, val) \
+ *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val)
+#define MMIO_OUT16(base, offset, val) \
+ *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+#define MMIO_OUT32(base, offset, val) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+#define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val)
+#define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val)
+#define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val)
+#endif /* __alpha__ */
+
+/*
+ * With Intel, the version in os-support/misc/SlowBcopy.s is used.
+ * This avoids port I/O during the copy (which causes problems with
+ * some hardware).
+ */
+#ifdef __alpha__
+#define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count)
+#define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count)
+#else /* __alpha__ */
+#define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count)
+#define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count)
+#endif /* __alpha__ */
+
#endif /* _COMPILER_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h
index 003b9aa2e..3adabfe25 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h
@@ -273,6 +273,9 @@ typedef struct {
drmHandle registerHandle;
Bool IsPCI; /* Current card is a PCI card */
+ drmSize pciSize;
+ drmHandle pciMemHandle;
+ unsigned char *PCI; /* Map */
drmSize agpSize;
drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
index 6cc71a9ce..8e8ebc465 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c
@@ -838,6 +838,7 @@ static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
if (info->scanline_direct) return;
--info->scanline_h;
while (left) {
+ write_mem_barrier();
if (left <= 8) {
/* Last scanline - finish write to DATA_LAST */
if (info->scanline_h == 0) {
@@ -979,6 +980,7 @@ static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
if (info->scanline_direct) return;
--info->scanline_h;
while (left) {
+ write_mem_barrier();
if (left <= 8) {
/* Last scanline - finish write to DATA_LAST */
if (info->scanline_h == 0) {
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
index 9d65ecb29..a7c7cdf42 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
@@ -47,12 +47,20 @@
/* X and server generic header files */
#include "xf86.h"
#include "windowstr.h"
+#include "xf86PciInfo.h"
/* GLX/DRI/DRM definitions */
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
#include "sarea.h"
+/* ?? HACK - for now, put this here... */
+/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
+#if defined(__alpha__)
+# define DRM_PAGE_SIZE 8192
+#else
+# define DRM_PAGE_SIZE 4096
+#endif
/* Initialize the visual configs that are supported by the hardware.
These are combined with the visual configs that the indirect
@@ -72,6 +80,9 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen)
case 8: /* 8bpp mode is not support */
case 15: /* FIXME */
case 24: /* FIXME */
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "R128DRIScreenInit failed (depth %d not supported). "
+ "Disabling DRI.\n", info->CurrentLayout.pixel_code);
return FALSE;
#define R128_USE_ACCUM 1
@@ -399,12 +410,12 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
unsigned long mode;
unsigned int vendor, device;
int ret;
- unsigned long cntl;
+ unsigned long cntl, chunk;
int s, l;
int flags;
if (drmAgpAcquire(info->drmFD) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n");
return FALSE;
}
@@ -457,11 +468,11 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
/* Initialize the CCE ring buffer data */
info->ringStart = info->agpOffset;
- info->ringMapSize = info->ringSize*1024*1024 + 4096;
+ info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1;
info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = 4096;
+ info->ringReadMapSize = DRM_PAGE_SIZE;
/* Reserve space for vertex/indirect buffers */
info->bufStart = info->ringReadOffset + info->ringReadMapSize;
@@ -576,21 +587,147 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
OUTREG(R128_AGP_BASE, info->ringHandle); /* Ring buf is at AGP offset 0 */
OUTREG(R128_AGP_CNTL, cntl);
+ /* Disable Rage 128's PCIGART registers */
+ chunk = INREG(R128_BM_CHUNK_0_VAL);
+ chunk &= ~(R128_BM_PTR_FORCE_TO_PCI |
+ R128_BM_PM4_RD_FORCE_TO_PCI |
+ R128_BM_GLOBAL_FORCE_TO_PCI);
+ OUTREG(R128_BM_CHUNK_0_VAL, chunk);
+
+ OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */
+
xf86EnablePciBusMaster(info->PciInfo, TRUE);
return TRUE;
}
-#if 0
-/* Fake the vertex buffers for PCI cards. */
-static Bool R128DRIPciInit(R128InfoPtr info)
+static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen)
{
- info->bufStart = 0;
- info->bufMapSize = info->bufSize*1024*1024;
+ unsigned char *R128MMIO = info->MMIO;
+ CARD32 chunk;
+ int ret;
+ int flags;
+
+ info->agpOffset = 0;
+
+ ret = drmScatterGatherAlloc(info->drmFD, info->agpSize*1024*1024,
+ &info->pciMemHandle);
+ if (ret < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] %d kB allocated with handle 0x%08x\n",
+ info->agpSize*1024, info->pciMemHandle);
+
+ /* Initialize the CCE ring buffer data */
+ info->ringStart = info->agpOffset;
+ info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+ info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1;
+
+ info->ringReadOffset = info->ringStart + info->ringMapSize;
+ info->ringReadMapSize = DRM_PAGE_SIZE;
+
+ /* Reserve space for vertex/indirect buffers */
+ info->bufStart = info->ringReadOffset + info->ringReadMapSize;
+ info->bufMapSize = info->bufSize*1024*1024;
+
+ flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
+
+ if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize,
+ DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add ring mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] ring handle = 0x%08lx\n", info->ringHandle);
+
+ if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
+ (drmAddressPtr)&info->ring) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring mapped at 0x%08lx\n",
+ (unsigned long)info->ring);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring contents 0x%08lx\n",
+ *(unsigned long *)info->ring);
+
+ if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,
+ DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add ring read ptr mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] ring read ptr handle = 0x%08lx\n",
+ info->ringReadPtrHandle);
+
+ if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
+ (drmAddressPtr)&info->ringReadPtr) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not map ring read ptr\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring read ptr mapped at 0x%08lx\n",
+ (unsigned long)info->ringReadPtr);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring read ptr contents 0x%08lx\n",
+ *(unsigned long *)info->ringReadPtr);
+
+ if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,
+ DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add vertex/indirect buffers mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] vertex/indirect buffers handle = 0x%08lx\n",
+ info->bufHandle);
+
+ if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize,
+ (drmAddressPtr)&info->buf) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not map vertex/indirect buffers\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Vertex/indirect buffers mapped at 0x%08lx\n",
+ (unsigned long)info->buf);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Vertex/indirect buffers contents 0x%08lx\n",
+ *(unsigned long *)info->buf);
+
+ switch (info->Chipset) {
+ case PCI_CHIP_RAGE128LE:
+ case PCI_CHIP_RAGE128RE:
+ case PCI_CHIP_RAGE128RK:
+ /* This is a PCI card, do nothing */
+ break;
+
+ case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML:
+ case PCI_CHIP_RAGE128RF:
+ case PCI_CHIP_RAGE128RG:
+ case PCI_CHIP_RAGE128RL:
+ case PCI_CHIP_RAGE128PF:
+ default:
+ /* This is really an AGP card, force PCI GART mode */
+ chunk = INREG(R128_BM_CHUNK_0_VAL);
+ chunk |= (R128_BM_PTR_FORCE_TO_PCI |
+ R128_BM_PM4_RD_FORCE_TO_PCI |
+ R128_BM_GLOBAL_FORCE_TO_PCI);
+ OUTREG(R128_BM_CHUNK_0_VAL, chunk);
+ OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */
+ break;
+ }
return TRUE;
}
-#endif
/* Add a map for the MMIO registers that will be accessed by any
DRI-based clients. */
@@ -655,11 +792,20 @@ static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen)
static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen)
{
/* Initialize vertex buffers */
- if ((info->bufNumBufs = drmAddBufs(info->drmFD,
- info->bufMapSize / R128_BUFFER_SIZE,
- R128_BUFFER_SIZE,
- DRM_AGP_BUFFER,
- info->bufStart)) <= 0) {
+ if (info->IsPCI) {
+ info->bufNumBufs = drmAddBufs(info->drmFD,
+ info->bufMapSize / R128_BUFFER_SIZE,
+ R128_BUFFER_SIZE,
+ DRM_SG_BUFFER,
+ info->bufStart);
+ } else {
+ info->bufNumBufs = drmAddBufs(info->drmFD,
+ info->bufMapSize / R128_BUFFER_SIZE,
+ R128_BUFFER_SIZE,
+ DRM_AGP_BUFFER,
+ info->bufStart);
+ }
+ if (info->bufNumBufs <= 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] Could not create vertex/indirect buffers list\n");
return FALSE;
@@ -853,22 +999,18 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
/* Initialize AGP */
if (!info->IsPCI && !R128DRIAgpInit(info, pScreen)) {
- R128DRICloseScreen(pScreen);
- return FALSE;
+ info->IsPCI = TRUE;
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "AGP failed to initialize -- falling back to PCI mode.\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "Make sure you have the agpgart kernel module loaded.\n");
}
-#if 0
- /* Initialize PCI */
+
+ /* Initialize PCIGART */
if (info->IsPCI && !R128DRIPciInit(info, pScreen)) {
R128DRICloseScreen(pScreen);
return FALSE;
}
-#else
- if (info->IsPCI) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n");
- R128DRICloseScreen(pScreen);
- return FALSE;
- }
-#endif
/* DRIScreenInit doesn't add all the
common mappings. Add additional
@@ -918,7 +1060,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
}
/* Initialize the vertex buffers list */
- if (!info->IsPCI && !R128DRIBufInit(info, pScreen)) {
+ if (!R128DRIBufInit(info, pScreen)) {
R128DRICloseScreen(pScreen);
return FALSE;
}
@@ -929,36 +1071,36 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
- pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate;
-
- pR128DRI->deviceID = info->Chipset;
- pR128DRI->width = pScrn->virtualX;
- pR128DRI->height = pScrn->virtualY;
- pR128DRI->depth = pScrn->depth;
- pR128DRI->bpp = pScrn->bitsPerPixel;
-
- pR128DRI->IsPCI = info->IsPCI;
- pR128DRI->AGPMode = info->agpMode;
-
- pR128DRI->frontOffset = info->frontOffset;
- pR128DRI->frontPitch = info->frontPitch;
- pR128DRI->backOffset = info->backOffset;
- pR128DRI->backPitch = info->backPitch;
- pR128DRI->depthOffset = info->depthOffset;
- pR128DRI->depthPitch = info->depthPitch;
- pR128DRI->spanOffset = info->spanOffset;
- pR128DRI->textureOffset = info->textureOffset;
- pR128DRI->textureSize = info->textureSize;
- pR128DRI->log2TexGran = info->log2TexGran;
-
- pR128DRI->registerHandle = info->registerHandle;
- pR128DRI->registerSize = info->registerSize;
-
- pR128DRI->agpTexHandle = info->agpTexHandle;
- pR128DRI->agpTexMapSize = info->agpTexMapSize;
- pR128DRI->log2AGPTexGran = info->log2AGPTexGran;
- pR128DRI->agpTexOffset = info->agpTexStart;
- pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+ pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate;
+
+ pR128DRI->deviceID = info->Chipset;
+ pR128DRI->width = pScrn->virtualX;
+ pR128DRI->height = pScrn->virtualY;
+ pR128DRI->depth = pScrn->depth;
+ pR128DRI->bpp = pScrn->bitsPerPixel;
+
+ pR128DRI->IsPCI = info->IsPCI;
+ pR128DRI->AGPMode = info->agpMode;
+
+ pR128DRI->frontOffset = info->frontOffset;
+ pR128DRI->frontPitch = info->frontPitch;
+ pR128DRI->backOffset = info->backOffset;
+ pR128DRI->backPitch = info->backPitch;
+ pR128DRI->depthOffset = info->depthOffset;
+ pR128DRI->depthPitch = info->depthPitch;
+ pR128DRI->spanOffset = info->spanOffset;
+ pR128DRI->textureOffset = info->textureOffset;
+ pR128DRI->textureSize = info->textureSize;
+ pR128DRI->log2TexGran = info->log2TexGran;
+
+ pR128DRI->registerHandle = info->registerHandle;
+ pR128DRI->registerSize = info->registerSize;
+
+ pR128DRI->agpTexHandle = info->agpTexHandle;
+ pR128DRI->agpTexMapSize = info->agpTexMapSize;
+ pR128DRI->log2AGPTexGran = info->log2AGPTexGran;
+ pR128DRI->agpTexOffset = info->agpTexStart;
+ pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
return TRUE;
}
@@ -1007,6 +1149,10 @@ void R128DRICloseScreen(ScreenPtr pScreen)
info->agpMemHandle = 0;
drmAgpRelease(info->drmFD);
}
+ if (info->pciMemHandle) {
+ drmScatterGatherFree(info->drmFD, info->pciMemHandle);
+ info->pciMemHandle = 0;
+ }
/* De-allocate all DRI resources */
DRICloseScreen(pScreen);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
index 5b86c33d3..ad254d7a4 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c
@@ -626,7 +626,7 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
R128PLLPtr pll = &info->pll;
-#if defined(__powerpc__)
+#if defined(__powerpc__) || defined(__alpha__)
/* there is no bios under Linux PowerPC but Open Firmware
does set up the PLL registers properly and we can use
those to calculate xclk and find the reference divider */
@@ -1186,9 +1186,7 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
- if (info->IsPCI) {
- info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
- } else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) {
+ if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n");
info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
} else {
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
index e9d584ab9..81d4c2fe2 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h
@@ -191,6 +191,10 @@
#define R128_BIOS_7_SCRATCH 0x002c
#define R128_BIOS_ROM 0x0f30 /* PCI */
#define R128_BIST 0x0f0f /* PCI */
+#define R128_BM_CHUNK_0_VAL 0x0a18
+# define R128_BM_PTR_FORCE_TO_PCI (1 << 21)
+# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22)
+# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23)
#define R128_BRUSH_DATA0 0x1480
#define R128_BRUSH_DATA1 0x1484
#define R128_BRUSH_DATA10 0x14a8
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
index 6916a0c13..13da7345d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
@@ -279,6 +279,9 @@ typedef struct {
drmHandle registerHandle;
Bool IsPCI; /* Current card is a PCI card */
+ drmSize pciSize;
+ drmHandle pciMemHandle;
+ unsigned char *PCI; /* Map */
Bool depthMoves; /* Enable depth moves -- slow! */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c
index b6b20af54..64fe54041 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c
@@ -723,7 +723,13 @@ static void RADEONSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
info->scanline_h = h;
info->scanline_words = (w + 31) >> 5;
- if ((info->scanline_words * h) <= 9) {
+#if defined(__alpha__)
+ /* always force indirect for Alpha */
+ if (0)
+#else
+ if ((info->scanline_words * h) <= 9)
+#endif
+ {
/* Turn on direct for less than 9 dword colour expansion */
info->scratch_buffer[0]
= (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST)
@@ -759,6 +765,7 @@ static void RADEONSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
if (info->scanline_direct) return;
--info->scanline_h;
while (left) {
+ write_mem_barrier();
if (left <= 8) {
/* Last scanline - finish write to DATA_LAST */
if (info->scanline_h == 0) {
@@ -836,7 +843,13 @@ static void RADEONSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
info->scanline_h = h;
info->scanline_words = (w * info->scanline_bpp + 31) >> 5;
- if ((info->scanline_words * h) <= 9) {
+#if defined(__alpha__)
+ /* always force indirect for Alpha */
+ if (0)
+#else
+ if ((info->scanline_words * h) <= 9)
+#endif
+ {
/* Turn on direct for less than 9 dword colour expansion */
info->scratch_buffer[0]
= (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST)
@@ -872,6 +885,7 @@ static void RADEONSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
if (info->scanline_direct) return;
--info->scanline_h;
while (left) {
+ write_mem_barrier();
if (left <= 8) {
/* Last scanline - finish write to DATA_LAST */
if (info->scanline_h == 0) {
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
index b6bf4af61..31ad8b126 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
@@ -52,6 +52,13 @@
#include "GL/glxtokens.h"
#include "sarea.h"
+/* ?? HACK - for now, put this here... */
+/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
+#if defined(__alpha__)
+# define DRM_PAGE_SIZE 8192
+#else
+# define DRM_PAGE_SIZE 4096
+#endif
/* Initialize the visual configs that are supported by the hardware.
These are combined with the visual configs that the indirect
@@ -757,11 +764,11 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
/* Initialize the CP ring buffer data */
info->ringStart = info->agpOffset;
- info->ringMapSize = info->ringSize*1024*1024 + 4096;
+ info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1;
info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = 4096;
+ info->ringReadMapSize = DRM_PAGE_SIZE;
/* Reserve space for vertex/indirect buffers */
info->bufStart = info->ringReadOffset + info->ringReadMapSize;
@@ -865,11 +872,105 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
}
#if 0
-/* Fake the vertex buffers for PCI cards. */
+/* Initialize the PCIGART state. Request memory for use in PCI space,
+ and initialize the Radeon registers to point to that memory. */
static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
{
- info->bufStart = 0;
- info->bufMapSize = info->bufSize*1024*1024;
+ int ret;
+ int flags;
+
+ info->agpOffset = 0;
+
+ ret = drmScatterGatherAlloc(info->drmFD, info->agpSize*1024*1024,
+ &info->pciMemHandle);
+ if (ret < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] %d kB allocated with handle 0x%08x\n",
+ info->agpSize*1024, info->pciMemHandle);
+
+ /* Initialize the CCE ring buffer data */
+ info->ringStart = info->agpOffset;
+ info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+ info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1;
+
+ info->ringReadOffset = info->ringStart + info->ringMapSize;
+ info->ringReadMapSize = DRM_PAGE_SIZE;
+
+ /* Reserve space for vertex/indirect buffers */
+ info->bufStart = info->ringReadOffset + info->ringReadMapSize;
+ info->bufMapSize = info->bufSize*1024*1024;
+
+ flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
+
+ if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize,
+ DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add ring mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] ring handle = 0x%08lx\n", info->ringHandle);
+
+ if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
+ (drmAddressPtr)&info->ring) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring mapped at 0x%08lx\n",
+ (unsigned long)info->ring);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring contents 0x%08lx\n",
+ *(unsigned long *)info->ring);
+
+ if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,
+ DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add ring read ptr mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] ring read ptr handle = 0x%08lx\n",
+ info->ringReadPtrHandle);
+
+ if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
+ (drmAddressPtr)&info->ringReadPtr) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not map ring read ptr\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring read ptr mapped at 0x%08lx\n",
+ (unsigned long)info->ringReadPtr);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Ring read ptr contents 0x%08lx\n",
+ *(unsigned long *)info->ringReadPtr);
+
+ if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,
+ DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not add vertex/indirect buffers mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] vertex/indirect buffers handle = 0x%08lx\n",
+ info->bufHandle);
+
+ if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize,
+ (drmAddressPtr)&info->buf) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] Could not map vertex/indirect buffers\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Vertex/indirect buffers mapped at 0x%08lx\n",
+ (unsigned long)info->buf);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[pci] Vertex/indirect buffers contents 0x%08lx\n",
+ *(unsigned long *)info->buf);
return TRUE;
}
@@ -937,11 +1038,24 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen)
{
/* Initialize vertex buffers */
- if ((info->bufNumBufs = drmAddBufs(info->drmFD,
- info->bufMapSize / RADEON_BUFFER_SIZE,
- RADEON_BUFFER_SIZE,
- DRM_AGP_BUFFER,
- info->bufStart)) <= 0) {
+ if (info->IsPCI) {
+#if 1
+ return TRUE;
+#else
+ info->bufNumBufs = drmAddBufs(info->drmFD,
+ info->bufMapSize / RADEON_BUFFER_SIZE,
+ RADEON_BUFFER_SIZE,
+ DRM_SG_BUFFER,
+ info->bufStart);
+#endif
+ } else {
+ info->bufNumBufs = drmAddBufs(info->drmFD,
+ info->bufMapSize / RADEON_BUFFER_SIZE,
+ RADEON_BUFFER_SIZE,
+ DRM_AGP_BUFFER,
+ info->bufStart);
+ }
+ if (info->bufNumBufs <= 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] Could not create vertex/indirect buffers list\n");
return FALSE;
@@ -1306,20 +1420,31 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
drmFreeVersion(version);
}
+#if 1
/* Initialize AGP */
if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) {
RADEONDRICloseScreen(pScreen);
return FALSE;
}
-#if 0
+
/* Initialize PCI */
- if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) {
+ if (info->IsPCI) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n");
RADEONDRICloseScreen(pScreen);
return FALSE;
}
#else
- if (info->IsPCI) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n");
+ /* Initialize AGP */
+ if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) {
+ info->IsPCI = TRUE;
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "AGP failed to initialize -- falling back to PCI mode.\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "Make sure you have the agpgart kernel module loaded.\n");
+ }
+
+ /* Initialize PCI */
+ if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) {
RADEONDRICloseScreen(pScreen);
return FALSE;
}
@@ -1373,7 +1498,7 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
}
/* Initialize the vertex buffers list */
- if (!info->IsPCI && !RADEONDRIBufInit(info, pScreen)) {
+ if (!RADEONDRIBufInit(info, pScreen)) {
RADEONDRICloseScreen(pScreen);
return FALSE;
}
@@ -1387,39 +1512,39 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
RADEONDRISAREAInit(pScreen, pSAREAPriv);
- pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate;
+ pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate;
- pRADEONDRI->deviceID = info->Chipset;
- pRADEONDRI->width = pScrn->virtualX;
- pRADEONDRI->height = pScrn->virtualY;
- pRADEONDRI->depth = pScrn->depth;
- pRADEONDRI->bpp = pScrn->bitsPerPixel;
+ pRADEONDRI->deviceID = info->Chipset;
+ pRADEONDRI->width = pScrn->virtualX;
+ pRADEONDRI->height = pScrn->virtualY;
+ pRADEONDRI->depth = pScrn->depth;
+ pRADEONDRI->bpp = pScrn->bitsPerPixel;
- pRADEONDRI->IsPCI = info->IsPCI;
- pRADEONDRI->AGPMode = info->agpMode;
+ pRADEONDRI->IsPCI = info->IsPCI;
+ pRADEONDRI->AGPMode = info->agpMode;
- pRADEONDRI->frontOffset = info->frontOffset;
- pRADEONDRI->frontPitch = info->frontPitch;
- pRADEONDRI->backOffset = info->backOffset;
- pRADEONDRI->backPitch = info->backPitch;
- pRADEONDRI->depthOffset = info->depthOffset;
- pRADEONDRI->depthPitch = info->depthPitch;
- pRADEONDRI->textureOffset = info->textureOffset;
- pRADEONDRI->textureSize = info->textureSize;
- pRADEONDRI->log2TexGran = info->log2TexGran;
+ pRADEONDRI->frontOffset = info->frontOffset;
+ pRADEONDRI->frontPitch = info->frontPitch;
+ pRADEONDRI->backOffset = info->backOffset;
+ pRADEONDRI->backPitch = info->backPitch;
+ pRADEONDRI->depthOffset = info->depthOffset;
+ pRADEONDRI->depthPitch = info->depthPitch;
+ pRADEONDRI->textureOffset = info->textureOffset;
+ pRADEONDRI->textureSize = info->textureSize;
+ pRADEONDRI->log2TexGran = info->log2TexGran;
- pRADEONDRI->registerHandle = info->registerHandle;
- pRADEONDRI->registerSize = info->registerSize;
+ pRADEONDRI->registerHandle = info->registerHandle;
+ pRADEONDRI->registerSize = info->registerSize;
- pRADEONDRI->statusHandle = info->ringReadPtrHandle;
- pRADEONDRI->statusSize = info->ringReadMapSize;
+ pRADEONDRI->statusHandle = info->ringReadPtrHandle;
+ pRADEONDRI->statusSize = info->ringReadMapSize;
- pRADEONDRI->agpTexHandle = info->agpTexHandle;
- pRADEONDRI->agpTexMapSize = info->agpTexMapSize;
- pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran;
- pRADEONDRI->agpTexOffset = info->agpTexStart;
+ pRADEONDRI->agpTexHandle = info->agpTexHandle;
+ pRADEONDRI->agpTexMapSize = info->agpTexMapSize;
+ pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran;
+ pRADEONDRI->agpTexOffset = info->agpTexStart;
- pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+ pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
#ifdef PER_CONTEXT_SAREA
/* Set per-context SAREA size */
@@ -1473,6 +1598,10 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
info->agpMemHandle = 0;
drmAgpRelease(info->drmFD);
}
+ if (info->pciMemHandle) {
+ drmScatterGatherFree(info->drmFD, info->pciMemHandle);
+ info->pciMemHandle = 0;
+ }
/* De-allocate all DRI resources */
DRICloseScreen(pScreen);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
index cc4c1d3bf..276ba052f 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
@@ -1103,9 +1103,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->IsPCI) {
- info->CPMode = RADEON_DEFAULT_CP_PIO_MODE;
- } else if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) {
+ if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n");
info->CPMode = RADEON_DEFAULT_CP_PIO_MODE;
} else {
diff --git a/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
index c420d9226..9b89785fa 100644
--- a/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
+++ b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
@@ -879,7 +879,6 @@ LOOKUP xfree86LookupTab[] = {
SYMFUNC(xf86WriteMmioNB32)
SYMFUNC(xf86WriteMmioNB16)
SYMFUNC(xf86WriteMmioNB8)
- SYMFUNC(memcpy)
#endif
#if defined(sun) && defined(SVR4)
SYMFUNC(inb)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
index 394b69e4f..df0c82727 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.22 1999/08/21 13:48:40 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.43 2001/01/06 20:19:15 tsi Exp $ */
/*
* Pci.c - New server PCI access functions
*
@@ -170,6 +170,7 @@
#include "compiler.h"
#include "xf86.h"
#include "xf86Priv.h"
+#define XF86_OS_PRIVS
#include "xf86_OSproc.h"
#include "Pci.h"
@@ -205,8 +206,9 @@ pciBusFuncs_t pciNOOPFuncs = {
pciAddrNOOP
};
-pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES];
+pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES] = { NULL, };
int pciNumBuses = 0; /* Actual number of PCI buses */
+static Bool inProbe = FALSE;
static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, };
#ifdef INCLUDE_LOCKPCI
@@ -239,7 +241,13 @@ pciInit()
xf86Verbose = DEBUGPCI;
#endif
- ARCH_PCI_INIT();
+ ARCH_PCI_INIT();
+ if (!pciNumBuses)
+#if defined(ARCH_PCI_OS_INIT)
+ ARCH_PCI_OS_INIT();
+#else
+ xf86Msg(X_ERROR,"No OS PCI support available\n");
+#endif
}
@@ -281,7 +289,7 @@ ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset);
if (!pciInitialized)
pciInit();
- if (bus < pciNumBuses && pciBusInfo[bus] &&
+ if ((bus < pciNumBuses || inProbe) && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs.pciReadLong) {
CARD32 rv = (*pciBusInfo[bus]->funcs.pciReadLong)(tag, offset);
@@ -421,7 +429,7 @@ pciLongFunc(PCITAG tag, pciFunc func)
}
ADDRESS
-pciBusAddrToHostAddr(PCITAG tag, ADDRESS addr)
+pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr)
{
int bus = PCI_BUS_FROM_TAG(tag);
@@ -430,13 +438,13 @@ pciBusAddrToHostAddr(PCITAG tag, ADDRESS addr)
if (bus < pciNumBuses && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs.pciAddrBusToHost)
- return (*pciBusInfo[bus]->funcs.pciAddrBusToHost)(tag, addr);
+ return (*pciBusInfo[bus]->funcs.pciAddrBusToHost)(tag, type, addr);
else
return(addr);
}
ADDRESS
-pciHostAddrToBusAddr(PCITAG tag, ADDRESS addr)
+pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr)
{
int bus = PCI_BUS_FROM_TAG(tag);
@@ -445,7 +453,7 @@ pciHostAddrToBusAddr(PCITAG tag, ADDRESS addr)
if (bus < pciNumBuses && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs.pciAddrHostToBus)
- return (*pciBusInfo[bus]->funcs.pciAddrHostToBus)(tag, addr);
+ return (*pciBusInfo[bus]->funcs.pciAddrHostToBus)(tag, type, addr);
else
return(addr);
}
@@ -489,6 +497,12 @@ pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
if (!pciInitialized)
pciInit();
+ if (xf86GetPciSizeFromOS(tag, index, &bits)) {
+ if (min)
+ *min = TRUE;
+ return bits;
+ }
+
if (min)
*min = destructive;
@@ -535,7 +549,8 @@ pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
bits++;
mask2 >>= 1;
}
- return bits;
+ if (bits > 32)
+ return bits;
}
}
if (index < 6)
@@ -544,7 +559,10 @@ pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
else
mask1 = PCIGETIO(mask1);
else
- mask1 = PCIGETROM(mask1);
+ if (addr1 & PCI_MAP_ROM_DECODE_ENABLE)
+ mask1 = PCIGETROM(mask1);
+ else
+ mask1 = 0;
if (mask1 == 0)
return 0;
bits = 0;
@@ -553,7 +571,7 @@ pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
mask1 >>= 1;
}
/* I/O maps can be no larger than 8 bits */
- if (PCI_MAP_IS_IO(addr1) && bits > 8)
+ if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
bits = 8;
/* ROM maps can be no larger than 24 bits */
if (index == 6 && bits > 24)
@@ -610,6 +628,7 @@ pciGenFindNext(void)
{
unsigned long devid, tmp;
unsigned char base_class, sub_class, sec_bus, pri_bus;
+ Bool speculativeProbe = FALSE;
#ifdef DEBUGPCI
ErrorF("pciGenFindNext\n");
@@ -671,7 +690,13 @@ ErrorF("pciGenFindNext: next bus\n");
/*
* No more devices for this bus. Next bus please
*/
- if (++pciBusNum >= pciNumBuses) {
+ if (speculativeProbe) {
+ xfree(pciBusInfo[pciBusNum]);
+ pciBusInfo[pciBusNum] = NULL;
+ }
+
+
+ if (++pciBusNum >= MAX_PCI_BUSES) {
#ifdef DEBUGPCI
ErrorF("pciGenFindNext: out of buses\n");
#endif
@@ -686,8 +711,12 @@ ErrorF("pciGenFindNext: out of buses\n");
#ifdef DEBUGPCI
ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusNum]);
#endif
- if (!pciBusInfo[pciBusNum])
- continue; /* Bus not defined, next please */
+ if (!pciBusInfo[pciBusNum]) {
+ pciBusInfo[pciBusNum] = xnfalloc(sizeof(pciBusInfo_t));
+ *pciBusInfo[pciBusNum] = *pciBusInfo[0];
+
+ speculativeProbe = TRUE;
+ }
/*
* At this point, pciBusNum, pciDevNum, and pciFuncNum have been
@@ -698,13 +727,20 @@ ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusN
ErrorF("pciGenFindNext: [%d, %d, %d]\n", pciBusNum, pciDevNum, pciFuncNum);
#endif
pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum);
+ inProbe = TRUE;
devid = pciReadLong(pciDeviceTag, 0);
+ inProbe = FALSE;
#ifdef DEBUGPCI
ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, devid);
#endif
if (devid == 0xffffffff)
continue; /* Nobody home. Next device please */
+ if (speculativeProbe && (pciNumBuses <= pciBusNum))
+ pciNumBuses = pciBusNum + 1;
+
+ speculativeProbe = FALSE;
+
/*
* Before checking for a specific devid, look for enabled
* PCI to PCI bridge devices. If one is found, create and
@@ -714,7 +750,8 @@ ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, de
tmp = pciReadLong(pciDeviceTag, PCI_CLASS_REG);
base_class = PCI_CLASS_EXTRACT(tmp);
sub_class = PCI_SUBCLASS_EXTRACT(tmp);
- if (base_class == PCI_CLASS_BRIDGE && sub_class == PCI_SUBCLASS_BRIDGE_PCI) {
+ if (base_class == PCI_CLASS_BRIDGE)
+ if (sub_class == PCI_SUBCLASS_BRIDGE_PCI) {
tmp = pciReadLong(pciDeviceTag, PCI_PCI_BRIDGE_BUS_REG);
sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp);
pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp);
@@ -884,7 +921,7 @@ pciSetBitsLongNULL(PCITAG tag, int offset, CARD32 mask, CARD32 val)
}
ADDRESS
-pciAddrNOOP(PCITAG tag, ADDRESS addr)
+pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS addr)
{
return(addr);
}
@@ -937,7 +974,9 @@ ErrorF("xf86scanpci: tag = 0x%lx\n", tag);
/* Get base address sizes for type 0 headers */
if ((devp->pci_header_type & 0x7f) == 0)
for (i = 0; i < 7; i++)
- devp->basesize[i] = pciGetBaseSize(tag, i, FALSE, NULL);
+ devp->basesize[i] = pciGetBaseSize(tag, i, FALSE,
+ &devp->minBasesize);
+ devp->listed_class = 0;
#ifdef OLD_FORMAT
xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%02x,0x%02x,0x%1x "
@@ -966,17 +1005,24 @@ ErrorF("xf86scanpci: tag = pciFindNext = 0x%lx\n", tag);
#ifndef OLD_FORMAT
xf86MsgVerb(X_INFO, 2, "PCI: End of PCI scan\n");
#endif
-
+
return pci_devp;
}
+CARD32
+pciCheckForBrokenBase(PCITAG Tag,int basereg)
+{
+ pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0xffffffff);
+ return pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2));
+}
+
#if defined(INCLUDE_XF86_MAP_PCI_MEM)
pointer
-xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, unsigned long Base,
+xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, ADDRESS Base,
unsigned long Size)
{
- unsigned long hostbase = pciBusAddrToHostAddr(Tag, Base);
+ ADDRESS hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM,Base);
pointer base;
CARD32 save = 0;
@@ -1006,14 +1052,15 @@ xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, unsigned long Base,
return((pointer)base);
}
-
-int
-xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
+static int
+readPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
unsigned char *Buf, int Len)
{
ADDRESS hostbase;
+ CARD8 *image = Buf;
+ unsigned long offset;
CARD32 romaddr, savebase = 0, romsave = 0, newbase = 0;
- int ret;
+ int ret, length, rlength, n;
/* XXX This assumes that memory access is enabled */
@@ -1024,34 +1071,77 @@ xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
*/
romsave = pciReadLong(Tag, PCI_MAP_ROM_REG);
romaddr = PCIGETROM(romsave);
- if ((newbase = getValidBIOSBase(Tag,basereg)) != romaddr) {
+ if ((newbase = getValidBIOSBase(Tag, &basereg)) != romaddr) {
+RetryWithBase:
romaddr = PCIGETROM(newbase);
- if (romaddr != 0 && romaddr == newbase) {
-#if 0
- savebase = pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2));
- if (PCIGETROM(savebase) == romaddr)
- pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0);
- else
- savebase = 0;
-#endif
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr);
- } else
- romaddr = 0;
+ if (romaddr) {
+ /* move mem base out of the way if in conflicts with ROM */
+ if ((basereg >= 0) && (basereg <= 5)) {
+ if (!savebase)
+ savebase = pciReadLong(Tag, PCI_MAP_REG_START+(basereg<<2));
+ if (PCIGETROM(savebase) == romaddr) {
+ xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]"
+ " for device %i:%i:%i\n", basereg,
+ PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag),
+ PCI_FUNC_FROM_TAG(Tag));
+ pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2),
+ (CARD32)~0);
+ }
+ }
+ }
}
+
+
if (romaddr == 0) {
xf86Msg(X_WARNING, "xf86ReadPciBIOS: cannot locate a BIOS address\n");
return -1;
- }
- hostbase = pciBusAddrToHostAddr(Tag, PCIGETROM(romaddr));
-
+ }
+ xf86MsgVerb(X_INFO, 5,
+ "xf86ReadPciBIOS: found ValidBIOSBase for %i:%i:%i: %x\n",
+ PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag), PCI_FUNC_FROM_TAG(Tag),
+ newbase);
+
+ hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr));
+#ifdef DEBUG
+ ErrorF("ReadPciBIOS: base = 0x%x\n",romaddr);
+#endif
/* Enable ROM address decoding */
pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr | PCI_MAP_ROM_DECODE_ENABLE);
- ret = xf86ReadBIOS(hostbase, Offset, Buf, Len);
+ /* Read BIOS in 64kB chunks */
+ ret = 0;
+ offset = Offset;
+ while ((length = Len) > 0) {
+ if (length > 0x10000) length = 0x10000;
+ rlength = xf86ReadBIOS(hostbase, offset, image, length);
+ if (rlength < 0) {
+ ret = rlength;
+ break;
+ }
+ ret += rlength;
+ if (rlength < length) break;
+ offset += length;
+ image += length;
+ Len -= length;
+ }
+
+ if ((ret != Len) || (Buf[0] != 0x55) || (Buf[1] != 0xaa) || !Buf[2] ||
+ (Len < (Buf[2] << 9))) {
+ n = 0;
+ if ((basereg >= 0) && (basereg <= 5) && xf86PciVideoInfo) do {
+ pciVideoPtr pvp;
+
+ if (!(pvp = xf86PciVideoInfo[n++])) break;
+ if (pciTag(pvp->bus, pvp->device, pvp->func) == Tag) {
+ if (newbase == pvp->memBase[basereg]) break;
+ newbase = pvp->memBase[basereg];
+ goto RetryWithBase;
+ }
+ } while (1);
+ }
/* Restore ROM address decoding */
pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
-
/* Restore the base register if it was changed. */
if (savebase)
pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), savebase);
@@ -1059,23 +1149,48 @@ xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
return ret;
}
-#elif defined(__sparc__)
-
-pointer
-xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, pointer Base,
- unsigned long Size)
-{
- FatalError("xf86MapPciMem: Unsupported on SPARC\n");
- return((pointer)-1);
-}
+typedef CARD32 (*ReadProcPtr)(PCITAG, int);
+typedef void (*WriteProcPtr)(PCITAG, int, CARD32);
int
xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
unsigned char *Buf, int Len)
{
- FatalError("xf86ReadPciBIOS: Unsupported on SPARC\n");
- return -1;
-}
+ int size, num;
+ CARD32 Acc1, Acc2;
+ PCITAG *pTag;
+ int i;
+
+ size = readPciBIOS(Offset,Tag,basereg,Buf,Len);
+
+ if ((size == Len) && (Buf[0] == 0x55) && (Buf[1] == 0xaa) && Buf[2] &&
+ (Len >= (Buf[2] << 9)))
+ return size;
+
+ num = pciTestMultiDeviceCard(PCI_BUS_FROM_TAG(Tag),
+ PCI_DEV_FROM_TAG(Tag),
+ PCI_FUNC_FROM_TAG(Tag),&pTag);
+
+ if (!num) return size;
+
+#define PCI_ENA (PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE)
+ Acc1 = ((ReadProcPtr)(pciLongFunc(Tag,READ)))(Tag,PCI_CMD_STAT_REG);
+ ((WriteProcPtr)(pciLongFunc(Tag,WRITE)))(Tag,
+ PCI_CMD_STAT_REG,(Acc1 & ~PCI_ENA));
+
+ for (i = 0; i < num; i++) {
+ Acc2 = ((ReadProcPtr)(pciLongFunc(pTag[i],READ)))(pTag[i],PCI_CMD_STAT_REG);
+ ((WriteProcPtr)(pciLongFunc(pTag[i],WRITE)))(pTag[i],
+ PCI_CMD_STAT_REG,(Acc2 | PCI_ENA));
+ size = readPciBIOS(Offset,pTag[i],0,Buf,Len);
+ ((WriteProcPtr)(pciLongFunc(pTag[i],WRITE)))(pTag[i],PCI_CMD_STAT_REG,Acc2);
+ if ((size == Len) && (Buf[0] == 0x55) && (Buf[1] == 0xaa) && Buf[2] &&
+ (Len >= (Buf[2] << 9)))
+ break;
+ }
+ ((WriteProcPtr)(pciLongFunc(Tag,WRITE)))(Tag,PCI_CMD_STAT_REG,Acc1);
+ return size;
+}
#endif /* INCLUDE_XF86_MAP_PCI_MEM */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
index 470c25b38..702fca0d7 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
@@ -47,7 +47,7 @@
# **** End of SMP/MODVERSIONS detection
-MODS = gamma.o tdfx.o
+MODS = gamma.o tdfx.o r128.o radeon.o
LIBS =
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
@@ -61,6 +61,13 @@ GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
TDFXOBJS = tdfx_drv.o
TDFXHEADERS = tdfx.h $(DRMHEADERS)
+R128OBJS = r128_drv.o r128_cce.o r128_state.o
+R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
+
+RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o
+RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
+ $(DRMTEMPLATES)
+
INC = /usr/include
CFLAGS = -O2 $(WARNINGS)
@@ -132,7 +139,7 @@ ifeq ($(AGP),1)
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
DRMTEMPLATES += drm_agpsupport.h
DRMHEADERS += agpsupport-pre24.h
-MODS += mga.o r128.o radeon.o
+MODS += mga.o
ifeq ($(MACHINE),i386)
MODS += i810.o
endif
@@ -140,19 +147,16 @@ ifeq ($(MACHINE),i686)
MODS += i810.o
endif
-
MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o
MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
I810OBJS = i810_drv.o i810_dma.o
I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
-R128OBJS = r128_drv.o r128_cce.o r128_state.o
-R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
+endif
-RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o
-RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
- $(DRMTEMPLATES)
+ifeq ($(MACHINE),alpha)
+MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6
endif
ifeq ($(SIS),1)
@@ -218,26 +222,27 @@ tdfx.o: $(TDFXOBJS) $(LIBS)
sis.o: $(SISOBJS) $(LIBS)
$(LD) -r $^ -o $@
-ifeq ($(AGP),1)
-mga_drv.o: mga_drv.c
+r128_drv.o: r128_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-mga.o: $(MGAOBJS)
+r128.o: $(R128OBJS) $(LIBS)
$(LD) -r $^ -o $@
-i810_drv.o: i810_drv.c
+radeon_drv.o: radeon_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-i810.o: $(I810OBJS) $(LIBS)
+radeon.o: $(RADEONOBJS) $(LIBS)
$(LD) -r $^ -o $@
-r128_drv.o: r128_drv.c
+ifeq ($(AGP),1)
+mga_drv.o: mga_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-r128.o: $(R128OBJS) $(LIBS)
+mga.o: $(MGAOBJS)
$(LD) -r $^ -o $@
-radeon_drv.o: radeon_drv.c
+i810_drv.o: i810_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-radeon.o: $(RADEONOBJS) $(LIBS)
+i810.o: $(I810OBJS) $(LIBS)
$(LD) -r $^ -o $@
+
endif
.PHONY: ChangeLog
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ati_pcigart.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ati_pcigart.h
new file mode 100644
index 000000000..93c5148fb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ati_pcigart.h
@@ -0,0 +1,138 @@
+/* ati_pcigart.h -- ATI PCI GART support -*- linux-c -*-
+ * Created: Wed Dec 13 21:52:19 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>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if PAGE_SIZE == 8192
+# define ATI_PCIGART_TABLE_ORDER 2
+# define ATI_PCIGART_TABLE_PAGES (1 << 2)
+#elif PAGE_SIZE == 4096
+# define ATI_PCIGART_TABLE_ORDER 3
+# define ATI_PCIGART_TABLE_PAGES (1 << 3)
+#elif
+# error - PAGE_SIZE not 8K or 4K
+#endif
+
+# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
+# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
+
+static unsigned long DRM(ati_alloc_pcigart_table)( void )
+{
+ unsigned long address;
+ 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;
+ }
+
+ page = virt_to_page( address );
+
+ 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 );
+ return address;
+}
+
+static void DRM(ati_free_pcigart_table)( unsigned long address )
+{
+ struct page *page;
+ int i;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( !address ) return;
+
+ page = virt_to_page( address );
+
+ for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+ atomic_dec( &page->count );
+ ClearPageReserved( page );
+ }
+
+ free_pages( address, ATI_PCIGART_TABLE_ORDER );
+}
+
+unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
+{
+ drm_sg_mem_t *entry = dev->sg;
+ unsigned long address;
+ unsigned long pages;
+ u32 *pci_gart, page_base;
+ int i, j;
+
+ if ( !entry ) {
+ DRM_ERROR( "no scatter/gather memory!\n" );
+ return 0;
+ }
+
+ address = DRM(ati_alloc_pcigart_table)();
+ if ( !address ) {
+ DRM_ERROR( "cannot allocate PCI GART page!\n" );
+ return 0;
+ }
+
+ 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) );
+
+ for ( i = 0 ; i < pages ; i++ ) {
+ page_base = virt_to_bus( entry->pagelist[i]->virtual );
+ for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ *pci_gart++ = cpu_to_le32( page_base );
+ page_base += ATI_PCIGART_PAGE_SIZE;
+ }
+ }
+
+#if __i386__
+ asm volatile ( "wbinvd" ::: "memory" );
+#else
+ mb();
+#endif
+
+ return address;
+}
+
+int DRM(ati_pcigart_cleanup)( unsigned long address )
+{
+
+ if ( address ) {
+ DRM(ati_free_pcigart_table)( address );
+ }
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index f1abaabff..3def97f74 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -126,10 +126,11 @@ typedef struct drm_control {
} drm_control_t;
typedef enum drm_map_type {
- _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
- _DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2, /* shared, cached */
- _DRM_AGP = 3 /* AGP/GART */
+ _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /* no caching, no core dump */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3, /* AGP/GART */
+ _DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -238,7 +239,8 @@ typedef struct drm_buf_desc {
int high_mark; /* High water mark */
enum {
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
- _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
+ _DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
+ _DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
} flags;
unsigned long agp_start; /* Start address of where the agp buffers
* are in the agp aperture */
@@ -344,6 +346,11 @@ typedef struct drm_agp_info {
unsigned short id_device;
} drm_agp_info_t;
+typedef struct drm_scatter_gather {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for mapping / unmapping */
+} drm_scatter_gather_t;
+
#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)
@@ -399,6 +406,9 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
+#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
+
/* MGA specific ioctls */
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index 274e318aa..085d1cb83 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -53,7 +53,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/mm.h>
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__powerpc__)
#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
#include <asm/io.h>
@@ -145,6 +145,7 @@
#define DRM_MEM_BOUNDAGP 17
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
+#define DRM_MEM_SGLISTS 20
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
@@ -199,7 +200,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
unsigned long prev, cmp;
__asm__ __volatile__(
- "1: ldl_l %0,%2\n"
+ "1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
@@ -210,7 +211,8 @@ __cmpxchg_u32(volatile int *m, int old, int new)
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m));
+ : "r"((long) old), "r"(new), "m"(*m)
+ : "memory" );
return prev;
}
@@ -221,7 +223,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
unsigned long prev, cmp;
__asm__ __volatile__(
- "1: ldq_l %0,%2\n"
+ "1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
@@ -232,7 +234,8 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m));
+ : "r"((long) old), "r"(new), "m"(*m)
+ : "memory" );
return prev;
}
@@ -284,12 +287,43 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
return old;
}
+#elif defined(__powerpc__)
+extern void __cmpxchg_called_with_bad_pointer(void);
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+
+ switch (size) {
+ case 4:
+ __asm__ __volatile__(
+ "sync;"
+ "0: lwarx %0,0,%1 ;"
+ " cmpl 0,%0,%3;"
+ " bne 1f;"
+ " stwcx. %2,0,%1;"
+ " bne- 0b;"
+ "1: "
+ "sync;"
+ : "=&r"(prev)
+ : "r"(ptr), "r"(new), "r"(old)
+ : "cr0", "memory");
+ return prev;
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#endif /* i386, powerpc & alpha */
+
+#ifndef __alpha__
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
(unsigned long)(n),sizeof(*(ptr))))
-#endif /* i386 & alpha */
#endif
+#endif /* !__HAVE_ARCH_CMPXCHG */
+
/* Macros to make printk easier */
#define DRM_ERROR(fmt, arg...) \
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
@@ -547,7 +581,8 @@ typedef struct drm_device_dma {
unsigned long *pagelist;
unsigned long byte_count;
enum {
- _DRM_DMA_USE_AGP = 0x01
+ _DRM_DMA_USE_AGP = 0x01,
+ _DRM_DMA_USE_SG = 0x02
} flags;
/* DMA support */
@@ -579,6 +614,13 @@ typedef struct drm_agp_head {
} drm_agp_head_t;
#endif
+typedef struct drm_sg_mem {
+ unsigned long handle;
+ void *virtual;
+ int pages;
+ struct page **pagelist;
+} drm_sg_mem_t;
+
typedef struct drm_sigdata {
int context;
drm_hw_lock_t *lock;
@@ -667,6 +709,10 @@ typedef struct drm_device {
#if __REALLY_HAVE_AGP
drm_agp_head_t *agp;
#endif
+#ifdef __alpha__
+ struct pci_controler *hose;
+#endif
+ drm_sg_mem_t *sg; /* Scatter gather memory */
unsigned long *ctx_bitmap;
void *dev_private;
drm_sigdata_t sigdata; /* For block_all_signals */
@@ -718,6 +764,9 @@ extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
+extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
#else
/* Return type changed in 2.3.23 */
extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
@@ -729,6 +778,9 @@ extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
+extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
#endif
extern void DRM(vm_open)(struct vm_area_struct *vma);
extern void DRM(vm_close)(struct vm_area_struct *vma);
@@ -947,5 +999,16 @@ extern int DRM(proc_cleanup)(int minor,
struct proc_dir_entry *root,
struct proc_dir_entry *dev_root);
+ /* Scatter Gather Support (drm_scatter.h) */
+extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
+extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int DRM(sg_free)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+ /* ATI PCIGART support (ati_pcigart.h) */
+extern unsigned long DRM(ati_pcigart_init)(drm_device_t *dev);
+extern int DRM(ati_pcigart_cleanup)(unsigned long address);
+
#endif /* __KERNEL__ */
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
index dfd0d8fc2..9b056c75f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h
@@ -52,7 +52,8 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
agp_kern_info *kern;
drm_agp_info_t info;
- if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
+ return -EINVAL;
kern = &dev->agp->agp_info;
info.agp_version_major = kern->version.major;
@@ -77,7 +78,8 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (!dev->agp|| dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
+ if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+ return -EINVAL;
if ((retcode = drm_agp->acquire())) return retcode;
dev->agp->acquired = 1;
return 0;
@@ -89,7 +91,8 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- if (!dev->agp->acquired || !drm_agp->release) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
+ return -EINVAL;
drm_agp->release();
dev->agp->acquired = 0;
return 0;
@@ -108,7 +111,8 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_agp_mode_t mode;
- if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
+ return -EINVAL;
if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
return -EFAULT;
@@ -131,7 +135,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned long pages;
u32 type;
- if (!dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired) return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
@@ -188,7 +192,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
drm_agp_binding_t request;
drm_agp_mem_t *entry;
- if (!dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired) return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
@@ -207,7 +211,8 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
int retcode;
int page;
- if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
+ return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
@@ -229,7 +234,7 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
- if (!dev->agp->acquired) return -EINVAL;
+ if (!dev->agp || !dev->agp->acquired) return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
index b11110481..16af7bd54 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
@@ -37,6 +37,10 @@
#define __HAVE_PCI_DMA 0
#endif
+#ifndef __HAVE_SG
+#define __HAVE_SG 0
+#endif
+
#ifndef DRIVER_BUF_PRIV_T
#define DRIVER_BUF_PRIV_T u32
#endif
@@ -103,13 +107,16 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
switch ( map->type ) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
-#ifndef __sparc__
+#if !defined(__sparc__) && !defined(__alpha__)
if ( map->offset + map->size < map->offset ||
map->offset < virt_to_phys(high_memory) ) {
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
return -EINVAL;
}
#endif
+#ifdef __alpha__
+ map->offset += dev->hose->mem_space->start;
+#endif
#if __REALLY_HAVE_MTRR
if ( map->type == _DRM_FRAME_BUFFER ||
(map->flags & _DRM_WRITE_COMBINING) ) {
@@ -135,10 +142,21 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
break;
#if __REALLY_HAVE_AGP
case _DRM_AGP:
+#ifdef __alpha__
+ map->offset += dev->hose->mem_space->start;
+#endif
map->offset = map->offset + dev->agp->base;
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
break;
#endif
+ case _DRM_SCATTER_GATHER:
+ if (!dev->sg) {
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
+ map->offset = map->offset + dev->sg->handle;
+ break;
+
default:
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
return -EINVAL;
@@ -237,6 +255,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
vfree(map->handle);
break;
case _DRM_AGP:
+ case _DRM_SCATTER_GATHER:
break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
@@ -565,6 +584,159 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
}
#endif /* __HAVE_PCI_DMA */
+#ifdef __HAVE_SG
+int DRM(addbufs_sg)( 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_buf_desc_t request;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
+
+ if ( !dma ) return -EINVAL;
+
+ if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
+ sizeof(request) ) )
+ return -EFAULT;
+
+ count = request.count;
+ order = DRM(order)( request.size );
+ size = 1 << order;
+
+ alignment = (request.flags & _DRM_PAGE_ALIGN)
+ ? PAGE_ALIGN(size) : size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ byte_count = 0;
+ agp_offset = request.agp_start;
+
+ DRM_DEBUG( "count: %d\n", count );
+ DRM_DEBUG( "order: %d\n", order );
+ DRM_DEBUG( "size: %d\n", size );
+ DRM_DEBUG( "agp_offset: %ld\n", agp_offset );
+ DRM_DEBUG( "alignment: %d\n", alignment );
+ DRM_DEBUG( "page_order: %d\n", page_order );
+ DRM_DEBUG( "total: %d\n", total );
+
+ if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+ if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+ spin_lock( &dev->count_lock );
+ if ( dev->buf_use ) {
+ spin_unlock( &dev->count_lock );
+ return -EBUSY;
+ }
+ atomic_inc( &dev->buf_alloc );
+ spin_unlock( &dev->count_lock );
+
+ down( &dev->struct_sem );
+ entry = &dma->bufs[order];
+ if ( entry->buf_count ) {
+ up( &dev->struct_sem );
+ 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 ) {
+ up( &dev->struct_sem );
+ atomic_dec( &dev->buf_alloc );
+ return -ENOMEM;
+ }
+ memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+
+ offset = 0;
+
+ while ( entry->buf_count < count ) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+
+ buf->offset = (dma->byte_count + offset);
+ buf->bus_address = agp_offset + offset;
+ buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ init_waitqueue_head( &buf->dma_wait );
+ buf->pid = 0;
+
+ buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
+ buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
+ DRM_MEM_BUFS );
+ memset( buf->dev_private, 0, buf->dev_priv_size );
+
+#if __HAVE_DMA_HISTOGRAM
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
+#endif
+ DRM_DEBUG( "buffer %d @ %p\n",
+ entry->buf_count, buf->address );
+
+ offset += alignment;
+ entry->buf_count++;
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+ dma->buflist = DRM(realloc)( dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist),
+ DRM_MEM_BUFS );
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ }
+
+ dma->buf_count += entry->buf_count;
+ dma->byte_count += byte_count;
+
+ DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+ DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+#if __HAVE_DMA_FREELIST
+ 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] );
+ }
+#endif
+ up( &dev->struct_sem );
+
+ request.count = entry->buf_count;
+ request.size = size;
+
+ if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
+ return -EFAULT;
+
+ dma->flags = _DRM_DMA_USE_SG;
+
+ atomic_dec( &dev->buf_alloc );
+ return 0;
+}
+#endif /* __HAVE_SG */
+
int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -579,6 +751,11 @@ int DRM(addbufs)( struct inode *inode, struct file *filp,
return DRM(addbufs_agp)( inode, filp, cmd, arg );
else
#endif
+#if __HAVE_SG
+ if ( request.flags & _DRM_SG_BUFFER )
+ return DRM(addbufs_sg)( inode, filp, cmd, arg );
+ else
+#endif
#if __HAVE_PCI_DMA
return DRM(addbufs_pci)( inode, filp, cmd, arg );
#else
@@ -760,7 +937,8 @@ int DRM(mapbufs)( struct inode *inode, struct file *filp,
return -EFAULT;
if ( request.count >= dma->buf_count ) {
- if ( __HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP) ) {
+ if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
+ (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
if ( !map ) {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
index 7447ca6d4..3791d7a87 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
@@ -81,6 +81,9 @@
#ifndef __HAVE_COUNTERS
#define __HAVE_COUNTERS 0
#endif
+#ifndef __HAVE_SG
+#define __HAVE_SG 0
+#endif
#ifndef DRIVER_PREINIT
#define DRIVER_PREINIT()
@@ -178,6 +181,11 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
#endif
+#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
+
DRIVER_IOCTLS
};
@@ -415,6 +423,12 @@ static int DRM(takedown)( drm_device_t *dev )
* handled in the AGP/GART driver.
*/
break;
+ case _DRM_SCATTER_GATHER:
+ if(dev->sg) {
+ DRM(sg_cleanup)(dev->sg);
+ dev->sg = NULL;
+ }
+ break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h
index dd5747669..75752b3ac 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h
@@ -70,6 +70,21 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
}
up(&dev->struct_sem);
+#ifdef __alpha__
+ /*
+ * Default the hose
+ */
+ if (!dev->hose) {
+ struct pci_dev *pci_dev;
+ pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+ if (pci_dev) dev->hose = pci_dev->sysdata;
+ if (!dev->hose) {
+ struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+ if (b) dev->hose = b->sysdata;
+ }
+ }
+#endif
+
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_init.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_init.h
index 9ae984147..d9d8e3a23 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_init.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_init.h
@@ -32,7 +32,11 @@
#define __NO_VERSION__
#include "drmP.h"
+#if 0
+int DRM(flags) = DRM_FLAG_DEBUG;
+#else
int DRM(flags) = 0;
+#endif
/* drm_parse_option parses a single option. See description for
* drm_parse_options for details.
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
index 2fba6b0c2..1cc8f31f0 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
@@ -95,6 +95,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
DRM_MEM_DRIVER);
sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
+#ifdef __alpha__
+ do {
+ struct pci_dev *pci_dev;
+ int b, d, f;
+ char *p;
+
+ for(p = dev->unique; p && *p && *p != ':'; p++);
+ if (!p || !*p) break;
+ b = (int)simple_strtoul(p+1, &p, 10);
+ if (*p != ':') break;
+ d = (int)simple_strtoul(p+1, &p, 10);
+ if (*p != ':') break;
+ f = (int)simple_strtoul(p+1, &p, 10);
+ if (*p) break;
+
+ pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
+ if (pci_dev)
+ dev->hose = pci_dev->sysdata;
+ } while(0);
+#endif
+
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h
index 1763d9b41..498937d4c 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_memory.h
@@ -63,6 +63,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
[DRM_MEM_MAPPINGS] = { "mappings" },
[DRM_MEM_BUFLISTS] = { "buflists" },
[DRM_MEM_AGPLISTS] = { "agplist" },
+ [DRM_MEM_SGLISTS] = { "sglist" },
[DRM_MEM_TOTALAGP] = { "totalagp" },
[DRM_MEM_BOUNDAGP] = { "boundagp" },
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_scatter.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_scatter.h
new file mode 100644
index 000000000..a0371074e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_scatter.h
@@ -0,0 +1,218 @@
+/* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*-
+ * Created: Mon Dec 18 23:20:54 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>
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/vmalloc.h>
+#include "drmP.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++ ) {
+ page = entry->pagelist[i];
+ if ( page )
+ ClearPageReserved( page );
+ }
+
+ vfree( entry->virtual );
+
+ DRM(free)( entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ DRM(free)( entry,
+ sizeof(*entry),
+ DRM_MEM_SGLISTS );
+}
+
+int DRM(sg_alloc)( 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_scatter_gather_t request;
+ drm_sg_mem_t *entry;
+ unsigned long pages, i, j;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( dev->sg )
+ return -EINVAL;
+
+ if ( copy_from_user( &request,
+ (drm_scatter_gather_t *)arg,
+ sizeof(request) ) )
+ return -EFAULT;
+
+ entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
+ if ( !entry )
+ return -ENOMEM;
+
+ memset( entry, 0, sizeof(*entry) );
+
+ pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+
+ entry->pages = pages;
+ entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ if ( !entry->pagelist ) {
+ DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
+ return -ENOMEM;
+ }
+
+ entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+ if ( !entry->virtual ) {
+ DRM(free)( entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ DRM(free)( entry,
+ sizeof(*entry),
+ DRM_MEM_SGLISTS );
+ 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 );
+
+ 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;
+ }
+
+ dev->sg = entry;
+
+#if DEBUG_SCATTER
+ /* Verify that each page points to its virtual address, and vice
+ * versa.
+ */
+ {
+ int error = 0;
+
+ for ( i = 0 ; i < pages ; i++ ) {
+ unsigned long *tmp;
+
+ tmp = (unsigned long *)entry->pagelist[i]->virtual;
+ for ( j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++ ) {
+ *tmp = 0xcafebabe;
+ }
+ tmp = (unsigned long *)((u8 *)entry->virtual +
+ (PAGE_SIZE * i));
+ for( j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++ ) {
+ if ( *tmp != 0xcafebabe && error == 0 ) {
+ error = 1;
+ DRM_ERROR( "Scatter allocation error, "
+ "pagelist does not match "
+ "virtual mapping\n" );
+ }
+ }
+ tmp = (unsigned long *)entry->pagelist[i]->virtual;
+ for(j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++) {
+ *tmp = 0;
+ }
+ }
+ if (error == 0)
+ DRM_ERROR( "Scatter allocation matches pagelist\n" );
+ }
+#endif
+
+ return 0;
+
+ failed:
+ DRM(sg_cleanup)( entry );
+ return -ENOMEM;
+}
+
+int DRM(sg_free)( 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_scatter_gather_t request;
+ drm_sg_mem_t *entry;
+
+ if ( copy_from_user( &request,
+ (drm_scatter_gather_t *)arg,
+ sizeof(request) ) )
+ return -EFAULT;
+
+ entry = dev->sg;
+ dev->sg = NULL;
+
+ if ( !entry || entry->handle != request.handle )
+ return -EINVAL;
+
+ DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
+
+ DRM(sg_cleanup)( entry );
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
index fb51926ba..771c11bd2 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
@@ -50,6 +50,12 @@ struct vm_operations_struct drm_vm_dma_ops = {
close: DRM(vm_close),
};
+struct vm_operations_struct drm_vm_sg_ops = {
+ nopage: DRM(vm_sg_nopage),
+ open: DRM(vm_open),
+ close: DRM(vm_close),
+};
+
#if LINUX_VERSION_CODE < 0x020317
unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address,
@@ -93,7 +99,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
/* We have to walk page tables here because we need large SAREA's, and
- * they need to be virtually contigious in kernel space.
+ * they need to be virtually contiguous in kernel space.
*/
pgd = pgd_offset_k( i );
if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
@@ -187,6 +193,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
vfree(map->handle);
break;
case _DRM_AGP:
+ case _DRM_SCATTER_GATHER:
break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
@@ -230,6 +237,48 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
#endif
}
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+#else
+ /* Return type changed in 2.3.23 */
+struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+#endif
+{
+#if LINUX_VERSION_CODE >= 0x020300
+ drm_map_t *map = (drm_map_t *)vma->vm_private_data;
+#else
+ drm_map_t *map = (drm_map_t *)vma->vm_pte;
+#endif
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_sg_mem_t *entry = dev->sg;
+ unsigned long offset;
+ unsigned long map_offset;
+ unsigned long page_offset;
+ struct page *page;
+
+ if (!entry) return NOPAGE_SIGBUS; /* Error */
+ if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
+
+
+ offset = address - vma->vm_start;
+ map_offset = map->offset - dev->sg->handle;
+ page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+ 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
+ return page;
+#endif
+}
+
void DRM(vm_open)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
@@ -322,6 +371,7 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
drm_map_list_t *r_list;
+ unsigned long offset = 0;
struct list_head *list;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
@@ -374,19 +424,26 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
}
#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);
+#elif defined(__powerpc__)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
}
+#ifdef __alpha__
+ offset = dev->hose->dense_mem_base -
+ dev->hose->mem_space->start;
+#endif
if (remap_page_range(vma->vm_start,
- VM_OFFSET(vma),
+ VM_OFFSET(vma) + offset,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%lx\n",
map->type,
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
@@ -400,6 +457,15 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
DRM_KERNEL advisory is supported. */
vma->vm_flags |= VM_LOCKED;
break;
+ case _DRM_SCATTER_GATHER:
+ vma->vm_ops = &drm_vm_sg_ops;
+#if LINUX_VERSION_CODE >= 0x020300
+ vma->vm_private_data = (void *)map;
+#else
+ vma->vm_pte = (unsigned long)map;
+#endif
+ vma->vm_flags |= VM_LOCKED;
+ break;
default:
return -EINVAL; /* This should never happen. */
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
index 066b4e480..4af2ca2e8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
@@ -237,7 +237,7 @@ typedef struct drm_mga_init {
MGA_CLEANUP_DMA = 0x02
} func;
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int chipset;
int sgram;
@@ -254,12 +254,12 @@ typedef struct drm_mga_init {
unsigned int texture_offset[MGA_NR_TEX_HEAPS];
unsigned int texture_size[MGA_NR_TEX_HEAPS];
- unsigned int fb_offset;
- unsigned int mmio_offset;
- unsigned int status_offset;
- unsigned int warp_offset;
- unsigned int primary_offset;
- unsigned int buffers_offset;
+ 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 {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h
index 83e002afa..926b4bfd2 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128.h
@@ -37,9 +37,11 @@
/* General customization:
*/
#define __HAVE_AGP 1
-#define __MUST_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:
*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
index c0e20c213..1ced05fe9 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
@@ -178,6 +178,8 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
{
int i;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
r128_do_wait_for_idle( dev_priv );
R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
@@ -208,7 +210,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv )
int i;
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
+ 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 ) &&
@@ -249,7 +251,7 @@ 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 );
- *dev_priv->ring.head = 0;
+ SET_RING_HEAD( &dev_priv->ring, 0 );
dev_priv->ring.tail = 0;
}
@@ -312,19 +314,43 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
u32 ring_start;
u32 tmp;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
/* The manual (p. 2) says this address is in "VM space". This
* means it's an offset from the start of AGP space.
*/
- ring_start = dev_priv->cce_ring->offset - dev->agp->base;
+#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. */
- *dev_priv->ring.head = 0;
- R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
- dev_priv->ring_rptr->offset );
+ 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,
+ virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+ DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+ virt_to_bus(entry->pagelist[page_ofs]->virtual),
+ entry->handle + tmp_ofs );
+ }
/* Set watermark control */
R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
@@ -346,6 +372,8 @@ 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__ );
+
dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
return -ENOMEM;
@@ -355,11 +383,9 @@ 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 ) {
+ if ( dev_priv->is_pci && !dev->sg ) {
+ DRM_DEBUG( "PCI GART memory not allocated!\n" );
+ DRM_ERROR( "PCI GART memory not allocated!\n" );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -368,6 +394,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
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" );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -387,6 +414,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
( 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" );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -476,9 +504,24 @@ 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);
- DRM_IOREMAP( dev_priv->cce_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ if ( !dev_priv->is_pci ) {
+ DRM_IOREMAP( dev_priv->cce_ring );
+ DRM_IOREMAP( dev_priv->ring_rptr );
+ DRM_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 __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);
@@ -501,6 +544,20 @@ 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 ) {
+ dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
+ if ( !dev_priv->phys_pci_gart ) {
+ DRM_DEBUG( "failed to init PCI GART!\n" );
+ DRM_ERROR( "failed to init PCI GART!\n" );
+ DRM(free)( dev_priv, sizeof(*dev_priv),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+ R128_WRITE( R128_PCI_GART_PAGE,
+ virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+ }
+
r128_cce_init_ring_buffer( dev );
r128_cce_load_microcode( dev_priv );
r128_do_engine_reset( dev );
@@ -513,9 +570,11 @@ int r128_do_cleanup_cce( drm_device_t *dev )
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_IOREMAPFREE( dev_priv->cce_ring );
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
- DRM_IOREMAPFREE( dev_priv->buffers );
+ if ( !dev_priv->is_pci ) {
+ DRM_IOREMAPFREE( dev_priv->cce_ring );
+ DRM_IOREMAPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPFREE( dev_priv->buffers );
+ }
DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
DRM_MEM_DRIVER );
@@ -532,6 +591,8 @@ int r128_cce_init( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_r128_init_t init;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
return -EFAULT;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
index 86aba175f..fc1261eae 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
@@ -175,7 +175,7 @@ typedef struct drm_r128_init {
R128_INIT_CCE = 0x01,
R128_CLEANUP_CCE = 0x02
} func;
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int is_pci;
int cce_mode;
int cce_secure;
@@ -189,12 +189,12 @@ typedef struct drm_r128_init {
unsigned int depth_offset, depth_pitch;
unsigned int span_offset;
- 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;
+ 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_r128_init_t;
typedef struct drm_r128_cce_stop {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
index daae0f875..584cb29c3 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
@@ -33,16 +33,17 @@
#include "r128.h"
#include "drmP.h"
#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 "20010308"
+#define DRIVER_DATE "20010405"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 1
-#define DRIVER_PATCHLEVEL 5
+#define DRIVER_PATCHLEVEL 6
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { r128_cce_buffers, 1, 0 }, \
@@ -88,3 +89,4 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
+#include "drm_scatter.h"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
index 6216b9a1b..fbc692298 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
@@ -28,11 +28,15 @@
* Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
+ * Michel Dänzer <daenzerm@student.ethz.ch>
*/
#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 )
+
typedef struct drm_r128_freelist {
unsigned int age;
drm_buf_t *buf;
@@ -67,6 +71,8 @@ typedef struct drm_r128_private {
int usec_timeout;
int is_pci;
+ unsigned long phys_pci_gart;
+ unsigned long cce_buffers_offset;
atomic_t idle_count;
@@ -134,7 +140,7 @@ extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
static inline void
r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring )
{
- ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32);
+ ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32);
if ( ring->space <= 0 )
ring->space += ring->size;
}
@@ -248,6 +254,7 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
# define R128_PC_FLUSH_ALL 0x00ff
# define R128_PC_BUSY (1 << 31)
+#define R128_PCI_GART_PAGE 0x017c
#define R128_PRIM_TEX_CNTL_C 0x1cb0
#define R128_SCALE_3D_CNTL 0x1a00
@@ -365,7 +372,7 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
-#define R128_MAX_VB_AGE 0xffffffff
+#define R128_MAX_VB_AGE 0x7fffffff
#define R128_MAX_VB_VERTS (0xffff)
#define R128_RING_HIGH_MARK 128
@@ -373,17 +380,36 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
#define R128_PERFORMANCE_BOXES 0
-#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
+#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 )
-#define R128_READ(reg) R128_DEREF( reg )
-#define R128_WRITE(reg,val) do { R128_DEREF( reg ) = val; } while (0)
+#ifdef __alpha__
+#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg)))
+static inline u32 _R128_READ(u32 *addr) {
+ mb();
+ return *(volatile u32 *)addr;
+}
+#define R128_WRITE(reg,val) \
+ do { wmb(); 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_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) {
+ mb();
+ return *(volatile u8 *)addr;
+}
+#define R128_WRITE8(reg,val) \
+ do { wmb(); 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_WRITE_PLL(addr,val) \
do { \
@@ -485,7 +511,7 @@ do { \
#define ADVANCE_RING() do { \
if ( R128_VERBOSE ) { \
- DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
+ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
if ( R128_BROKEN_CCE && write < 32 ) { \
@@ -503,7 +529,7 @@ do { \
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), write ); \
} \
- ring[write++] = (x); \
+ ring[write++] = cpu_to_le32( x ); \
write &= tail_mask; \
} while (0)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
index 9fc6b485c..7eafd72d6 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
@@ -660,7 +660,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
u32 *data = (u32 *)
((char *)dev_priv->buffers->handle
+ buf->offset + start);
- data[dwords++] = R128_CCE_PACKET2;
+ data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
}
buf_priv->dispatched = 1;
@@ -704,7 +704,7 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
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->agp->base;
+ int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
int prim = buf_priv->prim;
u32 *data;
int dwords;
@@ -727,16 +727,21 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
data = (u32 *)((char *)dev_priv->buffers->handle
+ buf->offset + start);
- data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+ data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
+ dwords-2 ) );
- data[1] = offset;
- data[2] = R128_MAX_VB_VERTS;
- data[3] = format;
- data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
- (count << 16));
+ 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 {
@@ -842,23 +847,23 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
- data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
- data[1] = (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] = (blit->pitch << 21) | (blit->offset >> 5);
- data[3] = 0xffffffff;
- data[4] = 0xffffffff;
- data[5] = (blit->y << 16) | blit->x;
- data[6] = (blit->height << 16) | blit->width;
- data[7] = dwords;
+ 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);
@@ -1299,8 +1304,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN( dev );
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
@@ -1362,8 +1367,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN( dev );
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h
index db238b1b4..0fdeb82a8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon.h
@@ -37,9 +37,11 @@
/* General customization:
*/
#define __HAVE_AGP 1
-#define __MUST_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:
*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
index ed8b1bbca..c255a3e05 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
@@ -318,6 +318,16 @@ static void radeon_status( drm_radeon_private_t *dev_priv )
(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
@@ -401,6 +411,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__ );
radeon_do_wait_for_idle( dev_priv );
@@ -419,6 +430,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__ );
#if 0
u32 tmp;
@@ -432,6 +444,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__ );
BEGIN_RING( 6 );
@@ -449,6 +462,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__ );
radeon_do_wait_for_idle( dev_priv );
@@ -472,6 +486,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__ );
cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
@@ -485,6 +500,8 @@ 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__ );
+
RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
dev_priv->cp_running = 0;
@@ -551,18 +568,29 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
drm_radeon_private_t *dev_priv = dev->dev_private;
u32 ring_start, cur_read_ptr;
u32 tmp;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
/* Initialize the memory controller */
RADEON_WRITE( RADEON_MC_FB_LOCATION,
(dev_priv->agp_vm_start - 1) & 0xffff0000 );
- RADEON_WRITE( RADEON_MC_AGP_LOCATION,
- (((dev_priv->agp_vm_start - 1 +
- dev_priv->agp_size) & 0xffff0000) |
- (dev_priv->agp_vm_start >> 16)) );
- ring_start = (dev_priv->cp_ring->offset
- - dev->agp->base
- + dev_priv->agp_vm_start);
+ 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 );
@@ -575,17 +603,29 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
*dev_priv->ring.head = cur_read_ptr;
dev_priv->ring.tail = cur_read_ptr;
- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
+ 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,
+ virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+ DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+ virt_to_bus(entry->pagelist[page_ofs]->virtual),
+ entry->handle + tmp_ofs );
+ }
/* Set ring buffer size */
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
radeon_do_wait_for_idle( dev_priv );
- /* Turn off PCI GART */
- tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN;
- RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-
/* Turn on bus mastering */
tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
RADEON_WRITE( RADEON_BUS_CNTL, tmp );
@@ -602,6 +642,8 @@ 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__ );
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
@@ -612,11 +654,20 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->is_pci = init->is_pci;
- /* We don't support PCI cards until PCI GART is implemented.
- * Fail here so we can remove all checks for PCI cards around
- * the CP ring code.
+#if 1
+ /* 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" );
+ DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+#endif
+
+ if ( dev_priv->is_pci && !dev->sg ) {
+ DRM_DEBUG( "PCI GART memory not allocated!\n" );
+ DRM_ERROR( "PCI GART memory not allocated!\n" );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -625,6 +676,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
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" );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -642,6 +694,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
*/
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 );
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -735,15 +788,45 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
- DRM_IOREMAP( dev_priv->cp_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ if ( !dev_priv->is_pci ) {
+ DRM_IOREMAP( dev_priv->cp_ring );
+ DRM_IOREMAP( dev_priv->ring_rptr );
+ DRM_IOREMAP( dev_priv->buffers );
+ } 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 );
- dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
- - dev->agp->base
- + dev_priv->agp_vm_start);
+#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);
@@ -787,6 +870,44 @@ 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 ( dev_priv->is_pci ) {
+ dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
+ if ( !dev_priv->phys_pci_gart ) {
+ DRM_DEBUG( "failed to init PCI GART!\n" );
+ DRM_ERROR( "failed to init PCI GART!\n" );
+ DRM(free)( dev_priv, sizeof(*dev_priv),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+ /* 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,
+ virt_to_bus( (void *)dev_priv->phys_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, 0 );
+ } else {
+ /* Turn off PCI GART
+ */
+ tmp = RADEON_READ( RADEON_AIC_CNTL )
+ & ~RADEON_PCIGART_TRANSLATE_EN;
+ RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+ }
+
radeon_cp_load_microcode( dev_priv );
radeon_cp_init_ring_buffer( dev );
radeon_do_engine_reset( dev );
@@ -800,12 +921,16 @@ 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__ );
+
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_IOREMAPFREE( dev_priv->cp_ring );
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
- DRM_IOREMAPFREE( dev_priv->buffers );
+ if ( !dev_priv->is_pci ) {
+ DRM_IOREMAPFREE( dev_priv->cp_ring );
+ DRM_IOREMAPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPFREE( dev_priv->buffers );
+ }
DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
DRM_MEM_DRIVER );
@@ -1173,7 +1298,10 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
}
/* 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 -EBUSY;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
index 50a7d6ed8..4ae387ff0 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
@@ -236,7 +236,7 @@ typedef struct drm_radeon_init {
RADEON_INIT_CP = 0x01,
RADEON_CLEANUP_CP = 0x02
} func;
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int is_pci;
int cp_mode;
int agp_size;
@@ -249,12 +249,12 @@ typedef struct drm_radeon_init {
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
- 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;
+ 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 {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
index b022c3bb1..d76326676 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
@@ -31,16 +31,17 @@
#include "radeon.h"
#include "drmP.h"
#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 "20010402"
+#define DRIVER_DATE "20010405"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 1
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_PATCHLEVEL 1
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
@@ -85,3 +86,4 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
+#include "drm_scatter.h"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
index f176bb560..249358477 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
@@ -64,7 +64,7 @@ typedef struct drm_radeon_private {
int agp_size;
u32 agp_vm_start;
- u32 agp_buffers_offset;
+ unsigned long agp_buffers_offset;
int cp_mode;
int cp_running;
@@ -83,6 +83,7 @@ typedef struct drm_radeon_private {
int usec_timeout;
int is_pci;
+ unsigned long phys_pci_gart;
atomic_t idle_count;
@@ -433,6 +434,12 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#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
@@ -508,16 +515,40 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#define RADEON_RING_HIGH_MARK 128
-#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
+#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg )
+#ifdef __alpha__
+#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
+static inline u32 _RADEON_READ(u32 *addr) {
+ mb();
+ return *(volatile u32 *)addr;
+}
+#define RADEON_WRITE(reg,val) do { \
+ wmb();
+ RADEON_DEREF(reg) = val;
+} while (0)
+#else
#define RADEON_READ(reg) RADEON_DEREF( reg )
#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
+#endif
#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg )
+#ifdef __alpha__
+#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
+static inline u8 _RADEON_READ8(u8 *addr) {
+ mb();
+ return *(volatile u8 *)addr;
+}
+#define RADEON_WRITE8(reg,val) do { \
+ wmb();
+ RADEON_DEREF8( reg ) = val;
+} while (0)
+#else
#define RADEON_READ8(reg) RADEON_DEREF8( reg )
#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
+#endif
#define RADEON_WRITE_PLL( addr, val ) do { \
RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \
@@ -673,7 +704,7 @@ do { \
#define ADVANCE_RING() do { \
if ( RADEON_VERBOSE ) { \
- DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
+ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
radeon_flush_write_combine(); \
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
index 9360c43b0..0a209245b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
@@ -1227,8 +1227,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN( dev );
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
@@ -1290,8 +1290,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN( dev );
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
@@ -1420,8 +1420,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
LOCK_TEST_WITH_RETURN( dev );
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
index 826758817..bb719edb6 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
@@ -67,11 +67,6 @@ extern int xf86RemoveSIGIOHandler(int fd);
# endif
#endif
-#ifdef __alpha__
-extern unsigned long _bus_base(void);
-#define BUS_BASE _bus_base()
-#endif
-
/* Not all systems have MAP_FAILED defined */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
@@ -490,11 +485,6 @@ int drmAddMap(int fd,
drm_map_t map;
map.offset = offset;
-#ifdef __alpha__
- /* Make sure we add the bus_base to all but shm */
- if (type != DRM_SHM)
- map.offset += BUS_BASE;
-#endif
map.size = size;
map.handle = 0;
map.type = type;
@@ -998,6 +988,28 @@ unsigned int drmAgpDeviceId(int fd)
return i.id_device;
}
+int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle)
+{
+ drm_scatter_gather_t sg;
+
+ *handle = 0;
+ sg.size = size;
+ sg.handle = 0;
+ if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno;
+ *handle = sg.handle;
+ return 0;
+}
+
+int drmScatterGatherFree(int fd, unsigned long handle)
+{
+ drm_scatter_gather_t sg;
+
+ sg.size = 0;
+ sg.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno;
+ return 0;
+}
+
int drmError(int err, const char *label)
{
switch (err) {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
index e71607a42..4c4de1308 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.24 1999/04/18 04:08:52 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.45 2001/02/15 11:03:56 alanh Exp $ */
/*
* Copyright 1992 by Orest Zborowski <obz@Kodak.com>
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
@@ -33,8 +33,10 @@
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86OSpriv.h"
-
-#include "compiler.h"
+#include "lnx.h"
+#ifdef __alpha__
+#include "xf86Axp.h"
+#endif
#ifdef HAS_MTRR_SUPPORT
#include <asm/mtrr.h>
@@ -46,39 +48,55 @@
static Bool ExtendedEnabled = FALSE;
+#ifdef __ia64__
+#include "compiler.h"
+#include <sys/io.h>
+#endif
+
#ifdef __alpha__
-/*
- * The Jensen lacks dense memory, thus we have to address the bus via
- * the sparse addressing scheme.
- *
- * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
- */
+# ifdef LIBC_IS_FIXED
+extern void sethae(unsigned long hae);
+# else
+# include <unistd.h>
+# define sethae(x) syscall(301,x);
+# endif
-#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
-#define SPARSE (5)
-#define isJensen (1)
-#else
-#define isJensen (!_bus_base())
-#define SPARSE (7)
-#endif
+/* define to test the Sparse addressing on a non-Jensen */
+# ifdef TEST_JENSEN_CODE
+# define isJensen (1)
+# else
+# define isJensen (axpSystem == JENSEN)
+# endif
+
+# define BUS_BASE bus_base
+
+#else
-#define BUS_BASE (isJensen ? _bus_base_sparse() : _bus_base())
-#define JENSEN_SHIFT(x) (isJensen ? ((long)x<<SPARSE) : (long)x)
-#else /* ! __alpha__ */
-#define BUS_BASE 0
-#define JENSEN_SHIFT(x) (x)
-#endif /* ! __alpha__ */
+#define BUS_BASE (0)
+
+#endif /* __alpha__ */
/***************************************************************************/
/* Video Memory Mapping section */
/***************************************************************************/
-static pointer mapVidMem(int, unsigned long, unsigned long);
+static pointer mapVidMem(int, unsigned long, unsigned long, int);
static void unmapVidMem(int, pointer, unsigned long);
-#ifdef __alpha__
-static pointer mapVidMemSparse(int, unsigned long, unsigned long);
+#if defined (__alpha__)
+static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
+extern axpDevice lnxGetAXP(void);
static void unmapVidMemSparse(int, pointer, unsigned long);
+# if defined(JENSEN_SUPPORT)
+static pointer mapVidMemJensen(int, unsigned long, unsigned long, int);
+static void unmapVidMemJensen(int, pointer, unsigned long);
+# endif
+static axpDevice axpSystem = -1;
+static Bool needSparse;
+static unsigned long hae_thresh;
+static unsigned long hae_mask;
+static unsigned long bus_base;
+static unsigned long sparse_size;
#endif
#ifdef HAS_MTRR_SUPPORT
@@ -280,17 +298,45 @@ undoWC(int screenNum, pointer regioninfo)
#endif /* HAS_MTRR_SUPPORT */
-
void
xf86OSInitVidMem(VidMemInfoPtr pVidMem)
{
pVidMem->linearSupported = TRUE;
+#ifdef __alpha__
+ if (axpSystem == -1) {
+ axpSystem = lnxGetAXP();
+ if (needSparse = (_bus_base_sparse() > 0)) {
+ hae_thresh = xf86AXPParams[axpSystem].hae_thresh;
+ hae_mask = xf86AXPParams[axpSystem].hae_mask;
+ sparse_size = xf86AXPParams[axpSystem].size;
+ }
+ bus_base = _bus_base();
+ }
+ if (isJensen) {
+# ifndef JENSEN_SUPPORT
+ FatalError("Jensen is not supported any more\n"
+ "If you are intereseted in fixing Jensen support\n"
+ "please contact xfree86@xfree86.org\n");
+# else
+ xf86Msg(X_INFO,"Machine type is Jensen\n");
+ pVidMem->mapMem = mapVidMemJensen;
+ pVidMem->unmapMem = unmapVidMemJensen;
+# endif /* JENSEN_SUPPORT */
+ } else if (needSparse) {
+ xf86Msg(X_INFO,"Machine needs sparse mapping\n");
+ pVidMem->mapMem = mapVidMemSparse;
+ pVidMem->unmapMem = unmapVidMemSparse;
+ } else {
+ xf86Msg(X_INFO,"Machine type has 8/16 bit access\n");
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+ }
+#else
pVidMem->mapMem = mapVidMem;
pVidMem->unmapMem = unmapVidMem;
-#ifdef __alpha__
- pVidMem->mapMemSparse = mapVidMemSparse;
- pVidMem->unmapMemSparse = unmapVidMemSparse;
-#endif
+#endif /* __alpha__ */
+
+
#ifdef HAS_MTRR_SUPPORT
pVidMem->setWC = setWC;
pVidMem->undoWC = undoWC;
@@ -298,38 +344,75 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
pVidMem->initialised = TRUE;
}
+
static pointer
-mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
- pointer base;
- int fd;
-
- if ((fd = open("/dev/mem", O_RDWR)) < 0)
- {
- FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
- strerror(errno));
- }
- /* This requires linux-0.99.pl10 or above */
- base = mmap((caddr_t)0, JENSEN_SHIFT(Size),
- PROT_READ|PROT_WRITE,
- MAP_SHARED, fd,
- (off_t)(JENSEN_SHIFT((off_t)Base) + BUS_BASE));
- close(fd);
- if (base == MAP_FAILED)
- {
- FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
- strerror(errno));
- }
+ pointer base;
+ int fd;
+ int mapflags = MAP_SHARED;
+ memType realBase, alignOff;
+
+ realBase = Base & ~(getpagesize() - 1);
+ alignOff = Base - realBase;
+#ifdef DEBUG
+ ErrorF("base: %lx, realBase: %lx, alignOff: %lx \n",
+ Base,realBase,alignOff);
+#endif
+
+#if defined(__ia64__)
+#ifndef MAP_WRITECOMBINED
+#define MAP_WRITECOMBINED 0x00010000
+#endif
+#ifndef MAP_NONCACHED
+#define MAP_NONCACHED 0x00020000
+#endif
+ if(flags & VIDMEM_FRAMEBUFFER)
+ mapflags |= MAP_WRITECOMBINED;
+ else
+ mapflags |= MAP_NONCACHED;
+#endif
- return base;
+#if defined(__ia64__)
+ /* this will disappear when people upgrade their kernels */
+ if ((fd = open(DEV_MEM, O_RDWR|O_SYNC)) < 0)
+#else
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0)
+#endif
+ {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+ /* This requires linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, Size + alignOff,
+ PROT_READ|PROT_WRITE,
+ mapflags, fd,
+ (off_t)(off_t)realBase + BUS_BASE);
+ close(fd);
+ if (base == MAP_FAILED) {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer"
+ " (0x%08x,0x%x) (%s)\n", Base, Size,
+ strerror(errno));
+ }
+#ifdef DEBUG
+ ErrorF("base: %lx aligned base: %lx\n",base, base + alignOff);
+#endif
+ return (char *)base + alignOff;
}
-
+
static void
unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
{
- munmap((caddr_t)JENSEN_SHIFT(Base), JENSEN_SHIFT(Size));
+ memType alignOff = (memType)Base
+ - ((memType)Base & ~(getpagesize() - 1));
+
+#ifdef DEBUG
+ ErrorF("alignment offset: %lx\n",alignOff);
+#endif
+ munmap((caddr_t)((memType)Base - alignOff), (Size + alignOff));
}
+
/***************************************************************************/
/* I/O Permissions section */
/***************************************************************************/
@@ -338,16 +421,6 @@ unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
/* FIXME: init this... */
volatile unsigned char *ioBase = MAP_FAILED;
-void
-ppc_flush_icache(char *addr)
-{
- /* cut+paste from linux glibc */
- __asm__ volatile (" dcbf 0,3");
- __asm__ volatile (" icbi 0,3");
- __asm__ volatile (" addi 3,3,32");
- __asm__ volatile (" dcbf 0,3");
- __asm__ volatile (" icbi 0,3");
-}
#endif
void
@@ -356,8 +429,8 @@ xf86EnableIO(void)
if (ExtendedEnabled)
return;
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
- if (iopl(3))
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
+ if (ioperm(0, 1024, 1) || iopl(3))
FatalError("%s: Failed to set IOPL for I/O\n",
"xf86EnableIOPorts");
#endif
@@ -372,8 +445,9 @@ xf86DisableIO(void)
if (!ExtendedEnabled)
return;
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
iopl(0);
+ ioperm(0, 1024, 0);
#endif
ExtendedEnabled = FALSE;
@@ -389,21 +463,28 @@ Bool
xf86DisableInterrupts()
{
if (!ExtendedEnabled)
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
- if (iopl(3))
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
+ if (iopl(3) || ioperm(0, 1024, 1))
return (FALSE);
#endif
-#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__)
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__) || defined(__mips__)
#else
#ifdef __GNUC__
- __asm__ __volatile__("cli");
+#if defined(__ia64__)
+ __asm__ __volatile__ (";; rsm psr.i;; srlz.d" ::: "memory");
+#else
+ __asm__ __volatile__("cli");
+#endif
#else
asm("cli");
#endif
#endif
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
- if (!ExtendedEnabled)
- iopl(0);
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
+ if (!ExtendedEnabled) {
+ iopl(0);
+ ioperm(0, 1024, 0);
+ }
+
#endif
return (TRUE);
}
@@ -412,215 +493,447 @@ void
xf86EnableInterrupts()
{
if (!ExtendedEnabled)
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
- if (iopl(3))
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
+ if (iopl(3) || ioperm(0, 1024, 1))
return;
#endif
-#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__)
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__) || defined(__mips__)
#else
#ifdef __GNUC__
- __asm__ __volatile__("sti");
+#if defined(__ia64__)
+ __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory");
+#else
+ __asm__ __volatile__("sti");
+#endif
#else
asm("sti");
#endif
#endif
-#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
- if (!ExtendedEnabled)
- iopl(0);
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__) && !defined(__mips__)
+ if (!ExtendedEnabled) {
+ iopl(0);
+ ioperm(0, 1024, 0);
+ }
#endif
return;
}
-#if defined(__alpha__)
+#if defined (__alpha__)
+
+#define vuip volatile unsigned int *
-static int xf86SparseShift = 5; /* default to all but JENSEN */
+static unsigned long msb_set = 0;
+static pointer lnxSBase = 0;
+static pointer lnxBase = 0;
+
+extern int readDense8(pointer Base, register unsigned long Offset);
+extern int readDense16(pointer Base, register unsigned long Offset);
+extern int readDense32(pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense8(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense16(int Value, pointer Base, register unsigned long Offset);
+extern void
+writeDense32(int Value, pointer Base, register unsigned long Offset);
+
+static int readSparse8(pointer Base, register unsigned long Offset);
+static int readSparse16(pointer Base, register unsigned long Offset);
+static int readSparse32(pointer Base, register unsigned long Offset);
+static void
+writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparse32(int Value, pointer Base, register unsigned long Offset);
static pointer
-mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size)
+mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
- pointer base;
- int fd;
-
- if (!_bus_base()) xf86SparseShift = 7; /* Uh, oh, JENSEN... */
-
- Size <<= xf86SparseShift;
- Base = Base << xf86SparseShift;
-
- if ((fd = open("/dev/mem", O_RDWR)) < 0)
- {
- FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
- strerror(errno));
- }
- /* This requirers linux-0.99.pl10 or above */
- base = mmap((caddr_t)0, Size,
+ int fd;
+ static Bool was_here = FALSE;
+
+ if (!was_here) {
+ was_here = TRUE;
+
+ xf86WriteMmio8 = writeSparse8;
+ xf86WriteMmio16 = writeSparse16;
+ xf86WriteMmio32 = writeSparse32;
+ xf86WriteMmioNB8 = writeSparseNB8;
+ xf86WriteMmioNB16 = writeSparseNB16;
+ xf86WriteMmioNB32 = writeSparseNB32;
+ xf86ReadMmio8 = readSparse8;
+ xf86ReadMmio16 = readSparse16;
+ xf86ReadMmio32 = readSparse32;
+
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0) {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+ /* This requirers linux-0.99.pl10 or above */
+ lnxBase = mmap((caddr_t)0, 0x100000000,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd,
- (off_t)Base + _bus_base_sparse());
- close(fd);
- if (base == MAP_FAILED)
- {
- FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
- strerror(errno));
- }
- return base;
+ (off_t) bus_base);
+ lnxSBase = mmap((caddr_t)0, 0x400000000,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t) _bus_base_sparse());
+
+ close(fd);
+
+ if (lnxSBase == MAP_FAILED || lnxBase == MAP_FAILED) {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
+ strerror(errno));
+ }
+ }
+ return (pointer)((unsigned long)lnxBase + Base);
}
static void
unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
{
- Size <<= xf86SparseShift;
-
- munmap((caddr_t)Base, Size);
}
-#define vuip volatile unsigned int *
-
-extern void sethae(unsigned long hae);
-
-int
-xf86ReadSparse8(pointer Base, unsigned long Offset)
+static int
+readSparse8(pointer Base, register unsigned long Offset)
{
- unsigned long result, shift;
- unsigned long msb = 0;
+ register unsigned long result, shift;
+ register unsigned long msb;
- shift = (Offset & 0x3) * 8;
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ shift = (Offset & 0x3) << 3;
+ if (Offset >= (hae_thresh)) {
+ msb = Offset & hae_mask;
Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- result = *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift));
- if (msb)
- sethae(0);
+
+ mem_barrier();
+ result = *(vuip) ((unsigned long)lnxSBase + (Offset << 5));
result >>= shift;
return 0xffUL & result;
}
-int
-xf86ReadSparse16(pointer Base, unsigned long Offset)
+static int
+readSparse16(pointer Base, register unsigned long Offset)
{
- unsigned long result, shift;
- unsigned long msb = 0;
+ register unsigned long result, shift;
+ register unsigned long msb;
- shift = (Offset & 0x2) * 8;
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ shift = (Offset & 0x2) << 3;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2)));
- if (msb)
- sethae(0);
+
+ mem_barrier();
+ result = *(vuip)((unsigned long)lnxSBase+(Offset<<5)+(1<<(5-2)));
result >>= shift;
return 0xffffUL & result;
}
-int
-xf86ReadSparse32(pointer Base, unsigned long Offset)
+static int
+readSparse32(pointer Base, register unsigned long Offset)
{
- unsigned long result;
- unsigned long msb = 0;
+ mem_barrier();
+ return *(vuip)((unsigned long)Base+(Offset));
+}
- if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000UL;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+static void
+writeSparse8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned long msb;
+ register unsigned int b = Value & 0xffU;
+
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2)));
- if (msb)
- sethae(0);
- return result;
+
+ write_mem_barrier();
+ *(vuip) ((unsigned long)lnxSBase + (Offset << 5)) = b * 0x01010101;
}
-void
-xf86WriteSparse8(int Value, pointer Base, unsigned long Offset)
+static void
+writeSparse16(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long msb = 0;
- unsigned int b = Value & 0xffU;
-
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+ register unsigned long msb;
+ register unsigned int w = Value & 0xffffU;
+
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift)) = b * 0x01010101;
- if (msb)
- sethae(0);
-#if defined(__alpha__)
- /* CAUTION: if you make changes inside this block you need to */
- /* make them to the other two identical blocks in this file */
- mem_barrier();
-#endif
+ write_mem_barrier();
+ *(vuip)((unsigned long)lnxSBase+(Offset<<5)+(1<<(5-2))) =
+ w * 0x00010001;
+}
+static void
+writeSparse32(int Value, pointer Base, register unsigned long Offset)
+{
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base + (Offset)) = Value;
+ return;
}
-void
-xf86WriteSparse16(int Value, pointer Base, unsigned long Offset)
+static void
+writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
{
- unsigned long msb = 0;
- unsigned int w = Value & 0xffffU;
+ register unsigned long msb;
+ register unsigned int b = Value & 0xffU;
+
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
+ }
+ *(vuip) ((unsigned long)lnxSBase + (Offset << 5)) = b * 0x01010101;
+}
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
+static void
+writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned long msb;
+ register unsigned int w = Value & 0xffffU;
+
+ Offset += (unsigned long)Base - (unsigned long)lnxBase;
+ if (Offset >= hae_thresh) {
+ msb = Offset & hae_mask;
+ Offset -= msb;
+ if (msb_set != msb) {
+ sethae(msb);
+ msb_set = msb;
+ }
}
- *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2))) =
+ *(vuip)((unsigned long)lnxSBase+(Offset<<5)+(1<<(5-2))) =
w * 0x00010001;
- if (msb)
- sethae(0);
+}
-#if defined(__alpha__)
- /* CAUTION: if you make changes inside this block you need to */
- /* make them to the other two identical blocks in this file */
- mem_barrier();
+static void
+writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
+{
+ *(vuip)((unsigned long)Base + (Offset)) = Value;
+ return;
+}
+
+void (*xf86WriteMmio8)(int Value, pointer Base, unsigned long Offset)
+ = writeDense8;
+void (*xf86WriteMmio16)(int Value, pointer Base, unsigned long Offset)
+ = writeDense16;
+void (*xf86WriteMmio32)(int Value, pointer Base, unsigned long Offset)
+ = writeDense32;
+void (*xf86WriteMmioNB8)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB8;
+void (*xf86WriteMmioNB16)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB16;
+void (*xf86WriteMmioNB32)(int Value, pointer Base, unsigned long Offset)
+ = writeDenseNB32;
+int (*xf86ReadMmio8)(pointer Base, unsigned long Offset)
+ = readDense8;
+int (*xf86ReadMmio16)(pointer Base, unsigned long Offset)
+ = readDense16;
+int (*xf86ReadMmio32)(pointer Base, unsigned long Offset)
+ = readDense32;
+
+#ifdef JENSEN_SUPPORT
+
+static int
+readSparseJensen8(pointer Base, register unsigned long Offset);
+static int
+readSparseJensen16(pointer Base, register unsigned long Offset);
+static int
+readSparseJensen32(pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensen32(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB8(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB16(int Value, pointer Base, register unsigned long Offset);
+static void
+writeSparseJensenNB32(int Value, pointer Base, register unsigned long Offset);
+
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme.
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+#ifdef TEST_JENSEN_CODE
+#define SPARSE (5)
+#else
+#define SPARSE (7)
#endif
+#define JENSEN_SHIFT(x) ((long)x<<SPARSE)
+
+static pointer
+mapVidMemJensen(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
+{
+ pointer base;
+ int fd;
+
+ xf86WriteMmio8 = writeSparseJensen8;
+ xf86WriteMmio16 = writeSparseJensen16;
+ xf86WriteMmio32 = writeSparseJensen32;
+ xf86WriteMmioNB8 = writeSparseJensenNB8;
+ xf86WriteMmioNB16 = writeSparseJensenNB16;
+ xf86WriteMmioNB32 = writeSparseJensenNB32;
+ xf86ReadMmio8 = readSparseJensen8;
+ xf86ReadMmio16 = readSparseJensen16;
+ xf86ReadMmio32 = readSparseJensen32;
+
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0) {
+ FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
+ strerror(errno));
+ }
+ /* This requires linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, JENSEN_SHIFT(Size),
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t)(JENSEN_SHIFT((off_t)Base) + _bus_base_sparse()));
+ close(fd);
+ if (base == MAP_FAILED) {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer"
+ " (0x%08x,0x%x) (%s)\n", Base, Size,
+ strerror(errno));
+ }
+ return base;
}
-void
-xf86WriteSparse32(int Value, pointer Base, unsigned long Offset)
+static void
+unmapVidMemJensen(int ScreenNum, pointer Base, unsigned long Size)
{
- unsigned long msb = 0;
+ munmap((caddr_t)Base, JENSEN_SHIFT(Size));
+}
- if (xf86SparseShift != 7) { /* not JENSEN */
- if (Offset >= (1UL << 24)) {
- msb = Offset & 0xf8000000;
- Offset -= msb;
- if (msb) {
- sethae(msb);
- }
- }
- }
- *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2))) = Value;
- if (msb)
- sethae(0);
+static int
+readSparseJensen8(pointer Base, register unsigned long Offset)
+{
+ register unsigned long result, shift;
-#if defined(__alpha__)
- /* CAUTION: if you make changes inside this block you need to */
- /* make them to the other two identical blocks in this file */
mem_barrier();
-#endif
+ shift = (Offset & 0x3) << 3;
+
+ result = *(vuip) ((unsigned long)Base + (Offset << SPARSE));
+
+ result >>= shift;
+ return 0xffUL & result;
+}
+
+static int
+readSparseJensen16(pointer Base, register unsigned long Offset)
+{
+ register unsigned long result, shift;
+
+ mem_barrier();
+ shift = (Offset & 0x2) << 3;
+
+ result = *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2)));
+
+ result >>= shift;
+ return 0xffffUL & result;
}
+
+static int
+readSparseJensen32(pointer Base, register unsigned long Offset)
+{
+ register unsigned long result;
+
+ mem_barrier();
+ result = *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2)));
+
+ return result;
+}
+
+static void
+writeSparseJensen8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int b = Value & 0xffU;
+
+ write_mem_barrier();
+ *(vuip) ((unsigned long)Base + (Offset << SPARSE)) = b * 0x01010101;
+}
+
+static void
+writeSparseJensen16(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int w = Value & 0xffffU;
+
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2))) =
+ w * 0x00010001;
+}
+
+static void
+writeSparseJensen32(int Value, pointer Base, register unsigned long Offset)
+{
+ write_mem_barrier();
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2))) = Value;
+}
+
+static void
+writeSparseJensenNB8(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int b = Value & 0xffU;
+
+ *(vuip) ((unsigned long)Base + (Offset << SPARSE)) = b * 0x01010101;
+}
+
+static void
+writeSparseJensenNB16(int Value, pointer Base, register unsigned long Offset)
+{
+ register unsigned int w = Value & 0xffffU;
+
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(1<<(SPARSE-2))) =
+ w * 0x00010001;
+}
+
+static void
+writeSparseJensenNB32(int Value, pointer Base, register unsigned long Offset)
+{
+ *(vuip)((unsigned long)Base+(Offset<<SPARSE)+(3<<(SPARSE-2))) = Value;
+}
+#endif /* JENSEN_SUPPORT */
+
#endif /* __alpha__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index f1abaabff..3def97f74 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -126,10 +126,11 @@ typedef struct drm_control {
} drm_control_t;
typedef enum drm_map_type {
- _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
- _DRM_REGISTERS = 1, /* no caching, no core dump */
- _DRM_SHM = 2, /* shared, cached */
- _DRM_AGP = 3 /* AGP/GART */
+ _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /* no caching, no core dump */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3, /* AGP/GART */
+ _DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
} drm_map_type_t;
typedef enum drm_map_flags {
@@ -238,7 +239,8 @@ typedef struct drm_buf_desc {
int high_mark; /* High water mark */
enum {
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
- _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
+ _DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
+ _DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
} flags;
unsigned long agp_start; /* Start address of where the agp buffers
* are in the agp aperture */
@@ -344,6 +346,11 @@ typedef struct drm_agp_info {
unsigned short id_device;
} drm_agp_info_t;
+typedef struct drm_scatter_gather {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for mapping / unmapping */
+} drm_scatter_gather_t;
+
#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)
@@ -399,6 +406,9 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
+#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
+
/* MGA specific ioctls */
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index 180e15844..7a07c7e0f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -93,7 +93,8 @@ typedef enum {
DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */
DRM_REGISTERS = 1, /* no caching, no core dump */
DRM_SHM = 2, /* shared, cached */
- DRM_AGP = 3 /* AGP/GART */
+ DRM_AGP = 3, /* AGP/GART */
+ DRM_SCATTER_GATHER = 4 /* PCI scatter/gather */
} drmMapType;
typedef enum {
@@ -125,7 +126,8 @@ typedef enum { /* These values *MUST* match drm.h */
typedef enum {
DRM_PAGE_ALIGN = 0x01,
- DRM_AGP_BUFFER = 0x02
+ DRM_AGP_BUFFER = 0x02,
+ DRM_SG_BUFFER = 0x04
} drmBufDescFlags;
typedef enum {
@@ -313,6 +315,25 @@ do { register unsigned int __old __asm("o0"); \
} while (0)
#endif
+
+#elif defined(__powerpc__)
+
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ __asm__ __volatile__( \
+ "sync;" \
+ "0: lwarx %0,0,%1;" \
+ " xor. %0,%3,%0;" \
+ " bne 1f;" \
+ " stwcx. %2,0,%1;" \
+ " bne- 0b;" \
+ "1: " \
+ "sync;" \
+ : "=&r"(__ret) \
+ : "r"(lock), "r"(new), "r"(old) \
+ : "cr0", "memory"); \
+ } while (0)
+
#endif /* architecture */
#endif /* __GNUC__ >= 2 */
@@ -498,6 +519,11 @@ extern unsigned long drmAgpMemoryAvail(int fd);
extern unsigned int drmAgpVendorId(int fd);
extern unsigned int drmAgpDeviceId(int fd);
+/* PCI scatter/gather support: X server (root) only */
+extern int drmScatterGatherAlloc(int fd, unsigned long size,
+ unsigned long *handle);
+extern int drmScatterGatherFree(int fd, unsigned long handle);
+
/* Support routines */
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
index bd4773092..40dedda9e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
@@ -15,7 +15,7 @@ typedef struct {
} drmMGAWarpIndex;
typedef struct {
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int chipset;
int sgram;
@@ -32,12 +32,12 @@ typedef struct {
unsigned int texture_offset[2];
unsigned int texture_size[2];
- unsigned int fb_offset;
- unsigned int mmio_offset;
- unsigned int status_offset;
- unsigned int warp_offset;
- unsigned int primary_offset;
- unsigned int buffers_offset;
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long status_offset;
+ unsigned long warp_offset;
+ unsigned long primary_offset;
+ unsigned long buffers_offset;
} drmMGAInit;
extern int drmMGAInitDMA( int fd, drmMGAInit *info );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
index 5d332081b..3bd2af4b9 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
@@ -46,7 +46,7 @@
#define DRM_R128_DEPTH 0x4
typedef struct {
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int is_pci;
int cce_mode;
int cce_secure; /* FIXME: Deprecated, we should remove this */
@@ -60,12 +60,12 @@ typedef struct {
unsigned int depth_offset, depth_pitch;
unsigned int span_offset;
- 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;
+ 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;
} drmR128Init;
extern int drmR128InitCCE( int fd, drmR128Init *info );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
index e3bf83fdd..f94a9790c 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
@@ -43,7 +43,7 @@
#define DRM_RADEON_DEPTH 0x4
typedef struct {
- int sarea_priv_offset;
+ unsigned long sarea_priv_offset;
int is_pci;
int cp_mode;
int agp_size;
@@ -56,12 +56,12 @@ typedef struct {
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
- 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;
+ 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;
} drmRadeonInit;
typedef struct {