Commit | Line | Data |
---|---|---|
af359dea C |
1 | /*- |
2 | * Copyright (c) 1982, 1986, 1988 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
3907f97a | 32 | * |
af359dea | 33 | * @(#)ka780.c 7.4 (Berkeley) 5/9/91 |
025fd248 MK |
34 | */ |
35 | ||
36 | #if VAX780 | |
37 | ||
38 | /* | |
39 | * 780-specific code. | |
40 | */ | |
41 | ||
b28b3a13 | 42 | #include "sys/param.h" |
025fd248 | 43 | |
b28b3a13 | 44 | #include "../include/cpu.h" |
025fd248 | 45 | #include "mem.h" |
b28b3a13 | 46 | #include "../include/mtpr.h" |
025fd248 MK |
47 | |
48 | /* | |
49 | * Memory controller register usage varies per controller. | |
50 | */ | |
51 | struct mcr780 { | |
52 | int mc_reg[4]; | |
53 | }; | |
54 | ||
55 | #define M780_ICRD 0x40000000 /* inhibit crd interrupts, in [2] */ | |
56 | #define M780_HIER 0x20000000 /* high error rate, in reg[2] */ | |
57 | #define M780_ERLOG 0x10000000 /* error log request, in reg[2] */ | |
58 | /* on a 780, memory crd's occur only when bit 15 is set in the SBIER */ | |
59 | /* register; bit 14 there is an error bit which we also clear */ | |
60 | /* these bits are in the back of the ``red book'' (or in the VMS code) */ | |
61 | ||
62 | #define M780C_INH(mcr) \ | |
63 | (((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) | |
64 | #define M780C_ENA(mcr) \ | |
65 | (((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) | |
66 | #define M780C_ERR(mcr) \ | |
67 | ((mcr)->mc_reg[2] & (M780_ERLOG)) | |
68 | ||
69 | #define M780C_SYN(mcr) ((mcr)->mc_reg[2] & 0xff) | |
70 | #define M780C_ADDR(mcr) (((mcr)->mc_reg[2] >> 8) & 0xfffff) | |
71 | ||
72 | #define M780EL_INH(mcr) \ | |
73 | (((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) | |
74 | #define M780EL_ENA(mcr) \ | |
75 | (((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) | |
76 | #define M780EL_ERR(mcr) \ | |
77 | ((mcr)->mc_reg[2] & (M780_ERLOG)) | |
78 | ||
79 | #define M780EL_SYN(mcr) ((mcr)->mc_reg[2] & 0x7f) | |
80 | #define M780EL_ADDR(mcr) (((mcr)->mc_reg[2] >> 11) & 0x1ffff) | |
81 | ||
82 | #define M780EU_INH(mcr) \ | |
83 | (((mcr)->mc_reg[3] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) | |
84 | #define M780EU_ENA(mcr) \ | |
85 | (((mcr)->mc_reg[3] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) | |
86 | #define M780EU_ERR(mcr) \ | |
87 | ((mcr)->mc_reg[3] & (M780_ERLOG)) | |
88 | ||
89 | #define M780EU_SYN(mcr) ((mcr)->mc_reg[3] & 0x7f) | |
90 | #define M780EU_ADDR(mcr) (((mcr)->mc_reg[3] >> 11) & 0x1ffff) | |
91 | ||
92 | /* enable crd interrrupts */ | |
93 | ka780_memenable() | |
94 | { | |
95 | register struct mcr780 *mcr; | |
96 | register int m; | |
97 | ||
98 | for (m = 0; m < nmcr; m++) { | |
99 | mcr = (struct mcr780 *)mcraddr[m]; | |
100 | switch (mcrtype[m]) { | |
101 | ||
102 | case M780C: | |
103 | M780C_ENA(mcr); | |
104 | break; | |
105 | ||
106 | case M780EL: | |
107 | M780EL_ENA(mcr); | |
108 | break; | |
109 | ||
110 | case M780EU: | |
111 | M780EU_ENA(mcr); | |
112 | break; | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
117 | /* log crd errors */ | |
118 | ka780_memerr() | |
119 | { | |
120 | register struct mcr780 *mcr; | |
121 | register int m; | |
122 | ||
123 | for (m = 0; m < nmcr; m++) { | |
124 | mcr = (struct mcr780 *)mcraddr[m]; | |
125 | switch (mcrtype[m]) { | |
126 | ||
127 | case M780C: | |
128 | if (M780C_ERR(mcr)) { | |
129 | printf("mcr%d: soft ecc addr %x syn %x\n", | |
130 | m, M780C_ADDR(mcr), M780C_SYN(mcr)); | |
131 | #ifdef TRENDATA | |
132 | memlog(m, mcr); | |
133 | #endif | |
134 | M780C_INH(mcr); | |
135 | } | |
136 | break; | |
137 | ||
138 | case M780EL: | |
139 | if (M780EL_ERR(mcr)) { | |
140 | printf("mcr%d: soft ecc addr %x syn %x\n", | |
141 | m, M780EL_ADDR(mcr), M780EL_SYN(mcr)); | |
142 | M780EL_INH(mcr); | |
143 | } | |
144 | break; | |
145 | ||
146 | case M780EU: | |
147 | if (M780EU_ERR(mcr)) { | |
148 | printf("mcr%d: soft ecc addr %x syn %x\n", | |
149 | m, M780EU_ADDR(mcr), M780EU_SYN(mcr)); | |
150 | M780EU_INH(mcr); | |
151 | } | |
152 | break; | |
153 | } | |
154 | } | |
155 | } | |
156 | ||
157 | #ifdef TRENDATA | |
158 | /* | |
159 | * Figure out what chip to replace on Trendata boards. | |
160 | * Assumes all your memory is Trendata or the non-Trendata | |
161 | * memory never fails.. | |
162 | */ | |
163 | struct { | |
164 | u_char m_syndrome; | |
165 | char m_chip[4]; | |
166 | } memlogtab[] = { | |
167 | 0x01, "C00", 0x02, "C01", 0x04, "C02", 0x08, "C03", | |
168 | 0x10, "C04", 0x19, "L01", 0x1A, "L02", 0x1C, "L04", | |
169 | 0x1F, "L07", 0x20, "C05", 0x38, "L00", 0x3B, "L03", | |
170 | 0x3D, "L05", 0x3E, "L06", 0x40, "C06", 0x49, "L09", | |
171 | 0x4A, "L10", 0x4c, "L12", 0x4F, "L15", 0x51, "L17", | |
172 | 0x52, "L18", 0x54, "L20", 0x57, "L23", 0x58, "L24", | |
173 | 0x5B, "L27", 0x5D, "L29", 0x5E, "L30", 0x68, "L08", | |
174 | 0x6B, "L11", 0x6D, "L13", 0x6E, "L14", 0x70, "L16", | |
175 | 0x73, "L19", 0x75, "L21", 0x76, "L22", 0x79, "L25", | |
176 | 0x7A, "L26", 0x7C, "L28", 0x7F, "L31", 0x80, "C07", | |
177 | 0x89, "U01", 0x8A, "U02", 0x8C, "U04", 0x8F, "U07", | |
178 | 0x91, "U09", 0x92, "U10", 0x94, "U12", 0x97, "U15", | |
179 | 0x98, "U16", 0x9B, "U19", 0x9D, "U21", 0x9E, "U22", | |
180 | 0xA8, "U00", 0xAB, "U03", 0xAD, "U05", 0xAE, "U06", | |
181 | 0xB0, "U08", 0xB3, "U11", 0xB5, "U13", 0xB6, "U14", | |
182 | 0xB9, "U17", 0xBA, "U18", 0xBC, "U20", 0xBF, "U23", | |
183 | 0xC1, "U25", 0xC2, "U26", 0xC4, "U28", 0xC7, "U31", | |
184 | 0xE0, "U24", 0xE3, "U27", 0xE5, "U29", 0xE6, "U30" | |
185 | }; | |
186 | ||
187 | memlog(m, mcr) | |
188 | int m; | |
189 | struct mcr780 *mcr; | |
190 | { | |
191 | register i; | |
192 | ||
193 | for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++) | |
194 | if ((u_char)(M780C_SYN(mcr)) == memlogtab[i].m_syndrome) { | |
195 | printf ( | |
196 | "mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n", | |
197 | m, | |
198 | memlogtab[i].m_chip, | |
199 | (M780C_ADDR(mcr) & 0x8000) ? "upper" : "lower", | |
200 | (M780C_ADDR(mcr) >> 16)); | |
201 | return; | |
202 | } | |
203 | printf ("mcr%d: multiple errors, not traceable\n", m); | |
204 | break; | |
205 | } | |
206 | #endif TRENDATA | |
207 | ||
208 | extern char *mc780750[]; | |
209 | ||
210 | struct mc780frame { | |
211 | int mc8_bcnt; /* byte count == 0x28 */ | |
212 | int mc8_summary; /* summary parameter (as above) */ | |
213 | int mc8_cpues; /* cpu error status */ | |
214 | int mc8_upc; /* micro pc */ | |
215 | int mc8_vaviba; /* va/viba register */ | |
216 | int mc8_dreg; /* d register */ | |
217 | int mc8_tber0; /* tbuf error reg 0 */ | |
218 | int mc8_tber1; /* tbuf error reg 1 */ | |
219 | int mc8_timo; /* timeout address divided by 4 */ | |
220 | int mc8_parity; /* parity */ | |
221 | int mc8_sbier; /* sbi error register */ | |
222 | int mc8_pc; /* trapped pc */ | |
223 | int mc8_psl; /* trapped psl */ | |
224 | }; | |
225 | ||
226 | ka780_mchk(cmcf) | |
227 | caddr_t cmcf; | |
228 | { | |
229 | register struct mc780frame *mcf = (struct mc780frame *)cmcf; | |
230 | register int type = mcf->mc8_summary; | |
231 | register int sbifs; | |
232 | ||
233 | printf("machine check %x: %s%s\n", type, mc780750[type&0xf], | |
234 | (type&0xf0) ? " abort" : " fault"); | |
235 | printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n", | |
236 | mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba, | |
237 | mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1); | |
238 | sbifs = mfpr(SBIFS); | |
239 | printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n", | |
240 | mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier, | |
241 | mcf->mc8_pc, mcf->mc8_psl, sbifs); | |
242 | /* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK BOOK'' */ | |
243 | /* AND SHOULD BE PUT IN AN ``sbi.h'' */ | |
244 | mtpr(SBIFS, sbifs &~ 0x2000000); | |
245 | mtpr(SBIER, mfpr(SBIER) | 0x70c0); | |
246 | return (MCHK_PANIC); | |
247 | } | |
248 | #endif |