diff options
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 { |