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