18dd3e0eeSmrg/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.23tsi Exp $ */ 28dd3e0eeSmrg/* 38dd3e0eeSmrg 48dd3e0eeSmrgCopyright (c) 1995 Jon Tombs 58dd3e0eeSmrgCopyright (c) 1995,1996 The XFree86 Project, Inc 68dd3e0eeSmrg 78dd3e0eeSmrg*/ 88dd3e0eeSmrg 98dd3e0eeSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD */ 108dd3e0eeSmrg 118dd3e0eeSmrg 128dd3e0eeSmrg#if defined(linux) 138dd3e0eeSmrg#define HAS_MMAP_ANON 148dd3e0eeSmrg#include <sys/types.h> 158dd3e0eeSmrg#include <sys/mman.h> 168dd3e0eeSmrg/* kernel header doesn't work with -ansi */ 178dd3e0eeSmrg/* #include <asm/page.h> */ /* PAGE_SIZE */ 188dd3e0eeSmrg#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ 198dd3e0eeSmrg#define HAS_GETPAGESIZE 208dd3e0eeSmrg#endif /* linux */ 218dd3e0eeSmrg 228dd3e0eeSmrg#if defined(CSRG_BASED) 238dd3e0eeSmrg#define HAS_MMAP_ANON 248dd3e0eeSmrg#define HAS_GETPAGESIZE 258dd3e0eeSmrg#include <sys/types.h> 268dd3e0eeSmrg#include <sys/mman.h> 278dd3e0eeSmrg#endif /* CSRG_BASED */ 288dd3e0eeSmrg 29565394e5Smrg#if defined(SVR4) 308dd3e0eeSmrg#define MMAP_DEV_ZERO 318dd3e0eeSmrg#include <sys/types.h> 328dd3e0eeSmrg#include <sys/mman.h> 338dd3e0eeSmrg#include <unistd.h> 34565394e5Smrg#endif /* SVR4 */ 358dd3e0eeSmrg 368dd3e0eeSmrg#ifdef XNO_SYSCONF 378dd3e0eeSmrg#undef _SC_PAGESIZE 388dd3e0eeSmrg#endif 398dd3e0eeSmrg 408dd3e0eeSmrg#include <X11/Xlibint.h> 41329fdfe9Smrg#include <X11/extensions/Xxf86dga.h> 42329fdfe9Smrg#include <X11/extensions/xf86dgaproto.h> 438dd3e0eeSmrg#include <X11/extensions/Xext.h> 448dd3e0eeSmrg#include <X11/extensions/extutil.h> 458dd3e0eeSmrg 468dd3e0eeSmrgextern XExtDisplayInfo* xdga_find_display(Display*); 47d5a688bcSmrgextern const char *xdga_extension_name; 488dd3e0eeSmrg 498dd3e0eeSmrg#define XF86DGACheckExtension(dpy,i,val) \ 508dd3e0eeSmrg XextCheckExtension (dpy, i, xdga_extension_name, val) 518dd3e0eeSmrg 528dd3e0eeSmrg/***************************************************************************** 538dd3e0eeSmrg * * 548dd3e0eeSmrg * public XFree86-DGA Extension routines * 558dd3e0eeSmrg * * 568dd3e0eeSmrg *****************************************************************************/ 578dd3e0eeSmrg 588dd3e0eeSmrgBool XF86DGAQueryExtension ( 598dd3e0eeSmrg Display *dpy, 608dd3e0eeSmrg int *event_basep, 618dd3e0eeSmrg int *error_basep 628dd3e0eeSmrg){ 638dd3e0eeSmrg return XDGAQueryExtension(dpy, event_basep, error_basep); 648dd3e0eeSmrg} 658dd3e0eeSmrg 668dd3e0eeSmrgBool XF86DGAQueryVersion( 678dd3e0eeSmrg Display* dpy, 68d5a688bcSmrg int* majorVersion, 698dd3e0eeSmrg int* minorVersion 708dd3e0eeSmrg){ 718dd3e0eeSmrg return XDGAQueryVersion(dpy, majorVersion, minorVersion); 728dd3e0eeSmrg} 738dd3e0eeSmrg 748dd3e0eeSmrgBool XF86DGAGetVideoLL( 758dd3e0eeSmrg Display* dpy, 768dd3e0eeSmrg int screen, 778dd3e0eeSmrg unsigned int *offset, 78d5a688bcSmrg int *width, 79d5a688bcSmrg int *bank_size, 808dd3e0eeSmrg int *ram_size 818dd3e0eeSmrg){ 828dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 838dd3e0eeSmrg xXF86DGAGetVideoLLReply rep; 848dd3e0eeSmrg xXF86DGAGetVideoLLReq *req; 858dd3e0eeSmrg 868dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 878dd3e0eeSmrg 888dd3e0eeSmrg LockDisplay(dpy); 898dd3e0eeSmrg GetReq(XF86DGAGetVideoLL, req); 908dd3e0eeSmrg req->reqType = info->codes->major_opcode; 918dd3e0eeSmrg req->dgaReqType = X_XF86DGAGetVideoLL; 928dd3e0eeSmrg req->screen = screen; 938dd3e0eeSmrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 948dd3e0eeSmrg UnlockDisplay(dpy); 958dd3e0eeSmrg SyncHandle(); 968dd3e0eeSmrg return False; 978dd3e0eeSmrg } 988dd3e0eeSmrg 998dd3e0eeSmrg *offset = rep.offset; 1008dd3e0eeSmrg *width = rep.width; 1018dd3e0eeSmrg *bank_size = rep.bank_size; 1028dd3e0eeSmrg *ram_size = rep.ram_size; 103d5a688bcSmrg 1048dd3e0eeSmrg UnlockDisplay(dpy); 1058dd3e0eeSmrg SyncHandle(); 1068dd3e0eeSmrg return True; 1078dd3e0eeSmrg} 1088dd3e0eeSmrg 109d5a688bcSmrg 1108dd3e0eeSmrgBool XF86DGADirectVideoLL( 1118dd3e0eeSmrg Display* dpy, 1128dd3e0eeSmrg int screen, 1138dd3e0eeSmrg int enable 1148dd3e0eeSmrg){ 1158dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 1168dd3e0eeSmrg xXF86DGADirectVideoReq *req; 1178dd3e0eeSmrg 1188dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 1198dd3e0eeSmrg 1208dd3e0eeSmrg LockDisplay(dpy); 1218dd3e0eeSmrg GetReq(XF86DGADirectVideo, req); 1228dd3e0eeSmrg req->reqType = info->codes->major_opcode; 1238dd3e0eeSmrg req->dgaReqType = X_XF86DGADirectVideo; 1248dd3e0eeSmrg req->screen = screen; 1258dd3e0eeSmrg req->enable = enable; 1268dd3e0eeSmrg UnlockDisplay(dpy); 1278dd3e0eeSmrg SyncHandle(); 1288dd3e0eeSmrg XSync(dpy,False); 1298dd3e0eeSmrg return True; 1308dd3e0eeSmrg} 1318dd3e0eeSmrg 1328dd3e0eeSmrgBool XF86DGAGetViewPortSize( 1338dd3e0eeSmrg Display* dpy, 1348dd3e0eeSmrg int screen, 135d5a688bcSmrg int *width, 1368dd3e0eeSmrg int *height 1378dd3e0eeSmrg){ 1388dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 1398dd3e0eeSmrg xXF86DGAGetViewPortSizeReply rep; 1408dd3e0eeSmrg xXF86DGAGetViewPortSizeReq *req; 1418dd3e0eeSmrg 1428dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 1438dd3e0eeSmrg 1448dd3e0eeSmrg LockDisplay(dpy); 1458dd3e0eeSmrg GetReq(XF86DGAGetViewPortSize, req); 1468dd3e0eeSmrg req->reqType = info->codes->major_opcode; 1478dd3e0eeSmrg req->dgaReqType = X_XF86DGAGetViewPortSize; 1488dd3e0eeSmrg req->screen = screen; 1498dd3e0eeSmrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 1508dd3e0eeSmrg UnlockDisplay(dpy); 1518dd3e0eeSmrg SyncHandle(); 1528dd3e0eeSmrg return False; 1538dd3e0eeSmrg } 1548dd3e0eeSmrg 1558dd3e0eeSmrg *width = rep.width; 1568dd3e0eeSmrg *height = rep.height; 157d5a688bcSmrg 1588dd3e0eeSmrg UnlockDisplay(dpy); 1598dd3e0eeSmrg SyncHandle(); 1608dd3e0eeSmrg return True; 1618dd3e0eeSmrg} 162d5a688bcSmrg 163d5a688bcSmrg 1648dd3e0eeSmrgBool XF86DGASetViewPort( 1658dd3e0eeSmrg Display* dpy, 1668dd3e0eeSmrg int screen, 167d5a688bcSmrg int x, 1688dd3e0eeSmrg int y 1698dd3e0eeSmrg){ 1708dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 1718dd3e0eeSmrg xXF86DGASetViewPortReq *req; 1728dd3e0eeSmrg 1738dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 1748dd3e0eeSmrg 1758dd3e0eeSmrg LockDisplay(dpy); 1768dd3e0eeSmrg GetReq(XF86DGASetViewPort, req); 1778dd3e0eeSmrg req->reqType = info->codes->major_opcode; 1788dd3e0eeSmrg req->dgaReqType = X_XF86DGASetViewPort; 1798dd3e0eeSmrg req->screen = screen; 1808dd3e0eeSmrg req->x = x; 1818dd3e0eeSmrg req->y = y; 1828dd3e0eeSmrg UnlockDisplay(dpy); 1838dd3e0eeSmrg SyncHandle(); 1848dd3e0eeSmrg XSync(dpy,False); 1858dd3e0eeSmrg return True; 1868dd3e0eeSmrg} 1878dd3e0eeSmrg 188d5a688bcSmrg 1898dd3e0eeSmrgBool XF86DGAGetVidPage( 1908dd3e0eeSmrg Display* dpy, 1918dd3e0eeSmrg int screen, 1928dd3e0eeSmrg int *vpage 1938dd3e0eeSmrg){ 1948dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 1958dd3e0eeSmrg xXF86DGAGetVidPageReply rep; 1968dd3e0eeSmrg xXF86DGAGetVidPageReq *req; 1978dd3e0eeSmrg 1988dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 1998dd3e0eeSmrg 2008dd3e0eeSmrg LockDisplay(dpy); 2018dd3e0eeSmrg GetReq(XF86DGAGetVidPage, req); 2028dd3e0eeSmrg req->reqType = info->codes->major_opcode; 2038dd3e0eeSmrg req->dgaReqType = X_XF86DGAGetVidPage; 2048dd3e0eeSmrg req->screen = screen; 2058dd3e0eeSmrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 2068dd3e0eeSmrg UnlockDisplay(dpy); 2078dd3e0eeSmrg SyncHandle(); 2088dd3e0eeSmrg return False; 2098dd3e0eeSmrg } 2108dd3e0eeSmrg 2118dd3e0eeSmrg *vpage = rep.vpage; 2128dd3e0eeSmrg UnlockDisplay(dpy); 2138dd3e0eeSmrg SyncHandle(); 2148dd3e0eeSmrg return True; 2158dd3e0eeSmrg} 2168dd3e0eeSmrg 217d5a688bcSmrg 2188dd3e0eeSmrgBool XF86DGASetVidPage( 2198dd3e0eeSmrg Display* dpy, 2208dd3e0eeSmrg int screen, 2218dd3e0eeSmrg int vpage 2228dd3e0eeSmrg){ 2238dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 2248dd3e0eeSmrg xXF86DGASetVidPageReq *req; 2258dd3e0eeSmrg 2268dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 2278dd3e0eeSmrg 2288dd3e0eeSmrg LockDisplay(dpy); 2298dd3e0eeSmrg GetReq(XF86DGASetVidPage, req); 2308dd3e0eeSmrg req->reqType = info->codes->major_opcode; 2318dd3e0eeSmrg req->dgaReqType = X_XF86DGASetVidPage; 2328dd3e0eeSmrg req->screen = screen; 2338dd3e0eeSmrg req->vpage = vpage; 2348dd3e0eeSmrg UnlockDisplay(dpy); 2358dd3e0eeSmrg SyncHandle(); 2368dd3e0eeSmrg XSync(dpy,False); 2378dd3e0eeSmrg return True; 2388dd3e0eeSmrg} 2398dd3e0eeSmrg 2408dd3e0eeSmrgBool XF86DGAInstallColormap( 2418dd3e0eeSmrg Display* dpy, 2428dd3e0eeSmrg int screen, 2438dd3e0eeSmrg Colormap cmap 2448dd3e0eeSmrg){ 2458dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 2468dd3e0eeSmrg xXF86DGAInstallColormapReq *req; 2478dd3e0eeSmrg 2488dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 2498dd3e0eeSmrg 2508dd3e0eeSmrg LockDisplay(dpy); 2518dd3e0eeSmrg GetReq(XF86DGAInstallColormap, req); 2528dd3e0eeSmrg req->reqType = info->codes->major_opcode; 2538dd3e0eeSmrg req->dgaReqType = X_XF86DGAInstallColormap; 2548dd3e0eeSmrg req->screen = screen; 2558dd3e0eeSmrg req->id = cmap; 2568dd3e0eeSmrg UnlockDisplay(dpy); 2578dd3e0eeSmrg SyncHandle(); 2588dd3e0eeSmrg XSync(dpy,False); 2598dd3e0eeSmrg return True; 2608dd3e0eeSmrg} 2618dd3e0eeSmrg 2628dd3e0eeSmrgBool XF86DGAQueryDirectVideo( 2638dd3e0eeSmrg Display *dpy, 2648dd3e0eeSmrg int screen, 2658dd3e0eeSmrg int *flags 2668dd3e0eeSmrg){ 2678dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 2688dd3e0eeSmrg xXF86DGAQueryDirectVideoReply rep; 2698dd3e0eeSmrg xXF86DGAQueryDirectVideoReq *req; 2708dd3e0eeSmrg 2718dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 2728dd3e0eeSmrg 2738dd3e0eeSmrg LockDisplay(dpy); 2748dd3e0eeSmrg GetReq(XF86DGAQueryDirectVideo, req); 2758dd3e0eeSmrg req->reqType = info->codes->major_opcode; 2768dd3e0eeSmrg req->dgaReqType = X_XF86DGAQueryDirectVideo; 2778dd3e0eeSmrg req->screen = screen; 2788dd3e0eeSmrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 2798dd3e0eeSmrg UnlockDisplay(dpy); 2808dd3e0eeSmrg SyncHandle(); 2818dd3e0eeSmrg return False; 2828dd3e0eeSmrg } 2838dd3e0eeSmrg *flags = rep.flags; 2848dd3e0eeSmrg UnlockDisplay(dpy); 2858dd3e0eeSmrg SyncHandle(); 2868dd3e0eeSmrg return True; 2878dd3e0eeSmrg} 2888dd3e0eeSmrg 2898dd3e0eeSmrgBool XF86DGAViewPortChanged( 2908dd3e0eeSmrg Display *dpy, 2918dd3e0eeSmrg int screen, 2928dd3e0eeSmrg int n 2938dd3e0eeSmrg){ 2948dd3e0eeSmrg XExtDisplayInfo *info = xdga_find_display (dpy); 2958dd3e0eeSmrg xXF86DGAViewPortChangedReply rep; 2968dd3e0eeSmrg xXF86DGAViewPortChangedReq *req; 2978dd3e0eeSmrg 2988dd3e0eeSmrg XF86DGACheckExtension (dpy, info, False); 2998dd3e0eeSmrg 3008dd3e0eeSmrg LockDisplay(dpy); 3018dd3e0eeSmrg GetReq(XF86DGAViewPortChanged, req); 3028dd3e0eeSmrg req->reqType = info->codes->major_opcode; 3038dd3e0eeSmrg req->dgaReqType = X_XF86DGAViewPortChanged; 3048dd3e0eeSmrg req->screen = screen; 3058dd3e0eeSmrg req->n = n; 3068dd3e0eeSmrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 3078dd3e0eeSmrg UnlockDisplay(dpy); 3088dd3e0eeSmrg SyncHandle(); 3098dd3e0eeSmrg return False; 3108dd3e0eeSmrg } 3118dd3e0eeSmrg UnlockDisplay(dpy); 3128dd3e0eeSmrg SyncHandle(); 3138dd3e0eeSmrg return rep.result; 3148dd3e0eeSmrg} 3158dd3e0eeSmrg 3168dd3e0eeSmrg 3178dd3e0eeSmrg 3188dd3e0eeSmrg/* Helper functions */ 3198dd3e0eeSmrg 3208dd3e0eeSmrg#include <X11/Xmd.h> 3218dd3e0eeSmrg#include <stdlib.h> 3228dd3e0eeSmrg#include <stdio.h> 3238dd3e0eeSmrg#include <fcntl.h> 324565394e5Smrg#include <sys/mman.h> 3258dd3e0eeSmrg#include <sys/wait.h> 3268dd3e0eeSmrg#include <signal.h> 3278dd3e0eeSmrg#include <unistd.h> 3288dd3e0eeSmrg 3298dd3e0eeSmrg#if defined(SVR4) && !defined(sun) 3308dd3e0eeSmrg#define DEV_MEM "/dev/pmem" 3318dd3e0eeSmrg#elif defined(SVR4) && defined(sun) 3328dd3e0eeSmrg#define DEV_MEM "/dev/xsvc" 3338dd3e0eeSmrg#elif defined(HAS_APERTURE_DRV) 3348dd3e0eeSmrg#define DEV_MEM "/dev/xf86" 3358dd3e0eeSmrg#else 3368dd3e0eeSmrg#define DEV_MEM "/dev/mem" 3378dd3e0eeSmrg#endif 3388dd3e0eeSmrg 3398dd3e0eeSmrgtypedef struct { 3408dd3e0eeSmrg unsigned long physaddr; /* actual requested physical address */ 3418dd3e0eeSmrg unsigned long size; /* actual requested map size */ 3428dd3e0eeSmrg unsigned long delta; /* delta to account for page alignment */ 3438dd3e0eeSmrg void * vaddr; /* mapped address, without the delta */ 3448dd3e0eeSmrg int refcount; /* reference count */ 3458dd3e0eeSmrg} MapRec, *MapPtr; 3468dd3e0eeSmrg 3478dd3e0eeSmrgtypedef struct { 3488dd3e0eeSmrg Display * display; 3498dd3e0eeSmrg int screen; 3508dd3e0eeSmrg MapPtr map; 3518dd3e0eeSmrg} ScrRec, *ScrPtr; 3528dd3e0eeSmrg 3538dd3e0eeSmrgstatic int mapFd = -1; 3548dd3e0eeSmrgstatic int numMaps = 0; 3558dd3e0eeSmrgstatic int numScrs = 0; 3568dd3e0eeSmrgstatic MapPtr *mapList = NULL; 3578dd3e0eeSmrgstatic ScrPtr *scrList = NULL; 3588dd3e0eeSmrg 3598dd3e0eeSmrgstatic MapPtr 3608dd3e0eeSmrgAddMap(void) 3618dd3e0eeSmrg{ 3628dd3e0eeSmrg MapPtr *old; 3638dd3e0eeSmrg 3648dd3e0eeSmrg old = mapList; 3658dd3e0eeSmrg mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1)); 3668dd3e0eeSmrg if (!mapList) { 3678dd3e0eeSmrg mapList = old; 3688dd3e0eeSmrg return NULL; 3698dd3e0eeSmrg } 3708dd3e0eeSmrg mapList[numMaps] = malloc(sizeof(MapRec)); 3718dd3e0eeSmrg if (!mapList[numMaps]) 3728dd3e0eeSmrg return NULL; 3738dd3e0eeSmrg return mapList[numMaps++]; 3748dd3e0eeSmrg} 3758dd3e0eeSmrg 3768dd3e0eeSmrgstatic ScrPtr 3778dd3e0eeSmrgAddScr(void) 3788dd3e0eeSmrg{ 3798dd3e0eeSmrg ScrPtr *old; 3808dd3e0eeSmrg 3818dd3e0eeSmrg old = scrList; 3828dd3e0eeSmrg scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1)); 3838dd3e0eeSmrg if (!scrList) { 3848dd3e0eeSmrg scrList = old; 3858dd3e0eeSmrg return NULL; 3868dd3e0eeSmrg } 3878dd3e0eeSmrg scrList[numScrs] = malloc(sizeof(ScrRec)); 3888dd3e0eeSmrg if (!scrList[numScrs]) 3898dd3e0eeSmrg return NULL; 3908dd3e0eeSmrg return scrList[numScrs++]; 3918dd3e0eeSmrg} 3928dd3e0eeSmrg 3938dd3e0eeSmrgstatic MapPtr 3948dd3e0eeSmrgFindMap(unsigned long address, unsigned long size) 3958dd3e0eeSmrg{ 3968dd3e0eeSmrg int i; 3978dd3e0eeSmrg 3988dd3e0eeSmrg for (i = 0; i < numMaps; i++) { 3998dd3e0eeSmrg if (mapList[i]->physaddr == address && 4008dd3e0eeSmrg mapList[i]->size == size) 4018dd3e0eeSmrg return mapList[i]; 4028dd3e0eeSmrg } 4038dd3e0eeSmrg return NULL; 4048dd3e0eeSmrg} 4058dd3e0eeSmrg 4068dd3e0eeSmrgstatic ScrPtr 4078dd3e0eeSmrgFindScr(Display *display, int screen) 4088dd3e0eeSmrg{ 4098dd3e0eeSmrg int i; 4108dd3e0eeSmrg 4118dd3e0eeSmrg for (i = 0; i < numScrs; i++) { 4128dd3e0eeSmrg if (scrList[i]->display == display && 4138dd3e0eeSmrg scrList[i]->screen == screen) 4148dd3e0eeSmrg return scrList[i]; 4158dd3e0eeSmrg } 4168dd3e0eeSmrg return NULL; 4178dd3e0eeSmrg} 4188dd3e0eeSmrg 4198dd3e0eeSmrgstatic void * 4208dd3e0eeSmrgMapPhysAddress(unsigned long address, unsigned long size) 4218dd3e0eeSmrg{ 4228dd3e0eeSmrg unsigned long offset, delta; 4238dd3e0eeSmrg int pagesize = -1; 4248dd3e0eeSmrg void *vaddr; 4258dd3e0eeSmrg MapPtr mp; 4268dd3e0eeSmrg 4278dd3e0eeSmrg if ((mp = FindMap(address, size))) { 4288dd3e0eeSmrg mp->refcount++; 4298dd3e0eeSmrg return (void *)((unsigned long)mp->vaddr + mp->delta); 4308dd3e0eeSmrg } 4318dd3e0eeSmrg 4328dd3e0eeSmrg#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE) 4338dd3e0eeSmrg pagesize = sysconf(_SC_PAGESIZE); 4348dd3e0eeSmrg#endif 4358dd3e0eeSmrg#ifdef _SC_PAGE_SIZE 4368dd3e0eeSmrg if (pagesize == -1) 4378dd3e0eeSmrg pagesize = sysconf(_SC_PAGE_SIZE); 4388dd3e0eeSmrg#endif 4398dd3e0eeSmrg#ifdef HAS_GETPAGESIZE 4408dd3e0eeSmrg if (pagesize == -1) 4418dd3e0eeSmrg pagesize = getpagesize(); 4428dd3e0eeSmrg#endif 4438dd3e0eeSmrg#ifdef PAGE_SIZE 4448dd3e0eeSmrg if (pagesize == -1) 4458dd3e0eeSmrg pagesize = PAGE_SIZE; 4468dd3e0eeSmrg#endif 4478dd3e0eeSmrg if (pagesize == -1) 4488dd3e0eeSmrg pagesize = 4096; 4498dd3e0eeSmrg 4508dd3e0eeSmrg delta = address % pagesize; 4518dd3e0eeSmrg offset = address - delta; 4528dd3e0eeSmrg#ifndef MAP_FILE 4538dd3e0eeSmrg#define MAP_FILE 0 4548dd3e0eeSmrg#endif 4558dd3e0eeSmrg if (mapFd < 0) { 4568dd3e0eeSmrg if ((mapFd = open(DEV_MEM, O_RDWR)) < 0) 4578dd3e0eeSmrg return NULL; 4588dd3e0eeSmrg } 4598dd3e0eeSmrg vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE, 460565394e5Smrg MAP_FILE | MAP_SHARED, mapFd, (off_t)offset); 4618dd3e0eeSmrg if (vaddr == (void *)-1) 4628dd3e0eeSmrg return NULL; 4638dd3e0eeSmrg 4648dd3e0eeSmrg if (!vaddr) { 4658dd3e0eeSmrg if (!(mp = AddMap())) 4668dd3e0eeSmrg return NULL; 4678dd3e0eeSmrg mp->physaddr = address; 4688dd3e0eeSmrg mp->size = size; 4698dd3e0eeSmrg mp->delta = delta; 4708dd3e0eeSmrg mp->vaddr = vaddr; 4718dd3e0eeSmrg mp->refcount = 1; 4728dd3e0eeSmrg } 4738dd3e0eeSmrg return (void *)((unsigned long)vaddr + delta); 4748dd3e0eeSmrg} 4758dd3e0eeSmrg 4768dd3e0eeSmrg/* 4778dd3e0eeSmrg * Still need to find a clean way of detecting the death of a DGA app 4788dd3e0eeSmrg * and returning things to normal - Jon 4798dd3e0eeSmrg * This is here to help debugging without rebooting... Also C-A-BS 4808dd3e0eeSmrg * should restore text mode. 4818dd3e0eeSmrg */ 4828dd3e0eeSmrg 4838dd3e0eeSmrgint 4848dd3e0eeSmrgXF86DGAForkApp(int screen) 4858dd3e0eeSmrg{ 4868dd3e0eeSmrg pid_t pid; 4878dd3e0eeSmrg int status; 4888dd3e0eeSmrg int i; 4898dd3e0eeSmrg 4908dd3e0eeSmrg /* fork the app, parent hangs around to clean up */ 4918dd3e0eeSmrg if ((pid = fork()) > 0) { 4928dd3e0eeSmrg ScrPtr sp; 4938dd3e0eeSmrg 4948dd3e0eeSmrg waitpid(pid, &status, 0); 4958dd3e0eeSmrg for (i = 0; i < numScrs; i++) { 4968dd3e0eeSmrg sp = scrList[i]; 4978dd3e0eeSmrg XF86DGADirectVideoLL(sp->display, sp->screen, 0); 4988dd3e0eeSmrg XSync(sp->display, False); 4998dd3e0eeSmrg } 5008dd3e0eeSmrg if (WIFEXITED(status)) 5018dd3e0eeSmrg _exit(0); 5028dd3e0eeSmrg else 5038dd3e0eeSmrg _exit(-1); 5048dd3e0eeSmrg } 5058dd3e0eeSmrg return pid; 5068dd3e0eeSmrg} 5078dd3e0eeSmrg 5088dd3e0eeSmrg 5098dd3e0eeSmrgBool 5108dd3e0eeSmrgXF86DGADirectVideo( 5118dd3e0eeSmrg Display *dis, 5128dd3e0eeSmrg int screen, 5138dd3e0eeSmrg int enable 5148dd3e0eeSmrg){ 5158dd3e0eeSmrg ScrPtr sp; 5168dd3e0eeSmrg MapPtr mp = NULL; 5178dd3e0eeSmrg 5188dd3e0eeSmrg if ((sp = FindScr(dis, screen))) 5198dd3e0eeSmrg mp = sp->map; 5208dd3e0eeSmrg 5218dd3e0eeSmrg if (enable & XF86DGADirectGraphics) { 5228dd3e0eeSmrg if (mp && mp->vaddr) 5238dd3e0eeSmrg mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE); 5248dd3e0eeSmrg } else { 5258dd3e0eeSmrg if (mp && mp->vaddr) 5268dd3e0eeSmrg mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ); 5278dd3e0eeSmrg } 5288dd3e0eeSmrg 5298dd3e0eeSmrg XF86DGADirectVideoLL(dis, screen, enable); 5308dd3e0eeSmrg return 1; 5318dd3e0eeSmrg} 5328dd3e0eeSmrg 5338dd3e0eeSmrg 5348dd3e0eeSmrgstatic void 535da01b833Schristos#ifdef __NetBSD__ 536da01b833Schristos__attribute__ ((__destructor__)) 537da01b833Schristos#endif 538188cbdcfStsutsuiXF86cleanup_atexit(void) 5398dd3e0eeSmrg{ 5408dd3e0eeSmrg ScrPtr sp; 5418dd3e0eeSmrg int i; 5428dd3e0eeSmrg static char beenhere = 0; 5438dd3e0eeSmrg 5448dd3e0eeSmrg if (beenhere) 545188cbdcfStsutsui return; 5468dd3e0eeSmrg beenhere = 1; 5478dd3e0eeSmrg 5488dd3e0eeSmrg for (i = 0; i < numScrs; i++) { 5498dd3e0eeSmrg sp = scrList[i]; 5508dd3e0eeSmrg XF86DGADirectVideo(sp->display, sp->screen, 0); 5518dd3e0eeSmrg XSync(sp->display, False); 5528dd3e0eeSmrg } 553188cbdcfStsutsui} 554188cbdcfStsutsui 555188cbdcfStsutsuistatic void 556188cbdcfStsutsuiXF86cleanup(int sig) 557188cbdcfStsutsui{ 558188cbdcfStsutsui /* XXX FIXME XF86cleanup_atexit() is not async-signal-safe */ 559188cbdcfStsutsui XF86cleanup_atexit(); 560188cbdcfStsutsui 5618dd3e0eeSmrg _exit(3); 5628dd3e0eeSmrg} 5638dd3e0eeSmrg 5648dd3e0eeSmrgBool 5658dd3e0eeSmrgXF86DGAGetVideo( 5668dd3e0eeSmrg Display *dis, 5678dd3e0eeSmrg int screen, 5688dd3e0eeSmrg char **addr, 569d5a688bcSmrg int *width, 570d5a688bcSmrg int *bank, 5718dd3e0eeSmrg int *ram 5728dd3e0eeSmrg){ 5738dd3e0eeSmrg unsigned int offset; 5748dd3e0eeSmrg static int beenHere = 0; 5758dd3e0eeSmrg ScrPtr sp; 5768dd3e0eeSmrg MapPtr mp; 5778dd3e0eeSmrg 5788dd3e0eeSmrg if (!(sp = FindScr(dis, screen))) { 5798dd3e0eeSmrg if (!(sp = AddScr())) { 5808dd3e0eeSmrg fprintf(stderr, "XF86DGAGetVideo: malloc failure\n"); 5818dd3e0eeSmrg exit(-2); 5828dd3e0eeSmrg } 5838dd3e0eeSmrg sp->display = dis; 5848dd3e0eeSmrg sp->screen = screen; 5858dd3e0eeSmrg sp->map = NULL; 5868dd3e0eeSmrg } 5878dd3e0eeSmrg 5888dd3e0eeSmrg XF86DGAGetVideoLL(dis, screen , &offset, width, bank, ram); 5898dd3e0eeSmrg 5908dd3e0eeSmrg *addr = MapPhysAddress(offset, *bank); 5918dd3e0eeSmrg if (*addr == NULL) { 5928dd3e0eeSmrg fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n", 5938dd3e0eeSmrg strerror(errno)); 5948dd3e0eeSmrg exit(-2); 5958dd3e0eeSmrg } 5968dd3e0eeSmrg 5978dd3e0eeSmrg if ((mp = FindMap(offset, *bank))) 5988dd3e0eeSmrg sp->map = mp; 5998dd3e0eeSmrg 6008dd3e0eeSmrg if (!beenHere) { 6018dd3e0eeSmrg beenHere = 1; 602da01b833Schristos#ifndef __NetBSD__ 603188cbdcfStsutsui atexit((void(*)(void))XF86cleanup_atexit); 604da01b833Schristos#endif 6058dd3e0eeSmrg /* one shot XF86cleanup attempts */ 6068dd3e0eeSmrg signal(SIGSEGV, XF86cleanup); 6078dd3e0eeSmrg#ifdef SIGBUS 6088dd3e0eeSmrg signal(SIGBUS, XF86cleanup); 6098dd3e0eeSmrg#endif 6108dd3e0eeSmrg signal(SIGHUP, XF86cleanup); 611d5a688bcSmrg signal(SIGFPE, XF86cleanup); 6128dd3e0eeSmrg } 6138dd3e0eeSmrg 6148dd3e0eeSmrg return 1; 6158dd3e0eeSmrg} 616