Charles.Forsyth20060303644188019 years agoHistory
308 lines · 5.5 KB · C
RawDownload
/* *  Namespace Interface for Ziatech 5512 System Registers */#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"  enum{	Qdir,	Qsysid,	Qwatchdog,	Qledctl,	Qpower,	Qswitch,	Qstat,}; staticDirtab zttab[]={	".",			{Qdir,0,QTDIR},		0,	0555,	"id",			{Qsysid, 0},		0,	0444,	"watchdog",	{Qwatchdog, 0}, 	0,	0600,	"ledctl",		{Qledctl, 0},		0,	0666,	"powerstat",	{Qpower, 0},		0,	0444,	"switch",		{Qswitch, 0},		0,	0444,	"stat",		{Qstat, 0},			0,	0444,}; extern int watchdog;voidwatchdog_strobe(void){	uchar sysreg; 	sysreg = inb(0x78);	sysreg &= (~1);	outb(0x78, sysreg);	/* disable/strobe watchdog */	sysreg |= 1;	outb(0x78, sysreg);	/* enable watchdog */} static voidztreset(void)						/* default in dev.c */{	uchar sysreg; 	if(watchdog)		addclock0link(watchdog_strobe);	/* clear status LEDs */	sysreg = inb(0xe2);	sysreg &= ~3;		/* clear usr1 */	sysreg &= ~(3 << 2); /* clear usr2 */	outb(0xe2, sysreg);} static Chan*ztattach(char* spec){	return devattach('Z', spec);} static intztwalk(Chan* c, char* name){	return devwalk(c, name, zttab, nelem(zttab), devgen);} static voidztstat(Chan* c, char* db){	devstat(c, db, zttab, nelem(zttab), devgen);} static Chan*ztopen(Chan* c, int omode){	return devopen(c, omode, zttab, nelem(zttab), devgen);} static voidztclose(Chan* c){	USED(c);} static longztread(Chan* c, void* a, long n, vlong offset){	uchar sysreg;	char buf[256]; 	USED(offset); 	switch(c->qid.path & ~CHDIR) {	case Qdir:		return devdirread(c, a, n, zttab, nelem(zttab), devgen);	case Qsysid: {		ulong rev;		sysreg = inb(0xe3);		rev = (ulong) (sysreg & 0x7f);		sysreg = inb(0xe2);		sprint(buf, "Board Rev: %lud\nSerial #: %lud\n", rev, (ulong)(sysreg >> 4));		return readstr(offset, a, n, buf);		};	case Qwatchdog:		sysreg = inb(0x78);		if((sysreg & 1) == 1) {			n = readstr(offset, a, n, "enabled");		} else {			n = readstr(offset, a, n, "disabled");		}		return n;	case Qledctl:		{		char usr1[6], usr2[6];		sysreg = inb(0xe2);		switch( sysreg & 3 ) {			case 0:			case 3:				sprint(usr1, "off");				break;			case 1:				sprint(usr1, "red");				break;			case 2:				sprint(usr1, "green");		};		switch( (sysreg >> 2) & 3) {			case 0:			case 3:				sprint(usr2, "off");				break;			case 1:				sprint(usr2, "red");				break;			case 2:				sprint(usr2, "green");		};		sprint(buf, "usr1: %s\nusr2: %s\n",usr1, usr2);		return readstr(offset, a, n, buf);		};	case Qpower:		sysreg = inb(0xe4);		sprint(buf, "DEG#: %d\nFAL#: %d\n", (sysreg & 2), (sysreg & 1));		return readstr(offset, a, n, buf);	case Qswitch:		sysreg = inb(0xe4);		sprint(buf, "%d %d %d %d", (sysreg & (1<<6)), (sysreg & (1<<5)), (sysreg & (1<<4)), (sysreg & (1<<3)));		return readstr(offset, a, n, buf);	case Qstat: {		char bus[10],cpu[20], mode[20], boot[20]; 		sysreg = inb(0xe5);		switch (sysreg & 0x7) {			case 1: 				sprint(bus, "66 MHz");				break;			case 2:				sprint(bus, "60 MHz");				break;			case 3:				sprint(bus, "50 MHz");				break;			default:				sprint(bus, "unknown");		};		switch ((sysreg>>3)&0x7) {			case 0:				sprint(cpu, "75, 90, 100 MHz");				break;			case 1:				sprint(cpu, "120, 133 MHz");				break;			case 2:				sprint(cpu, "180, 200 MHz");				break;			case 3:				sprint(cpu, "150, 166 MHz");			default:				sprint(cpu, "unknown");		};		if(sysreg & (1<<6)) 			sprint(mode, "Port 80 test mode");		else			sprint(mode, "Normal decode");		if(sysreg & (1<<7))			sprint(boot,"EEPROM");		else			sprint(boot,"Flash");		sprint(buf,"Bus Frequency: %s\nPentium: %s\nTest Mode Status: %s\nBIOS Boot ROM: %s\n",				bus, cpu, mode, boot);		return readstr(offset, a, n, buf);		};	default:		n=0;		break;	}	return n;}   static longztwrite(Chan* c, void *vp, long n, vlong offset){	uchar sysreg;	char buf[256];	char *a;	int nf;	char *fields[3]; 	a = vp;	if(n >= sizeof(buf))		n = sizeof(buf)-1;	strncpy(buf, a, n);	buf[n] = 0;	 	USED(a, offset); 	switch(c->qid.path & ~CHDIR){	case Qwatchdog:		sysreg = inb(0x78); 		if(strncmp(buf, "enable", 6) == 0) {			if((sysreg & 1) != 1)		 		addclock0link(watchdog_strobe);			break;		}		n = 0;		error(Ebadarg);	case Qledctl:		nf = getfields(buf, fields, 3, 1, " \t\n");		if(nf < 2) {			error(Ebadarg);			n = 0;			break;		}		sysreg = inb(0xe2);		USED(sysreg);		if(strncmp(fields[0],"usr1", 4)==0) {			sysreg &= ~3;			if(strncmp(fields[1], "off", 3)==0) {				outb(0xe2, sysreg);				break;			} 			if(strncmp(fields[1], "red", 3)==0) {				sysreg |= 1;				outb(0xe2, sysreg);				break;			} 			if(strncmp(fields[1], "green", 5)==0) {				sysreg |= 2;				outb(0xe2, sysreg);				break;			} 				}		if(strncmp(fields[0],"usr2", 4)==0) {			sysreg &= ~(3 << 2);			if(strncmp(fields[1], "off", 3)==0) {				outb(0xe2, sysreg);				break;			} 			if(strncmp(fields[1], "red", 3)==0) {				sysreg |= (1 << 2);				outb(0xe2, sysreg);				break;			} 			if(strncmp(fields[1], "green", 5)==0) {				sysreg |= (2 << 2);				outb(0xe2, sysreg);				break;			} 				}		n = 0;		error(Ebadarg);	default:		error(Ebadusefd);	}	return n;}   Dev zt5512devtab = {				/* defaults in dev.c */	'Z',	"Ziatech5512", 	ztreset,						/* devreset */	devinit,						/* devinit */	ztattach,	devdetach,	devclone,						/* devclone */	ztwalk,	ztstat,	ztopen,	devcreate,					/* devcreate */	ztclose,	ztread,	devbread,						/* devbread */	ztwrite,	devbwrite,					/* devbwrite */	devremove,					/* devremove */	devwstat,						/* devwstat */};