xref: /original-bsd/sys/vax/vax/ka650.c (revision 8431ec24)
1 /*
2  * Copyright (c) 1988 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Mt. Xinu.
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  *	@(#)ka650.c	7.5 (Berkeley) 11/08/88
21  */
22 
23 #if VAX650
24 
25 /*
26  * vax650-specific code.
27  */
28 
29 #include "param.h"
30 #include "time.h"
31 #include "kernel.h"
32 #include "systm.h"
33 
34 #include "cpu.h"
35 #include "clock.h"
36 #include "psl.h"
37 #include "mem.h"
38 #include "mtpr.h"
39 #include "ka650.h"
40 
41 
42 ka650_init()
43 {
44 	ioaccess(KA650_MERR, KA650MERRmap, sizeof(ka650merr));
45 	ioaccess(KA650_CBD, KA650CBDmap, sizeof(ka650cbd));
46 	ioaccess(KA650_SSC, KA650SSCmap, sizeof(ka650ssc));
47 	ioaccess(KA650_IPCR, KA650IPCRmap, sizeof(ka650ipcr));
48 	ioaccess(KA650_CACHE, KA650CACHEmap, KA650_CACHESIZE);
49 	ka650encache();
50 	if (ctob(physmem) > ka650merr.merr_qbmbr) {
51 		printf("physmem(0x%x) > qbmbr(0x%x)\n",
52 		    ctob(physmem), ka650merr.merr_qbmbr);
53 		panic("qbus map unprotected");
54 	}
55 }
56 
57 ka650_clkstartrt()
58 {
59 	mtpr(ICCS, ICCS_IE);
60 }
61 
62 ka650_memnop()
63 {
64 	/* void */
65 }
66 
67 ka650_memerr()
68 {
69 	register char *cp = (char *)0;
70 	register int m;
71 	extern u_int cache2tag;
72 
73 	if (ka650cbd.cbd_cacr & CACR_CPE) {
74 		printf("cache 2 tag parity error: ");
75 		if (time.tv_sec - cache2tag < 7) {
76 			ka650discache();
77 			printf("cacheing disabled\n");
78 		} else {
79 			cache2tag = time.tv_sec;
80 			printf("flushing cache\n");
81 			ka650encache();
82 		}
83 	}
84 	m = ka650merr.merr_errstat;
85 	ka650merr.merr_errstat = MEM_EMASK;
86 	if (m & MEM_CDAL) {
87 		cp = "Bus Parity";
88 	} else if (m & MEM_RDS) {
89 		cp = "Hard ECC";
90 	} else if (m & MEM_CRD) {
91 		cp = "Soft ECC";
92 	}
93 	if (cp) {
94 		printf("%sMemory %s Error: page 0x%x\n",
95 			(m & MEM_DMA) ? "DMA " : "", cp,
96 			(m & MEM_PAGE) >> MEM_PAGESHFT);
97 	}
98 }
99 
100 #define NMC650	15
101 char *mc650[] = {
102 	0,			"FPA proto err",	"FPA resv inst",
103 	"FPA Ill Stat 2",	"FPA Ill Stat 1",	"PTE in P0, TB miss",
104 	"PTE in P1, TB miss",	"PTE in P0, Mod",	"PTE in P1, Mod",
105 	"Illegal intr IPL",	"MOVC state error",	"bus read error",
106 	"SCB read error",	"bus write error",	"PCB write error"
107 };
108 u_int	cache1tag;
109 u_int	cache1data;
110 u_int	cdalerr;
111 u_int	cache2tag;
112 
113 struct mc650frame {
114 	int	mc65_bcnt;		/* byte count == 0xc */
115 	int	mc65_summary;		/* summary parameter */
116 	int	mc65_mrvaddr;		/* most recent vad */
117 	int	mc65_istate1;		/* internal state */
118 	int	mc65_istate2;		/* internal state */
119 	int	mc65_pc;		/* trapped pc */
120 	int	mc65_psl;		/* trapped psl */
121 };
122 
123 ka650_mchk(cmcf)
124 	caddr_t cmcf;
125 {
126 	register struct mc650frame *mcf = (struct mc650frame *)cmcf;
127 	register u_int type = mcf->mc65_summary;
128 	register u_int i;
129 
130 	printf("machine check %x", type);
131 	if (type >= 0x80 && type <= 0x83)
132 		type -= (0x80 + 11);
133 	if (type < NMC650 && mc650[type])
134 		printf(": %s", mc650[type]);
135 	printf("\n\tvap %x istate1 %x istate2 %x pc %x psl %x\n",
136 	    mcf->mc65_mrvaddr, mcf->mc65_istate1, mcf->mc65_istate2,
137 	    mcf->mc65_pc, mcf->mc65_psl);
138 	printf("dmaser=0x%b qbear=0x%x dmaear=0x%x\n",
139 	    ka650merr.merr_dser, DMASER_BITS, ka650merr.merr_qbear,
140 	    ka650merr.merr_dear);
141 	ka650merr.merr_dser = DSER_CLEAR;
142 
143 	i = mfpr(CAER);
144 	mtpr(CAER, CAER_MCC | CAER_DAT | CAER_TAG);
145 	if (i & CAER_MCC) {
146 		printf("cache 1 ");
147 		if (i & CAER_DAT) {
148 			printf("data");
149 			i = cache1data;
150 			cache1data = time.tv_sec;
151 		}
152 		if (i & CAER_TAG) {
153 			printf("tag");
154 			i = cache1tag;
155 			cache1tag = time.tv_sec;
156 		}
157 	} else if ((i & CAER_MCD) || (ka650merr.merr_errstat & MEM_CDAL)) {
158 		printf("CDAL");
159 		i = cdalerr;
160 		cdalerr = time.tv_sec;
161 	}
162 	if (time.tv_sec - i < 7) {
163 		ka650discache();
164 		printf(" parity error:  cacheing disabled\n");
165 	} else {
166 		printf(" parity error:  flushing cache\n");
167 		ka650encache();
168 	}
169 	/*
170 	 * May be able to recover if type is 1-4, 0x80 or 0x81, but
171 	 * only if FPD is set in the saved PSL, or bit VCR in Istate2
172 	 * is clear.
173 	 */
174 	if ((type > 0 && type < 5) || type == 11 || type == 12) {
175 		if ((mcf->mc65_psl & PSL_FPD)
176 		    || !(mcf->mc65_istate2 & IS2_VCR)) {
177 			ka650_memerr();
178 			return (MCHK_RECOVERED);
179 		}
180 	}
181 	return (MCHK_PANIC);
182 }
183 
184 /*
185  * Make sure both caches are off and not in diagnostic mode.  Clear the
186  * 2nd level cache (by writing to each quadword entry), then enable it.
187  * Enable 1st level cache too.
188  */
189 ka650encache()
190 {
191 	register int i;
192 
193 	ka650discache();
194 	for (i = 0; i < (KA650_CACHESIZE / sizeof(ka650cache[0])); i += 2)
195 		ka650cache[i] = 0;
196 	ka650cbd.cbd_cacr = CACR_CEN;
197 	mtpr(CADR, CADR_SEN2 | CADR_SEN1 | CADR_CENI | CADR_CEND);
198 }
199 
200 ka650discache()
201 {
202 	mtpr(CADR, 0);
203 	ka650cbd.cbd_cacr = CACR_CPE;
204 }
205 #endif
206