Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/vganvidia.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/vganvidia.c 2001/0404
## diff -e /dev/null /n/emeliedump/2001/0404/sys/src/9/pc/vganvidia.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"

#define	Image	IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"

enum {
	Pramin = 0x00710000,
	Pramdac = 0x00680000
};

enum {
	hwCurPos = Pramdac + 0x0300,
	hwCurImage = Pramin + (0x00010000 - 0x0800),
};

static ushort nvidiadid[] = {
	0x0020,		/* Riva TNT */
	0x0028,		/* Riva TNT2 */
	0x0029,		/* Riva TNT2 (Ultra)*/
	0x002C,		/* Riva TNT2 (Vanta) */
	0x002D,		/* Riva TNT2 M64 */
	0x00A0,		/* Riva TNT2 (Integrated) */
	0x0100,		/* GeForce 256 */
	0x0101,		/* GeForce DDR */
	0x0103,		/* Quadro */
	0x0110,		/* GeForce2 MX */
	0x0111,		/* GeForce2 MX DDR */
	0x0112,		/* GeForce 2 Go */
	0x0113,		/* Quadro 2 MXR */
	0x0150,		/* GeForce2 GTS */
	0x0151,		/* GeForce2 GTS (rev 1) */
	0x0152,		/* GeForce2 Ultra */
	0x0153,		/* Quadro 2 Pro */
	0,
};

static Pcidev*
nvidiapci(void)
{
	Pcidev *p;
	ushort *did;

	if((p = pcimatch(nil, 0x10DE, 0)) == nil)
		return nil;
	for(did = nvidiadid; *did; did++){
		if(*did == p->did)
			return p;
	}

	return nil;
}


static ulong
nvidialinear(VGAscr* scr, int* size, int* align)
{
	Pcidev *p;
	int oapsize, wasupamem;
	ulong aperture, oaperture;

	oaperture = scr->aperture;
	oapsize = scr->apsize;
	wasupamem = scr->isupamem;

	aperture = 0;
	if(p = nvidiapci()){
		aperture = p->mem[1].bar & ~0x0F;
		*size = p->mem[1].size;
	}

	if(wasupamem) {
		if(oaperture == aperture)
			return oaperture;
		upafree(oaperture, oapsize);
	}
	scr->isupamem = 0;

	aperture = upamalloc(aperture, *size, *align);
	if(aperture == 0){
		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
			aperture = oaperture;
			scr->isupamem = 1;
		}
		else
			scr->isupamem = 0;
	}
	else
		scr->isupamem = 1;

	return aperture;
}

static void
nvidiaenable(VGAscr* scr)
{
	Pcidev *p;
	Physseg seg;
	ulong aperture;
	int align, size;

	/*
	 * Only once, can't be disabled for now.
	 * scr->io holds the physical address of
	 * the MMIO registers.
	 */
	if(scr->io)
		return;
	p = nvidiapci();
	if(p == nil)
		return;

	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
	if (scr->io == 0)
		return;

	memset(&seg, 0, sizeof(seg));
	seg.attr = SG_PHYSICAL;
	seg.name = smalloc(NAMELEN);
	snprint(seg.name, NAMELEN, "nvidiammio");
	seg.pa = scr->io;
	seg.size = p->mem[0].size;
	addphysseg(&seg);

	size = p->mem[1].size;
	align = 0;
	aperture = nvidialinear(scr, &size, &align);
	if(aperture) {
		scr->aperture = aperture;
		scr->apsize = size;
		memset(&seg, 0, sizeof(seg));
		seg.attr = SG_PHYSICAL;
		seg.name = smalloc(NAMELEN);
		snprint(seg.name, NAMELEN, "nvidiascreen");
		seg.pa = aperture;
		seg.size = size;
		addphysseg(&seg);
	}
}

static void
nvidiacurdisable(VGAscr* scr)
{
	if(scr->io == 0)
		return;

	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
}

static void
nvidiacurload(VGAscr* scr, Cursor* curs)
{
	ulong*	p;
	int		i,j;
	ushort	c,s;
	ulong	tmp;

	if(scr->io == 0)
		return;

	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);

	p = KADDR(scr->io + hwCurImage);

	for (i=0; i<16; i++) {
		c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
		s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
		tmp = 0;
		for (j=0; j<16; j++) {
			if(s&0x8000)
				tmp |= 0x80000000;
			else if(c&0x8000)
				tmp |= 0xFFFF0000;
			if (j&0x1) {
				*p++ = tmp;
				tmp = 0;
			} else {
				tmp>>=16;
			}
			c<<=1;
			s<<=1;
		}
		for (j=0; j<8; j++)
			*p++ = 0;
	}
	for (i=0; i<256; i++)
		*p++ = 0;

	scr->offset = curs->offset;
	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);

	return;
}

