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

📄 nvidia.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Portions of this file derived from work with the following copyright */ /***************************************************************************\|*                                                                           *||*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *||*                                                                           *||*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *||*     international laws.  Users and possessors of this source code are     *||*     hereby granted a nonexclusive,  royalty-free copyright license to     *||*     use this code in individual and commercial software.                  *||*                                                                           *||*     Any use of this source code must include,  in the user documenta-     *||*     tion and  internal comments to the code,  notices to the end user     *||*     as follows:                                                           *||*                                                                           *||*       Copyright 2003 NVIDIA, Corporation.  All rights reserved.           *||*                                                                           *||*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *||*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *||*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *||*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *||*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *||*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *||*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *||*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *||*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *||*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *||*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *||*                                                                           *||*     U.S. Government  End  Users.   This source code  is a "commercial     *||*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *||*     consisting  of "commercial  computer  software"  and  "commercial     *||*     computer  software  documentation,"  as such  terms  are  used in     *||*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *||*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *||*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *||*     all U.S. Government End Users  acquire the source code  with only     *||*     those rights set forth herein.                                        *||*                                                                           *| \***************************************************************************/#include <u.h>#include <libc.h>#include <bio.h>#include "pci.h"#include "vga.h"typedef struct Nvidia	Nvidia;struct Nvidia {	Pcidev*	pci;	int	did;	/* not always == pci->did */	int	arch;	int	crystalfreq;	ulong*	mmio;	ulong*	pfb;			/* mmio pointers */	ulong*	pramdac;	ulong*	pextdev;	ulong*	pmc;	ulong*	ptimer;	ulong*	pfifo;	ulong*	pramin;	ulong*	pgraph;	ulong*	fifo;	ulong*	pcrtc;	ushort	repaint0;	ushort	repaint1;	ushort	screen;	ushort	pixel;	ushort	horiz;	ushort	cursor0;	ushort	cursor1;	ushort	cursor2;	ushort	interlace;	ushort	extra;	ushort	crtcowner;	ushort	timingH;	ushort	timingV;	ulong	vpll;	ulong	vpllB;	ulong	vpll2;	ulong	vpll2B;	ulong	pllsel;	ulong	general;	ulong	scale;	ulong	config;	ulong	head;	ulong	head2;	ulong	cursorconfig;	ulong	dither;	ulong	crtcsync;	ulong	displayV;	int	islcd;	int	fpwidth;	int	fpheight;	int	twoheads;	int	twostagepll;	int	crtcnumber;};static voidgetpcixdid(Nvidia* nv){	ulong	pcicmd, pciid;	ushort	vid, did;	pcicmd = pcicfgr32(nv->pci, PciPCR);	pcicfgw32(nv->pci, PciPCR, pcicmd | 0x02);	pciid = nv->mmio[0x1800/4];	pcicfgw32(nv->pci, PciPCR, pcicmd);	vid = pciid >> 16;	did = (pciid & 0xFFFF);	if (did == 0x10DE)		did = vid;	else if (vid == 0xDE10)		did = ((pciid << 8) & 0xFF00) | ((pciid >> 8) & 0x00FF);	nv->did = did;}static voidsnarf(Vga* vga, Ctlr* ctlr){	Nvidia *nv;	Pcidev *p;	ulong *mmio, tmp;	int implementation;	if(vga->private == nil){		vga->private = alloc(sizeof(Nvidia));		nv = vga->private;		p = nil;		while((p = pcimatch(p, 0x10DE, 0)) != nil){			if((p->ccru>>8) == 3)				break;		}		if(p == nil)			error("%s: not found\n", ctlr->name);		vgactlw("type", ctlr->name);		mmio = segattach(0, "nvidiammio", 0, p->mem[0].size);		if(mmio == (void*)-1)			error("%s: segattach nvidiammio, size %d: %r\n",				ctlr->name, p->mem[0].size);		nv->pci = p;		nv->mmio = mmio;		nv->pfb = mmio+0x00100000/4;		nv->pramdac = mmio+0x00680000/4;		nv->pextdev = mmio+0x00101000/4;		nv->pmc = mmio+0x00000000/4;		nv->ptimer = mmio+0x00009000/4;		nv->pfifo = mmio+0x00002000/4;		nv->pramin = mmio+0x00710000/4;		nv->pgraph = mmio+0x00400000/4;		nv->fifo = mmio+0x00800000/4;		nv->pcrtc= mmio+0x00600000/4;		nv->did = p->did;		if ((nv->did & 0xfff0) == 0x00f0)			getpcixdid(nv);		switch (nv->did & 0x0ff0) {		case 0x0020:		case 0x00A0:			nv->arch = 4;			break;		case 0x0100:	/* GeForce 256 */		case 0x0110:	/* GeForce2 MX */		case 0x0150:	/* GeForce2 */		case 0x0170:	/* GeForce4 MX */		case 0x0180:	/* GeForce4 MX (8x AGP) */		case 0x01A0:	/* nForce */		case 0x01F0:	/* nForce2 */			nv->arch = 10;			break;		case 0x0200:	/* GeForce3 */		case 0x0250:	/* GeForce4 Ti */		case 0x0280:	/* GeForce4 Ti (8x AGP) */			nv->arch = 20;			break;		case 0x0300:	/* GeForceFX 5800 */		case 0x0310:	/* GeForceFX 5600 */		case 0x0320:	/* GeForceFX 5200 */		case 0x0330:	/* GeForceFX 5900 */		case 0x0340:	/* GeForceFX 5700 */			nv->arch = 30;			break;		case 0x0040:		case 0x00C0:		case 0x0120:		case 0x0130:		case 0x0140:	/* GeForce 6600 */		case 0x0160:		case 0x01D0:		case 0x0090:		case 0x0210:			nv->arch = 40;			break;		default:			error("%s: DID %4.4uX unsupported\n", ctlr->name, nv->did);			break;		}	}	nv = vga->private;	implementation = nv->did & 0x0ff0;	/*	 * Unlock	 */	vgaxo(Crtx, 0x1F, 0x57);	if (nv->pextdev[0x00000000] & 0x00000040)		nv->crystalfreq = RefFreq;	else		nv->crystalfreq = 13500000;	if ((implementation == 0x0170) ||	    (implementation == 0x0180) ||	    (implementation == 0x01F0) ||	    (implementation >= 0x0250))		if(nv->pextdev[0x00000000] & (1 << 22))			nv->crystalfreq = 27000000;	nv->twoheads = (nv->arch >= 10) &&			(implementation != 0x0100) &&			(implementation != 0x0150) &&			(implementation != 0x01A0) &&			(implementation != 0x0200);	nv->twostagepll = (implementation == 0x0310) ||				(implementation == 0x0340) ||				(nv->arch >= 40);	if (nv->twoheads && (implementation != 0x0110))		if(nv->pextdev[0x00000000] & (1 << 22))			nv->crystalfreq = 27000000;	/* laptop chips */	switch (nv->did & 0xffff) {	case 0x0112:	case 0x0174:	case 0x0175:	case 0x0176:	case 0x0177:	case 0x0179:	case 0x017C:	case 0x017D:	case 0x0186:	case 0x0187:	case 0x0189:	/* 0x0189 not in nwaples's driver */	case 0x018D:	case 0x0286:	case 0x028C:	case 0x0316:	case 0x0317:	case 0x031A:	case 0x031B:	case 0x031C:	case 0x031D:	case 0x031E:	case 0x031F:	case 0x0324:	case 0x0325:	case 0x0328:	case 0x0329:	case 0x032C:	case 0x032D:	case 0x0347:	case 0x0348:	case 0x0349:	case 0x034B:	case 0x034C:	case 0x0160:	case 0x0166:	case 0x00C8:	case 0x00CC:	case 0x0144:	case 0x0146:	case 0x0148:		nv->islcd = 1;		break;	default:		break;	}	if (nv->arch == 4) {		tmp = nv->pfb[0x00000000];		if (tmp & 0x0100) {			vga->vmz = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;		} else {			tmp &= 0x03;			if (tmp)				vga->vmz = (1024*1024*2) << tmp;			else				vga->vmz = 1024*1024*32;		}	} else if (implementation == 0x01a0) {		p = nil;		tmp = MKBUS(BusPCI, 0, 0, 1);		while((p = pcimatch(p, 0x10DE, 0)) != nil){			if(p->tbdf == tmp)				break;		}		tmp = pcicfgr32(p, 0x7C);		vga->vmz = (((tmp >> 6) & 31) + 1) * 1024 * 1024;	} else if (implementation == 0x01f0) {		p = nil;		tmp = MKBUS(BusPCI, 0, 0, 1);		while((p = pcimatch(p, 0x10DE, 0)) != nil){			if(p->tbdf == tmp)				break;		}		tmp = pcicfgr32(p, 0x84);		vga->vmz = (((tmp >> 4) & 127) + 1) * 1024 * 1024;	} else {		tmp = (nv->pfb[0x0000020C/4] >> 20) & 0xFFF;		if (tmp == 0)			tmp = 16;		vga->vmz = 1024*1024*tmp;	}	nv->repaint0 = vgaxi(Crtx, 0x19);	nv->repaint1 = vgaxi(Crtx, 0x1A);	nv->screen = vgaxi(Crtx, 0x25);	nv->pixel = vgaxi(Crtx, 0x28);	nv->horiz = vgaxi(Crtx, 0x2D);	nv->cursor0 = vgaxi(Crtx, 0x30);	nv->cursor1 = vgaxi(Crtx, 0x31);	nv->cursor2 = vgaxi(Crtx, 0x2F);	nv->interlace = vgaxi(Crtx, 0x39);	nv->vpll = nv->pramdac[0x00000508/4];	if (nv->twoheads)		nv->vpll2 = nv->pramdac[0x00000520/4];	if (nv->twostagepll) {		nv->vpllB = nv->pramdac[0x00000578/4];		nv->vpll2B = nv->pramdac[0x0000057C/4];	}	nv->pllsel = nv->pramdac[0x0000050C/4];	nv->general = nv->pramdac[0x00000600/4];	nv->scale = nv->pramdac[0x00000848/4];	nv->config = nv->pfb[0x00000200/4];	if (nv->pixel & 0x80){		nv->islcd = 1;	}	if (nv->arch >= 10) {		if (nv->twoheads) {			nv->head = nv->pcrtc[0x0860/4];			nv->head2 = nv->pcrtc[0x2860/4];			nv->crtcowner = vgaxi(Crtx, 0x44);		}		nv->extra = vgaxi(Crtx, 0x41);		nv->cursorconfig = nv->pcrtc[0x0810/4];		if (implementation == 0x0110)			nv->dither = nv->pramdac[0x0528/4];		else if (nv->twoheads)			nv->dither = nv->pramdac[0x083C/4];	}	/*	 * DFP.	 */	if (nv->islcd) {		nv->fpwidth = nv->pramdac[0x0820/4] + 1;		nv->fpheight = nv->pramdac[0x0800/4] + 1;		nv->crtcsync = nv->pramdac[0x0828/4];	}	nv->crtcnumber = 0;	ctlr->flag |= Fsnarf;}static voidoptions(Vga*, Ctlr* ctlr){	ctlr->flag |= Hlinear|Foptions;}static voidclock(Vga* vga, Ctlr* ctlr){	int m, n, p, f, d;	Nvidia *nv;	double trouble;	int fmin, mmin, nmin, crystalfreq;	nv = vga->private;	if(vga->f[0] == 0)		vga->f[0] = vga->mode->frequency;	vga->d[0] = vga->f[0]+1;	vga->n[1] = 255;	if (nv->twostagepll) {		vga->p[1] = 6;		vga->m[1] = 13;		vga->f[1] = 400000000 << 2;		crystalfreq = nv->crystalfreq << 2;		fmin = 100000000 << 2;		mmin = 1;

⌨️ 快捷键说明

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