diff options
author | kem <kem> | 2001-03-14 22:22:46 +0000 |
---|---|---|
committer | kem <kem> | 2001-03-14 22:22:46 +0000 |
commit | 2efa15fa1220f10727c2246ee8e23c1cb896898e (patch) | |
tree | b605ce8f892b0769a6e18889fd479b57a1cbd22c | |
parent | b4164fb80338d44569f432af82c91738bb3584e2 (diff) |
Merged sarea-1-0-0sarea-1-0-0-20010314-merge
63 files changed, 968 insertions, 353 deletions
diff --git a/xc/lib/GL/dri/xf86dristr.h b/xc/lib/GL/dri/xf86dristr.h index d2e42a3e3..e380de8a9 100644 --- a/xc/lib/GL/dri/xf86dristr.h +++ b/xc/lib/GL/dri/xf86dristr.h @@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XF86DRINAME "XFree86-DRI" -#define XF86DRI_MAJOR_VERSION 3 /* current version numbers */ +#define XF86DRI_MAJOR_VERSION 4 /* current version numbers */ #define XF86DRI_MINOR_VERSION 0 #define XF86DRI_PATCH_VERSION 0 diff --git a/xc/lib/GL/mesa/dri/dri_mesa.c b/xc/lib/GL/mesa/dri/dri_mesa.c index 57dc6a15f..dd9fdddc8 100644 --- a/xc/lib/GL/mesa/dri/dri_mesa.c +++ b/xc/lib/GL/mesa/dri/dri_mesa.c @@ -663,19 +663,6 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, return NULL; } - if (!psp->dummyContextPriv.driScreenPriv) { - if (!XF86DRICreateContext(dpy, vis->screen, vis->visual, - &psp->dummyContextPriv.contextID, - &psp->dummyContextPriv.hHWContext)) { - return NULL; - } - psp->dummyContextPriv.driScreenPriv = psp; - psp->dummyContextPriv.mesaContext = NULL; - psp->dummyContextPriv.driDrawablePriv = NULL; - psp->dummyContextPriv.driverPrivate = NULL; - /* No other fields should be used! */ - } - /* Create the hash table */ if (!psp->drawHash) psp->drawHash = drmHashCreate(); @@ -695,6 +682,29 @@ static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, return NULL; } + /* This is moved because the Xserver creates a global dummy context + * the first time XF86DRICreateContext is called. + */ + + if (!psp->dummyContextPriv.driScreenPriv) { +#if 0 + /* We no longer use this cause we have the shared dummyContext + * in the SAREA. + */ + if (!XF86DRICreateContext(dpy, vis->screen, vis->visual, + &psp->dummyContextPriv.contextID, + &psp->dummyContextPriv.hHWContext)) { + return NULL; + } +#endif + psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; + psp->dummyContextPriv.driScreenPriv = psp; + psp->dummyContextPriv.mesaContext = NULL; + psp->dummyContextPriv.driDrawablePriv = NULL; + psp->dummyContextPriv.driverPrivate = NULL; + /* No other fields should be used! */ + } + for (i = 0; i < psp->numVisuals; i++) { if (psp->visuals[i].vid == vis->visualid) { GLvisual *mesaVis = psp->visuals[i].mesaVisual; @@ -748,9 +758,9 @@ static void driMesaDestroyContext(Display *dpy, int scrn, void *contextPrivate) } } __driMesaGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); (*pcp->driScreenPriv->MesaAPI.DestroyContext)(pcp); gl_destroy_context(pcp->mesaContext); + (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); Xfree(pcp); } } diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c index a442ee913..81fbc4c97 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c @@ -59,9 +59,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 3 || minor < 0) { char msg[1000]; - sprintf(msg, "gamma DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "gamma DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -70,8 +70,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DDX driver version is compatible */ if (sPriv->ddxMajor != 1 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0) { + sPriv->ddxMinor < 0) { char msg[1000]; sprintf(msg, "gamma DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); __driMesaMessage(msg); @@ -80,8 +79,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DRM driver version is compatible */ if (sPriv->drmMajor != 1 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0) { + sPriv->drmMinor < 0) { char msg[1000]; sprintf(msg, "gamm DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_init.h b/xc/lib/GL/mesa/src/drv/i810/i810_init.h index cdcdfd1b6..21c4f78d5 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_init.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810_init.h @@ -79,6 +79,7 @@ typedef struct { __DRIscreenPrivate *driScrnPriv; drmBufMapPtr bufs; int use_copy_buf; + unsigned int sarea_priv_offset; } i810ScreenPrivate; diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c index 43d1d4973..2208de78a 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c @@ -135,9 +135,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { char msg[1000]; - sprintf(msg, "i810 DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "i810 DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -146,8 +146,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DDX driver version is compatible */ if (sPriv->ddxMajor != 1 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0) { + sPriv->ddxMinor < 0) { char msg[1000]; sprintf(msg, "i810 DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); __driMesaMessage(msg); @@ -156,8 +155,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DRM driver version is compatible */ if (sPriv->drmMajor != 1 || - sPriv->drmMinor != 1 || - sPriv->drmPatch < 0) { + sPriv->drmMinor < 1) { char msg[1000]; sprintf(msg, "i810 DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); @@ -244,6 +242,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) i810Screen->tex.handle = gDRIPriv->textures; i810Screen->tex.size = gDRIPriv->textureSize; + i810Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; if (drmMap(sPriv->fd, i810Screen->tex.handle, @@ -316,7 +315,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; drm_i810_sarea_t *saPriv=(drm_i810_sarea_t *)(((char*)sPriv->pSAREA)+ - sizeof(XF86DRISAREARec)); + i810Screen->sarea_priv_offset); imesa = (i810ContextPtr)Xcalloc(sizeof(i810Context), 1); if (!imesa) { diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index 092cff055..d10969df4 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -107,9 +107,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { char msg[1000]; - sprintf(msg, "MGA DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "MGA DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -118,8 +118,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DDX driver version is compatible */ if (sPriv->ddxMajor != 1 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0) { + sPriv->ddxMinor < 0) { char msg[1000]; sprintf(msg, "MGA DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); __driMesaMessage(msg); @@ -128,8 +127,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DRM driver version is compatible */ if (sPriv->drmMajor != 3 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0) { + sPriv->drmMinor < 0) { char msg[1000]; sprintf(msg, "MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); @@ -250,6 +248,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) __driMesaMessage("Couldn't map dma buffers"); return GL_FALSE; } + mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset; mgaDDFastPathInit(); mgaDDEltPathInit(); @@ -313,7 +312,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; MGASAREAPrivPtr saPriv = (MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+ - sizeof(XF86DRISAREARec)); + mgaScreen->sarea_priv_offset); if (MGA_DEBUG&DEBUG_VERBOSE_DRI) fprintf(stderr, "XMesaCreateContext\n"); diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h index d04b27dbf..5dcede8ec 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h @@ -80,6 +80,7 @@ typedef struct mga_screen_private_s { drmRegion status; drmRegion primary; drmRegion buffers; + unsigned int sarea_priv_offset; } mgaScreenPrivate; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index 03b871538..7c6afa8c0 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -88,7 +88,7 @@ GLboolean r128CreateContext( Display *dpy, GLvisual *glVisual, r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private); rmesa->sarea = (R128SAREAPrivPtr)((char *)sPriv->pSAREA + - sizeof(XF86DRISAREARec)); + r128scrn->sarea_priv_offset); rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); if ( !rmesa->tmp_matrix ) { diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c index 029ccd4ca..d634ec0d8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -68,9 +68,9 @@ r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) { int major, minor, patch; if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { - if ( major != 3 || minor != 0 || patch < 0 ) { + if ( major != 4 || minor < 0 ) { char msg[128]; - sprintf( msg, "r128 DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch ); + sprintf( msg, "r128 DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch ); __driMesaMessage( msg ); return GL_FALSE; } @@ -79,8 +79,7 @@ r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 4 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0 ) { + sPriv->ddxMinor < 0 ) { char msg[128]; sprintf( msg, "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); __driMesaMessage( msg ); @@ -89,8 +88,7 @@ r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) /* Check that the DRM driver version is compatible */ if ( sPriv->drmMajor != 2 || - sPriv->drmMinor != 1 || - sPriv->drmPatch < 0 ) { + sPriv->drmMinor < 1 ) { char msg[128]; sprintf( msg, "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); __driMesaMessage( msg ); @@ -105,6 +103,7 @@ r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) * not we are using a PCI card. */ r128Screen->IsPCI = r128DRIPriv->IsPCI; + r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset; r128Screen->mmio.handle = r128DRIPriv->registerHandle; r128Screen->mmio.size = r128DRIPriv->registerSize; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h index b3e6259e8..8f88e5cb8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -74,6 +74,7 @@ typedef struct { drmBufMapPtr buffers; __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; } r128ScreenRec, *r128ScreenPtr; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c index 41991d0bf..535337cb3 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -61,9 +61,9 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { char msg[1000]; - sprintf(msg, "R128 DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "R128 DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -72,8 +72,7 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if (sPriv->ddxMajor != 4 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0) { + sPriv->ddxMinor < 0) { char msg[1000]; sprintf(msg, "R128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); __driMesaMessage(msg); @@ -82,10 +81,9 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DRM driver version is compatible */ if (sPriv->drmMajor != 2 || - sPriv->drmMinor != 1 || - sPriv->drmPatch < 4) { + sPriv->drmMinor < 1) { char msg[1000]; - sprintf(msg, "R128 DRI driver expected DRM driver version 2.1.x (x>=4) but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + sprintf(msg, "R128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); return GL_FALSE; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c index 366f094ca..172e0f62a 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -61,6 +61,25 @@ int RADEON_DEBUG = (0 ); #endif +#ifdef PER_CONTEXT_SAREA +char *radeonGetPerContextSAREA(int fd, + drmContext hHWContext, + drmSize size) +{ + drmHandle handle; + drmAddress address; + + if(drmGetContextPrivateMapping(fd, hHWContext, &handle) < 0) { + return NULL; + } + if(drmMap(fd, handle, size, &address) < 0) { + return NULL; + } + + return address; +} +#endif + /* Create the device specific context. */ GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, @@ -89,7 +108,18 @@ GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, radeonScreen = rmesa->radeonScreen = (radeonScreenPtr)(sPriv->private); rmesa->sarea = (RADEONSAREAPrivPtr)((char *)sPriv->pSAREA + - sizeof(XF86DRISAREARec)); + radeonScreen->sarea_priv_offset); + +#ifdef PER_CONTEXT_SAREA + rmesa->private_sarea = radeonGetPerContextSAREA(rmesa->driFd, + rmesa->hHWContext, + radeonScreen->private_sarea_size); + if(!rmesa->private_sarea) { + fprintf(stderr, "Can't map private SAREA\n"); + FREE( rmesa ); + return GL_FALSE; + } +#endif rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); if ( !rmesa->tmp_matrix ) { @@ -176,10 +206,19 @@ GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, void radeonDestroyContext( radeonContextPtr rmesa ) { if ( rmesa ) { + radeonScreenPtr radeonScreen = rmesa->radeonScreen; radeonTexObjPtr t, next_t; int i; - for ( i = 0 ; i < rmesa->radeonScreen->numTexHeaps ; i++ ) { +#ifdef PER_CONTEXT_SAREA + if ( rmesa->private_sarea ) { + drmUnmap( (drmAddress)rmesa->private_sarea, + radeonScreen->private_sarea_size ); + rmesa->private_sarea = NULL; + } +#endif + + for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) { foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { radeonDestroyTexObj( rmesa, t ); } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h index 1b9c0ce9c..668b451a9 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -221,6 +221,10 @@ struct radeon_context { radeonScreenPtr radeonScreen; /* Screen private DRI data */ RADEONSAREAPrivPtr sarea; /* Private SAREA data */ +#ifdef PER_CONTEXT_SAREA + char *private_sarea; /* Per-context private SAREA */ +#endif + /* Performance counters */ GLuint boxes; /* Draw performance boxes */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c index dea4bb1ef..b3da87bd3 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -65,9 +65,9 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) { int major, minor, patch; if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { - if ( major != 3 || minor != 0 || patch < 0 ) { + if ( major != 4 || minor < 0 ) { char msg[128]; - sprintf( msg, "Radeon DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch ); + sprintf( msg, "Radeon DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch ); __driMesaMessage( msg ); return GL_FALSE; } @@ -76,8 +76,7 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 4 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0 ) { + sPriv->ddxMinor < 0 ) { char msg[128]; sprintf( msg, "Radeon DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); __driMesaMessage( msg ); @@ -86,8 +85,7 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) /* Check that the DRM driver version is compatible */ if ( sPriv->drmMajor != 1 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0 ) { + sPriv->drmMinor < 0 ) { char msg[128]; sprintf( msg, "Radeon DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); __driMesaMessage( msg ); @@ -192,6 +190,11 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) } radeonScreen->driScreen = sPriv; + radeonScreen->sarea_priv_offset = radeonDRIPriv->sarea_priv_offset; + +#ifdef PER_CONTEXT_SAREA + radeonScreen->perctx_sarea_size = radeonDRIPriv->perctx_sarea_size; +#endif radeonDDSetupInit(); radeonDDTriangleFuncsInit(); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h index 4aeb5d73f..81265eaaf 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -68,6 +68,10 @@ typedef struct { int texSize[RADEON_NR_TEX_HEAPS]; int logTexGranularity[RADEON_NR_TEX_HEAPS]; +#ifdef PER_CONTEXT_SAREA + drmSize private_sarea_size; +#endif + radeonRegionRec mmio; radeonRegionRec status; radeonRegionRec agpTextures; @@ -77,7 +81,7 @@ typedef struct { __volatile__ CARD32 *scratch; __DRIscreenPrivate *driScreen; - + unsigned int sarea_priv_offset; } radeonScreenRec, *radeonScreenPtr; extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c index db6d1595e..45bb64fd5 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c @@ -62,9 +62,9 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) { int major, minor, patch; if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { - if ( major != 3 || minor != 0 || patch < 0 ) { + if ( major != 4 || minor < 0 ) { char msg[128]; - sprintf( msg, "RADEON DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch ); + sprintf( msg, "RADEON DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch ); __driMesaMessage( msg ); return GL_FALSE; } @@ -73,8 +73,7 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 4 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0 ) { + sPriv->ddxMinor < 0 ) { char msg[128]; sprintf( msg, "RADEON DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); __driMesaMessage( msg ); @@ -83,8 +82,7 @@ GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DRM driver version is compatible */ if ( sPriv->drmMajor != 1 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0 ) { + sPriv->drmMinor < 0 ) { char msg[128]; sprintf( msg, "RADEON DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); __driMesaMessage( msg ); diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c index 0c6e399c1..293c42fd7 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c @@ -131,7 +131,7 @@ GLboolean tdfxCreateContext( Display *dpy, GLvisual *mesaVis, __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private; TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) ((char *) sPriv->pSAREA + - sizeof(XF86DRISAREARec)); + fxScreen->sarea_priv_offset); fxMesa = (tdfxContextPtr) Xmalloc( sizeof(tdfxContextRec) ); diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c index f63541be9..e7877d7d0 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_lock.c @@ -49,7 +49,7 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + - sizeof(XF86DRISAREARec)); + fxMesa->fxScreen->sarea_priv_offset); int stamp = dPriv->lastStamp; int one_rect = (fxMesa->numClipRects <= 1); diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c index 801cf42e0..ce3907604 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c @@ -77,7 +77,7 @@ GLboolean tdfxCreateScreen( __DRIscreenPrivate *sPriv ) fxScreen->depthOffset = fxDRIPriv->depthOffset; fxScreen->textureOffset = fxDRIPriv->textureOffset; fxScreen->textureSize = fxDRIPriv->textureSize; - + fxScreen->sarea_priv_offset = fxDRIPriv->sarea_priv_offset; if ( drmMap( sPriv->fd, fxScreen->regs.handle, fxScreen->regs.size, &fxScreen->regs.map ) ) { diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h index 330c394a6..ca654eda3 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.h @@ -67,6 +67,7 @@ typedef struct { int textureSize; __DRIscreenPrivate *driScrnPriv; + unsigned int sarea_priv_offset; } tdfxScreenPrivate; diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c index bf44acda6..00935e2de 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c @@ -64,11 +64,10 @@ XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check the DRI version */ if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { - if ( major != 3 || - minor != 0 || - patch < 0 ) { + if ( major != 4 || + minor < 0 ) { sprintf( msg, - "3dfx DRI driver expected DRI version 3.0.x " + "3dfx DRI driver expected DRI version 4.0.x " "but got version %d.%d.%d", major, minor, patch ); __driMesaMessage( msg ); @@ -78,8 +77,7 @@ XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 1 || - sPriv->ddxMinor != 0 || - sPriv->ddxPatch < 0 ) { + sPriv->ddxMinor < 0 ) { sprintf( msg, "3dfx DRI driver expected DDX driver version 1.0.x " "but got version %d.%d.%d", @@ -90,8 +88,7 @@ XMesaInitDriver( __DRIscreenPrivate *sPriv ) /* Check that the DRM driver version is compatible */ if ( sPriv->drmMajor != 1 || - sPriv->drmMinor != 0 || - sPriv->drmPatch < 0 ) { + sPriv->drmMinor < 0 ) { sprintf( msg, "3dfx DRI driver expected DRM driver version 1.0.x " "but got version %d.%d.%d", diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c index 0f62df601..7ad699bc7 100644 --- a/xc/programs/Xserver/GL/dri/dri.c +++ b/xc/programs/Xserver/GL/dri/dri.c @@ -81,6 +81,7 @@ static RESTYPE DRIFullScreenResType; static RESTYPE DRIDrawablePrivResType; static RESTYPE DRIContextPrivResType; +static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv); /* Wrapper just like xf86DrvMsg, but without the verbosity level checking. @@ -145,6 +146,9 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) pDRIPriv->nrWindows = 0; pDRIPriv->fullscreen = NULL; + pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx; + pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv; + if (drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString) < 0) { pDRIPriv->directRenderingSupport = FALSE; pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; @@ -405,6 +409,10 @@ DRICloseScreen(ScreenPtr pScreen) } } + if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) { + DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv); + } + if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) { DRIDrvMsg(pScreen->myNum, X_ERROR, "failed to destroy server context\n"); @@ -647,10 +655,72 @@ DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv) return TRUE; } +static Bool +DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; + __GLXvisualConfig *pGLXVis = pGLXScreen->pGlxVisual; + void **pVisualConfigPriv = pGLXScreen->pVisualPriv; + DRIContextPrivPtr pDRIContextPriv; + void *contextStore; + VisualPtr visual; + int visNum; + + visual = pScreen->visuals; + + /* Find the X visual that corresponds the the first GLX visual */ + for (visNum = 0; + visNum < pScreen->numVisuals; + visNum++, visual++) { + if (pGLXVis->vid == visual->vid) + break; + } + if (visNum == pScreen->numVisuals) return FALSE; + + if (!(pDRIContextPriv = + DRICreateContextPriv(pScreen, + &pDRIPriv->pSAREA->dummy_context, 0))) { + return FALSE; + } + + contextStore = DRIGetContextStore(pDRIContextPriv); + if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) { + if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual, + pDRIPriv->pSAREA->dummy_context, + *pVisualConfigPriv, + (DRIContextType)(long)contextStore)) { + DRIDestroyContextPriv(pDRIContextPriv); + return FALSE; + } + } + + pDRIPriv->dummyCtxPriv = pDRIContextPriv; + return TRUE; +} + +static void +DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv; + void *contextStore; + + if (!pDRIContextPriv) return; + if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) { + contextStore = DRIGetContextStore(pDRIContextPriv); + pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen, + pDRIContextPriv->hwContext, + (DRIContextType)(long)contextStore); + } + + DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv); + pDRIPriv->dummyCtxPriv = NULL; +} + Bool DRICreateContext(ScreenPtr pScreen, VisualPtr visual, - XID context, drmContextPtr pHWContext -) + XID context, drmContextPtr pHWContext) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; @@ -660,6 +730,14 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, void *contextStore; int visNum; + if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) { + if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) { + DRIDrvMsg(pScreen->myNum, X_INFO, + "[drm] Could not create dummy context\n"); + return FALSE; + } + } + /* Find the GLX visual associated with the one requested */ for (visNum = 0; visNum < pGLXScreen->numVisuals; @@ -675,7 +753,7 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, return FALSE; } - contextStore=DRIGetContextStore(pDRIContextPriv); + contextStore = DRIGetContextStore(pDRIContextPriv); if (pDRIPriv->pDriverInfo->CreateContext) { if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual, *pHWContext, *pVisualConfigPriv, @@ -709,9 +787,10 @@ DRIContextPrivDelete(pointer pResource, XID id) pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen); if (pDRIPriv->pDriverInfo->DestroyContext) { - contextStore=DRIGetContextStore(pDRIContextPriv); - (pDRIPriv->pDriverInfo->DestroyContext)(pDRIContextPriv->pScreen, - pDRIContextPriv->hwContext, (DRIContextType)(long)contextStore); + contextStore = DRIGetContextStore(pDRIContextPriv); + pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen, + pDRIContextPriv->hwContext, + (DRIContextType)(long)contextStore); } return DRIDestroyContextPriv(pDRIContextPriv); } @@ -738,41 +817,35 @@ DRIClipNotifyAllDrawables(ScreenPtr pScreen) static void DRITransitionToSharedBuffers(ScreenPtr pScreen) { -/* ErrorF("DRITransitionToSharedBuffers\n"); */ - DRIClipNotifyAllDrawables( pScreen ); + DRIClipNotifyAllDrawables( pScreen ); } static void DRITransitionToPrivateBuffers(ScreenPtr pScreen) { -/* ErrorF("DRITransitionToPrivateBuffers\n"); */ - DRIClipNotifyAllDrawables( pScreen ); + DRIClipNotifyAllDrawables( pScreen ); } static void DRITransitionTo3d(ScreenPtr pScreen) { - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; - -/* ErrorF("DRITransitionTo3d\n"); */ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; - if (pDRIInfo->TransitionTo3d) - pDRIInfo->TransitionTo3d( pScreen ); + if (pDRIInfo->TransitionTo3d) + pDRIInfo->TransitionTo3d( pScreen ); } static void DRITransitionTo2d(ScreenPtr pScreen) { - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; - -/* ErrorF("DRITransitionTo2d\n"); */ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo; - if (pDRIInfo->TransitionTo2d) - pDRIInfo->TransitionTo2d( pScreen ); + if (pDRIInfo->TransitionTo2d) + pDRIInfo->TransitionTo2d( pScreen ); } diff --git a/xc/programs/Xserver/GL/dri/dri.h b/xc/programs/Xserver/GL/dri/dri.h index f0e26bc82..bb0f811aa 100644 --- a/xc/programs/Xserver/GL/dri/dri.h +++ b/xc/programs/Xserver/GL/dri/dri.h @@ -147,6 +147,8 @@ typedef struct { DRIWindowRequests bufferRequests; int devPrivateSize; void* devPrivate; + Bool createDummyCtx; + Bool createDummyCtxPriv; } DRIInfoRec, *DRIInfoPtr; diff --git a/xc/programs/Xserver/GL/dri/dristruct.h b/xc/programs/Xserver/GL/dri/dristruct.h index 54a4646f3..0cc083583 100644 --- a/xc/programs/Xserver/GL/dri/dristruct.h +++ b/xc/programs/Xserver/GL/dri/dristruct.h @@ -93,6 +93,9 @@ typedef struct _DRIScreenPrivRec XF86DRIClipRectRec fullscreen_rect; /* fake rect for fullscreen mode */ DRIWrappedFuncsRec wrap; DrawablePtr DRIDrawables[SAREA_MAX_DRAWABLES]; + DRIContextPrivPtr dummyCtxPriv; /* Pointer to dummy context */ + Bool createDummyCtx; + Bool createDummyCtxPriv; } DRIScreenPrivRec, *DRIScreenPrivPtr; #endif /* DRI_STRUCT_H */ diff --git a/xc/programs/Xserver/GL/dri/sarea.h b/xc/programs/Xserver/GL/dri/sarea.h index e24f44fdd..1464a541d 100644 --- a/xc/programs/Xserver/GL/dri/sarea.h +++ b/xc/programs/Xserver/GL/dri/sarea.h @@ -73,6 +73,7 @@ typedef struct _XF86DRISAREA { drmLock drawable_lock; XF86DRISAREADrawableRec drawableTable[SAREA_MAX_DRAWABLES]; XF86DRISAREAFrameRec frame; + drmContext dummy_context; } XF86DRISAREARec, *XF86DRISAREAPtr; #endif 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 a1247ab5e..5d55ad114 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -737,10 +737,10 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "R128DRIScreenInit failed " - "(DRI version = %d.%d.%d, expected 3.0.x). " + "(DRI version = %d.%d.%d, expected 4.0.x). " "Disabling DRI.\n", major, minor, patch); return FALSE; @@ -819,6 +819,9 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = R128DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n"); xfree(pDRIInfo->devPrivate); @@ -832,8 +835,7 @@ Bool R128DRIScreenInit(ScreenPtr pScreen) version = drmGetVersion(info->drmFD); if (version) { if (version->version_major != 2 || - version->version_minor != 1 || - version->version_patchlevel < 0) { + version->version_minor < 1) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "R128DRIScreenInit failed " @@ -956,6 +958,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) pR128DRI->agpTexMapSize = info->agpTexMapSize; pR128DRI->log2AGPTexGran = info->log2AGPTexGran; pR128DRI->agpTexOffset = info->agpTexStart; + pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h index 5aa4f5056..01857a0e3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -96,6 +96,7 @@ typedef struct { drmSize agpTexMapSize; int log2AGPTexGran; int agpTexOffset; + unsigned int sarea_priv_offset; } R128DRIRec, *R128DRIPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h index 7a2285200..911122b21 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -366,6 +366,10 @@ typedef struct { CARD32 re_width_height; CARD32 aux_sc_cntl; + +#ifdef PER_CONTEXT_SAREA + int perctx_sarea_size; +#endif #endif XF86VideoAdaptorPtr adaptor; 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 cad22ad8b..704041d91 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -244,7 +244,36 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, drmContext hwContext, void *pVisualConfigPriv, DRIContextType contextStore) { - /* Nothing yet */ +#ifdef PER_CONTEXT_SAREA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONDRIContextPtr ctx_info; + + ctx_info = (RADEONDRIContextPtr)contextStore; + if (!ctx_info) return FALSE; + + if (drmAddMap(info->drmFD, 0, + info->perctx_sarea_size, + DRM_SHM, + DRM_REMOVABLE, + &ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not create private sarea for ctx id (%d)\n", + (int)hwContext); + return FALSE; + } + + if (drmAddContextPrivateMapping(info->drmFD, hwContext, + ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not associate private sarea to ctx id (%d)\n", + (int)hwContext); + drmRmMap(info->drmFD, ctx_info->sarea_handle); + return FALSE; + } + + ctx_info->ctx_id = hwContext; +#endif return TRUE; } @@ -252,7 +281,20 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext, DRIContextType contextStore) { - /* Nothing yet */ +#ifdef PER_CONTEXT_SAREA + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONDRIContextPtr ctx_info; + + ctx_info = (RADEONDRIContextPtr) contextStore; + if (!ctx_info) return; + + if (drmRmMap(info->drmFD, ctx_info->sarea_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[DRI] could not remove private sarea for ctx id (%d)\n", + (int)hwContext); + } +#endif } /* Called when the X server is woken up to allow the last client's @@ -1145,10 +1187,10 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "RADEONDRIScreenInit failed " - "(DRI version = %d.%d.%d, expected 3.0.x). " + "(DRI version = %d.%d.%d, expected 4.0.x). " "Disabling DRI.\n", major, minor, patch); return FALSE; @@ -1192,6 +1234,11 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) < RADEON_MAX_DRAWABLES ? SAREA_MAX_DRAWABLES : RADEON_MAX_DRAWABLES); +#ifdef PER_CONTEXT_SAREA + /* This is only here for testing per-context SAREAs. When used, the + magic number below would be properly defined in a header file. */ + info->perctx_sarea_size = 64 * 1024; +#endif #ifdef NOT_DONE /* FIXME: Need to extend DRI protocol to pass this size back to @@ -1227,6 +1274,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n"); xfree(pDRIInfo->devPrivate); @@ -1240,8 +1290,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) version = drmGetVersion(info->drmFD); if (version) { if (version->version_major != 1 || - version->version_minor != 0 || - version->version_patchlevel < 0) { + version->version_minor < 0) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "RADEONDRIScreenInit failed " @@ -1335,6 +1384,7 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) /* Initialize the SAREA private data structure */ pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + RADEONDRISAREAInit(pScreen, pSAREAPriv); pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; @@ -1369,6 +1419,13 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran; pRADEONDRI->agpTexOffset = info->agpTexStart; + pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + +#ifdef PER_CONTEXT_SAREA + /* Set per-context SAREA size */ + pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size; +#endif + return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index 27d5be961..bfbc07b40 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -96,6 +96,11 @@ typedef struct { drmSize agpTexMapSize; int log2AGPTexGran; int agpTexOffset; + unsigned int sarea_priv_offset; + +#ifdef PER_CONTEXT_SAREA + drmSize perctx_sarea_size; +#endif } RADEONDRIRec, *RADEONDRIPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h index 9225c5cda..ffbd869c5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h @@ -38,6 +38,8 @@ #define _RADEON_DRIPRIV_H_ #include "GL/glxint.h" +#include "xf86drm.h" +#include "xf86drmRadeon.h" #define RADEON_MAX_DRAWABLES 256 @@ -50,8 +52,13 @@ typedef struct { } RADEONConfigPrivRec, *RADEONConfigPrivPtr; typedef struct { +#ifdef PER_CONTEXT_SAREA + drmContext ctx_id; + drmHandle sarea_handle; +#else /* Nothing here yet */ int dummy; +#endif } RADEONDRIContextRec, *RADEONDRIContextPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c index 57eb82299..6cf4650f2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c @@ -351,9 +351,9 @@ GLINTDRIScreenInit(ScreenPtr pScreen) { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, - "GLINTDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n", + "GLINTDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n", major, minor, patch); return FALSE; } @@ -425,6 +425,9 @@ GLINTDRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = GLINTDRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &(pGlint->drmSubFD))) { DRIDestroyInfoRec(pGlint->pDRIInfo); xfree(pGlintDRI); @@ -436,8 +439,7 @@ GLINTDRIScreenInit(ScreenPtr pScreen) drmVersionPtr version = drmGetVersion(pGlint->drmSubFD); if (version) { if (version->version_major != 1 || - version->version_minor != 0 || - version->version_patchlevel < 0) { + version->version_minor < 0) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "GLINTDRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n", diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c index 92fbdc925..03ec81480 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c @@ -68,14 +68,15 @@ Bool I810InitDma(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); I810RingBuffer *ring = &(pI810->LpRing); + I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; drmI810Init info; Bool ret_val; info.start = ring->mem.Start; info.end = ring->mem.End; info.size = ring->mem.Size; - info.ring_map_idx = 6; - info.buffer_map_idx = 5; + info.mmio_offset = (unsigned int)pI810DRI->regs; + info.buffers_offset = (unsigned int)pI810->buffer_map; info.sarea_off = sizeof(XF86DRISAREARec); info.front_offset = 0; @@ -203,7 +204,6 @@ static unsigned int mylog2(unsigned int n) return log2; } - Bool I810DRIScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -240,9 +240,9 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, - "I810DRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n", + "I810DRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n", major, minor, patch); return FALSE; } @@ -310,6 +310,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = I810DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; /* This adds the framebuffer as a drm map *before* we have asked agp * to allocate it. Scary stuff, hold on... @@ -328,8 +330,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) drmVersionPtr version = drmGetVersion(pI810->drmSubFD); if (version) { if (version->version_major != 1 || - version->version_minor != 1 || - version->version_patchlevel < 0) { + version->version_minor < 1) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "I810DRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n", @@ -734,6 +735,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->auxPitch = pI810->auxPitch; pI810DRI->auxPitchBits = pI810->auxPitchBits; + pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); if (!(I810InitVisualConfigs(pScreen))) { xf86DrvMsg(pScreen->myNum, X_ERROR, "I810InitVisualConfigs failed\n"); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h index bbb0cc927..70a32f594 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h @@ -50,6 +50,7 @@ typedef struct { drmBufMapPtr drmBufs; int irq; + unsigned int sarea_priv_offset; } I810DRIRec, *I810DRIPtr; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index d6699eb09..73fbb11bd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -927,10 +927,10 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) { int major, minor, patch; DRIQueryVersion( &major, &minor, &patch ); - if ( major != 3 || minor != 0 || patch < 0 ) { + if ( major != 4 || minor < 0) { xf86DrvMsg( pScreen->myNum, X_ERROR, "[drm] MGADRIScreenInit failed " - "(DRI version = %d.%d.%d, expected 3.0.x). " + "(DRI version = %d.%d.%d, expected 4.0.x). " "Disabling DRI.\n", major, minor, patch ); return FALSE; @@ -973,6 +973,9 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) pDRIInfo->wrap.ValidateTree = NULL; pDRIInfo->wrap.PostValidateTree = NULL; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if ( SAREA_MAX_DRAWABLES < MGA_MAX_DRAWABLES ) { pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; } else { @@ -1062,8 +1065,7 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) drmVersionPtr version = drmGetVersion(pMga->drmFD); if ( version ) { if ( version->version_major != 3 || - version->version_minor != 0 || - version->version_patchlevel < 0 ) { + version->version_minor < 0) { /* incompatible drm version */ xf86DrvMsg( pScreen->myNum, X_ERROR, "[drm] MGADRIScreenInit failed " @@ -1193,7 +1195,7 @@ Bool MGADRIFinishScreenInit( ScreenPtr pScreen ) pMGADRI->primary.size = pMGADRIServer->primary.size; pMGADRI->buffers.handle = pMGADRIServer->buffers.handle; pMGADRI->buffers.size = pMGADRIServer->buffers.size; - + pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h index b3e72d46f..7e6794348 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h @@ -115,7 +115,7 @@ typedef struct { drmRegion status; drmRegion primary; drmRegion buffers; - + unsigned int sarea_priv_offset; } MGADRIRec, *MGADRIPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c index 79cb34251..9dc2feb48 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c @@ -194,9 +194,9 @@ Bool SISDRIScreenInit(ScreenPtr pScreen) { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] SISDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n", + "[drm] SISDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n", major, minor, patch); return FALSE; } @@ -262,6 +262,9 @@ Bool SISDRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = SISDRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &pSIS->drmSubFD)) { xfree(pDRIInfo->devPrivate); pDRIInfo->devPrivate=0; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c index b10dd018d..af7d6a1cb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c @@ -260,6 +260,9 @@ FFBDRIScreenInit(ScreenPtr pScreen) /* Our InitBuffers depends heavily on this setting. */ pDRIInfo->bufferRequests = DRI_3D_WINDOWS_ONLY; + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &(pFfb->drmSubFD))) { DRIDestroyInfoRec(pFfb->pDRIInfo); xfree(pFfbDRI); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c index 0ce50455a..5d160998d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c @@ -300,9 +300,9 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen) { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); - if (major != 3 || minor != 0 || patch < 0) { + if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, - "TDFXDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n", + "TDFXDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n", major, minor, patch); return FALSE; } @@ -381,6 +381,9 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen) pDRIInfo->TransitionTo3d = TDFXDRITransitionTo3d; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->createDummyCtx = FALSE; + pDRIInfo->createDummyCtxPriv = FALSE; + if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) { xfree(pDRIInfo->devPrivate); pDRIInfo->devPrivate=0; @@ -396,8 +399,7 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen) drmVersionPtr version = drmGetVersion(pTDFX->drmSubFD); if (version) { if (version->version_major != 1 || - version->version_minor != 0 || - version->version_patchlevel < 0) { + version->version_minor < 0) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "TDFXDRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n", @@ -489,6 +491,7 @@ TDFXDRIFinishScreenInit(ScreenPtr pScreen) pTDFXDRI->fbOffset=pTDFX->fbOffset; pTDFXDRI->backOffset=pTDFX->backOffset; pTDFXDRI->depthOffset=pTDFX->depthOffset; + pTDFXDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); return DRIFinishScreenInit(pScreen); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h index 7da92b83a..96fa44c99 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h @@ -22,6 +22,7 @@ typedef struct { int depthOffset; int textureOffset; int textureSize; + unsigned int sarea_priv_offset; } TDFXDRIRec, *TDFXDRIPtr; #endif 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 30b75e1e3..ddabc2771 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 @@ -138,9 +138,15 @@ typedef enum drm_map_flags { _DRM_LOCKED = 0x04, /* shared, cached, locked */ _DRM_KERNEL = 0x08, /* kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */ - _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */ + _DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */ + _DRM_REMOVABLE = 0x40 /* Removable mapping */ } drm_map_flags_t; +typedef struct drm_ctx_priv_map { + unsigned int ctx_id; /* Context requesting private mapping */ + void *handle; /* Handle of map */ +} drm_ctx_priv_map_t; + typedef struct drm_map { unsigned long offset; /* Requested physical address (0 for SAREA)*/ unsigned long size; /* Requested physical size (bytes) */ @@ -365,6 +371,11 @@ typedef struct drm_agp_info { #define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) #define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_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 4032689a2..a7e4d5732 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 @@ -73,6 +73,7 @@ #if LINUX_VERSION_CODE < 0x020400 #include "compat-pre24.h" #endif +#include <asm/pgalloc.h> #include "drm.h" /* DRM template customization defaults @@ -329,16 +330,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, DRM(ioremapfree)( (map)->handle, (map)->size ); \ } while (0) -#define DRM_FIND_MAP(map, o) \ - do { \ - int i; \ - for ( i = 0 ; i < dev->map_count ; i++ ) { \ - if ( dev->maplist[i]->offset == o ) { \ - map = dev->maplist[i]; \ - break; \ - } \ - } \ - } while (0) +#define DRM_FIND_MAP(_map, _o) \ +do { \ + struct list_head *_list; \ + list_for_each(_list, &dev->maplist->head) { \ + drm_map_list_t *_r_list; \ + _r_list = (drm_map_list_t *)_list; \ + if(_r_list->map && \ + _r_list->map->offset == (_o)) { \ + (_map) = _r_list->map; \ + break; \ + } \ + } \ +} while(0) /* Internal types and structures */ #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) @@ -349,6 +353,10 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) #define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) +#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ + (_map) = (_dev)->context_sareas[_ctx]; \ +} while(0) + typedef int drm_ioctl_t( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -577,6 +585,11 @@ typedef struct drm_sigdata { drm_hw_lock_t *lock; } drm_sigdata_t; +typedef struct drm_map_list { + struct list_head head; + drm_map_t *map; +} drm_map_list_t; + typedef struct drm_device { const char *name; /* Simple driver name */ char *unique; /* Unique identifier: e.g., busid */ @@ -609,9 +622,12 @@ typedef struct drm_device { drm_magic_head_t magiclist[DRM_HASH_SIZE]; /* Memory management */ - drm_map_t **maplist; /* Vector of pointers to regions */ + drm_map_list_t *maplist; /* Linked list of regions */ int map_count; /* Number of mappable regions */ + drm_map_t **context_sareas; + int max_context; + drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */ drm_lock_data_t lock; /* Information on hardware lock */ @@ -700,9 +716,6 @@ extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access); -extern unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, - unsigned long address, - int write_access); extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access); @@ -714,15 +727,13 @@ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, unsigned long address, int write_access); -extern struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, - unsigned long address, - int write_access); extern struct page *DRM(vm_dma_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); +extern void DRM(vm_shm_close)(struct vm_area_struct *vma); extern int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma); extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma); @@ -788,6 +799,11 @@ extern int DRM(ctxbitmap_init)( drm_device_t *dev ); extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev ); #endif +extern int DRM(setsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int DRM(getsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + /* Drawable IOCTL support (drm_drawable.h) */ extern int DRM(adddraw)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); @@ -830,6 +846,8 @@ extern int DRM(notifier)(void *priv); extern int DRM(order)( unsigned long size ); extern int DRM(addmap)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern int DRM(rmmap)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); #if __HAVE_DMA extern int DRM(addbufs)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); 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 b7e27d172..1d5403225 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 @@ -69,6 +69,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_map_t *map; + drm_map_list_t *list; if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ @@ -81,6 +82,14 @@ int DRM(addmap)( struct inode *inode, struct file *filp, return -EFAULT; } + /* Only allow shared memory to be removable since we only keep enough + * book keeping information about shared memory to allow for removal + * when processes fork. + */ + if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) { + DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); + return -EINVAL; + } DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n", map->offset, map->size, map->type ); if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) { @@ -100,7 +109,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp, return -EINVAL; } #endif -#ifdef CONFIG_MTRR +#ifdef __REALLY_HAVE_MTRR if ( map->type == _DRM_FRAME_BUFFER || (map->flags & _DRM_WRITE_COMBINING) ) { map->mtrr = mtrr_add( map->offset, map->size, @@ -111,9 +120,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp, break; case _DRM_SHM: - map->handle = (void *)DRM(alloc_pages)( DRM(order)( map->size ) - - PAGE_SHIFT, - DRM_MEM_SAREA ); + map->handle = vmalloc_32(map->size); DRM_DEBUG( "%ld %d %p\n", map->size, DRM(order)( map->size ), map->handle ); if ( !map->handle ) { @@ -136,22 +143,17 @@ int DRM(addmap)( struct inode *inode, struct file *filp, return -EINVAL; } - down( &dev->struct_sem ); - if ( dev->maplist ) { - ++dev->map_count; - dev->maplist = DRM(realloc)( dev->maplist, - (dev->map_count-1) - * sizeof(*dev->maplist), - dev->map_count - * sizeof(*dev->maplist), - DRM_MEM_MAPS ); - } else { - dev->map_count = 1; - dev->maplist = DRM(alloc)( dev->map_count*sizeof(*dev->maplist), - DRM_MEM_MAPS ); + list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS); + if(!list) { + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + return -EINVAL; } - dev->maplist[dev->map_count-1] = map; - up( &dev->struct_sem ); + memset(list, 0, sizeof(*list)); + list->map = map; + + down(&dev->struct_sem); + list_add(&list->head, &dev->maplist->head); + up(&dev->struct_sem); if ( copy_to_user( (drm_map_t *)arg, map, sizeof(*map) ) ) return -EFAULT; @@ -164,6 +166,84 @@ int DRM(addmap)( struct inode *inode, struct file *filp, return 0; } + +/* Remove a map private from list and deallocate resources if the mapping + * isn't in use. + */ + +int DRM(rmmap)(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; + struct list_head *list; + drm_map_list_t *r_list; + drm_vma_entry_t *pt, *prev; + drm_map_t *map; + drm_map_t request; + int found_maps = 0; + + if (copy_from_user(&request, (drm_map_t *)arg, + sizeof(request))) { + return -EFAULT; + } + + down(&dev->struct_sem); + list = &dev->maplist->head; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *) list; + + if(r_list->map && + r_list->map->handle == request.handle && + r_list->map->flags & _DRM_REMOVABLE) break; + } + + /* List has wrapped around to the head pointer, or its empty we didn't + * find anything. + */ + if(list == (&dev->maplist->head)) { + up(&dev->struct_sem); + return -EINVAL; + } + map = r_list->map; + list_del(list); + DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); + + for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { +#if LINUX_VERSION_CODE >= 0x020300 + if (pt->vma->vm_private_data == map) found_maps++; +#else + if (pt->vma->vm_pte == map) found_maps++; +#endif + } + + if(!found_maps) { + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: +#ifdef __REALLY_HAVE_MTRR + if (map->mtrr >= 0) { + int retcode; + retcode = mtrr_del(map->mtrr, + map->offset, + map->size); + DRM_DEBUG("mtrr_del = %d\n", retcode); + } +#endif + DRM(ioremapfree)(map->handle, map->size); + break; + case _DRM_SHM: + vfree(map->handle); + break; + case _DRM_AGP: + break; + } + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + } + up(&dev->struct_sem); + return 0; +} + #if __HAVE_DMA #if __REALLY_HAVE_AGP diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h index e2b6170a8..4ac896ef5 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h @@ -41,9 +41,13 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) { if ( ctx_handle < 0 ) goto failed; + if ( !dev->ctx_bitmap ) goto failed; if ( ctx_handle < DRM_MAX_CTXBITMAP ) { + down(&dev->struct_sem); clear_bit( ctx_handle, dev->ctx_bitmap ); + dev->context_sareas[ctx_handle] = NULL; + up(&dev->struct_sem); return; } failed: @@ -56,12 +60,37 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) { int bit; + if(!dev->ctx_bitmap) return -1; + + down(&dev->struct_sem); bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP ); if ( bit < DRM_MAX_CTXBITMAP ) { set_bit( bit, dev->ctx_bitmap ); DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit ); + if((bit+1) > dev->max_context) { + dev->max_context = (bit+1); + if(dev->context_sareas) { + dev->context_sareas = DRM(realloc)( + dev->context_sareas, + (dev->max_context - 1) * + sizeof(*dev->context_sareas), + dev->max_context * + sizeof(*dev->context_sareas), + DRM_MEM_MAPS); + dev->context_sareas[bit] = NULL; + } else { + /* max_context == 1 at this point */ + dev->context_sareas = DRM(alloc)( + dev->max_context * + sizeof(*dev->context_sareas), + DRM_MEM_MAPS); + dev->context_sareas[bit] = NULL; + } + } + up(&dev->struct_sem); return bit; } + up(&dev->struct_sem); return -1; } @@ -70,12 +99,18 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) int i; int temp; + down(&dev->struct_sem); dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE, DRM_MEM_CTXBITMAP ); if ( dev->ctx_bitmap == NULL ) { + up(&dev->struct_sem); return -ENOMEM; } memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE ); + dev->context_sareas = NULL; + dev->max_context = -1; + up(&dev->struct_sem); + for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) { temp = DRM(ctxbitmap_next)( dev ); DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp ); @@ -86,9 +121,86 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) { + down(&dev->struct_sem); + if( dev->context_sareas ) DRM(free)( dev->context_sareas, + sizeof(*dev->context_sareas) * + dev->max_context, + DRM_MEM_MAPS ); DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP ); + up(&dev->struct_sem); +} + +/* ================================================================ + * Per Context SAREA Support + */ + +int DRM(getsareactx)(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_ctx_priv_map_t request; + drm_map_t *map; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + + map = dev->context_sareas[request.ctx_id]; + up(&dev->struct_sem); + + request.handle = map->handle; + if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request))) + return -EFAULT; + return 0; } +int DRM(setsareactx)(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_ctx_priv_map_t request; + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; + + if (copy_from_user(&request, + (drm_ctx_priv_map_t *)arg, + sizeof(request))) + return -EFAULT; + + down(&dev->struct_sem); + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + if(r_list->map && + r_list->map->handle == request.handle) break; + } + if (list == &(dev->maplist->head)) { + up(&dev->struct_sem); + return -EINVAL; + } + map = r_list->map; + up(&dev->struct_sem); + + if (!map) return -EINVAL; + + down(&dev->struct_sem); + if ((int)request.ctx_id >= dev->max_context) { + up(&dev->struct_sem); + return -EINVAL; + } + dev->context_sareas[request.ctx_id] = map; + up(&dev->struct_sem); + return 0; +} /* ================================================================ * The actual DRM context handling routines 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 c19b63983..7447ca6d4 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 @@ -118,60 +118,64 @@ static struct file_operations DRM(fops) = { }; -static drm_ioctl_desc_t DRM(ioctls)[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 }, - - [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 }, - - [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 }, +static drm_ioctl_desc_t DRM(ioctls)[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 }, #if __HAVE_DMA - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ #if __HAVE_DMA_IRQ - [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif #endif #if __REALLY_HAVE_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 }, #endif DRIVER_IOCTLS @@ -262,8 +266,14 @@ static int DRM(setup)( drm_device_t *dev ) dev->magiclist[i].head = NULL; dev->magiclist[i].tail = NULL; } - dev->maplist = NULL; + + dev->maplist = DRM(alloc)(sizeof(*dev->maplist), + DRM_MEM_MAPS); + if(dev->maplist == NULL) return -ENOMEM; + memset(dev->maplist, 0, sizeof(*dev->maplist)); + INIT_LIST_HEAD(&dev->maplist->head); dev->map_count = 0; + dev->vmalist = NULL; dev->lock.hw_lock = NULL; init_waitqueue_head( &dev->lock.lock_queue ); @@ -307,6 +317,8 @@ static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; drm_map_t *map; + drm_map_list_t *r_list; + struct list_head *list; drm_vma_entry_t *vma, *vma_next; int i; @@ -373,10 +385,13 @@ static int DRM(takedown)( drm_device_t *dev ) dev->vmalist = NULL; } - /* Clear map area and mtrr information */ - if ( dev->maplist ) { - for ( i = 0 ; i < dev->map_count ; i++ ) { - map = dev->maplist[i]; + if( dev->maplist ) { + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); + if(!map) continue; + switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: @@ -392,25 +407,20 @@ static int DRM(takedown)( drm_device_t *dev ) DRM(ioremapfree)( map->handle, map->size ); break; case _DRM_SHM: - DRM(free_pages)( (unsigned long)map->handle, - DRM(order)( map->size ) - - PAGE_SHIFT, - DRM_MEM_SAREA ); + vfree(map->handle); break; + case _DRM_AGP: /* Do nothing here, because this is all * handled in the AGP/GART driver. */ break; } - DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); - } - DRM(free)( dev->maplist, - dev->map_count * sizeof(*dev->maplist), - DRM_MEM_MAPS ); + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + } + DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; - dev->map_count = 0; - } + } #if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES if ( dev->queuelist ) { 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 ce6ac2e68..2fba6b0c2 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 @@ -105,22 +105,40 @@ int DRM(getmap)( struct inode *inode, struct file *filp, drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_map_t map; + drm_map_list_t *r_list = NULL; + struct list_head *list; int idx; + int i; if (copy_from_user(&map, (drm_map_t *)arg, sizeof(map))) return -EFAULT; idx = map.offset; + down(&dev->struct_sem); if (idx < 0 || idx >= dev->map_count) { up(&dev->struct_sem); return -EINVAL; } - map.offset = dev->maplist[idx]->offset; - map.size = dev->maplist[idx]->size; - map.type = dev->maplist[idx]->type; - map.flags = dev->maplist[idx]->flags; - map.handle = dev->maplist[idx]->handle; - map.mtrr = dev->maplist[idx]->mtrr; + + i = 0; + list_for_each(list, &dev->maplist->head) { + if(i == idx) { + r_list = (drm_map_list_t *)list; + break; + } + i++; + } + if(!r_list || !r_list->map) { + up(&dev->struct_sem); + return -EINVAL; + } + + map.offset = r_list->map->offset; + map.size = r_list->map->size; + map.type = r_list->map->type; + map.flags = r_list->map->flags; + map.handle = r_list->map->handle; + map.mtrr = r_list->map->mtrr; up(&dev->struct_sem); if (copy_to_user((drm_map_t *)arg, &map, sizeof(map))) return -EFAULT; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h index ee9c0cbc8..f65f42b71 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h @@ -165,6 +165,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, drm_device_t *dev = (drm_device_t *)data; int len = 0; drm_map_t *map; + drm_map_list_t *r_list; + struct list_head *list; + /* Hardcoded from _DRM_FRAME_BUFFER, _DRM_REGISTERS, _DRM_SHM, and _DRM_AGP. */ @@ -182,8 +185,11 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, DRM_PROC_PRINT("slot offset size type flags " "address mtrr\n\n"); - for (i = 0; i < dev->map_count; i++) { - map = dev->maplist[i]; + i = 0; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if(!map) continue; if (map->type < 0 || map->type > 3) type = "??"; else type = types[map->type]; DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", @@ -198,6 +204,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, } else { DRM_PROC_PRINT("%4d\n", map->mtrr); } + i++; } if (len > request + offset) return request; 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 347816ac3..123eea299 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 @@ -41,13 +41,7 @@ struct vm_operations_struct drm_vm_ops = { struct vm_operations_struct drm_vm_shm_ops = { nopage: DRM(vm_shm_nopage), open: DRM(vm_open), - close: DRM(vm_close), -}; - -struct vm_operations_struct drm_vm_shm_lock_ops = { - nopage: DRM(vm_shm_nopage_lock), - open: DRM(vm_open), - close: DRM(vm_close), + close: DRM(vm_shm_close), }; struct vm_operations_struct drm_vm_dma_ops = { @@ -88,12 +82,26 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, #endif unsigned long physical; unsigned long offset; + unsigned long i; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) return NOPAGE_OOM; /* Nothing allocated */ offset = address - vma->vm_start; - physical = (unsigned long)map->handle + offset; + 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. + */ + pgd = pgd_offset_k( i ); + if( !pgd_present( *pgd ) ) return NOPAGE_OOM; + pmd = pmd_offset( pgd, i ); + if( !pmd_present( *pmd ) ) return NOPAGE_OOM; + pte = pte_offset( pmd, i ); + if( !pte_present( *pte ) ) return NOPAGE_OOM; + physical = (unsigned long)pte_page( *pte )->virtual; atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical); @@ -104,37 +112,87 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, #endif } -#if LINUX_VERSION_CODE < 0x020317 -unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, - unsigned long address, - int write_access) -#else - /* Return type changed in 2.3.23 */ -struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma, - unsigned long address, - int write_access) -#endif +/* Special close routine which deletes map information if we are the last + * person to close a mapping and its not in the global maplist. + */ + +void DRM(vm_shm_close)(struct vm_area_struct *vma) { - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->dev; - unsigned long physical; - unsigned long offset; - unsigned long page; + drm_file_t *priv = vma->vm_file->private_data; + drm_device_t *dev = priv->dev; + drm_vma_entry_t *pt, *prev; + drm_map_t *map; + drm_map_list_t *r_list; + struct list_head *list; + int found_maps = 0; - if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */ - if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */ + DRM_DEBUG("0x%08lx,0x%08lx\n", + vma->vm_start, vma->vm_end - vma->vm_start); +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif + atomic_dec(&dev->vma_count); - offset = address - vma->vm_start; - page = offset >> PAGE_SHIFT; - physical = (unsigned long)dev->lock.hw_lock + offset; - atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */ +#if LINUX_VERSION_CODE >= 0x020300 + map = vma->vm_private_data; +#else + map = vma->vm_pte; +#endif - DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical); -#if LINUX_VERSION_CODE < 0x020317 - return physical; + down(&dev->struct_sem); + for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { +#if LINUX_VERSION_CODE >= 0x020300 + if (pt->vma->vm_private_data == map) found_maps++; #else - return virt_to_page(physical); + if (pt->vma->vm_pte == map) found_maps++; #endif + if (pt->vma == vma) { + if (prev) { + prev->next = pt->next; + } else { + dev->vmalist = pt->next; + } + DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS); + } + } + /* We were the only map that was found */ + if(found_maps == 1 && + map->flags & _DRM_REMOVABLE) { + /* Check to see if we are in the maplist, if we are not, then + * we delete this mappings information. + */ + found_maps = 0; + list = &dev->maplist->head; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *) list; + if (r_list->map == map) found_maps++; + } + + if(!found_maps) { + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: +#ifdef __REALLY_HAVE_MTRR + if (map->mtrr >= 0) { + int retcode; + retcode = mtrr_del(map->mtrr, + map->offset, + map->size); + DRM_DEBUG("mtrr_del = %d\n", retcode); + } +#endif + DRM(ioremapfree)(map->handle, map->size); + break; + case _DRM_SHM: + vfree(map->handle); + break; + case _DRM_AGP: + break; + } + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + } + } + up(&dev->struct_sem); } #if LINUX_VERSION_CODE < 0x020317 @@ -176,9 +234,7 @@ void DRM(vm_open)(struct vm_area_struct *vma) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; -#if DRM_DEBUG_CODE drm_vma_entry_t *vma_entry; -#endif DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); @@ -188,8 +244,6 @@ void DRM(vm_open)(struct vm_area_struct *vma) MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ #endif - -#if DRM_DEBUG_CODE vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS); if (vma_entry) { down(&dev->struct_sem); @@ -199,16 +253,13 @@ void DRM(vm_open)(struct vm_area_struct *vma) dev->vmalist = vma_entry; up(&dev->struct_sem); } -#endif } void DRM(vm_close)(struct vm_area_struct *vma) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->dev; -#if DRM_DEBUG_CODE drm_vma_entry_t *pt, *prev; -#endif DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); @@ -217,7 +268,6 @@ void DRM(vm_close)(struct vm_area_struct *vma) #endif atomic_dec(&dev->vma_count); -#if DRM_DEBUG_CODE down(&dev->struct_sem); for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { if (pt->vma == vma) { @@ -231,7 +281,6 @@ void DRM(vm_close)(struct vm_area_struct *vma) } } up(&dev->struct_sem); -#endif } int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma) @@ -272,7 +321,8 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_map_t *map = NULL; - int i; + drm_map_list_t *r_list; + struct list_head *list; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); @@ -286,12 +336,13 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) once, so it doesn't have to be optimized for performance, even if the list was a bit longer. */ - for (i = 0; i < dev->map_count; i++) { - map = dev->maplist[i]; + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if (!map) continue; if (map->offset == VM_OFFSET(vma)) break; } - if (i >= dev->map_count) return -EINVAL; if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -339,17 +390,12 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) vma->vm_ops = &drm_vm_ops; break; case _DRM_SHM: - if (map->flags & _DRM_CONTAINS_LOCK) - vma->vm_ops = &drm_vm_shm_lock_ops; - else { - vma->vm_ops = &drm_vm_shm_ops; + vma->vm_ops = &drm_vm_shm_ops; #if LINUX_VERSION_CODE >= 0x020300 - vma->vm_private_data = (void *)map; + vma->vm_private_data = (void *)map; #else - vma->vm_pte = (unsigned long)map; + vma->vm_pte = (unsigned long)map; #endif - } - /* Don't let this area swap. Change when DRM_KERNEL advisory is supported. */ vma->vm_flags |= VM_LOCKED; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h index 383c54af5..232ed018b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h @@ -68,17 +68,23 @@ #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 #define DRIVER_PREINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ } while (0) #define DRIVER_POSTINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ } while (0) #define DRIVER_UNINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c index 2238d1268..d3a9414d7 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c @@ -41,6 +41,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) ; @@ -49,6 +52,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, void gamma_dma_quiescent_single(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -65,6 +71,9 @@ void gamma_dma_quiescent_single(drm_device_t *dev) void gamma_dma_quiescent_dual(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -90,19 +99,27 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) void gamma_dma_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; } static inline int gamma_dma_is_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + return !GAMMA_READ(GAMMA_DMACOUNT); } void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { - drm_device_t *dev = (drm_device_t *)device; - drm_device_dma_t *dma = dev->dma; + drm_device_t *dev = (drm_device_t *)device; + drm_device_dma_t *dma = dev->dma; + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h index d8cca6676..68b520700 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h @@ -35,6 +35,10 @@ typedef struct drm_gamma_private { drm_map_t *buffers; + drm_map_t *mmio0; + drm_map_t *mmio1; + drm_map_t *mmio2; + drm_map_t *mmio3; } drm_gamma_private_t; #define LOCK_TEST_WITH_RETURN( dev ) \ @@ -60,16 +64,6 @@ extern int gamma_find_devices(void); extern int gamma_found(void); -/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the - kernel must be specified here. Currently, the number is 2. This must - match the order the X server uses for instantiating register regions , - or must be passed in a new ioctl. */ -#define GAMMA_REG(reg) \ - (2 \ - + ((reg < 0x1000) \ - ? 0 \ - : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3)))) - #define GAMMA_OFF(reg) \ ((reg < 0x1000) \ ? reg \ @@ -79,7 +73,12 @@ extern int gamma_found(void); ? (reg - 0x10000) \ : (reg - 0x11000)))) -#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle) +#define GAMMA_BASE(reg) ((unsigned long) \ + ((reg < 0x1000) ? dev_priv->mmio0->handle : \ + ((reg < 0x10000) ? dev_priv->mmio1->handle : \ + ((reg < 0x11000) ? dev_priv->mmio2->handle : \ + dev_priv->mmio3->handle)))) + #define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) #define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) #define GAMMA_READ(reg) GAMMA_DEREF(reg) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h index 303ddd5ee..ed25b2a99 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h @@ -63,6 +63,8 @@ #define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_IRQ_BH 1 #define DRIVER_PREINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ u16 tmp; \ tmp = I810_READ16( I810REG_HWSTAM ); \ tmp = tmp & 0x6000; \ @@ -77,6 +79,8 @@ } while (0) #define DRIVER_POSTINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ u16 tmp; \ tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ tmp = tmp & 0x6000; \ @@ -85,6 +89,8 @@ } while (0) #define DRIVER_UNINSTALL() do { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ u16 tmp; \ tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \ tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ @@ -101,10 +107,6 @@ #define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t #define DRIVER_AGP_BUFFERS_MAP( dev ) \ -({ \ - drm_i810_private_t *dev_priv = (dev)->dev_private; \ - drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx]; \ - map; \ -}) + ((drm_i810_private_t *)((dev)->dev_private))->buffer_map #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c index e27406a62..4c90496a7 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c @@ -396,23 +396,26 @@ static int i810_dma_initialize(drm_device_t *dev, drm_i810_private_t *dev_priv, drm_i810_init_t *init) { - drm_map_t *sarea_map; + struct list_head *list; dev->dev_private = (void *) dev_priv; memset(dev_priv, 0, sizeof(drm_i810_private_t)); - if (init->ring_map_idx >= dev->map_count || - init->buffer_map_idx >= dev->map_count) { - i810_dma_cleanup(dev); - DRM_ERROR("ring_map or buffer_map are invalid\n"); - return -EINVAL; - } + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea_map = r_list->map; + break; + } + } + + DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset ); + DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset ); - dev_priv->ring_map_idx = init->ring_map_idx; - dev_priv->buffer_map_idx = init->buffer_map_idx; - sarea_map = dev->maplist[0]; dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *)sarea_map->handle + + ((u8 *)dev_priv->sarea_map->handle + init->sarea_priv_offset); atomic_set(&dev_priv->flush_done, 0); @@ -865,6 +868,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, void i810_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; u16 temp; atomic_inc(&dev->counts[_DRM_STAT_IRQ]); diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h index c5f51c9ad..cee189b7b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h @@ -98,8 +98,8 @@ typedef struct _drm_i810_init { I810_INIT_DMA = 0x01, I810_CLEANUP_DMA = 0x02 } func; - int ring_map_idx; - int buffer_map_idx; + unsigned int mmio_offset; + unsigned int buffers_offset; int sarea_priv_offset; unsigned int ring_start; unsigned int ring_end; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h index 43d44e028..e1b17148e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h @@ -54,11 +54,12 @@ typedef struct _drm_i810_ring_buffer{ } drm_i810_ring_buffer_t; typedef struct drm_i810_private { - int ring_map_idx; - int buffer_map_idx; + drm_map_t *sarea_map; + drm_map_t *buffer_map; + drm_map_t *mmio_map; - drm_i810_ring_buffer_t ring; drm_i810_sarea_t *sarea_priv; + drm_i810_ring_buffer_t ring; unsigned long hw_status_page; unsigned long counter; @@ -108,9 +109,8 @@ int i810_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#define I810_REG(reg) 2 #define I810_BASE(reg) ((unsigned long) \ - dev->maplist[I810_REG(reg)]->handle) + dev_priv->mmio_map->handle) #define I810_ADDR(reg) (I810_BASE(reg) + reg) #define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) #define I810_READ(reg) I810_DEREF(reg) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c index c76e54eb4..ec80fb417 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c @@ -436,6 +436,7 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) { drm_mga_private_t *dev_priv; + struct list_head *list; int ret; DRM_DEBUG( "%s\n", __FUNCTION__ ); @@ -467,7 +468,15 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->depth_offset = init->depth_offset; dev_priv->depth_pitch = init->depth_pitch; - dev_priv->sarea = dev->maplist[0]; + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea = r_list->map; + break; + } + } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 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 5c67bec9f..c0e20c213 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 @@ -344,7 +344,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev ) static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) { drm_r128_private_t *dev_priv; - int i; + struct list_head *list; dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -451,15 +451,15 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | (dev_priv->span_offset >> 5)); - /* FIXME: We want multiple shared areas, including one shared - * only by the X Server and kernel module. - */ - for ( i = 0 ; i < dev->map_count ; i++ ) { - if ( dev->maplist[i]->type == _DRM_SHM ) { - dev_priv->sarea = dev->maplist[i]; - break; - } - } + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea = r_list->map; + break; + } + } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 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 cea8c327a..ed8b1bbca 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 @@ -601,7 +601,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev ) static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - int i; + struct list_head *list; dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) @@ -710,15 +710,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); - /* FIXME: We want multiple shared areas, including one shared - * only by the X Server and kernel module. - */ - for ( i = 0 ; i < dev->map_count ; i++ ) { - if ( dev->maplist[i]->type == _DRM_SHM ) { - dev_priv->sarea = dev->maplist[i]; - break; - } - } + list_for_each(list, &dev->maplist->head) { + drm_map_list_t *r_list = (drm_map_list_t *)list; + if( r_list->map && + r_list->map->type == _DRM_SHM && + r_list->map->flags & _DRM_CONTAINS_LOCK ) { + dev_priv->sarea = r_list->map; + break; + } + } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 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 73a083e38..a640d5987 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 @@ -513,6 +513,16 @@ int drmAddMap(int fd, return 0; } +int drmRmMap(int fd, drmHandle handle) +{ + drm_map_t map; + + map.handle = (void *)handle; + + if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno; + return 0; +} + int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, int agp_offset) { @@ -1088,6 +1098,29 @@ void *drmGetContextTag(int fd, drmContext context) return value; } +int drmAddContextPrivateMapping(int fd, drmContext ctx_id, drmHandle handle) +{ + drm_ctx_priv_map_t map; + + map.ctx_id = ctx_id; + map.handle = (void *)handle; + + if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno; + return 0; +} + +int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle) +{ + drm_ctx_priv_map_t map; + + map.ctx_id = ctx_id; + + if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno; + if (handle) *handle = (drmHandle)map.handle; + + return 0; +} + int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, drmMapType *type, drmMapFlags *flags, drmHandle *handle, int *mtrr) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c index d5a7e2263..fb632a481 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c @@ -70,8 +70,8 @@ Bool drmI810InitDma(int driSubFD, drmI810Init *info) memset(&init, 0, sizeof(drm_i810_init_t)); init.func = I810_INIT_DMA; - init.ring_map_idx = info->ring_map_idx; - init.buffer_map_idx = info->buffer_map_idx; + init.mmio_offset = info->mmio_offset; + init.buffers_offset = info->buffers_offset; init.ring_start = info->start; init.ring_end = info->end; init.ring_size = info->size; 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 30b75e1e3..ddabc2771 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 @@ -138,9 +138,15 @@ typedef enum drm_map_flags { _DRM_LOCKED = 0x04, /* shared, cached, locked */ _DRM_KERNEL = 0x08, /* kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */ - _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */ + _DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */ + _DRM_REMOVABLE = 0x40 /* Removable mapping */ } drm_map_flags_t; +typedef struct drm_ctx_priv_map { + unsigned int ctx_id; /* Context requesting private mapping */ + void *handle; /* Handle of map */ +} drm_ctx_priv_map_t; + typedef struct drm_map { unsigned long offset; /* Requested physical address (0 for SAREA)*/ unsigned long size; /* Requested physical size (bytes) */ @@ -365,6 +371,11 @@ typedef struct drm_agp_info { #define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) #define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h index 83753c90c..180e15844 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h @@ -102,7 +102,8 @@ typedef enum { DRM_LOCKED = 0x0004, /* Physical pages locked */ DRM_KERNEL = 0x0008, /* Kernel requires access */ DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */ - DRM_CONTAINS_LOCK = 0x0020 /* SHM page that contains lock */ + DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */ + DRM_REMOVABLE = 0x0040 /* Removable mapping */ } drmMapFlags; typedef enum { /* These values *MUST* match drm.h */ @@ -425,6 +426,10 @@ extern int drmAddMap(int fd, drmMapType type, drmMapFlags flags, drmHandlePtr handle); +extern int drmRmMap(int fd, drmHandle handle); +extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id, + drmHandle handle); + extern int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, int agp_offset); @@ -467,6 +472,8 @@ extern int drmGetLock(int fd, drmLockFlags flags); extern int drmUnlock(int fd, drmContext context); extern int drmFinish(int fd, int context, drmLockFlags flags); +extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id, + drmHandlePtr handle); /* AGP/GART support: X server (root) only */ extern int drmAgpAcquire(int fd); diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h index 6c11b7a10..32927453b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h @@ -25,9 +25,9 @@ typedef struct _drmI810Init { unsigned int start; unsigned int end; - unsigned int size; - int ring_map_idx; - int buffer_map_idx; + unsigned int size; + unsigned int mmio_offset; + unsigned int buffers_offset; int sarea_off; unsigned int front_offset; |