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