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