xref: /netbsd/sys/arch/vax/vax/ka860.c (revision bf9ec67e)
1 /*	$NetBSD: ka860.c,v 1.16 2000/08/09 03:02:54 tv Exp $	*/
2 /*
3  * Copyright (c) 1986, 1988 Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by the University of
17  *	California, Berkeley and its contributors.
18  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)ka860.c	7.4 (Berkeley) 12/16/90
35  */
36 
37 /*
38  * VAX 8600 specific routines.
39  * Also contains abus spec's and memory init routines.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/device.h>
44 #include <sys/systm.h>
45 
46 #include <machine/cpu.h>
47 #include <machine/clock.h>
48 #include <machine/mtpr.h>
49 #include <machine/nexus.h>
50 #include <machine/ioa.h>
51 #include <machine/sid.h>
52 
53 #include <vax/vax/gencons.h>
54 
55 static	void	ka86_memerr __P((void));
56 static	int	ka86_mchk __P((caddr_t));
57 static	void	ka86_reboot __P((int));
58 static	void	ka86_clrf __P((void));
59 static	void	ka860_init __P((struct device *));
60 
61 void	crlattach __P((void));
62 
63 struct	cpu_dep	ka860_calls = {
64 	0,
65 	ka86_mchk,
66 	ka86_memerr,
67 	0,
68 	generic_clkread,
69 	generic_clkwrite,
70 	6,      /* ~VUPS */
71 	10,	/* SCB pages */
72 	0,	/* Halt call, nothing special */
73 	ka86_reboot,
74 	ka86_clrf,
75 };
76 
77 /*
78  * 8600 memory register (MERG) bit definitions
79  */
80 #define M8600_ICRD	0x400		/* inhibit crd interrupts */
81 #define M8600_TB_ERR	0xf00		/* translation buffer error mask */
82 
83 /*
84  * MDECC register
85  */
86 #define M8600_ADDR_PE	0x080000	/* address parity error */
87 #define M8600_DBL_ERR	0x100000	/* data double bit error */
88 #define M8600_SNG_ERR	0x200000	/* data single bit error */
89 #define M8600_BDT_ERR	0x400000	/* bad data error */
90 
91 /*
92  * ESPA register is used to address scratch pad registers in the Ebox.
93  * To access a register in the scratch pad, write the ESPA with the address
94  * and then read the ESPD register.
95  *
96  * NOTE:  In assmebly code, the mfpr instruction that reads the ESPD
97  *	  register must immedately follow the mtpr instruction that setup
98  *	  the ESPA register -- per the VENUS processor register spec.
99  *
100  * The scratchpad registers that are supplied for a single bit ECC
101  * error are:
102  */
103 #define SPAD_MSTAT1	0x25		/* scratch pad mstat1 register	*/
104 #define SPAD_MSTAT2	0x26		/* scratch pad mstat2 register	*/
105 #define SPAD_MDECC	0x27		/* scratch pad mdecc register	*/
106 #define SPAD_MEAR	0x2a		/* scratch pad mear register	*/
107 
108 #define M8600_MEMERR(mdecc) ((mdecc) & 0x780000)
109 #define M8600_HRDERR(mdecc) ((mdecc) & 0x580000)
110 #define M8600_SYN(mdecc) (((mdecc) >> 9) & 0x3f)
111 #define M8600_ADDR(mear) ((mear) & 0x3ffffffc)
112 #define M8600_ARRAY(mear) (((mear) >> 22) & 0x0f)
113 
114 #define M8600_MDECC_BITS \
115 "\20\27BAD_DT_ERR\26SNG_BIT_ERR\25DBL_BIT_ERR\24ADDR_PE"
116 
117 #define M8600_MSTAT1_BITS "\20\30CPR_PE_A\27CPR_PE_B\26ABUS_DT_PE\
118 \25ABUS_CTL_MSK_PE\24ABUS_ADR_PE\23ABUS_C/A_CYCLE\22ABUS_ADP_1\21ABUS_ADP_0\
119 \20TB_MISS\17BLK_HIT\16C0_TAG_MISS\15CHE_MISS\14TB_VAL_ERR\13TB_PTE_B_PE\
120 \12TB_PTE_A_PE\11TB_TAG_PE\10WR_DT_PE_B3\7WR_DT_PE_B2\6WR_DT_PE_B1\
121 \5WR_DT_PE_B0\4CHE_RD_DT_PE\3CHE_SEL\2ANY_REFL\1CP_BW_CHE_DT_PE"
122 
123 #define M8600_MSTAT2_BITS "\20\20CP_BYT_WR\17ABUS_BD_DT_CODE\10MULT_ERR\
124 \7CHE_TAG_PE\6CHE_TAG_W_PE\5CHE_WRTN_BIT\4NXM\3CP-IO_BUF_ERR\2MBOX_LOCK"
125 
126 /* log CRD errors */
127 void
128 ka86_memerr()
129 {
130 	register int reg11 = 0; /* known to be r11 below */
131 	int mdecc, mear, mstat1, mstat2, array;
132 
133 	/*
134 	 * Scratchpad registers in the Ebox must be read by
135 	 * storing their ID number in ESPA and then immediately
136 	 * reading ESPD's contents with no other intervening
137 	 * machine instructions!
138 	 *
139 	 * The asm's below have a number of constants which
140 	 * are defined correctly above and in mtpr.h.
141 	 */
142 #ifdef lint
143 	reg11 = 0;
144 #else
145 	asm("mtpr $0x27,$0x4e; mfpr $0x4f,%0":: "r" (reg11));
146 #endif
147 	mdecc = reg11;	/* must acknowledge interrupt? */
148 	if (M8600_MEMERR(mdecc)) {
149 		asm("mtpr $0x2a,$0x4e; mfpr $0x4f,%0":: "r" (reg11));
150 		mear = reg11;
151 		asm("mtpr $0x25,$0x4e; mfpr $0x4f,%0":: "r" (reg11));
152 		mstat1 = reg11;
153 		asm("mtpr $0x26,$0x4e; mfpr $0x4f,%0":: "r" (reg11));
154 		mstat2 = reg11;
155 		array = M8600_ARRAY(mear);
156 
157 		{
158 			char sbuf[256], sbuf2[256];
159 
160 			printf("mcr0: ecc error, addr %x (array %d) syn %x\n",
161 				M8600_ADDR(mear), array, M8600_SYN(mdecc));
162 
163 			bitmask_snprintf(mstat1, M8600_MSTAT1_BITS, sbuf, sizeof(sbuf));
164 			bitmask_snprintf(mstat2, M8600_MSTAT2_BITS, sbuf2, sizeof(sbuf2));
165 			printf("\tMSTAT1 = %s\n\tMSTAT2 = %s\n", sbuf, sbuf2);
166 		}
167 
168 		mtpr(0, PR_EHSR);
169 		mtpr(mfpr(PR_MERG) | M8600_ICRD, PR_MERG);
170 	}
171 }
172 
173 #define NMC8600 7
174 char *mc8600[] = {
175 	"unkn type",	"fbox error",	"ebox error",	"ibox error",
176 	"mbox error",	"tbuf error",	"mbox 1D error"
177 };
178 /* codes for above */
179 #define MC_FBOX		1
180 #define MC_EBOX		2
181 #define MC_IBOX		3
182 #define MC_MBOX		4
183 #define MC_TBUF		5
184 #define MC_MBOX1D	6
185 
186 /* error bits */
187 #define MBOX_FE		0x8000		/* Mbox fatal error */
188 #define FBOX_SERV	0x10000000	/* Fbox service error */
189 #define IBOX_ERR	0x2000		/* Ibox error */
190 #define EBOX_ERR	0x1e00		/* Ebox error */
191 #define MBOX_1D		0x81d0000	/* Mbox 1D error */
192 #define EDP_PE		0x200
193 
194 struct mc8600frame {
195 	int	mc86_bcnt;		/* byte count == 0x58 */
196 	int	mc86_ehmsts;
197 	int	mc86_evmqsav;
198 	int	mc86_ebcs;
199 	int	mc86_edpsr;
200 	int	mc86_cslint;
201 	int	mc86_ibesr;
202 	int	mc86_ebxwd1;
203 	int	mc86_ebxwd2;
204 	int	mc86_ivasav;
205 	int	mc86_vibasav;
206 	int	mc86_esasav;
207 	int	mc86_isasav;
208 	int	mc86_cpc;
209 	int	mc86_mstat1;
210 	int	mc86_mstat2;
211 	int	mc86_mdecc;
212 	int	mc86_merg;
213 	int	mc86_cshctl;
214 	int	mc86_mear;
215 	int	mc86_medr;
216 	int	mc86_accs;
217 	int	mc86_cses;
218 	int	mc86_pc;		/* trapped pc */
219 	int	mc86_psl;		/* trapped psl */
220 };
221 
222 /* machine check */
223 int
224 ka86_mchk(cmcf)
225 	caddr_t cmcf;
226 {
227 	register struct mc8600frame *mcf = (struct mc8600frame *)cmcf;
228 	register int type;
229 
230 	if (mcf->mc86_ebcs & MBOX_FE)
231 		mcf->mc86_ehmsts |= MC_MBOX;
232 	else if (mcf->mc86_ehmsts & FBOX_SERV)
233 		mcf->mc86_ehmsts |= MC_FBOX;
234 	else if (mcf->mc86_ebcs & EBOX_ERR) {
235 		if (mcf->mc86_ebcs & EDP_PE)
236 			mcf->mc86_ehmsts |= MC_MBOX;
237 		else
238 			mcf->mc86_ehmsts |= MC_EBOX;
239 	} else if (mcf->mc86_ehmsts & IBOX_ERR)
240 		mcf->mc86_ehmsts |= MC_IBOX;
241 	else if (mcf->mc86_mstat1 & M8600_TB_ERR)
242 		mcf->mc86_ehmsts |= MC_TBUF;
243 	else if ((mcf->mc86_cslint & MBOX_1D) == MBOX_1D)
244 		mcf->mc86_ehmsts |= MC_MBOX1D;
245 
246 	type = mcf->mc86_ehmsts & 0x7;
247 	printf("machine check %x: %s\n", type,
248 	    type < NMC8600 ? mc8600[type] : "???");
249 	printf("\tehm.sts %x evmqsav %x ebcs %x edpsr %x cslint %x\n",
250 	    mcf->mc86_ehmsts, mcf->mc86_evmqsav, mcf->mc86_ebcs,
251 	    mcf->mc86_edpsr, mcf->mc86_cslint);
252 	printf("\tibesr %x ebxwd %x %x ivasav %x vibasav %x\n",
253 	    mcf->mc86_ibesr, mcf->mc86_ebxwd1, mcf->mc86_ebxwd2,
254 	    mcf->mc86_ivasav, mcf->mc86_vibasav);
255 	printf("\tesasav %x isasav %x cpc %x mstat %x %x mdecc %x\n",
256 	    mcf->mc86_esasav, mcf->mc86_isasav, mcf->mc86_cpc,
257 	    mcf->mc86_mstat1, mcf->mc86_mstat2, mcf->mc86_mdecc);
258 	printf("\tmerg %x cshctl %x mear %x medr %x accs %x cses %x\n",
259 	    mcf->mc86_merg, mcf->mc86_cshctl, mcf->mc86_mear,
260 	    mcf->mc86_medr, mcf->mc86_accs, mcf->mc86_cses);
261 	printf("\tpc %x psl %x\n", mcf->mc86_pc, mcf->mc86_psl);
262 	mtpr(0, PR_EHSR);
263 	return (MCHK_PANIC);
264 }
265 
266 struct ka86 {
267 	unsigned snr:12,
268 		 plant:4,
269 		 eco:7,
270 		 v8650:1,
271 		 type:8;
272 };
273 
274 void
275 ka860_init(self)
276 	struct device *self;
277 {
278 	struct	ka86 *ka86 = (void *)&vax_cpudata;
279 
280 	/* Enable cache */
281 	mtpr(3, PR_CSWP);
282 
283 	printf(": CPU serial number %d(%d), hardware ECO level %d(%d)\n%s: ",
284 	    ka86->snr, ka86->plant, ka86->eco >> 4, ka86->eco, self->dv_xname);
285 	if (mfpr(PR_ACCS) & 255) {
286 		printf("FPA present, type %d, serial number %d, enabling.\n",
287 		    mfpr(PR_ACCS) & 255, mfpr(PR_ACCS) >> 16);
288 		mtpr(0x8000, PR_ACCS);
289 	} else
290 		printf("no FPA\n");
291 	/* enable CRD reports */
292 	mtpr(mfpr(PR_MERG) & ~M8600_ICRD, PR_MERG);
293 	crlattach();
294 }
295 
296 /*
297  * Clear restart flag.
298  */
299 void
300 ka86_clrf()
301 {
302 	/*
303 	 * We block all interrupts here so that there won't be any
304 	 * interrupts for an ongoing printout.
305 	 */
306 	int s = splhigh(), old = mfpr(PR_TXCS);
307 
308 #define	WAIT	while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
309 
310 	WAIT;
311 
312 	/* Enable channel to console */
313 	mtpr(GC_LT|GC_WRT, PR_TXCS);
314 	WAIT;
315 
316 	/* clear warm start flag */
317 	mtpr(GC_CWFL, PR_TXDB);
318 	WAIT;
319 
320 	/* clear cold start flag */
321 	mtpr(GC_CCFL, PR_TXDB);
322 	WAIT;
323 
324 	/* restore old state */
325 	mtpr(old|GC_WRT, PR_TXCS);
326 	splx(s);
327 }
328 
329 void
330 ka86_reboot(howto)
331 	int howto;
332 {
333 	WAIT;
334 
335 	/* Enable channel to console */
336 	mtpr(GC_LT|GC_WRT, PR_TXCS);
337 	WAIT;
338 
339 	mtpr(GC_BTFL, PR_TXDB);
340 	WAIT;
341 
342 	asm("halt");
343 }
344 
345 static	int abus_print __P((void *, const char *));
346 static  int abus_match __P((struct device *, struct cfdata *, void *));
347 static  void abus_attach __P((struct device *, struct device *, void*));
348 
349 struct  cfattach abus_ca = {
350         sizeof(struct device), abus_match, abus_attach
351 };
352 
353 /*
354  * Abus is the master bus on VAX 8600.
355  */
356 int
357 abus_match(parent, cf, aux)
358         struct device *parent;
359         struct cfdata *cf;
360         void *aux;
361 {
362         if (vax_bustype == VAX_ABUS)
363                 return 1;
364         return 0;
365 }
366 
367 void
368 abus_attach(parent, self, aux)
369         struct device *parent, *self;
370         void *aux;
371 {
372         volatile int tmp;
373         volatile struct sbia_regs *sbiar;
374         struct ioa *ioa;
375         int     type, i;
376 	struct bp_conf bp;
377 
378 	/*
379 	 * Init CPU.
380 	 */
381 	ka860_init(self);
382 
383         for (i = 0; i < MAXNIOA; i++) {
384                 ioa = (struct ioa *)vax_map_physmem((paddr_t)IOA8600(0),
385                     (IOAMAPSIZ / VAX_NBPG));
386                 if (badaddr((caddr_t)ioa, 4)) {
387                         vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG));
388                         continue;
389                 }
390                 tmp = ioa->ioacsr.ioa_csr;
391                 type = tmp & IOA_TYPMSK;
392 
393                 switch (type) {
394 
395                 case IOA_SBIA:
396                         bp.type = "sbi";
397                         bp.num = i;
398                         config_found(self, &bp, abus_print);
399                         sbiar = (void *)ioa;
400                         sbiar->sbi_errsum = -1;
401                         sbiar->sbi_error = 0x1000;
402                         sbiar->sbi_fltsts = 0xc0000;
403                         break;
404 
405                 default:
406                         printf("IOAdapter %x unsupported\n", type);
407                         break;
408                 }
409                 vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG));
410         }
411 }
412 
413 int
414 abus_print(aux, hej)
415         void *aux;
416         const char *hej;
417 {
418         struct bp_conf *bp = aux;
419         if (hej)
420                 printf("%s at %s", bp->type, hej);
421         return (UNCONF);
422 }
423