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