xref: /original-bsd/sys/vax/vax/ka780.c (revision 0999a820)
1 /*-
2  * Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ka780.c	7.4 (Berkeley) 05/09/91
8  */
9 
10 #if VAX780
11 
12 /*
13  * 780-specific code.
14  */
15 
16 #include "sys/param.h"
17 
18 #include "../include/cpu.h"
19 #include "mem.h"
20 #include "../include/mtpr.h"
21 
22 /*
23  * Memory controller register usage varies per controller.
24  */
25 struct	mcr780 {
26 	int	mc_reg[4];
27 };
28 
29 #define	M780_ICRD	0x40000000	/* inhibit crd interrupts, in [2] */
30 #define	M780_HIER	0x20000000	/* high error rate, in reg[2] */
31 #define	M780_ERLOG	0x10000000	/* error log request, in reg[2] */
32 /* on a 780, memory crd's occur only when bit 15 is set in the SBIER */
33 /* register; bit 14 there is an error bit which we also clear */
34 /* these bits are in the back of the ``red book'' (or in the VMS code) */
35 
36 #define	M780C_INH(mcr)	\
37 	(((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0))
38 #define	M780C_ENA(mcr)	\
39 	(((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14))
40 #define	M780C_ERR(mcr)	\
41 	((mcr)->mc_reg[2] & (M780_ERLOG))
42 
43 #define	M780C_SYN(mcr)	((mcr)->mc_reg[2] & 0xff)
44 #define	M780C_ADDR(mcr)	(((mcr)->mc_reg[2] >> 8) & 0xfffff)
45 
46 #define	M780EL_INH(mcr)	\
47 	(((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0))
48 #define	M780EL_ENA(mcr)	\
49 	(((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14))
50 #define	M780EL_ERR(mcr)	\
51 	((mcr)->mc_reg[2] & (M780_ERLOG))
52 
53 #define	M780EL_SYN(mcr)		((mcr)->mc_reg[2] & 0x7f)
54 #define	M780EL_ADDR(mcr)	(((mcr)->mc_reg[2] >> 11) & 0x1ffff)
55 
56 #define	M780EU_INH(mcr)	\
57 	(((mcr)->mc_reg[3] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0))
58 #define	M780EU_ENA(mcr)	\
59 	(((mcr)->mc_reg[3] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14))
60 #define	M780EU_ERR(mcr)	\
61 	((mcr)->mc_reg[3] & (M780_ERLOG))
62 
63 #define	M780EU_SYN(mcr)		((mcr)->mc_reg[3] & 0x7f)
64 #define	M780EU_ADDR(mcr)	(((mcr)->mc_reg[3] >> 11) & 0x1ffff)
65 
66 /* enable crd interrrupts */
67 ka780_memenable()
68 {
69 	register struct mcr780 *mcr;
70 	register int m;
71 
72 	for (m = 0; m < nmcr; m++) {
73 		mcr = (struct mcr780 *)mcraddr[m];
74 		switch (mcrtype[m]) {
75 
76 		case M780C:
77 			M780C_ENA(mcr);
78 			break;
79 
80 		case M780EL:
81 			M780EL_ENA(mcr);
82 			break;
83 
84 		case M780EU:
85 			M780EU_ENA(mcr);
86 			break;
87 		}
88 	}
89 }
90 
91 /* log crd errors */
92 ka780_memerr()
93 {
94 	register struct mcr780 *mcr;
95 	register int m;
96 
97 	for (m = 0; m < nmcr; m++) {
98 		mcr = (struct mcr780 *)mcraddr[m];
99 		switch (mcrtype[m]) {
100 
101 		case M780C:
102 			if (M780C_ERR(mcr)) {
103 				printf("mcr%d: soft ecc addr %x syn %x\n",
104 				    m, M780C_ADDR(mcr), M780C_SYN(mcr));
105 #ifdef TRENDATA
106 				memlog(m, mcr);
107 #endif
108 				M780C_INH(mcr);
109 			}
110 			break;
111 
112 		case M780EL:
113 			if (M780EL_ERR(mcr)) {
114 				printf("mcr%d: soft ecc addr %x syn %x\n",
115 				    m, M780EL_ADDR(mcr), M780EL_SYN(mcr));
116 				M780EL_INH(mcr);
117 			}
118 			break;
119 
120 		case M780EU:
121 			if (M780EU_ERR(mcr)) {
122 				printf("mcr%d: soft ecc addr %x syn %x\n",
123 				    m, M780EU_ADDR(mcr), M780EU_SYN(mcr));
124 				M780EU_INH(mcr);
125 			}
126 			break;
127 		}
128 	}
129 }
130 
131 #ifdef TRENDATA
132 /*
133  * Figure out what chip to replace on Trendata boards.
134  * Assumes all your memory is Trendata or the non-Trendata
135  * memory never fails..
136  */
137 struct {
138 	u_char	m_syndrome;
139 	char	m_chip[4];
140 } memlogtab[] = {
141 	0x01,	"C00",	0x02,	"C01",	0x04,	"C02",	0x08,	"C03",
142 	0x10,	"C04",	0x19,	"L01",	0x1A,	"L02",	0x1C,	"L04",
143 	0x1F,	"L07",	0x20,	"C05",	0x38,	"L00",	0x3B,	"L03",
144 	0x3D,	"L05",	0x3E,	"L06",	0x40,	"C06",	0x49,	"L09",
145 	0x4A,	"L10",	0x4c,	"L12",	0x4F,	"L15",	0x51,	"L17",
146 	0x52,	"L18",	0x54,	"L20",	0x57,	"L23",	0x58,	"L24",
147 	0x5B,	"L27",	0x5D,	"L29",	0x5E,	"L30",	0x68,	"L08",
148 	0x6B,	"L11",	0x6D,	"L13",	0x6E,	"L14",	0x70,	"L16",
149 	0x73,	"L19",	0x75,	"L21",	0x76,	"L22",	0x79,	"L25",
150 	0x7A,	"L26",	0x7C,	"L28",	0x7F,	"L31",	0x80,	"C07",
151 	0x89,	"U01",	0x8A,	"U02",	0x8C,	"U04",	0x8F,	"U07",
152 	0x91,	"U09",	0x92,	"U10",	0x94,	"U12",	0x97, 	"U15",
153 	0x98,	"U16",	0x9B,	"U19",	0x9D,	"U21",	0x9E, 	"U22",
154 	0xA8,	"U00",	0xAB,	"U03",	0xAD,	"U05",	0xAE,	"U06",
155 	0xB0,	"U08",	0xB3,	"U11",	0xB5,	"U13",	0xB6,	"U14",
156 	0xB9,	"U17",	0xBA,	"U18",	0xBC,	"U20",	0xBF,	"U23",
157 	0xC1,	"U25",	0xC2,	"U26",	0xC4,	"U28",	0xC7,	"U31",
158 	0xE0,	"U24",	0xE3,	"U27",	0xE5,	"U29",	0xE6,	"U30"
159 };
160 
161 memlog(m, mcr)
162 	int m;
163 	struct mcr780 *mcr;
164 {
165 	register i;
166 
167 	for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++)
168 		if ((u_char)(M780C_SYN(mcr)) == memlogtab[i].m_syndrome) {
169 			printf (
170 	"mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n",
171 				m,
172 				memlogtab[i].m_chip,
173 				(M780C_ADDR(mcr) & 0x8000) ? "upper" : "lower",
174 				(M780C_ADDR(mcr) >> 16));
175 			return;
176 		}
177 	printf ("mcr%d: multiple errors, not traceable\n", m);
178 	break;
179 }
180 #endif TRENDATA
181 
182 extern char *mc780750[];
183 
184 struct mc780frame {
185 	int	mc8_bcnt;		/* byte count == 0x28 */
186 	int	mc8_summary;		/* summary parameter (as above) */
187 	int	mc8_cpues;		/* cpu error status */
188 	int	mc8_upc;		/* micro pc */
189 	int	mc8_vaviba;		/* va/viba register */
190 	int	mc8_dreg;		/* d register */
191 	int	mc8_tber0;		/* tbuf error reg 0 */
192 	int	mc8_tber1;		/* tbuf error reg 1 */
193 	int	mc8_timo;		/* timeout address divided by 4 */
194 	int	mc8_parity;		/* parity */
195 	int	mc8_sbier;		/* sbi error register */
196 	int	mc8_pc;			/* trapped pc */
197 	int	mc8_psl;		/* trapped psl */
198 };
199 
200 ka780_mchk(cmcf)
201 	caddr_t cmcf;
202 {
203 	register struct mc780frame *mcf = (struct mc780frame *)cmcf;
204 	register int type = mcf->mc8_summary;
205 	register int sbifs;
206 
207 	printf("machine check %x: %s%s\n", type, mc780750[type&0xf],
208 	    (type&0xf0) ? " abort" : " fault");
209 	printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n",
210 	   mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba,
211 	   mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1);
212 	sbifs = mfpr(SBIFS);
213 	printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n",
214 	   mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier,
215 	   mcf->mc8_pc, mcf->mc8_psl, sbifs);
216 	/* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK BOOK'' */
217 	/* AND SHOULD BE PUT IN AN ``sbi.h'' */
218 	mtpr(SBIFS, sbifs &~ 0x2000000);
219 	mtpr(SBIER, mfpr(SBIER) | 0x70c0);
220 	return (MCHK_PANIC);
221 }
222 #endif
223