Commit | Line | Data |
---|---|---|
025fd248 | 1 | /* |
3907f97a MK |
2 | * Copyright (c) 1986, 1988 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
ad787160 C |
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. | |
3907f97a | 20 | * |
ad787160 C |
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. | |
32 | * | |
33 | * @(#)ka860.c 7.4 (Berkeley) 12/16/90 | |
025fd248 MK |
34 | */ |
35 | ||
36 | #if VAX8600 | |
37 | ||
38 | /* | |
39 | * VAX 8600 specific routines. | |
40 | */ | |
41 | ||
b28b3a13 | 42 | #include "sys/param.h" |
025fd248 | 43 | |
b28b3a13 KB |
44 | #include "../include/cpu.h" |
45 | #include "../include/mtpr.h" | |
025fd248 MK |
46 | |
47 | /* | |
48 | * 8600 memory register (MERG) bit definitions | |
49 | */ | |
50 | #define M8600_ICRD 0x400 /* inhibit crd interrupts */ | |
51 | #define M8600_TB_ERR 0xf00 /* translation buffer error mask */ | |
52 | ||
53 | /* | |
54 | * MDECC register | |
55 | */ | |
56 | #define M8600_ADDR_PE 0x080000 /* address parity error */ | |
57 | #define M8600_DBL_ERR 0x100000 /* data double bit error */ | |
58 | #define M8600_SNG_ERR 0x200000 /* data single bit error */ | |
59 | #define M8600_BDT_ERR 0x400000 /* bad data error */ | |
60 | ||
61 | /* | |
62 | * ESPA register is used to address scratch pad registers in the Ebox. | |
63 | * To access a register in the scratch pad, write the ESPA with the address | |
64 | * and then read the ESPD register. | |
65 | * | |
66 | * NOTE: In assmebly code, the mfpr instruction that reads the ESPD | |
67 | * register must immedately follow the mtpr instruction that setup | |
68 | * the ESPA register -- per the VENUS processor register spec. | |
69 | * | |
70 | * The scratchpad registers that are supplied for a single bit ECC | |
71 | * error are: | |
72 | */ | |
73 | #define SPAD_MSTAT1 0x25 /* scratch pad mstat1 register */ | |
74 | #define SPAD_MSTAT2 0x26 /* scratch pad mstat2 register */ | |
75 | #define SPAD_MDECC 0x27 /* scratch pad mdecc register */ | |
76 | #define SPAD_MEAR 0x2a /* scratch pad mear register */ | |
77 | ||
78 | #define M8600_MEMERR(mdecc) ((mdecc) & 0x780000) | |
79 | #define M8600_HRDERR(mdecc) ((mdecc) & 0x580000) | |
80 | #define M8600_SYN(mdecc) (((mdecc) >> 9) & 0x3f) | |
81 | #define M8600_ADDR(mear) ((mear) & 0x3ffffffc) | |
82 | #define M8600_ARRAY(mear) (((mear) >> 22) & 0x0f) | |
83 | ||
84 | #define M8600_MDECC_BITS \ | |
85 | "\20\27BAD_DT_ERR\26SNG_BIT_ERR\25DBL_BIT_ERR\24ADDR_PE" | |
86 | ||
87 | #define M8600_MSTAT1_BITS "\20\30CPR_PE_A\27CPR_PE_B\26ABUS_DT_PE\ | |
88 | \25ABUS_CTL_MSK_PE\24ABUS_ADR_PE\23ABUS_C/A_CYCLE\22ABUS_ADP_1\21ABUS_ADP_0\ | |
89 | \20TB_MISS\17BLK_HIT\16C0_TAG_MISS\15CHE_MISS\14TB_VAL_ERR\13TB_PTE_B_PE\ | |
90 | \12TB_PTE_A_PE\11TB_TAG_PE\10WR_DT_PE_B3\7WR_DT_PE_B2\6WR_DT_PE_B1\ | |
91 | \5WR_DT_PE_B0\4CHE_RD_DT_PE\3CHE_SEL\2ANY_REFL\1CP_BW_CHE_DT_PE" | |
92 | ||
93 | #define M8600_MSTAT2_BITS "\20\20CP_BYT_WR\17ABUS_BD_DT_CODE\10MULT_ERR\ | |
94 | \7CHE_TAG_PE\6CHE_TAG_W_PE\5CHE_WRTN_BIT\4NXM\3CP-IO_BUF_ERR\2MBOX_LOCK" | |
95 | ||
96 | /* enable CRD reports */ | |
97 | ka860_memenable() | |
98 | { | |
99 | ||
100 | mtpr(MERG, mfpr(MERG) & ~M8600_ICRD); | |
101 | } | |
102 | ||
103 | /* log CRD errors */ | |
104 | ka860_memerr() | |
105 | { | |
106 | register int reg11; /* known to be r11 below */ | |
107 | int mdecc, mear, mstat1, mstat2, array; | |
108 | ||
109 | /* | |
110 | * Scratchpad registers in the Ebox must be read by | |
111 | * storing their ID number in ESPA and then immediately | |
112 | * reading ESPD's contents with no other intervening | |
113 | * machine instructions! | |
114 | * | |
115 | * The asm's below have a number of constants which | |
116 | * are defined correctly above and in mtpr.h. | |
117 | */ | |
118 | #ifdef lint | |
119 | reg11 = 0; | |
120 | #else | |
121 | asm("mtpr $0x27,$0x4e; mfpr $0x4f,r11"); | |
122 | #endif | |
123 | mdecc = reg11; /* must acknowledge interrupt? */ | |
124 | if (M8600_MEMERR(mdecc)) { | |
125 | asm("mtpr $0x2a,$0x4e; mfpr $0x4f,r11"); | |
126 | mear = reg11; | |
127 | asm("mtpr $0x25,$0x4e; mfpr $0x4f,r11"); | |
128 | mstat1 = reg11; | |
129 | asm("mtpr $0x26,$0x4e; mfpr $0x4f,r11"); | |
130 | mstat2 = reg11; | |
131 | array = M8600_ARRAY(mear); | |
132 | ||
133 | printf("mcr0: ecc error, addr %x (array %d) syn %x\n", | |
134 | M8600_ADDR(mear), array, M8600_SYN(mdecc)); | |
135 | printf("\tMSTAT1 = %b\n\tMSTAT2 = %b\n", | |
136 | mstat1, M8600_MSTAT1_BITS, | |
137 | mstat2, M8600_MSTAT2_BITS); | |
138 | mtpr(EHSR, 0); | |
139 | mtpr(MERG, mfpr(MERG) | M8600_ICRD); | |
140 | } | |
141 | } | |
142 | ||
143 | #define NMC8600 7 | |
144 | char *mc8600[] = { | |
145 | "unkn type", "fbox error", "ebox error", "ibox error", | |
146 | "mbox error", "tbuf error", "mbox 1D error" | |
147 | }; | |
148 | /* codes for above */ | |
149 | #define MC_FBOX 1 | |
150 | #define MC_EBOX 2 | |
151 | #define MC_IBOX 3 | |
152 | #define MC_MBOX 4 | |
153 | #define MC_TBUF 5 | |
154 | #define MC_MBOX1D 6 | |
155 | ||
156 | /* error bits */ | |
157 | #define MBOX_FE 0x8000 /* Mbox fatal error */ | |
158 | #define FBOX_SERV 0x10000000 /* Fbox service error */ | |
159 | #define IBOX_ERR 0x2000 /* Ibox error */ | |
160 | #define EBOX_ERR 0x1e00 /* Ebox error */ | |
161 | #define MBOX_1D 0x81d0000 /* Mbox 1D error */ | |
162 | #define EDP_PE 0x200 | |
163 | ||
164 | struct mc8600frame { | |
165 | int mc86_bcnt; /* byte count == 0x58 */ | |
166 | int mc86_ehmsts; | |
167 | int mc86_evmqsav; | |
168 | int mc86_ebcs; | |
169 | int mc86_edpsr; | |
170 | int mc86_cslint; | |
171 | int mc86_ibesr; | |
172 | int mc86_ebxwd1; | |
173 | int mc86_ebxwd2; | |
174 | int mc86_ivasav; | |
175 | int mc86_vibasav; | |
176 | int mc86_esasav; | |
177 | int mc86_isasav; | |
178 | int mc86_cpc; | |
179 | int mc86_mstat1; | |
180 | int mc86_mstat2; | |
181 | int mc86_mdecc; | |
182 | int mc86_merg; | |
183 | int mc86_cshctl; | |
184 | int mc86_mear; | |
185 | int mc86_medr; | |
186 | int mc86_accs; | |
187 | int mc86_cses; | |
188 | int mc86_pc; /* trapped pc */ | |
189 | int mc86_psl; /* trapped psl */ | |
190 | }; | |
191 | ||
192 | /* machine check */ | |
193 | ka860_mchk(cmcf) | |
194 | caddr_t cmcf; | |
195 | { | |
196 | register struct mc8600frame *mcf = (struct mc8600frame *)cmcf; | |
197 | register int type; | |
198 | ||
199 | if (mcf->mc86_ebcs & MBOX_FE) | |
200 | mcf->mc86_ehmsts |= MC_MBOX; | |
201 | else if (mcf->mc86_ehmsts & FBOX_SERV) | |
202 | mcf->mc86_ehmsts |= MC_FBOX; | |
203 | else if (mcf->mc86_ebcs & EBOX_ERR) { | |
204 | if (mcf->mc86_ebcs & EDP_PE) | |
205 | mcf->mc86_ehmsts |= MC_MBOX; | |
206 | else | |
207 | mcf->mc86_ehmsts |= MC_EBOX; | |
208 | } else if (mcf->mc86_ehmsts & IBOX_ERR) | |
209 | mcf->mc86_ehmsts |= MC_IBOX; | |
210 | else if (mcf->mc86_mstat1 & M8600_TB_ERR) | |
211 | mcf->mc86_ehmsts |= MC_TBUF; | |
212 | else if ((mcf->mc86_cslint & MBOX_1D) == MBOX_1D) | |
213 | mcf->mc86_ehmsts |= MC_MBOX1D; | |
214 | ||
215 | type = mcf->mc86_ehmsts & 0x7; | |
216 | printf("machine check %x: %s\n", type, | |
217 | type < NMC8600 ? mc8600[type] : "???"); | |
218 | printf("\tehm.sts %x evmqsav %x ebcs %x edpsr %x cslint %x\n", | |
219 | mcf->mc86_ehmsts, mcf->mc86_evmqsav, mcf->mc86_ebcs, | |
220 | mcf->mc86_edpsr, mcf->mc86_cslint); | |
221 | printf("\tibesr %x ebxwd %x %x ivasav %x vibasav %x\n", | |
222 | mcf->mc86_ibesr, mcf->mc86_ebxwd1, mcf->mc86_ebxwd2, | |
223 | mcf->mc86_ivasav, mcf->mc86_vibasav); | |
224 | printf("\tesasav %x isasav %x cpc %x mstat %x %x mdecc %x\n", | |
225 | mcf->mc86_esasav, mcf->mc86_isasav, mcf->mc86_cpc, | |
226 | mcf->mc86_mstat1, mcf->mc86_mstat2, mcf->mc86_mdecc); | |
227 | printf("\tmerg %x cshctl %x mear %x medr %x accs %x cses %x\n", | |
228 | mcf->mc86_merg, mcf->mc86_cshctl, mcf->mc86_mear, | |
229 | mcf->mc86_medr, mcf->mc86_accs, mcf->mc86_cses); | |
230 | printf("\tpc %x psl %x\n", mcf->mc86_pc, mcf->mc86_psl); | |
231 | mtpr(EHSR, 0); | |
232 | return (MCHK_PANIC); | |
233 | } | |
234 | #endif |