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

📄 clgd546x.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "pci.h"#include "vga.h"/* * Laguna Visual Media Accelerators Family CL-GD546x. */typedef struct {	Pcidev*	pci;	uchar*	mmio;	int	mem;	int	format;			/* graphics and video format */	int	threshold;		/* display threshold */	int	tilectrl;		/* tiling control */	int	vsc;			/* vendor specific control */	int	control;		/* control */	int	tilectrl2D3D;		/* tiling control 2D3D */} Laguna;enum {	Format		= 0xC0,		/* graphics and video format */	Threshold	= 0xEA,		/* Display Threshold */	TileCtrl	= 0x2C4,	Vsc		= 0x3FC,	/* Vendor Specific Control (32-bits) */	Control		= 0x402,	/* 2D Control */	TileCtrl2D3D	= 0x407,	/* (8-bits) */};static intmmio8r(Laguna* laguna, int offset){	return *(laguna->mmio+offset) & 0xFF;}static voidmmio8w(Laguna* laguna, int offset, int data){	*(laguna->mmio+offset) = data;}static intmmio16r(Laguna* laguna, int offset){	return *((ushort*)(laguna->mmio+offset)) & 0xFFFF;}static voidmmio16w(Laguna* laguna, int offset, int data){	*((ushort*)(laguna->mmio+offset)) = data;}static intmmio32r(Laguna* laguna, int offset){	return *((ulong*)(laguna->mmio+offset));}static voidmmio32w(Laguna* laguna, int offset, int data){	*((ulong*)(laguna->mmio+offset)) = data;}static voidsnarf(Vga* vga, Ctlr* ctlr){	int f, i;	uchar *mmio;	Pcidev *p;	Laguna *laguna;	/*	 * Save all the registers, even though we'll only	 * change a handful.	 */	for(i = 0x06; i < 0x20; i++)		vga->sequencer[i] = vgaxi(Seqx, i);	for(i = 0x09; i < 0x0C; i++)		vga->graphics[i] = vgaxi(Grx, i);	for(i = 0x19; i < 0x20; i++)		vga->crt[i] = vgaxi(Crtx, i);	if(vga->private == nil){		vga->private = alloc(sizeof(Laguna));		if((p = pcimatch(0, 0x1013, 0)) == nil)			error("%s: not found\n", ctlr->name);		switch(p->did){		case 0xD0:			/* CL-GD5462 */			vga->f[1] = 170000000;			break;		case 0xD4:			/* CL-GD5464 */		case 0xD6:			/* CL-GD5465 */			vga->f[1] = 230000000;			break;		default:			error("%s: not found\n", ctlr->name);		}		if((f = open("#v/vgactl", OWRITE)) < 0)			error("%s: can't open vgactl\n", ctlr->name);		if(write(f, "type clgd546x", 13) != 13)			error("%s: can't set type\n", ctlr->name);		close(f);			mmio = segattach(0, "clgd546xmmio", 0, p->mem[1].size);		if(mmio == (void*)-1)			error("%s: can't attach mmio segment\n", ctlr->name);		laguna = vga->private;		laguna->pci = p;		laguna->mmio = mmio;	}	laguna = vga->private;	laguna->mem = (vga->sequencer[0x14] & 0x07)+1;	laguna->format = mmio16r(laguna, Format);	laguna->threshold = mmio16r(laguna, Threshold);	laguna->tilectrl = mmio16r(laguna, TileCtrl);	laguna->vsc = mmio32r(laguna, Vsc);	laguna->control = mmio16r(laguna, Control);	laguna->tilectrl2D3D = mmio8r(laguna, TileCtrl2D3D);	vga->vma = vga->vmz = laguna->pci->mem[0].size;	ctlr->flag |= Hlinear;	ctlr->flag |= Fsnarf;}static voidinit(Vga* vga, Ctlr* ctlr){	Mode *mode;	ushort x;	int format, interleave, fetches, nointerleave, notile, pagesize, tiles;	Laguna *laguna;	nointerleave = 1;	notile = 1;	pagesize = 0;	mode = vga->mode;	if(vga->f[0] == 0)		vga->f[0] = vga->mode->frequency;	if(vga->f[0] > vga->f[1])		error("%s: invalid pclk - %lud\n", ctlr->name, vga->f[0]);	if(mode->z > 8)		error("%s: depth %d not supported\n", ctlr->name, mode->z);	/*	 * VCLK3	 */	clgd54xxclock(vga, ctlr);	vga->misc |= 0x0C;	vga->sequencer[0x1E] = vga->n[0];	vga->sequencer[0x0E] = (vga->d[0]<<1)|vga->p[0];	vga->sequencer[0x07] = 0x00;	if(mode->z == 8)		vga->sequencer[0x07] |= 0x01;	vga->crt[0x14] = 0;	vga->crt[0x17] = 0xC3;	/*	 * Overflow bits.	 */	vga->crt[0x1A] = 0x00;	x = mode->ehb>>3;	if(x & 0x40)		vga->crt[0x1A] |= 0x10;	if(x & 0x80)		vga->crt[0x1A] |= 0x20;	if(vga->crt[0x16] & 0x100)		vga->crt[0x1A] |= 0x40;	if(vga->crt[0x16] & 0x200)		vga->crt[0x1A] |= 0x80;	vga->crt[0x1B] = 0x22;	if(vga->crt[0x13] & 0x100)		vga->crt[0x1B] |= 0x10;	vga->crt[0x1D] = 0x00;	if(vga->crt[0x13] & 0x200)		vga->crt[0x1D] |= 0x01;	vga->crt[0x1E] = 0x00;	if(vga->crt[0x10] & 0x400)		vga->crt[0x1E] |= 0x01;	if(vga->crt[0x15] & 0x400)		vga->crt[0x1E] |= 0x02;	if(vga->crt[0x12] & 0x400)		vga->crt[0x1E] |= 0x04;	if(vga->crt[0x06] & 0x400)		vga->crt[0x1E] |= 0x08;	if(vga->crt[0x04] & 0x100)		vga->crt[0x1E] |= 0x10;	if(vga->crt[0x02] & 0x100)		vga->crt[0x1E] |= 0x20;	if(vga->crt[0x01] & 0x100)		vga->crt[0x1E] |= 0x40;	if(vga->crt[0x00] & 0x100)		vga->crt[0x1E] |= 0x80;	vga->graphics[0x0B] = 0x00;	if(vga->vmz > 1024*1024)		vga->graphics[0x0B] |= 0x20;	if(mode->interlace == 'v'){		vga->crt[0x19] = vga->crt[0x00]/2;		vga->crt[0x1A] |= 0x01;	}	if(vga->linear && (ctlr->flag & Hlinear))		ctlr->flag |= Ulinear;	laguna = vga->private;	/*	 * Ignore wide tiles for now, this simplifies things.	 */	if(mode->x <= 640)		tiles = 5;	else if(mode->x <= 1024)		tiles = 8;	else if(mode->x <= 1280)		tiles = 10;	else if(mode->x <= 1664)		tiles = 13;	else if(mode->x <= 2048)		tiles = 16;	else if(mode->x <= 2560)		tiles = 20;	else if(mode->x <= 3228)		tiles = 26;	else		tiles = 32;	fetches = tiles;		/* -1? */	if(nointerleave)		interleave = 0;	else switch(laguna->mem){	default:		interleave = 0;		break;	case 2:		interleave = 1;		break;	case 4:	case 8:		interleave = 2;		break;	}	if(mode->z == 8)		format = 0;	else if(mode->z == 16)		format = (1<<12)|(2<<9);	else if(mode->z == 24)		format = (2<<12)|(2<<9);	else		format = (2<<12)|(2<<9);	//if(ctlr->flag & Ulinear)	//	laguna->vsc |= 0x10000000;	//else		laguna->vsc &= ~0x10000000;	laguna->format = format;	laguna->threshold = (interleave<<14)|(fetches<<8)|0x14;	laguna->tilectrl &= 0x3F;	laguna->tilectrl |= (interleave<<14)|(tiles<<8);	if(!notile)		laguna->tilectrl |= 0x80;	if(pagesize == 1)		laguna->tilectrl |= 0x10;	laguna->tilectrl2D3D = (interleave<<6)|tiles;	laguna->control = 0;	if(notile)		laguna->control |= 0x1000;	if(pagesize == 1)		laguna->control |= 0x0200;}static voidload(Vga* vga, Ctlr*){	Laguna *laguna;	vgaxo(Seqx, 0x0E, vga->sequencer[0x0E]);	vgaxo(Seqx, 0x1E, vga->sequencer[0x1E]);	vgaxo(Seqx, 0x07, vga->sequencer[0x07]);	if(vga->mode->interlace == 'v')		vgaxo(Crtx, 0x19, vga->crt[0x19]);	vgaxo(Crtx, 0x1A, vga->crt[0x1A]);	vgaxo(Crtx, 0x1B, vga->crt[0x1B]);	vgaxo(Crtx, 0x1D, vga->crt[0x1D]);	vgaxo(Crtx, 0x1E, vga->crt[0x1E]);	vgaxo(Grx, 0x0B, vga->graphics[0x0B]);	laguna = vga->private;	mmio16w(laguna, Format, laguna->format);	mmio32w(laguna, Vsc, laguna->vsc);	mmio16w(laguna, Threshold, laguna->threshold);	mmio16w(laguna, TileCtrl, laguna->tilectrl);	mmio8w(laguna, TileCtrl2D3D, laguna->tilectrl2D3D);	mmio16w(laguna, Control, laguna->control);}static voiddump(Vga* vga, Ctlr* ctlr){	int i;	char *name;	Laguna *laguna;	name = ctlr->name;	printitem(name, "Seq06");	for(i = 0x06; i < 0x20; i++)		printreg(vga->sequencer[i]);	printitem(name, "Crt19");	for(i = 0x19; i < 0x20; i++)		printreg(vga->crt[i]);	printitem(name, "Gr09");	for(i = 0x09; i < 0x0C; i++)		printreg(vga->graphics[i]);	laguna = vga->private;	Bprint(&stdout, "\n");	Bprint(&stdout, "%s mem\t\t%d\n", ctlr->name, laguna->mem*1024*1024);	Bprint(&stdout, "%s Format\t\t%uX\n", ctlr->name, laguna->format);	Bprint(&stdout, "%s Threshold\t\t\t%uX\n",		ctlr->name, laguna->threshold);	Bprint(&stdout, "%s TileCtrl\t\t\t%uX\n", ctlr->name, laguna->tilectrl);	Bprint(&stdout, "%s Vsc\t\t%uX\n", ctlr->name, laguna->vsc);	Bprint(&stdout, "%s Control\t\t%uX\n", ctlr->name, laguna->control);	Bprint(&stdout, "%s TileCtrlC2D3D\t\t%uX\n",		ctlr->name, laguna->tilectrl2D3D);}Ctlr clgd546x = {	"clgd546x",			/* name */	snarf,				/* snarf */	0,				/* options */	init,				/* init */	load,				/* load */	dump,				/* dump */};Ctlr clgd546xhwgc = {	"clgd546xhwgc",			/* name */	0,				/* snarf */	0,				/* options */	0,				/* init */	0,				/* load */	0,				/* dump */};

⌨️ 快捷键说明

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