|
|
1.1 root 1: /*
2: * Copyright (c) 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Chris Torek.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that the above copyright notice and this paragraph are
10: * duplicated in all such forms and that any documentation,
11: * advertising materials, and other materials related to such
12: * distribution and use acknowledge that the software was developed
13: * by the University of California, Berkeley. The name of the
14: * University may not be used to endorse or promote products derived
15: * from this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * @(#)ka820.c 7.2 (Berkeley) 7/9/88
21: */
22:
23: #if VAX8200
24:
25: /*
26: * KA820 specific CPU code. (Note that the VAX8200 uses a KA820, not
27: * a KA8200. Sigh.)
28: */
29:
30: #include "param.h"
31: #include "time.h"
32: #include "kernel.h"
33: #include "vmmac.h"
34:
35: #include "cpu.h"
36: #include "clock.h"
37: #include "ka820.h"
38: #include "mem.h"
39: #include "mtpr.h"
40: #include "pte.h"
41:
42: #include "../vaxbi/bireg.h"
43:
44: extern struct pte Clockmap[];
45: extern struct pte RX50map[];
46: extern struct pte Ka820map[];
47: struct ka820clock ka820clock;
48: struct ka820port ka820port;
49:
50: #ifdef notyet
51: extern struct pte BRAMmap[];
52: extern struct pte EEPROMmap[];
53: char bootram[KA820_BRPAGES * NBPG];
54: char eeprom[KA820_EEPAGES * NBPG];
55: #endif
56:
57: ka820_init()
58: {
59: register int csr;
60:
61: /* map in the various devices */
62: *(int *)&Ka820map[0] = PG_V|PG_KW|btop(KA820_PORTADDR);
63: *(int *)&RX50map[0] = PG_V|PG_KW|btop(KA820_RX50ADDR);
64: *(int *)&Clockmap[0] = PG_V|PG_KW|btop(KA820_CLOCKADDR);
65: #ifdef notyet
66: ioaccess(bootram, BRAMmap, KA820_BRPAGES * NBPG);
67: ioaccess(eeprom, EEPROMmap, KA820_EEPAGES * NBPG);
68: #else
69: mtpr(TBIA, 0);
70: #endif
71:
72: /* reset the console and enable the RX50 */
73: csr = ka820port.csr;
74: csr &= ~KA820PORT_RSTHALT; /* ??? */
75: csr |= KA820PORT_CONSCLR | KA820PORT_CRDCLR | KA820PORT_CONSEN |
76: KA820PORT_RXIE;
77: ka820port.csr = csr;
78: }
79:
80: /* Set system time from clock */
81: /* ARGSUSED */
82: ka820_clkread(base)
83: time_t base;
84: {
85: register struct ka820clock *clock = &ka820clock;
86: struct chiptime c;
87: int s, rv;
88:
89: rv = CLKREAD_OK;
90: /* I wish I knew the differences between these */
91: if ((clock->csr3 & KA820CLK_3_VALID) == 0) {
92: printf("WARNING: TOY clock not marked valid\n");
93: rv = CLKREAD_WARN;
94: }
95: if ((clock->csr1 & KA820CLK_1_GO) != KA820CLK_1_GO) {
96: printf("WARNING: TOY clock stopped\n");
97: rv = CLKREAD_WARN;
98: }
99: /* THIS IS NOT RIGHT (clock may change on us) */
100: s = splhigh();
101: while (clock->csr0 & KA820CLK_0_BUSY)
102: /* void */;
103: c.sec = clock->sec;
104: c.min = clock->min;
105: c.hour = clock->hr;
106: c.day = clock->day;
107: c.mon = clock->mon;
108: c.year = clock->yr;
109: splx(s);
110:
111: /* the darn thing needs tweaking! */
112: c.sec >>= 1; /* tweak */
113: c.min >>= 1; /* tweak */
114: c.hour >>= 1; /* tweak */
115: c.day >>= 1; /* tweak */
116: c.mon >>= 1; /* tweak */
117: c.year >>= 1; /* tweak */
118:
119: time.tv_sec = chiptotime(&c);
120: return (time.tv_sec ? rv : CLKREAD_BAD);
121: }
122:
123: /* store time into clock */
124: ka820_clkwrite()
125: {
126: register struct ka820clock *clock = &ka820clock;
127: struct chiptime c;
128: int s;
129:
130: timetochip(&c);
131:
132: /* play it again, sam (or mike or kirk or ...) */
133: c.sec <<= 1; /* tweak */
134: c.min <<= 1; /* tweak */
135: c.hour <<= 1; /* tweak */
136: c.day <<= 1; /* tweak */
137: c.mon <<= 1; /* tweak */
138: c.year <<= 1; /* tweak */
139:
140: s = splhigh();
141: clock->csr1 = KA820CLK_1_SET;
142: while (clock->csr0 & KA820CLK_0_BUSY)
143: /* void */;
144: clock->sec = c.sec;
145: clock->min = c.min;
146: clock->hr = c.hour;
147: clock->day = c.day;
148: clock->mon = c.mon;
149: clock->yr = c.year;
150: /* should we set a `rate'? */
151: clock->csr1 = KA820CLK_1_GO;
152: splx(s);
153: }
154:
155: /*
156: * MS820 support.
157: */
158: struct ms820regs {
159: struct biiregs biic; /* BI interface chip */
160: u_long ms_gpr[4]; /* the four gprs (unused) */
161: int ms_csr1; /* control/status register 1 */
162: int ms_csr2; /* control/status register 2 */
163: };
164:
165: /*
166: * Bits in CSR1.
167: */
168: #define MS1_ERRSUM 0x80000000 /* error summary (ro) */
169: #define MS1_ECCDIAG 0x40000000 /* ecc diagnostic (rw) */
170: #define MS1_ECCDISABLE 0x20000000 /* ecc disable (rw) */
171: #define MS1_MSIZEMASK 0x1ffc0000 /* mask for memory size (ro) */
172: #define MS1_RAMTYMASK 0x00030000 /* mask for ram type (ro) */
173: #define MS1_RAMTY64K 0x00000000 /* 64K chips */
174: #define MS1_RAMTY256K 0x00010000 /* 256K chips */
175: /* types 2 and 3 reserved */
176: #define MS1_CRDINH 0x00008000 /* inhibit crd interrupts (rw) */
177: #define MS1_MEMVALID 0x00004000 /* memory has been written (ro) */
178: #define MS1_INTLK 0x00002000 /* interlock flag (ro) */
179: #define MS1_BROKE 0x00001000 /* broken (rw) */
180: #define MS1_MBZ 0x00000880 /* zero */
181: #define MS1_MWRITEERR 0x00000400 /* rds during masked write (rw) */
182: #define MS1_CNTLERR 0x00000200 /* internal timing busted (rw) */
183: #define MS1_INTLV 0x00000100 /* internally interleaved (ro) */
184: #define MS1_DIAGC 0x0000007f /* ecc diagnostic bits (rw) */
185:
186: /*
187: * Bits in CSR2.
188: */
189: #define MS2_RDSERR 0x80000000 /* rds error (rw) */
190: #define MS2_HIERR 0x40000000 /* high error rate (rw) */
191: #define MS2_CRDERR 0x20000000 /* crd error (rw) */
192: #define MS2_ADRSERR 0x10000000 /* rds due to addr par err (rw) */
193: #define MS2_MBZ 0x0f000080 /* zero */
194: #define MS2_ADDR 0x00fffe00 /* address in error (relative) (ro) */
195: #define MS2_INTLVADDR 0x00000100 /* error was in bank 1 (ro) */
196: #define MS2_SYN 0x0000007f /* error syndrome (ro, rw diag) */
197:
198:
199: ka820_memenable()
200: {
201: register struct ms820regs *mcr;
202: register int m;
203:
204: for (m = 0; m < nmcr; m++) {
205: mcr = (struct ms820regs *)mcraddr[m];
206: /*
207: * This will be noisy. Should we do anything
208: * about that?
209: */
210: if ((mcr->biic.bi_csr & BICSR_STS) == 0)
211: printf("mcr%d: failed self test\n", m);
212: else {
213: mcr->ms_csr1 = MS1_MWRITEERR | MS1_CNTLERR;
214: mcr->ms_csr2 = MS2_RDSERR | MS2_HIERR |
215: MS2_CRDERR | MS2_ADRSERR;
216: }
217: }
218: }
219:
220: ka820_memerr()
221: {
222: register struct ms820regs *mcr;
223: register int m, hard;
224: register char *type;
225: static char b1[] = "\20\40ERRSUM\37ECCDIAG\36ECCDISABLE\20CRDINH\17VALID\
226: \16INTLK\15BROKE\13MWRITEERR\12CNTLERR\11INTLV";
227: static char b2[] = "\20\40RDS\37HIERR\36CRD\35ADRS";
228:
229: for (m = 0; m < nmcr; m++) {
230: mcr = (struct ms820regs *)mcraddr[m];
231: printf("mcr%d: csr1=%b csr2=%b\n", m, mcr->ms_csr1, b1, mcr->ms_csr2, b2);
232: if ((mcr->ms_csr1 & MS1_ERRSUM) == 0)
233: continue;
234: hard = 1;
235: if (mcr->ms_csr1 & MS1_BROKE)
236: type = "broke";
237: else if (mcr->ms_csr1 & MS1_CNTLERR)
238: type = "cntl err";
239: else if (mcr->ms_csr2 & MS2_ADRSERR)
240: type = "address parity err";
241: else if (mcr->ms_csr2 & MS2_RDSERR)
242: type = "rds err";
243: else if (mcr->ms_csr2 & MS2_CRDERR) {
244: hard = 0;
245: type = "";
246: } else
247: type = "mysterious error";
248: printf("mcr%d: %s%s%s addr %x bank %x syn %x\n", m,
249: hard ? "hard error: " : "soft ecc",
250: type, mcr->ms_csr2 & MS2_HIERR ?
251: " (+ other rds or crd err)" : "",
252: ((mcr->ms_csr2 & MS2_ADDR) + mcr->biic.bi_sadr) >> 9,
253: (mcr->ms_csr2 & MS2_INTLVADDR) != 0,
254: mcr->ms_csr2 & MS2_SYN);
255: mcr->ms_csr1 = mcr->ms_csr1 | MS1_CRDINH;
256: mcr->ms_csr2 = mcr->ms_csr2;
257: }
258: }
259:
260: /* these are bits 0 to 6 in the summary field */
261: char *mc8200[] = {
262: "cpu bad ipl", "ucode lost err",
263: "ucode par err", "DAL par err",
264: "BI bus err", "BTB tag par",
265: "cache tag par",
266: };
267: #define MC8200_BADIPL 0x01
268: #define MC8200_UERR 0x02
269: #define MC8200_UPAR 0x04
270: #define MC8200_DPAR 0x08
271: #define MC8200_BIERR 0x10
272: #define MC8200_BTAGPAR 0x20
273: #define MC8200_CTAGPAR 0x40
274:
275: struct mc8200frame {
276: int mc82_bcnt; /* byte count == 0x20 */
277: int mc82_summary; /* summary parameter */
278: int mc82_param1; /* parameter 1 */
279: int mc82_va; /* va register */
280: int mc82_vap; /* va prime register */
281: int mc82_ma; /* memory address */
282: int mc82_status; /* status word */
283: int mc82_epc; /* error pc */
284: int mc82_upc; /* micro pc */
285: int mc82_pc; /* current pc */
286: int mc82_psl; /* current psl */
287: };
288:
289: ka820_mchk(cmcf)
290: caddr_t cmcf;
291: {
292: register struct mc8200frame *mcf = (struct mc8200frame *)cmcf;
293: register int i, type = mcf->mc82_summary;
294: extern int cold;
295:
296: /* ignore BI bus errors during configuration */
297: if (cold && type == MC8200_BIERR) {
298: mtpr(MCESR, 0xf);
299: return (MCHK_RECOVERED);
300: }
301:
302: /*
303: * SOME ERRORS ARE RECOVERABLE
304: * do it later
305: */
306: printf("machine check %x: ", type);
307: for (i = 0; i < sizeof (mc8200) / sizeof (mc8200[0]); i++)
308: if (type & (1 << i))
309: printf(" %s,", mc8200[i]);
310: printf(" param1 %x\n", mcf->mc82_param1);
311: printf(
312: "\tva %x va' %x ma %x pc %x psl %x\n\tstatus %x errpc %x upc %x\n",
313: mcf->mc82_va, mcf->mc82_vap, mcf->mc82_ma,
314: mcf->mc82_pc, mcf->mc82_psl,
315: mcf->mc82_status, mcf->mc82_epc, mcf->mc82_upc);
316: return (MCHK_PANIC);
317: }
318:
319: /*
320: * Receive a character from logical console.
321: */
322: rxcdintr()
323: {
324: register int c = mfpr(RXCD);
325:
326: /* not sure what (if anything) to do with these */
327: printf("rxcd node %x c=0x%x\n", (c >> 8) & 0xf, c & 0xff);
328: }
329: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.