]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/alpha/kernel/err_titan.c
Remove two unneeded exports and make two symbols static in fs/mpage.c
[mirror_ubuntu-bionic-kernel.git] / arch / alpha / kernel / err_titan.c
1 /*
2 * linux/arch/alpha/kernel/err_titan.c
3 *
4 * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
5 *
6 * Error handling code supporting TITAN systems
7 */
8
9 #include <linux/init.h>
10 #include <linux/pci.h>
11 #include <linux/sched.h>
12
13 #include <asm/io.h>
14 #include <asm/core_titan.h>
15 #include <asm/hwrpb.h>
16 #include <asm/smp.h>
17 #include <asm/err_common.h>
18 #include <asm/err_ev6.h>
19 #include <asm/irq_regs.h>
20
21 #include "err_impl.h"
22 #include "proto.h"
23
24
25 static int
26 titan_parse_c_misc(u64 c_misc, int print)
27 {
28 #ifdef CONFIG_VERBOSE_MCHECK
29 char *src;
30 int nxs = 0;
31 #endif
32 int status = MCHK_DISPOSITION_REPORT;
33
34 #define TITAN__CCHIP_MISC__NXM (1UL << 28)
35 #define TITAN__CCHIP_MISC__NXS__S (29)
36 #define TITAN__CCHIP_MISC__NXS__M (0x7)
37
38 if (!(c_misc & TITAN__CCHIP_MISC__NXM))
39 return MCHK_DISPOSITION_UNKNOWN_ERROR;
40
41 #ifdef CONFIG_VERBOSE_MCHECK
42 if (!print)
43 return status;
44
45 nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS);
46 switch(nxs) {
47 case 0: /* CPU 0 */
48 case 1: /* CPU 1 */
49 case 2: /* CPU 2 */
50 case 3: /* CPU 3 */
51 src = "CPU";
52 /* num is already the CPU number */
53 break;
54 case 4: /* Pchip 0 */
55 case 5: /* Pchip 1 */
56 src = "Pchip";
57 nxs -= 4;
58 break;
59 default:/* reserved */
60 src = "Unknown, NXS =";
61 /* leave num untouched */
62 break;
63 }
64
65 printk("%s Non-existent memory access from: %s %d\n",
66 err_print_prefix, src, nxs);
67 #endif /* CONFIG_VERBOSE_MCHECK */
68
69 return status;
70 }
71
72 static int
73 titan_parse_p_serror(int which, u64 serror, int print)
74 {
75 int status = MCHK_DISPOSITION_REPORT;
76
77 #ifdef CONFIG_VERBOSE_MCHECK
78 char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"};
79 char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"};
80 #endif /* CONFIG_VERBOSE_MCHECK */
81
82 #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0)
83 #define TITAN__PCHIP_SERROR__UECC (1UL << 1)
84 #define TITAN__PCHIP_SERROR__CRE (1UL << 2)
85 #define TITAN__PCHIP_SERROR__NXIO (1UL << 3)
86 #define TITAN__PCHIP_SERROR__LOST_CRE (1UL << 4)
87 #define TITAN__PCHIP_SERROR__ECCMASK (TITAN__PCHIP_SERROR__UECC | \
88 TITAN__PCHIP_SERROR__CRE)
89 #define TITAN__PCHIP_SERROR__ERRMASK (TITAN__PCHIP_SERROR__LOST_UECC | \
90 TITAN__PCHIP_SERROR__UECC | \
91 TITAN__PCHIP_SERROR__CRE | \
92 TITAN__PCHIP_SERROR__NXIO | \
93 TITAN__PCHIP_SERROR__LOST_CRE)
94 #define TITAN__PCHIP_SERROR__SRC__S (52)
95 #define TITAN__PCHIP_SERROR__SRC__M (0x3)
96 #define TITAN__PCHIP_SERROR__CMD__S (54)
97 #define TITAN__PCHIP_SERROR__CMD__M (0x3)
98 #define TITAN__PCHIP_SERROR__SYN__S (56)
99 #define TITAN__PCHIP_SERROR__SYN__M (0xff)
100 #define TITAN__PCHIP_SERROR__ADDR__S (15)
101 #define TITAN__PCHIP_SERROR__ADDR__M (0xffffffffUL)
102
103 if (!(serror & TITAN__PCHIP_SERROR__ERRMASK))
104 return MCHK_DISPOSITION_UNKNOWN_ERROR;
105
106 #ifdef CONFIG_VERBOSE_MCHECK
107 if (!print)
108 return status;
109
110 printk("%s PChip %d SERROR: %016lx\n",
111 err_print_prefix, which, serror);
112 if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
113 printk("%s %sorrectable ECC Error:\n"
114 " Source: %-6s Command: %-8s Syndrome: 0x%08x\n"
115 " Address: 0x%lx\n",
116 err_print_prefix,
117 (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
118 serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
119 serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)],
120 (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN),
121 EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR));
122 }
123 if (serror & TITAN__PCHIP_SERROR__NXIO)
124 printk("%s Non Existent I/O Error\n", err_print_prefix);
125 if (serror & TITAN__PCHIP_SERROR__LOST_UECC)
126 printk("%s Lost Uncorrectable ECC Error\n",
127 err_print_prefix);
128 if (serror & TITAN__PCHIP_SERROR__LOST_CRE)
129 printk("%s Lost Correctable ECC Error\n", err_print_prefix);
130 #endif /* CONFIG_VERBOSE_MCHECK */
131
132 return status;
133 }
134
135 static int
136 titan_parse_p_perror(int which, int port, u64 perror, int print)
137 {
138 int cmd;
139 unsigned long addr;
140 int status = MCHK_DISPOSITION_REPORT;
141
142 #ifdef CONFIG_VERBOSE_MCHECK
143 char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle",
144 "I/O Read", "I/O Write",
145 "Reserved", "Reserved",
146 "Memory Read", "Memory Write",
147 "Reserved", "Reserved",
148 "Configuration Read", "Configuration Write",
149 "Memory Read Multiple", "Dual Address Cycle",
150 "Memory Read Line","Memory Write and Invalidate"
151 };
152 #endif /* CONFIG_VERBOSE_MCHECK */
153
154 #define TITAN__PCHIP_PERROR__LOST (1UL << 0)
155 #define TITAN__PCHIP_PERROR__SERR (1UL << 1)
156 #define TITAN__PCHIP_PERROR__PERR (1UL << 2)
157 #define TITAN__PCHIP_PERROR__DCRTO (1UL << 3)
158 #define TITAN__PCHIP_PERROR__SGE (1UL << 4)
159 #define TITAN__PCHIP_PERROR__APE (1UL << 5)
160 #define TITAN__PCHIP_PERROR__TA (1UL << 6)
161 #define TITAN__PCHIP_PERROR__DPE (1UL << 7)
162 #define TITAN__PCHIP_PERROR__NDS (1UL << 8)
163 #define TITAN__PCHIP_PERROR__IPTPR (1UL << 9)
164 #define TITAN__PCHIP_PERROR__IPTPW (1UL << 10)
165 #define TITAN__PCHIP_PERROR__ERRMASK (TITAN__PCHIP_PERROR__LOST | \
166 TITAN__PCHIP_PERROR__SERR | \
167 TITAN__PCHIP_PERROR__PERR | \
168 TITAN__PCHIP_PERROR__DCRTO | \
169 TITAN__PCHIP_PERROR__SGE | \
170 TITAN__PCHIP_PERROR__APE | \
171 TITAN__PCHIP_PERROR__TA | \
172 TITAN__PCHIP_PERROR__DPE | \
173 TITAN__PCHIP_PERROR__NDS | \
174 TITAN__PCHIP_PERROR__IPTPR | \
175 TITAN__PCHIP_PERROR__IPTPW)
176 #define TITAN__PCHIP_PERROR__DAC (1UL << 47)
177 #define TITAN__PCHIP_PERROR__MWIN (1UL << 48)
178 #define TITAN__PCHIP_PERROR__CMD__S (52)
179 #define TITAN__PCHIP_PERROR__CMD__M (0x0f)
180 #define TITAN__PCHIP_PERROR__ADDR__S (14)
181 #define TITAN__PCHIP_PERROR__ADDR__M (0x1fffffffful)
182
183 if (!(perror & TITAN__PCHIP_PERROR__ERRMASK))
184 return MCHK_DISPOSITION_UNKNOWN_ERROR;
185
186 cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD);
187 addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2;
188
189 /*
190 * Initializing the BIOS on a video card on a bus without
191 * a south bridge (subtractive decode agent) can result in
192 * master aborts as the BIOS probes the capabilities of the
193 * card. XFree86 does such initialization. If the error
194 * is a master abort (No DevSel as PCI Master) and the command
195 * is an I/O read or write below the address where we start
196 * assigning PCI I/O spaces (SRM uses 0x1000), then mark the
197 * error as dismissable so starting XFree86 doesn't result
198 * in a series of uncorrectable errors being reported. Also
199 * dismiss master aborts to VGA frame buffer space
200 * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000)
201 * for the same reason.
202 *
203 * Also mark the error dismissible if it looks like the right
204 * error but only the Lost bit is set. Since the BIOS initialization
205 * can cause multiple master aborts and the error interrupt can
206 * be handled on a different CPU than the BIOS code is run on,
207 * it is possible for a second master abort to occur between the
208 * time the PALcode reads PERROR and the time it writes PERROR
209 * to acknowledge the error. If this timing happens, a second
210 * error will be signalled after the first, and if no additional
211 * errors occur, will look like a Lost error with no additional
212 * errors on the same transaction as the previous error.
213 */
214 if (((perror & TITAN__PCHIP_PERROR__NDS) ||
215 ((perror & TITAN__PCHIP_PERROR__ERRMASK) ==
216 TITAN__PCHIP_PERROR__LOST)) &&
217 ((((cmd & 0xE) == 2) && (addr < 0x1000)) ||
218 (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) {
219 status = MCHK_DISPOSITION_DISMISS;
220 }
221
222 #ifdef CONFIG_VERBOSE_MCHECK
223 if (!print)
224 return status;
225
226 printk("%s PChip %d %cPERROR: %016lx\n",
227 err_print_prefix, which,
228 port ? 'A' : 'G', perror);
229 if (perror & TITAN__PCHIP_PERROR__IPTPW)
230 printk("%s Invalid Peer-to-Peer Write\n", err_print_prefix);
231 if (perror & TITAN__PCHIP_PERROR__IPTPR)
232 printk("%s Invalid Peer-to-Peer Read\n", err_print_prefix);
233 if (perror & TITAN__PCHIP_PERROR__NDS)
234 printk("%s No DEVSEL as PCI Master [Master Abort]\n",
235 err_print_prefix);
236 if (perror & TITAN__PCHIP_PERROR__DPE)
237 printk("%s Data Parity Error\n", err_print_prefix);
238 if (perror & TITAN__PCHIP_PERROR__TA)
239 printk("%s Target Abort\n", err_print_prefix);
240 if (perror & TITAN__PCHIP_PERROR__APE)
241 printk("%s Address Parity Error\n", err_print_prefix);
242 if (perror & TITAN__PCHIP_PERROR__SGE)
243 printk("%s Scatter-Gather Error, Invalid PTE\n",
244 err_print_prefix);
245 if (perror & TITAN__PCHIP_PERROR__DCRTO)
246 printk("%s Delayed-Completion Retry Timeout\n",
247 err_print_prefix);
248 if (perror & TITAN__PCHIP_PERROR__PERR)
249 printk("%s PERR Asserted\n", err_print_prefix);
250 if (perror & TITAN__PCHIP_PERROR__SERR)
251 printk("%s SERR Asserted\n", err_print_prefix);
252 if (perror & TITAN__PCHIP_PERROR__LOST)
253 printk("%s Lost Error\n", err_print_prefix);
254 printk("%s Command: 0x%x - %s\n"
255 " Address: 0x%lx\n",
256 err_print_prefix,
257 cmd, perror_cmd[cmd],
258 addr);
259 if (perror & TITAN__PCHIP_PERROR__DAC)
260 printk("%s Dual Address Cycle\n", err_print_prefix);
261 if (perror & TITAN__PCHIP_PERROR__MWIN)
262 printk("%s Hit in Monster Window\n", err_print_prefix);
263 #endif /* CONFIG_VERBOSE_MCHECK */
264
265 return status;
266 }
267
268 static int
269 titan_parse_p_agperror(int which, u64 agperror, int print)
270 {
271 int status = MCHK_DISPOSITION_REPORT;
272 #ifdef CONFIG_VERBOSE_MCHECK
273 int cmd, len;
274 unsigned long addr;
275
276 char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)",
277 "Write (low-priority)",
278 "Write (high-priority)",
279 "Reserved", "Reserved",
280 "Flush", "Fence"
281 };
282 #endif /* CONFIG_VERBOSE_MCHECK */
283
284 #define TITAN__PCHIP_AGPERROR__LOST (1UL << 0)
285 #define TITAN__PCHIP_AGPERROR__LPQFULL (1UL << 1)
286 #define TITAN__PCHIP_AGPERROR__HPQFULL (1UL << 2)
287 #define TITAN__PCHIP_AGPERROR__RESCMD (1UL << 3)
288 #define TITAN__PCHIP_AGPERROR__IPTE (1UL << 4)
289 #define TITAN__PCHIP_AGPERROR__PTP (1UL << 5)
290 #define TITAN__PCHIP_AGPERROR__NOWINDOW (1UL << 6)
291 #define TITAN__PCHIP_AGPERROR__ERRMASK (TITAN__PCHIP_AGPERROR__LOST | \
292 TITAN__PCHIP_AGPERROR__LPQFULL | \
293 TITAN__PCHIP_AGPERROR__HPQFULL | \
294 TITAN__PCHIP_AGPERROR__RESCMD | \
295 TITAN__PCHIP_AGPERROR__IPTE | \
296 TITAN__PCHIP_AGPERROR__PTP | \
297 TITAN__PCHIP_AGPERROR__NOWINDOW)
298 #define TITAN__PCHIP_AGPERROR__DAC (1UL << 48)
299 #define TITAN__PCHIP_AGPERROR__MWIN (1UL << 49)
300 #define TITAN__PCHIP_AGPERROR__FENCE (1UL << 59)
301 #define TITAN__PCHIP_AGPERROR__CMD__S (50)
302 #define TITAN__PCHIP_AGPERROR__CMD__M (0x07)
303 #define TITAN__PCHIP_AGPERROR__ADDR__S (15)
304 #define TITAN__PCHIP_AGPERROR__ADDR__M (0xffffffffUL)
305 #define TITAN__PCHIP_AGPERROR__LEN__S (53)
306 #define TITAN__PCHIP_AGPERROR__LEN__M (0x3f)
307
308 if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK))
309 return MCHK_DISPOSITION_UNKNOWN_ERROR;
310
311 #ifdef CONFIG_VERBOSE_MCHECK
312 if (!print)
313 return status;
314
315 cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD);
316 addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
317 len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
318
319 printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix,
320 which, agperror);
321 if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
322 printk("%s No Window\n", err_print_prefix);
323 if (agperror & TITAN__PCHIP_AGPERROR__PTP)
324 printk("%s Peer-to-Peer set\n", err_print_prefix);
325 if (agperror & TITAN__PCHIP_AGPERROR__IPTE)
326 printk("%s Invalid PTE\n", err_print_prefix);
327 if (agperror & TITAN__PCHIP_AGPERROR__RESCMD)
328 printk("%s Reserved Command\n", err_print_prefix);
329 if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL)
330 printk("%s HP Transaction Received while Queue Full\n",
331 err_print_prefix);
332 if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL)
333 printk("%s LP Transaction Received while Queue Full\n",
334 err_print_prefix);
335 if (agperror & TITAN__PCHIP_AGPERROR__LOST)
336 printk("%s Lost Error\n", err_print_prefix);
337 printk("%s Command: 0x%x - %s, %d Quadwords%s\n"
338 " Address: 0x%lx\n",
339 err_print_prefix, cmd, agperror_cmd[cmd], len,
340 (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "",
341 addr);
342 if (agperror & TITAN__PCHIP_AGPERROR__DAC)
343 printk("%s Dual Address Cycle\n", err_print_prefix);
344 if (agperror & TITAN__PCHIP_AGPERROR__MWIN)
345 printk("%s Hit in Monster Window\n", err_print_prefix);
346 #endif /* CONFIG_VERBOSE_MCHECK */
347
348 return status;
349 }
350
351 static int
352 titan_parse_p_chip(int which, u64 serror, u64 gperror,
353 u64 aperror, u64 agperror, int print)
354 {
355 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
356 status |= titan_parse_p_serror(which, serror, print);
357 status |= titan_parse_p_perror(which, 0, gperror, print);
358 status |= titan_parse_p_perror(which, 1, aperror, print);
359 status |= titan_parse_p_agperror(which, agperror, print);
360 return status;
361 }
362
363 int
364 titan_process_logout_frame(struct el_common *mchk_header, int print)
365 {
366 struct el_TITAN_sysdata_mcheck *tmchk =
367 (struct el_TITAN_sysdata_mcheck *)
368 ((unsigned long)mchk_header + mchk_header->sys_offset);
369 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
370
371 status |= titan_parse_c_misc(tmchk->c_misc, print);
372 status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror,
373 tmchk->p0_aperror, tmchk->p0_agperror,
374 print);
375 status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror,
376 tmchk->p1_aperror, tmchk->p1_agperror,
377 print);
378
379 return status;
380 }
381
382 void
383 titan_machine_check(u64 vector, u64 la_ptr)
384 {
385 struct el_common *mchk_header = (struct el_common *)la_ptr;
386 struct el_TITAN_sysdata_mcheck *tmchk =
387 (struct el_TITAN_sysdata_mcheck *)
388 ((unsigned long)mchk_header + mchk_header->sys_offset);
389 u64 irqmask;
390
391 /*
392 * Mask of Titan interrupt sources which are reported as machine checks
393 *
394 * 63 - CChip Error
395 * 62 - PChip 0 H_Error
396 * 61 - PChip 1 H_Error
397 * 60 - PChip 0 C_Error
398 * 59 - PChip 1 C_Error
399 */
400 #define TITAN_MCHECK_INTERRUPT_MASK 0xF800000000000000UL
401
402 /*
403 * Sync the processor
404 */
405 mb();
406 draina();
407
408 /*
409 * Only handle system errors here
410 */
411 if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) {
412 ev6_machine_check(vector, la_ptr);
413 return;
414 }
415
416 /*
417 * It's a system error, handle it here
418 *
419 * The PALcode has already cleared the error, so just parse it
420 */
421
422 /*
423 * Parse the logout frame without printing first. If the only error(s)
424 * found are classified as "dismissable", then just dismiss them and
425 * don't print any message
426 */
427 if (titan_process_logout_frame(mchk_header, 0) !=
428 MCHK_DISPOSITION_DISMISS) {
429 char *saved_err_prefix = err_print_prefix;
430 err_print_prefix = KERN_CRIT;
431
432 /*
433 * Either a nondismissable error was detected or no
434 * recognized error was detected in the logout frame
435 * -- report the error in either case
436 */
437 printk("%s"
438 "*System %s Error (Vector 0x%x) reported on CPU %d:\n",
439 err_print_prefix,
440 (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable",
441 (unsigned int)vector, (int)smp_processor_id());
442
443 #ifdef CONFIG_VERBOSE_MCHECK
444 titan_process_logout_frame(mchk_header, alpha_verbose_mcheck);
445 if (alpha_verbose_mcheck)
446 dik_show_regs(get_irq_regs(), NULL);
447 #endif /* CONFIG_VERBOSE_MCHECK */
448
449 err_print_prefix = saved_err_prefix;
450
451 /*
452 * Convert any pending interrupts which report as system
453 * machine checks to interrupts
454 */
455 irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK;
456 titan_dispatch_irqs(irqmask);
457 }
458
459
460 /*
461 * Release the logout frame
462 */
463 wrmces(0x7);
464 mb();
465 }
466
467 /*
468 * Subpacket Annotations
469 */
470 static char *el_titan_pchip0_extended_annotation[] = {
471 "Subpacket Header", "P0_SCTL", "P0_SERREN",
472 "P0_APCTL", "P0_APERREN", "P0_AGPERREN",
473 "P0_ASPRST", "P0_AWSBA0", "P0_AWSBA1",
474 "P0_AWSBA2", "P0_AWSBA3", "P0_AWSM0",
475 "P0_AWSM1", "P0_AWSM2", "P0_AWSM3",
476 "P0_ATBA0", "P0_ATBA1", "P0_ATBA2",
477 "P0_ATBA3", "P0_GPCTL", "P0_GPERREN",
478 "P0_GSPRST", "P0_GWSBA0", "P0_GWSBA1",
479 "P0_GWSBA2", "P0_GWSBA3", "P0_GWSM0",
480 "P0_GWSM1", "P0_GWSM2", "P0_GWSM3",
481 "P0_GTBA0", "P0_GTBA1", "P0_GTBA2",
482 "P0_GTBA3", NULL
483 };
484 static char *el_titan_pchip1_extended_annotation[] = {
485 "Subpacket Header", "P1_SCTL", "P1_SERREN",
486 "P1_APCTL", "P1_APERREN", "P1_AGPERREN",
487 "P1_ASPRST", "P1_AWSBA0", "P1_AWSBA1",
488 "P1_AWSBA2", "P1_AWSBA3", "P1_AWSM0",
489 "P1_AWSM1", "P1_AWSM2", "P1_AWSM3",
490 "P1_ATBA0", "P1_ATBA1", "P1_ATBA2",
491 "P1_ATBA3", "P1_GPCTL", "P1_GPERREN",
492 "P1_GSPRST", "P1_GWSBA0", "P1_GWSBA1",
493 "P1_GWSBA2", "P1_GWSBA3", "P1_GWSM0",
494 "P1_GWSM1", "P1_GWSM2", "P1_GWSM3",
495 "P1_GTBA0", "P1_GTBA1", "P1_GTBA2",
496 "P1_GTBA3", NULL
497 };
498 static char *el_titan_memory_extended_annotation[] = {
499 "Subpacket Header", "AAR0", "AAR1",
500 "AAR2", "AAR3", "P0_SCTL",
501 "P0_GPCTL", "P0_APCTL", "P1_SCTL",
502 "P1_GPCTL", "P1_SCTL", NULL
503 };
504
505 static struct el_subpacket_annotation el_titan_annotations[] = {
506 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
507 EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED,
508 1,
509 "Titan PChip 0 Extended Frame",
510 el_titan_pchip0_extended_annotation),
511 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
512 EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED,
513 1,
514 "Titan PChip 1 Extended Frame",
515 el_titan_pchip1_extended_annotation),
516 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
517 EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED,
518 1,
519 "Titan Memory Extended Frame",
520 el_titan_memory_extended_annotation),
521 SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
522 EL_TYPE__TERMINATION__TERMINATION,
523 1,
524 "Termination Subpacket",
525 NULL)
526 };
527
528 static struct el_subpacket *
529 el_process_regatta_subpacket(struct el_subpacket *header)
530 {
531 int status;
532
533 if (header->class != EL_CLASS__REGATTA_FAMILY) {
534 printk("%s ** Unexpected header CLASS %d TYPE %d, aborting\n",
535 err_print_prefix,
536 header->class, header->type);
537 return NULL;
538 }
539
540 switch(header->type) {
541 case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME:
542 case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME:
543 case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME:
544 case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT:
545 case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT:
546 printk("%s ** Occurred on CPU %d:\n",
547 err_print_prefix,
548 (int)header->by_type.regatta_frame.cpuid);
549 status = privateer_process_logout_frame((struct el_common *)
550 header->by_type.regatta_frame.data_start, 1);
551 break;
552 default:
553 printk("%s ** REGATTA TYPE %d SUBPACKET\n",
554 err_print_prefix, header->type);
555 el_annotate_subpacket(header);
556 break;
557 }
558
559
560 return (struct el_subpacket *)((unsigned long)header + header->length);
561 }
562
563 static struct el_subpacket_handler titan_subpacket_handler =
564 SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY,
565 el_process_regatta_subpacket);
566
567 void __init
568 titan_register_error_handlers(void)
569 {
570 size_t i;
571
572 for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++)
573 cdl_register_subpacket_annotation(&el_titan_annotations[i]);
574
575 cdl_register_subpacket_handler(&titan_subpacket_handler);
576
577 ev6_register_error_handlers();
578 }
579
580 \f
581 /*
582 * Privateer
583 */
584
585 static int
586 privateer_process_680_frame(struct el_common *mchk_header, int print)
587 {
588 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
589 #ifdef CONFIG_VERBOSE_MCHECK
590 struct el_PRIVATEER_envdata_mcheck *emchk =
591 (struct el_PRIVATEER_envdata_mcheck *)
592 ((unsigned long)mchk_header + mchk_header->sys_offset);
593
594 /* TODO - categorize errors, for now, no error */
595
596 if (!print)
597 return status;
598
599 /* TODO - decode instead of just dumping... */
600 printk("%s Summary Flags: %016lx\n"
601 " CChip DIRx: %016lx\n"
602 " System Management IR: %016lx\n"
603 " CPU IR: %016lx\n"
604 " Power Supply IR: %016lx\n"
605 " LM78 Fault Status: %016lx\n"
606 " System Doors: %016lx\n"
607 " Temperature Warning: %016lx\n"
608 " Fan Control: %016lx\n"
609 " Fatal Power Down Code: %016lx\n",
610 err_print_prefix,
611 emchk->summary,
612 emchk->c_dirx,
613 emchk->smir,
614 emchk->cpuir,
615 emchk->psir,
616 emchk->fault,
617 emchk->sys_doors,
618 emchk->temp_warn,
619 emchk->fan_ctrl,
620 emchk->code);
621 #endif /* CONFIG_VERBOSE_MCHECK */
622
623 return status;
624 }
625
626 int
627 privateer_process_logout_frame(struct el_common *mchk_header, int print)
628 {
629 struct el_common_EV6_mcheck *ev6mchk =
630 (struct el_common_EV6_mcheck *)mchk_header;
631 int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
632
633 /*
634 * Machine check codes
635 */
636 #define PRIVATEER_MCHK__CORR_ECC 0x86 /* 630 */
637 #define PRIVATEER_MCHK__DC_TAG_PERR 0x9E /* 630 */
638 #define PRIVATEER_MCHK__PAL_BUGCHECK 0x8E /* 670 */
639 #define PRIVATEER_MCHK__OS_BUGCHECK 0x90 /* 670 */
640 #define PRIVATEER_MCHK__PROC_HRD_ERR 0x98 /* 670 */
641 #define PRIVATEER_MCHK__ISTREAM_CMOV_PRX 0xA0 /* 670 */
642 #define PRIVATEER_MCHK__ISTREAM_CMOV_FLT 0xA2 /* 670 */
643 #define PRIVATEER_MCHK__SYS_HRD_ERR 0x202 /* 660 */
644 #define PRIVATEER_MCHK__SYS_CORR_ERR 0x204 /* 620 */
645 #define PRIVATEER_MCHK__SYS_ENVIRON 0x206 /* 680 */
646
647 switch(ev6mchk->MCHK_Code) {
648 /*
649 * Vector 630 - Processor, Correctable
650 */
651 case PRIVATEER_MCHK__CORR_ECC:
652 case PRIVATEER_MCHK__DC_TAG_PERR:
653 /*
654 * Fall through to vector 670 for processing...
655 */
656 /*
657 * Vector 670 - Processor, Uncorrectable
658 */
659 case PRIVATEER_MCHK__PAL_BUGCHECK:
660 case PRIVATEER_MCHK__OS_BUGCHECK:
661 case PRIVATEER_MCHK__PROC_HRD_ERR:
662 case PRIVATEER_MCHK__ISTREAM_CMOV_PRX:
663 case PRIVATEER_MCHK__ISTREAM_CMOV_FLT:
664 status |= ev6_process_logout_frame(mchk_header, print);
665 break;
666
667 /*
668 * Vector 620 - System, Correctable
669 */
670 case PRIVATEER_MCHK__SYS_CORR_ERR:
671 /*
672 * Fall through to vector 660 for processing...
673 */
674 /*
675 * Vector 660 - System, Uncorrectable
676 */
677 case PRIVATEER_MCHK__SYS_HRD_ERR:
678 status |= titan_process_logout_frame(mchk_header, print);
679 break;
680
681 /*
682 * Vector 680 - System, Environmental
683 */
684 case PRIVATEER_MCHK__SYS_ENVIRON: /* System, Environmental */
685 status |= privateer_process_680_frame(mchk_header, print);
686 break;
687
688 /*
689 * Unknown
690 */
691 default:
692 status |= MCHK_DISPOSITION_REPORT;
693 if (print) {
694 printk("%s** Unknown Error, frame follows\n",
695 err_print_prefix);
696 mchk_dump_logout_frame(mchk_header);
697 }
698
699 }
700
701 return status;
702 }
703
704 void
705 privateer_machine_check(u64 vector, u64 la_ptr)
706 {
707 struct el_common *mchk_header = (struct el_common *)la_ptr;
708 struct el_TITAN_sysdata_mcheck *tmchk =
709 (struct el_TITAN_sysdata_mcheck *)
710 (la_ptr + mchk_header->sys_offset);
711 u64 irqmask;
712 char *saved_err_prefix = err_print_prefix;
713
714 #define PRIVATEER_680_INTERRUPT_MASK (0xE00UL)
715 #define PRIVATEER_HOTPLUG_INTERRUPT_MASK (0xE00UL)
716
717 /*
718 * Sync the processor.
719 */
720 mb();
721 draina();
722
723 /*
724 * Only handle system events here.
725 */
726 if (vector != SCB_Q_SYSEVENT)
727 return titan_machine_check(vector, la_ptr);
728
729 /*
730 * Report the event - System Events should be reported even if no
731 * error is indicated since the event could indicate the return
732 * to normal status.
733 */
734 err_print_prefix = KERN_CRIT;
735 printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n",
736 err_print_prefix,
737 (unsigned int)vector, (int)smp_processor_id());
738 privateer_process_680_frame(mchk_header, 1);
739 err_print_prefix = saved_err_prefix;
740
741 /*
742 * Convert any pending interrupts which report as 680 machine
743 * checks to interrupts.
744 */
745 irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK;
746
747 /*
748 * Dispatch the interrupt(s).
749 */
750 titan_dispatch_irqs(irqmask);
751
752 /*
753 * Release the logout frame.
754 */
755 wrmces(0x7);
756 mb();
757 }