summaryrefslogtreecommitdiff
path: root/os/pc/devzt5512.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /os/pc/devzt5512.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'os/pc/devzt5512.c')
-rw-r--r--os/pc/devzt5512.c308
1 files changed, 308 insertions, 0 deletions
diff --git a/os/pc/devzt5512.c b/os/pc/devzt5512.c
new file mode 100644
index 00000000..af189fff
--- /dev/null
+++ b/os/pc/devzt5512.c
@@ -0,0 +1,308 @@
+/*
+ * 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,
+};
+
+static
+Dirtab 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;
+void
+watchdog_strobe(void)
+{
+ uchar sysreg;
+
+ sysreg = inb(0x78);
+ sysreg &= (~1);
+ outb(0x78, sysreg); /* disable/strobe watchdog */
+ sysreg |= 1;
+ outb(0x78, sysreg); /* enable watchdog */
+}
+
+static void
+ztreset(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 int
+ztwalk(Chan* c, char* name)
+{
+ return devwalk(c, name, zttab, nelem(zttab), devgen);
+}
+
+static void
+ztstat(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 void
+ztclose(Chan* c)
+{
+ USED(c);
+}
+
+static long
+ztread(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 long
+ztwrite(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 */
+};