1 | /*-------------------------------------*/ |
---|
2 | /* fault.c */ |
---|
3 | /* Last change : 13. 7.95 */ |
---|
4 | /*-------------------------------------*/ |
---|
5 | /* |
---|
6 | * $Id$ |
---|
7 | */ |
---|
8 | |
---|
9 | #include "prcb.h" |
---|
10 | #include "i960.h" |
---|
11 | #include "flttbl.h" |
---|
12 | #include "fault.h" |
---|
13 | #include "asmstub.h" |
---|
14 | #include <stdio.h> |
---|
15 | #include <string.h> |
---|
16 | |
---|
17 | extern void romFaultStart(void); |
---|
18 | |
---|
19 | /*-------------------------------------*/ |
---|
20 | /* Table of user-registered fault handler entry. |
---|
21 | */ |
---|
22 | typedef struct { |
---|
23 | UserFaultHandler hndl; /* Handler itself. */ |
---|
24 | int cnt; /* Handler is valid for cnt times. */ |
---|
25 | } UserFaultEntry; |
---|
26 | /* Table itself. |
---|
27 | */ |
---|
28 | static UserFaultEntry userFaultTable[] = { |
---|
29 | {0, 0}, /* Parallel */ |
---|
30 | {0, 0}, /* Trace */ |
---|
31 | {0, 0}, /* Operation */ |
---|
32 | {0, 0}, /* Arithmetic */ |
---|
33 | {0, 0}, /* Reserved */ |
---|
34 | {0, 0}, /* Constraint */ |
---|
35 | {0, 0}, /* Reserved */ |
---|
36 | {0, 0}, /* Protection */ |
---|
37 | {0, 0}, /* Reserved */ |
---|
38 | {0, 0} /* Type */ |
---|
39 | }; |
---|
40 | /* Number of Faults. |
---|
41 | */ |
---|
42 | #define FaultNmbr (sizeof(userFaultTable)/sizeof(UserFaultEntry)) |
---|
43 | |
---|
44 | int faultRegister(int fault, UserFaultHandler hndl, int cnt) |
---|
45 | { |
---|
46 | static unsigned int faultNewCheckSum(void); |
---|
47 | int rsl = 0; |
---|
48 | |
---|
49 | if (0 <= fault && fault <= FaultNmbr) { |
---|
50 | /* Register handler. |
---|
51 | */ |
---|
52 | userFaultTable[fault].hndl = hndl; |
---|
53 | userFaultTable[fault].cnt = cnt; |
---|
54 | /* Checksum has changed. |
---|
55 | */ |
---|
56 | faultCheckSum = faultNewCheckSum(); |
---|
57 | rsl = 1; |
---|
58 | } |
---|
59 | return rsl; |
---|
60 | } |
---|
61 | int faultOk(int fault) |
---|
62 | { |
---|
63 | static unsigned int faultNewCheckSum(void); |
---|
64 | int rsl = 0; |
---|
65 | |
---|
66 | if (0 <= fault && fault <= FaultNmbr) { |
---|
67 | /* Fault handler recovered successfully. |
---|
68 | * Can use it at least once more. |
---|
69 | */ |
---|
70 | userFaultTable[fault].cnt ++; |
---|
71 | /* Check sum has changed. |
---|
72 | */ |
---|
73 | #if 0 |
---|
74 | faultCheckSum = faultNewCheckSum(); |
---|
75 | #endif |
---|
76 | faultCheckSum ++; |
---|
77 | rsl = 1; |
---|
78 | } |
---|
79 | return rsl; |
---|
80 | } |
---|
81 | void faultBad(int invokedFromRom, |
---|
82 | unsigned int inst, unsigned int * faultBuffer, |
---|
83 | unsigned int type, unsigned int sbtp) |
---|
84 | { |
---|
85 | static void faultInfo(int invokedFromRom, |
---|
86 | unsigned int inst, unsigned int * faultBuffer, |
---|
87 | unsigned int type, unsigned int sbtp); |
---|
88 | |
---|
89 | /* Close the mem channel nicely. |
---|
90 | */ |
---|
91 | /* memChnlI960Fault();*/ |
---|
92 | /* Give some panic message. |
---|
93 | */ |
---|
94 | faultInfo(invokedFromRom, inst, faultBuffer, type, sbtp); |
---|
95 | /* At this point RAM is repaired. Do |
---|
96 | * whatever you want. |
---|
97 | */ |
---|
98 | #if 0 |
---|
99 | if (OsfIsUp) { |
---|
100 | asm_exit(romFaultStart, & ram_prcb); |
---|
101 | } |
---|
102 | else { |
---|
103 | asm_exit(romStart, & ram_prcb); |
---|
104 | } |
---|
105 | # endif |
---|
106 | asm_exit(romFaultStart, & ram_prcb); |
---|
107 | } |
---|
108 | void faultGood(unsigned int inst, unsigned int * faultBuffer, |
---|
109 | unsigned int type, unsigned int sbtp) |
---|
110 | { |
---|
111 | static unsigned int faultNewCheckSum(void); |
---|
112 | |
---|
113 | if (userFaultTable[type].hndl != 0 && userFaultTable[type].cnt > 0) { |
---|
114 | /* This is done to avoid the situation when |
---|
115 | * handler causes a fault and, thus, infinite recursion. |
---|
116 | */ |
---|
117 | userFaultTable[type].cnt --; |
---|
118 | /* Check sum has changed. |
---|
119 | */ |
---|
120 | #if 0 |
---|
121 | faultCheckSum = faultNewCheckSum(); |
---|
122 | #endif |
---|
123 | faultCheckSum --; |
---|
124 | /* Invoke handler. |
---|
125 | */ |
---|
126 | (* userFaultTable[type].hndl)(inst, faultBuffer, type, sbtp); |
---|
127 | /* If this returns => fault is bad. |
---|
128 | */ |
---|
129 | } |
---|
130 | faultBad(0, inst, faultBuffer, type, sbtp); |
---|
131 | } |
---|
132 | static unsigned int faultNewCheckSum(void) |
---|
133 | { |
---|
134 | unsigned int * f = faultStart; |
---|
135 | unsigned int * l = faultEnd; |
---|
136 | unsigned int sum; |
---|
137 | |
---|
138 | for (sum = 0; f < l; f ++) { |
---|
139 | sum += * f; |
---|
140 | } |
---|
141 | return sum; |
---|
142 | } |
---|
143 | static void faultInfo(int invokedFromRom, |
---|
144 | unsigned int inst, unsigned int * faultBuffer, |
---|
145 | unsigned int type, unsigned int sbtp) |
---|
146 | { |
---|
147 | char * typeStr; |
---|
148 | char * sbtpStr; |
---|
149 | static char * faultParallelSbtpStr(unsigned int); |
---|
150 | static char * faultTraceSbtpStr(unsigned int); |
---|
151 | static char * faultOperationSbtpStr(unsigned int); |
---|
152 | static char * faultArithmeticSbtpStr(unsigned int); |
---|
153 | static char * faultReservedSbtpStr(unsigned int); |
---|
154 | static char * faultConstraintSbtpStr(unsigned int); |
---|
155 | static char * faultProtectionSbtpStr(unsigned int); |
---|
156 | static char * faultTypeSbtpStr(unsigned int); |
---|
157 | static char * faultUnknownSbtpStr(unsigned int); |
---|
158 | static struct { |
---|
159 | char * name; |
---|
160 | char * (* sbtpStr)(unsigned int); |
---|
161 | } faultInfo[] = { |
---|
162 | {"Parallel", faultParallelSbtpStr}, |
---|
163 | {"Trace", faultTraceSbtpStr}, |
---|
164 | {"Operation", faultOperationSbtpStr}, |
---|
165 | {"Arithmetic", faultArithmeticSbtpStr}, |
---|
166 | {"Reserved", faultReservedSbtpStr}, |
---|
167 | {"Constraint", faultConstraintSbtpStr}, |
---|
168 | {"Reserved", faultReservedSbtpStr}, |
---|
169 | {"Protection", faultProtectionSbtpStr}, |
---|
170 | {"Reserved", faultReservedSbtpStr}, |
---|
171 | {"Type", faultTypeSbtpStr}, |
---|
172 | {"Unknown", faultUnknownSbtpStr} |
---|
173 | }; |
---|
174 | unsigned int ix; |
---|
175 | |
---|
176 | /* console_set_channel(CHANNEL_B);*/ |
---|
177 | ix = type >= FaultNmbr ? FaultNmbr : type; |
---|
178 | typeStr = faultInfo[ix].name; |
---|
179 | sbtpStr = (* faultInfo[ix].sbtpStr)(sbtp); |
---|
180 | printf("\nFault at 0x%08x: %s[%s]\n", |
---|
181 | faultBuffer[IP_REGNUM], typeStr, sbtpStr); |
---|
182 | printf("Bad instruction: 0x%08x\n", inst); |
---|
183 | printf("AC=0x%08x PC=0x%08x\n", |
---|
184 | faultBuffer[ACW_REGNUM], |
---|
185 | faultBuffer[PCW_REGNUM]); |
---|
186 | printf("g0=0x%08x g1=0x%08x g2=0x%08x g3=0x%08x\n", |
---|
187 | faultBuffer[G0_REGNUM+0], faultBuffer[G0_REGNUM+1], |
---|
188 | faultBuffer[G0_REGNUM+2], faultBuffer[G0_REGNUM+3]); |
---|
189 | printf("g4=0x%08x g5=0x%08x g6=0x%08x g7=0x%08x\n", |
---|
190 | faultBuffer[G0_REGNUM+4], faultBuffer[G0_REGNUM+5], |
---|
191 | faultBuffer[G0_REGNUM+6], faultBuffer[G0_REGNUM+7]); |
---|
192 | printf("g8=0x%08x g9=0x%08x gA=0x%08x gB=0x%08x\n", |
---|
193 | faultBuffer[G0_REGNUM+8], faultBuffer[G0_REGNUM+9], |
---|
194 | faultBuffer[G0_REGNUM+10], faultBuffer[G0_REGNUM+11]); |
---|
195 | printf("gC=0x%08x gD=0x%08x gE=0x%08x gF=0x%08x\n", |
---|
196 | faultBuffer[G0_REGNUM+12], faultBuffer[G0_REGNUM+13], |
---|
197 | faultBuffer[G0_REGNUM+14], faultBuffer[G0_REGNUM+15]); |
---|
198 | printf("r0=0x%08x r1=0x%08x r2=0x%08x r3=0x%08x\n", |
---|
199 | faultBuffer[R0_REGNUM+0], faultBuffer[R0_REGNUM+1], |
---|
200 | faultBuffer[R0_REGNUM+2], faultBuffer[R0_REGNUM+3]); |
---|
201 | printf("r4=0x%08x r5=0x%08x r6=0x%08x r7=0x%08x\n", |
---|
202 | faultBuffer[R0_REGNUM+4], faultBuffer[R0_REGNUM+5], |
---|
203 | faultBuffer[R0_REGNUM+6], faultBuffer[R0_REGNUM+7]); |
---|
204 | printf("r8=0x%08x r9=0x%08x rA=0x%08x rB=0x%08x\n", |
---|
205 | faultBuffer[R0_REGNUM+8], faultBuffer[R0_REGNUM+9], |
---|
206 | faultBuffer[R0_REGNUM+10], faultBuffer[R0_REGNUM+11]); |
---|
207 | printf("rC=0x%08x rD=0x%08x rE=0x%08x rF=0x%08x\n", |
---|
208 | faultBuffer[R0_REGNUM+12], faultBuffer[R0_REGNUM+13], |
---|
209 | faultBuffer[R0_REGNUM+14], faultBuffer[R0_REGNUM+15]); |
---|
210 | if (invokedFromRom) { |
---|
211 | printf("RAM image damaged. No chance to recover\n"); |
---|
212 | } |
---|
213 | else { |
---|
214 | printf("RAM image not damaged. Still no recovery\n"); |
---|
215 | } |
---|
216 | } |
---|
217 | static char * faultParallelSbtpStr(unsigned int sbtp) |
---|
218 | { |
---|
219 | static char buf[10]; |
---|
220 | |
---|
221 | sprintf(buf, "%d", sbtp); |
---|
222 | return buf; |
---|
223 | } |
---|
224 | static char * faultTraceSbtpStr(unsigned int sbtp) |
---|
225 | { |
---|
226 | static char buf[256]; |
---|
227 | int notEmpty; |
---|
228 | |
---|
229 | buf[0] = '\0'; |
---|
230 | notEmpty = 0; |
---|
231 | if (sbtp & 0x2) { |
---|
232 | strcat(buf, "Instruction"); |
---|
233 | notEmpty = 1; |
---|
234 | } |
---|
235 | if (sbtp & 0x4) { |
---|
236 | if (notEmpty) strcat(buf, ":"); |
---|
237 | strcat(buf, "Branch"); |
---|
238 | notEmpty = 1; |
---|
239 | } |
---|
240 | if (sbtp & 0x8) { |
---|
241 | if (notEmpty) strcat(buf, ":"); |
---|
242 | strcat(buf, "Call"); |
---|
243 | notEmpty = 1; |
---|
244 | } |
---|
245 | if (sbtp & 0x10) { |
---|
246 | if (notEmpty) strcat(buf, ":"); |
---|
247 | strcat(buf, "Return"); |
---|
248 | notEmpty = 1; |
---|
249 | } |
---|
250 | if (sbtp & 0x20) { |
---|
251 | if (notEmpty) strcat(buf, ":"); |
---|
252 | strcat(buf, "Prereturn"); |
---|
253 | notEmpty = 1; |
---|
254 | } |
---|
255 | if (sbtp & 0x40) { |
---|
256 | if (notEmpty) strcat(buf, ":"); |
---|
257 | strcat(buf, "Supervisor"); |
---|
258 | notEmpty = 1; |
---|
259 | } |
---|
260 | if (sbtp & 0x80) { |
---|
261 | if (notEmpty) strcat(buf, ":"); |
---|
262 | strcat(buf, "Breakpoint"); |
---|
263 | notEmpty = 1; |
---|
264 | } |
---|
265 | if (! notEmpty) { |
---|
266 | strcat(buf, "Unknown"); |
---|
267 | } |
---|
268 | return buf; |
---|
269 | } |
---|
270 | static char * faultOperationSbtpStr(unsigned int sbtp) |
---|
271 | { |
---|
272 | char * rsl; |
---|
273 | |
---|
274 | if (sbtp == 0x1) rsl = "Invalid Opcode"; |
---|
275 | else if (sbtp == 0x2) rsl = "Unimplemented"; |
---|
276 | else if (sbtp == 0x3) rsl = "Unaligned"; |
---|
277 | else if (sbtp == 0x4) rsl = "Invalid Operand"; |
---|
278 | else rsl = "Unknown"; |
---|
279 | return rsl; |
---|
280 | } |
---|
281 | static char * faultArithmeticSbtpStr(unsigned int sbtp) |
---|
282 | { |
---|
283 | char * rsl; |
---|
284 | |
---|
285 | if (sbtp == 0x1) rsl = "Integer Overflow"; |
---|
286 | else if (sbtp == 0x2) rsl = "Arithmetic Zero-Divide"; |
---|
287 | else rsl = "Unknown"; |
---|
288 | return rsl; |
---|
289 | } |
---|
290 | static char * faultReservedSbtpStr(unsigned int sbtp) |
---|
291 | { |
---|
292 | return "Unknown"; |
---|
293 | } |
---|
294 | static char * faultConstraintSbtpStr(unsigned int sbtp) |
---|
295 | { |
---|
296 | char * rsl; |
---|
297 | |
---|
298 | if (sbtp == 0x1) rsl = "Constraint Range"; |
---|
299 | else if (sbtp == 0x2) rsl = "Priveleged"; |
---|
300 | else rsl = "Unknown"; |
---|
301 | return rsl; |
---|
302 | } |
---|
303 | static char * faultProtectionSbtpStr(unsigned int sbtp) |
---|
304 | { |
---|
305 | char * rsl; |
---|
306 | |
---|
307 | if (sbtp == 0x1) rsl = "Length"; |
---|
308 | else rsl = "Unknown"; |
---|
309 | return rsl; |
---|
310 | } |
---|
311 | static char * faultTypeSbtpStr(unsigned int sbtp) |
---|
312 | { |
---|
313 | char * rsl; |
---|
314 | |
---|
315 | if (sbtp == 0x1) rsl = "Type Mismatch"; |
---|
316 | else rsl = "Unknown"; |
---|
317 | return rsl; |
---|
318 | } |
---|
319 | static char * faultUnknownSbtpStr(unsigned int sbtp) |
---|
320 | { |
---|
321 | return "Unknown"; |
---|
322 | } |
---|
323 | /*-------------*/ |
---|
324 | /* End of file */ |
---|
325 | /*-------------*/ |
---|
326 | |
---|