static int
nvidiacurmove(VGAscr* scr, Point p)
{
	ulong*	cursorpos;

	if(scr->io == 0)
		return 1;

	cursorpos = KADDR(scr->io + hwCurPos);
	*cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);

	return 0;
}

static void
nvidiacurenable(VGAscr* scr)
{
	nvidiaenable(scr);
	if(scr->io == 0)
		return;

	vgaxo(Crtx, 0x1F, 0x57);

	nvidiacurload(scr, &arrow);
	nvidiacurmove(scr, ZP);

	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
}

VGAdev vganvidiadev = {
	"nvidia",

	nvidiaenable,
	nil,
	nil,
	nvidialinear,
};

VGAcur vganvidiacur = {
	"nvidiahwgc",

	nvidiacurenable,
	nvidiacurdisable,
	nvidiacurload,
	nvidiacurmove,
};
.
## diffname pc/vganvidia.c 2001/0824
## diff -e /n/emeliedump/2001/0404/sys/src/9/pc/vganvidia.c /n/emeliedump/2001/0824/sys/src/9/pc/vganvidia.c
238a
	nvidiadrawinit,
.
231a
enum {
	RopFifo = 0x00000000, 
	ClipFifo = 0x00002000,
	PattFifo = 0x00004000,
	BltFifo = 0x00008000,
	BitmapFifo = 0x0000A000,
};

enum {
	RopRop3 = RopFifo + 0x300,

	ClipTopLeft = ClipFifo + 0x300,
	ClipWidthHeight = ClipFifo + 0x304,

	PattShape = PattFifo + 0x0308,
	PattColor0 = PattFifo + 0x0310,
	PattColor1 = PattFifo + 0x0314,
	PattMonochrome0 = PattFifo + 0x0318,
	PattMonochrome1 = PattFifo + 0x031C,

	BltTopLeftSrc = BltFifo + 0x0300,
	BltTopLeftDst = BltFifo + 0x0304,
	BltWidthHeight = BltFifo + 0x0308,

	BitmapColor1A = BitmapFifo + 0x03FC,
	BitmapURect0TopLeft = BitmapFifo + 0x0400,
	BitmapURect0WidthHeight = BitmapFifo + 0x0404,
};

