xref: /inferno-os/os/pc/devzt5512.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 /*
2  *  Namespace Interface for Ziatech 5512 System Registers
3  */
4 #include	"u.h"
5 #include	"../port/lib.h"
6 #include	"mem.h"
7 #include	"dat.h"
8 #include	"fns.h"
9 #include	"../port/error.h"
10 
11 
12 enum{
13 	Qdir,
14 	Qsysid,
15 	Qwatchdog,
16 	Qledctl,
17 	Qpower,
18 	Qswitch,
19 	Qstat,
20 };
21 
22 static
23 Dirtab zttab[]={
24 	".",			{Qdir,0,QTDIR},		0,	0555,
25 	"id",			{Qsysid, 0},		0,	0444,
26 	"watchdog",	{Qwatchdog, 0}, 	0,	0600,
27 	"ledctl",		{Qledctl, 0},		0,	0666,
28 	"powerstat",	{Qpower, 0},		0,	0444,
29 	"switch",		{Qswitch, 0},		0,	0444,
30 	"stat",		{Qstat, 0},			0,	0444,
31 };
32 
33 extern int watchdog;
34 void
watchdog_strobe(void)35 watchdog_strobe(void)
36 {
37 	uchar sysreg;
38 
39 	sysreg = inb(0x78);
40 	sysreg &= (~1);
41 	outb(0x78, sysreg);	/* disable/strobe watchdog */
42 	sysreg |= 1;
43 	outb(0x78, sysreg);	/* enable watchdog */
44 }
45 
46 static void
ztreset(void)47 ztreset(void)						/* default in dev.c */
48 {
49 	uchar sysreg;
50 
51 	if(watchdog)
52 		addclock0link(watchdog_strobe);
53 	/* clear status LEDs */
54 	sysreg = inb(0xe2);
55 	sysreg &= ~3;		/* clear usr1 */
56 	sysreg &= ~(3 << 2); /* clear usr2 */
57 	outb(0xe2, sysreg);
58 }
59 
60 static Chan*
ztattach(char * spec)61 ztattach(char* spec)
62 {
63 	return devattach('Z', spec);
64 }
65 
66 static int
ztwalk(Chan * c,char * name)67 ztwalk(Chan* c, char* name)
68 {
69 	return devwalk(c, name, zttab, nelem(zttab), devgen);
70 }
71 
72 static void
ztstat(Chan * c,char * db)73 ztstat(Chan* c, char* db)
74 {
75 	devstat(c, db, zttab, nelem(zttab), devgen);
76 }
77 
78 static Chan*
ztopen(Chan * c,int omode)79 ztopen(Chan* c, int omode)
80 {
81 	return devopen(c, omode, zttab, nelem(zttab), devgen);
82 }
83 
84 static void
ztclose(Chan * c)85 ztclose(Chan* c)
86 {
87 	USED(c);
88 }
89 
90 static long
ztread(Chan * c,void * a,long n,vlong offset)91 ztread(Chan* c, void* a, long n, vlong offset)
92 {
93 	uchar sysreg;
94 	char buf[256];
95 
96 	USED(offset);
97 
98 	switch(c->qid.path & ~CHDIR) {
99 	case Qdir:
100 		return devdirread(c, a, n, zttab, nelem(zttab), devgen);
101 	case Qsysid: {
102 		ulong rev;
103 		sysreg = inb(0xe3);
104 		rev = (ulong) (sysreg & 0x7f);
105 		sysreg = inb(0xe2);
106 		sprint(buf, "Board Rev: %lud\nSerial #: %lud\n", rev, (ulong)(sysreg >> 4));
107 		return readstr(offset, a, n, buf);
108 		};
109 	case Qwatchdog:
110 		sysreg = inb(0x78);
111 		if((sysreg & 1) == 1) {
112 			n = readstr(offset, a, n, "enabled");
113 		} else {
114 			n = readstr(offset, a, n, "disabled");
115 		}
116 		return n;
117 	case Qledctl:
118 		{
119 		char usr1[6], usr2[6];
120 		sysreg = inb(0xe2);
121 		switch( sysreg & 3 ) {
122 			case 0:
123 			case 3:
124 				sprint(usr1, "off");
125 				break;
126 			case 1:
127 				sprint(usr1, "red");
128 				break;
129 			case 2:
130 				sprint(usr1, "green");
131 		};
132 		switch( (sysreg >> 2) & 3) {
133 			case 0:
134 			case 3:
135 				sprint(usr2, "off");
136 				break;
137 			case 1:
138 				sprint(usr2, "red");
139 				break;
140 			case 2:
141 				sprint(usr2, "green");
142 		};
143 		sprint(buf, "usr1: %s\nusr2: %s\n",usr1, usr2);
144 		return readstr(offset, a, n, buf);
145 		};
146 	case Qpower:
147 		sysreg = inb(0xe4);
148 		sprint(buf, "DEG#: %d\nFAL#: %d\n", (sysreg & 2), (sysreg & 1));
149 		return readstr(offset, a, n, buf);
150 	case Qswitch:
151 		sysreg = inb(0xe4);
152 		sprint(buf, "%d %d %d %d", (sysreg & (1<<6)), (sysreg & (1<<5)), (sysreg & (1<<4)), (sysreg & (1<<3)));
153 		return readstr(offset, a, n, buf);
154 	case Qstat: {
155 		char bus[10],cpu[20], mode[20], boot[20];
156 
157 		sysreg = inb(0xe5);
158 		switch (sysreg & 0x7) {
159 			case 1:
160 				sprint(bus, "66 MHz");
161 				break;
162 			case 2:
163 				sprint(bus, "60 MHz");
164 				break;
165 			case 3:
166 				sprint(bus, "50 MHz");
167 				break;
168 			default:
169 				sprint(bus, "unknown");
170 		};
171 		switch ((sysreg>>3)&0x7) {
172 			case 0:
173 				sprint(cpu, "75, 90, 100 MHz");
174 				break;
175 			case 1:
176 				sprint(cpu, "120, 133 MHz");
177 				break;
178 			case 2:
179 				sprint(cpu, "180, 200 MHz");
180 				break;
181 			case 3:
182 				sprint(cpu, "150, 166 MHz");
183 			default:
184 				sprint(cpu, "unknown");
185 		};
186 		if(sysreg & (1<<6))
187 			sprint(mode, "Port 80 test mode");
188 		else
189 			sprint(mode, "Normal decode");
190 		if(sysreg & (1<<7))
191 			sprint(boot,"EEPROM");
192 		else
193 			sprint(boot,"Flash");
194 		sprint(buf,"Bus Frequency: %s\nPentium: %s\nTest Mode Status: %s\nBIOS Boot ROM: %s\n",
195 				bus, cpu, mode, boot);
196 		return readstr(offset, a, n, buf);
197 		};
198 	default:
199 		n=0;
200 		break;
201 	}
202 	return n;
203 }
204 
205 
206 
207 static long
ztwrite(Chan * c,void * vp,long n,vlong offset)208 ztwrite(Chan* c, void *vp, long n, vlong offset)
209 {
210 	uchar sysreg;
211 	char buf[256];
212 	char *a;
213 	int nf;
214 	char *fields[3];
215 
216 	a = vp;
217 	if(n >= sizeof(buf))
218 		n = sizeof(buf)-1;
219 	strncpy(buf, a, n);
220 	buf[n] = 0;
221 
222 	USED(a, offset);
223 
224 	switch(c->qid.path & ~CHDIR){
225 	case Qwatchdog:
226 		sysreg = inb(0x78);
227 
228 		if(strncmp(buf, "enable", 6) == 0) {
229 			if((sysreg & 1) != 1)
230 		 		addclock0link(watchdog_strobe);
231 			break;
232 		}
233 		n = 0;
234 		error(Ebadarg);
235 	case Qledctl:
236 		nf = getfields(buf, fields, 3, 1, " \t\n");
237 		if(nf < 2) {
238 			error(Ebadarg);
239 			n = 0;
240 			break;
241 		}
242 		sysreg = inb(0xe2);
243 		USED(sysreg);
244 		if(strncmp(fields[0],"usr1", 4)==0) {
245 			sysreg &= ~3;
246 			if(strncmp(fields[1], "off", 3)==0) {
247 				outb(0xe2, sysreg);
248 				break;
249 			}
250 			if(strncmp(fields[1], "red", 3)==0) {
251 				sysreg |= 1;
252 				outb(0xe2, sysreg);
253 				break;
254 			}
255 			if(strncmp(fields[1], "green", 5)==0) {
256 				sysreg |= 2;
257 				outb(0xe2, sysreg);
258 				break;
259 			}
260 		}
261 		if(strncmp(fields[0],"usr2", 4)==0) {
262 			sysreg &= ~(3 << 2);
263 			if(strncmp(fields[1], "off", 3)==0) {
264 				outb(0xe2, sysreg);
265 				break;
266 			}
267 			if(strncmp(fields[1], "red", 3)==0) {
268 				sysreg |= (1 << 2);
269 				outb(0xe2, sysreg);
270 				break;
271 			}
272 			if(strncmp(fields[1], "green", 5)==0) {
273 				sysreg |= (2 << 2);
274 				outb(0xe2, sysreg);
275 				break;
276 			}
277 		}
278 		n = 0;
279 		error(Ebadarg);
280 	default:
281 		error(Ebadusefd);
282 	}
283 	return n;
284 }
285 
286 
287 
288 Dev zt5512devtab = {				/* defaults in dev.c */
289 	'Z',
290 	"Ziatech5512",
291 
292 	ztreset,						/* devreset */
293 	devinit,						/* devinit */
294 	ztattach,
295 	devdetach,
296 	devclone,						/* devclone */
297 	ztwalk,
298 	ztstat,
299 	ztopen,
300 	devcreate,					/* devcreate */
301 	ztclose,
302 	ztread,
303 	devbread,						/* devbread */
304 	ztwrite,
305 	devbwrite,					/* devbwrite */
306 	devremove,					/* devremove */
307 	devwstat,						/* devwstat */
308 };
309