date and time created 88/12/14 15:29:27 by sklower
[unix-history] / usr / src / sys / vax / vax / ka820.c
CommitLineData
025fd248 1/*
35962040
KB
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) %G%
025fd248
MK
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
44extern struct pte Clockmap[];
45extern struct pte RX50map[];
46extern struct pte Ka820map[];
47struct ka820clock ka820clock;
48struct ka820port ka820port;
49
50#ifdef notyet
51extern struct pte BRAMmap[];
52extern struct pte EEPROMmap[];
53char bootram[KA820_BRPAGES * NBPG];
54char eeprom[KA820_EEPAGES * NBPG];
55#endif
56
57ka820_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 */
82ka820_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 */
124ka820_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 */
158struct 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
199ka820_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
220ka820_memerr()
221{
222 register struct ms820regs *mcr;
223 register int m, hard;
224 register char *type;
225static char b1[] = "\20\40ERRSUM\37ECCDIAG\36ECCDISABLE\20CRDINH\17VALID\
226\16INTLK\15BROKE\13MWRITEERR\12CNTLERR\11INTLV";
227static char b2[] = "\20\40RDS\37HIERR\36CRD\35ADRS";
228
229 for (m = 0; m < nmcr; m++) {
230 mcr = (struct ms820regs *)mcraddr[m];
231printf("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 */
261char *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
275struct 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
289ka820_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 */
322rxcdintr()
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