static void
waitforidle(VGAscr *scr)
{
	ulong*	pgraph;
	int x;

	pgraph = KADDR(scr->io + Pgraph);

	x = 0;
	while (pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
		;

	if(x >= 1000000)
		iprint("idle stat %d scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
}

static void
waitforfifo(VGAscr *scr, int fifo, int entries)
{
	ushort* fifofree;
	int x;

	x = 0;
	fifofree = KADDR(scr->io + Fifo + fifo + 0x10);

	while (((*fifofree >> 2) < entries) && x++ < 1000000)
		;

	if(x >= 1000000)
		iprint("fifo stat %d scrio %.8lux scr %p pc %luX\n", *fifofree, scr->io, scr, getcallerpc(&scr));
}

static int
nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
{
	ulong*	fifo;

	fifo = KADDR(scr->io + Fifo);

	waitforfifo(scr, BitmapFifo, 1);

	fifo[BitmapColor1A/4] = sval;

	waitforfifo(scr, BitmapFifo, 2);

	fifo[BitmapURect0TopLeft/4] = (r.min.x << 16) | r.min.y;
	fifo[BitmapURect0WidthHeight/4] = (Dx(r) << 16) | Dy(r);

	waitforidle(scr);

	return 1;
}

static int
nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
{
	ulong*	fifo;

	fifo = KADDR(scr->io + Fifo);

	waitforfifo(scr, BltFifo, 3);

	fifo[BltTopLeftSrc/4] = (sr.min.y << 16) | sr.min.x;
	fifo[BltTopLeftDst/4] = (r.min.y << 16) | r.min.x;
	fifo[BltWidthHeight/4] = (Dy(r) << 16) | Dx(r);

	waitforidle(scr);

	return 1;
}

void
nvidiablank(VGAscr*, int blank)
{
	uchar seq1, crtc1A;

	seq1 = vgaxi(Seqx, 1) & ~0x20;
	crtc1A = vgaxi(Crtx, 0x1A) & ~0xC0;

	if(blank) {
		seq1 |= 0x20;
		crtc1A |= 0xC0;
	}

	vgaxo(Seqx, 1, seq1);
	vgaxo(Crtx, 0x1A, crtc1A);
}

static void
nvidiadrawinit(VGAscr *scr)
{
	ulong*	fifo;

	fifo = KADDR(scr->io + Fifo);

	waitforfifo(scr, ClipFifo, 2);

	fifo[ClipTopLeft/4] = 0x0;
	fifo[ClipWidthHeight/4] = 0x80008000;

	waitforfifo(scr, PattFifo, 5);

	fifo[PattShape/4] = 0;
	fifo[PattColor0/4] = 0xffffffff;
	fifo[PattColor1/4] = 0xffffffff;
	fifo[PattMonochrome0/4] = 0xffffffff;
	fifo[PattMonochrome1/4] = 0xffffffff;

	waitforfifo(scr, RopFifo, 1);

	fifo[RopRop3/4] = 0xCC;

	waitforidle(scr);

	scr->blank = nvidiablank;
	scr->fill = nvidiahwfill;
	scr->scroll = nvidiahwscroll;
}

.
141,142c
		seg.name = "nvidiascreen";
.
127,128c
	seg.name = "nvidiammio";
.
17c
	Pramdac = 0x00680000,
	Fifo = 0x00800000,
	Pgraph = 0x00400000
.
## diffname pc/vganvidia.c 2001/0901
## diff -e /n/emeliedump/2001/0824/sys/src/9/pc/vganvidia.c /n/emeliedump/2001/0901/sys/src/9/pc/vganvidia.c
342c
//		crtc1A |= 0xC0;
		crtc1A |= 0x80;
.
274c
		iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
.
## diffname pc/vganvidia.c 2001/0908
## diff -e /n/emeliedump/2001/0901/sys/src/9/pc/vganvidia.c /n/emeliedump/2001/0908/sys/src/9/pc/vganvidia.c
140,145c
		addvgaseg("nvidiascreen", aperture, size);
.
127,133d
125a
	addvgaseg("nvidiammio", scr->io, p->mem[0].size);
.
108d
## diffname pc/vganvidia.c 2001/1015
## diff -e /n/emeliedump/2001/0908/sys/src/9/pc/vganvidia.c /n/emeliedump/2001/1015/sys/src/9/pc/vganvidia.c
364a
	hwblank = 1;
.
## diffname pc/vganvidia.c 2002/0409
## diff -e /n/emeliedump/2001/1015/sys/src/9/pc/vganvidia.c /n/emeliedump/2002/0409/sys/src/9/pc/vganvidia.c
44a
	0x0200,		/* GeForce3 */
.
## diffname pc/vganvidia.c 2002/0502
## diff -e /n/emeliedump/2002/0409/sys/src/9/pc/vganvidia.c /n/emeliedump/2002/0502/sys/src/9/pc/vganvidia.c
222,226c
	RopFifo 		= 0x00000000, 
	ClipFifo 		= 0x00002000,
	PattFifo 		= 0x00004000,
	BltFifo 		= 0x00008000,
	BitmapFifo 	= 0x0000A000,
.
45a
	0x0201,
	0x0202,
.
## diffname pc/vganvidia.c 2003/0326
## diff -e /n/emeliedump/2002/0502/sys/src/9/pc/vganvidia.c /n/emeliedump/2003/0326/sys/src/9/pc/vganvidia.c
331c
	if(blank){
.
277c
	while(((*fifofree >> 2) < entries) && x++ < 1000000)
.
261c
	while(pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
.
173c
			if (j&0x1){
.
168c
		for (j=0; j<16; j++){
.
164c
	for(i=0; i<16; i++) {
.
133c
	if(aperture){
.
126c
	if(scr->io == 0)
.
85c
	if(wasupamem){
.
67d
62,63d
57,60c
	p = nil;
	while((p = pcimatch(p, 0x10DE, 0)) != nil)
		if(p->did > 0x20 && p->ccrp == 3)	/* video card */
.
27,50c
/* Nvidia is good about backwards compatibility -- any did > 0x20 is fine */
.
## diffname pc/vganvidia.c 2003/0328
## diff -e /n/emeliedump/2003/0326/sys/src/9/pc/vganvidia.c /n/emeliedump/2003/0328/sys/src/9/pc/vganvidia.c
37a
	}
.
35,36c
	while((p = pcimatch(p, 0x10DE, 0)) != nil){
		if(p->did > 0x20 && p->ccrb == 3)	/* video card */
.
32d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].