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