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