⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 via_dri.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_dri.c,v 1.4 2003/09/24 02:43:30 dawes Exp $ *//* * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h> #include "driver.h"#include "drm.h"#include "imports.h"#include "dri_util.h"#include "via_context.h"#include "via_dri.h"#include "via_driver.h"#include "xf86drm.h"static void VIAEnableMMIO(DRIDriverContext * ctx);static void VIADisableMMIO(DRIDriverContext * ctx);static void VIADisableExtendedFIFO(DRIDriverContext *ctx);static void VIAEnableExtendedFIFO(DRIDriverContext *ctx);static void VIAInitialize2DEngine(DRIDriverContext *ctx);static void VIAInitialize3DEngine(DRIDriverContext *ctx);static int VIADRIScreenInit(DRIDriverContext * ctx);static void VIADRICloseScreen(DRIDriverContext * ctx);static int VIADRIFinishScreenInit(DRIDriverContext * ctx);/* _SOLO : missing macros normally defined by X code */#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)#define MMIO_IN8(base, addr) ((*(((volatile u_int8_t*)base)+(addr)))+0)#define MMIO_OUT8(base, addr, val) ((*(((volatile u_int8_t*)base)+(addr)))=((u_int8_t)val))#define MMIO_OUT16(base, addr, val) ((*(volatile u_int16_t*)(((u_int8_t*)base)+(addr)))=((u_int16_t)val))#define VIDEO	0 #define AGP		1#define AGP_PAGE_SIZE 4096#define AGP_PAGES 8192#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)#define AGP_CMDBUF_PAGES 512#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)static char VIAKernelDriverName[] = "via";static char VIAClientDriverName[] = "unichrome";static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia);static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia);static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia);static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia);static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia);static void VIADRIIrqInit( DRIDriverContext *ctx ){    VIAPtr pVia = VIAPTR(ctx);    VIADRIPtr pVIADRI = pVia->devPrivate;    pVIADRI->irqEnabled = drmGetInterruptFromBusID(pVia->drmFD,					   ctx->pciBus,					   ctx->pciDevice,					   ctx->pciFunc);    if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) {	xf86DrvMsg(pScreen->myNum, X_WARNING,		   "[drm] Failure adding irq handler. "		   "Falling back to irq-free operation.\n");	pVIADRI->irqEnabled = 0;    }    if (pVIADRI->irqEnabled)	xf86DrvMsg(pScreen->myNum, X_INFO,		   "[drm] Irq handler installed, using IRQ %d.\n",		   pVIADRI->irqEnabled);}static void VIADRIIrqExit( DRIDriverContext *ctx ) {    VIAPtr pVia = VIAPTR(ctx);    VIADRIPtr pVIADRI = pVia->devPrivate;    if (pVIADRI->irqEnabled) {	if (drmCtlUninstHandler(pVia->drmFD)) {	    xf86DrvMsg(pScreen-myNum, X_INFO,"[drm] Irq handler uninstalled.\n");	} else {	    xf86DrvMsg(pScreen->myNum, X_ERROR,		       "[drm] Could not uninstall irq handler.\n");	}    }}	    static void VIADRIRingBufferCleanup(DRIDriverContext *ctx){    VIAPtr pVia = VIAPTR(ctx);    VIADRIPtr pVIADRI = pVia->devPrivate;    drm_via_dma_init_t ringBufInit;    if (pVIADRI->ringBufActive) {	xf86DrvMsg(pScreen->myNum, X_INFO, 		   "[drm] Cleaning up DMA ring-buffer.\n");	ringBufInit.func = VIA_CLEANUP_DMA;	if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,			    sizeof(ringBufInit))) {	    xf86DrvMsg(pScreen->myNum, X_WARNING, 		       "[drm] Failed to clean up DMA ring-buffer: %d\n", errno);	}	pVIADRI->ringBufActive = 0;    }}static int VIADRIRingBufferInit(DRIDriverContext *ctx){    VIAPtr pVia = VIAPTR(ctx);    VIADRIPtr pVIADRI = pVia->devPrivate;    drm_via_dma_init_t ringBufInit;    drmVersionPtr drmVer;    pVIADRI->ringBufActive = 0;    if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {	return GL_FALSE;    }    if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) {	return GL_FALSE;    }     /*     * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.     */    switch (pVia->ChipId) {    case PCI_CHIP_VT3259:    	ringBufInit.reg_pause_addr = 0x40c;	break;    default:    	ringBufInit.reg_pause_addr = 0x418;	break;    }       ringBufInit.offset = pVia->agpSize;    ringBufInit.size = AGP_CMDBUF_SIZE;    ringBufInit.func = VIA_INIT_DMA;    if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,			sizeof(ringBufInit))) {	xf86DrvMsg(pScreen->myNum, X_ERROR, 		   "[drm] Failed to initialize DMA ring-buffer: %d\n", errno);	return GL_FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO, 	       "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n",	       ringBufInit.size, ringBufInit.offset);       pVIADRI->ringBufActive = 1;    return GL_TRUE;}	    static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia){    unsigned long  agp_phys;    drmAddress agpaddr;    VIADRIPtr pVIADRI;    pVIADRI = pVia->devPrivate;    pVia->agpSize = 0;    if (drmAgpAcquire(pVia->drmFD) < 0) {        xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);        return GL_FALSE;    }    if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {         xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");        return GL_FALSE;    }        xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");    if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) {        xf86DrvMsg(pScreen->myNum, X_ERROR,                 "[drm] drmAgpAlloc failed\n");        drmAgpRelease(pVia->drmFD);        return GL_FALSE;    }       if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {        xf86DrvMsg(pScreen->myNum, X_ERROR,                 "[drm] drmAgpBind failed\n");        drmAgpFree(pVia->drmFD, pVia->agpHandle);        drmAgpRelease(pVia->drmFD);        return GL_FALSE;    }    /*     * Place the ring-buffer last in the AGP region, and restrict the     * public map not to include the buffer for security reasons.     */    pVia->agpSize = AGP_SIZE - AGP_CMDBUF_SIZE;    pVia->agpAddr = drmAgpBase(pVia->drmFD);    xf86DrvMsg(pScreen->myNum, X_INFO,                 "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);		     pVIADRI->agp.size = pVia->agpSize;    if (drmAddMap(pVia->drmFD, (drm_handle_t)0,                 pVIADRI->agp.size, DRM_AGP, 0,                  &pVIADRI->agp.handle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,	    "[drm] Failed to map public agp area\n");        pVIADRI->agp.size = 0;        return GL_FALSE;    }      /* Map AGP from kernel to Xserver - Not really needed */    drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size, &agpaddr);    xf86DrvMsg(pScreen->myNum, X_INFO,                 "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);    xf86DrvMsg(pScreen->myNum, X_INFO,                 "[drm] agpSize = 0x%08lx\n", pVia->agpSize);    xf86DrvMsg(pScreen->myNum, X_INFO,                 "[drm] agp physical addr = 0x%08lx\n", agp_phys);    {	drm_via_agp_t agp;	agp.offset = 0;	agp.size = AGP_SIZE-AGP_CMDBUF_SIZE;	if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,			    sizeof(drm_via_agp_t)) < 0) {	    drmUnmap(&agpaddr,pVia->agpSize);	    drmRmMap(pVia->drmFD,pVIADRI->agp.handle);	    drmAgpUnbind(pVia->drmFD, pVia->agpHandle);	    drmAgpFree(pVia->drmFD, pVia->agpHandle);	    drmAgpRelease(pVia->drmFD);	    return GL_FALSE;	}    }    return GL_TRUE;}static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia){       int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;    int FBOffset = pVia->FBFreeStart;     VIADRIPtr pVIADRI = pVia->devPrivate;    pVIADRI->fbOffset = FBOffset;    pVIADRI->fbSize = pVia->videoRambytes;    {	drm_via_fb_t fb;	fb.offset = FBOffset;	fb.size = FBSize;		if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,			    sizeof(drm_via_fb_t)) < 0) {	    xf86DrvMsg(pScreen->myNum, X_ERROR,		       "[drm] failed to init frame buffer area\n");	    return GL_FALSE;	} else {	    xf86DrvMsg(pScreen->myNum, X_INFO,		       "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "		       "FBSize= 0x%08x\n",		       pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);	    return GL_TRUE;		}       }}static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia){    return GL_TRUE;	}static int VIADRIScreenInit(DRIDriverContext * ctx){    VIAPtr pVia = VIAPTR(ctx);    VIADRIPtr pVIADRI;    int err;#if 0    ctx->shared.SAREASize = ((sizeof(drm_sarea_t) + 0xfff) & 0x1000);#else    if (sizeof(drm_sarea_t)+sizeof(drm_via_sarea_t) > SAREA_MAX) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			"Data does not fit in SAREA\n");	return GL_FALSE;    }    ctx->shared.SAREASize = SAREA_MAX;#endif    ctx->drmFD = drmOpen(VIAKernelDriverName, NULL);    if (ctx->drmFD < 0) {        fprintf(stderr, "[drm] drmOpen failed\n");        return 0;    }    pVia->drmFD = ctx->drmFD;    err = drmSetBusid(ctx->drmFD, ctx->pciBusID);    if (err < 0) {        fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",                ctx->drmFD, ctx->pciBusID, strerror(-err));        return 0;    }    err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM,                  DRM_CONTAINS_LOCK, &ctx->shared.hSAREA);    if (err < 0) {        fprintf(stderr, "[drm] drmAddMap failed\n");        return 0;    }    fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",            ctx->shared.SAREASize, ctx->shared.hSAREA);    if (drmMap(ctx->drmFD,               ctx->shared.hSAREA,               ctx->shared.SAREASize,               (drmAddressPtr)(&ctx->pSAREA)) < 0)    {        fprintf(stderr, "[drm] drmMap failed\n");        return 0;    }    memset(ctx->pSAREA, 0, ctx->shared.SAREASize);    fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",            ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);    /* Need to AddMap the framebuffer and mmio regions here:     */    if (drmAddMap(ctx->drmFD,                  (drm_handle_t)ctx->FBStart,                  ctx->FBSize,                  DRM_FRAME_BUFFER,#ifndef _EMBEDDED                   0,#else                   DRM_READ_ONLY,#endif                   &ctx->shared.hFrameBuffer) < 0)    {        fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");        return 0;    }    fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",            ctx->shared.hFrameBuffer);    pVIADRI = (VIADRIPtr) CALLOC(sizeof(VIADRIRec));    if (!pVIADRI) {        drmClose(ctx->drmFD);        return GL_FALSE;    }    pVia->devPrivate = pVIADRI;    ctx->driverClientMsg = pVIADRI;    ctx->driverClientMsgSize = sizeof(*pVIADRI);    /* DRIScreenInit doesn't add all the common mappings.  Add additional mappings here. */    if (!VIADRIMapInit(ctx, pVia)) {	VIADRICloseScreen(ctx);	return GL_FALSE;    }    pVIADRI->regs.size = VIA_MMIO_REGSIZE;    pVIADRI->regs.handle = pVia->registerHandle;    xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",	pVIADRI->regs.handle);    if (drmMap(pVia->drmFD,               pVIADRI->regs.handle,               pVIADRI->regs.size,               (drmAddress *)&pVia->MapBase) != 0)    {        VIADRICloseScreen(ctx);        return GL_FALSE;    }    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );    VIAEnableMMIO(ctx);    /* Get video memory clock. */    VGAOUT8(0x3D4, 0x3D);    pVia->MemClk = (VGAIN8(0x3D5) & 0xF0) >> 4;    xf86DrvMsg(0, X_INFO, "[dri] MemClk (0x%x)\n", pVia->MemClk);    /* 3D rendering has noise if not enabled. */    VIAEnableExtendedFIFO(ctx);    VIAInitialize2DEngine(ctx);    /* Must disable MMIO or 3D won't work. */    VIADisableMMIO(ctx);    VIAInitialize3DEngine(ctx);    pVia->IsPCI = !VIADRIAgpInit(ctx, pVia);    if (pVia->IsPCI) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -