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