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