xref: /openbmc/linux/arch/alpha/kernel/err_titan.c (revision 2f116cbf)
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	(0x1fffffffful)
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)
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 		ev6_machine_check(vector, la_ptr);
412 		return;
413 	}
414 
415 	/*
416 	 * It's a system error, handle it here
417 	 *
418 	 * The PALcode has already cleared the error, so just parse it
419 	 */
420 
421 	/*
422 	 * Parse the logout frame without printing first. If the only error(s)
423 	 * found are classified as "dismissable", then just dismiss them and
424 	 * don't print any message
425 	 */
426 	if (titan_process_logout_frame(mchk_header, 0) !=
427 	    MCHK_DISPOSITION_DISMISS) {
428 		char *saved_err_prefix = err_print_prefix;
429 		err_print_prefix = KERN_CRIT;
430 
431 		/*
432 		 * Either a nondismissable error was detected or no
433 		 * recognized error was detected  in the logout frame
434 		 * -- report the error in either case
435 		 */
436 		printk("%s"
437 		       "*System %s Error (Vector 0x%x) reported on CPU %d:\n",
438 		       err_print_prefix,
439 		       (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable",
440 		       (unsigned int)vector, (int)smp_processor_id());
441 
442 #ifdef CONFIG_VERBOSE_MCHECK
443 		titan_process_logout_frame(mchk_header, alpha_verbose_mcheck);
444 		if (alpha_verbose_mcheck)
445 			dik_show_regs(get_irq_regs(), NULL);
446 #endif /* CONFIG_VERBOSE_MCHECK */
447 
448 		err_print_prefix = saved_err_prefix;
449 
450 		/*
451 		 * Convert any pending interrupts which report as system
452 		 * machine checks to interrupts
453 		 */
454 		irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK;
455 		titan_dispatch_irqs(irqmask);
456 	}
457 
458 
459 	/*
460 	 * Release the logout frame
461 	 */
462 	wrmces(0x7);
463 	mb();
464 }
465 
466 /*
467  * Subpacket Annotations
468  */
469 static char *el_titan_pchip0_extended_annotation[] = {
470 	"Subpacket Header", 	"P0_SCTL",	"P0_SERREN",
471 	"P0_APCTL",		"P0_APERREN",	"P0_AGPERREN",
472 	"P0_ASPRST",		"P0_AWSBA0",	"P0_AWSBA1",
473 	"P0_AWSBA2",		"P0_AWSBA3",	"P0_AWSM0",
474 	"P0_AWSM1",		"P0_AWSM2",	"P0_AWSM3",
475 	"P0_ATBA0",		"P0_ATBA1",	"P0_ATBA2",
476 	"P0_ATBA3",		"P0_GPCTL",	"P0_GPERREN",
477 	"P0_GSPRST",		"P0_GWSBA0",	"P0_GWSBA1",
478 	"P0_GWSBA2",		"P0_GWSBA3",	"P0_GWSM0",
479 	"P0_GWSM1",		"P0_GWSM2",	"P0_GWSM3",
480 	"P0_GTBA0",		"P0_GTBA1",	"P0_GTBA2",
481 	"P0_GTBA3",		NULL
482 };
483 static char *el_titan_pchip1_extended_annotation[] = {
484 	"Subpacket Header", 	"P1_SCTL",	"P1_SERREN",
485 	"P1_APCTL",		"P1_APERREN",	"P1_AGPERREN",
486 	"P1_ASPRST",		"P1_AWSBA0",	"P1_AWSBA1",
487 	"P1_AWSBA2",		"P1_AWSBA3",	"P1_AWSM0",
488 	"P1_AWSM1",		"P1_AWSM2",	"P1_AWSM3",
489 	"P1_ATBA0",		"P1_ATBA1",	"P1_ATBA2",
490 	"P1_ATBA3",		"P1_GPCTL",	"P1_GPERREN",
491 	"P1_GSPRST",		"P1_GWSBA0",	"P1_GWSBA1",
492 	"P1_GWSBA2",		"P1_GWSBA3",	"P1_GWSM0",
493 	"P1_GWSM1",		"P1_GWSM2",	"P1_GWSM3",
494 	"P1_GTBA0",		"P1_GTBA1",	"P1_GTBA2",
495 	"P1_GTBA3",		NULL
496 };
497 static char *el_titan_memory_extended_annotation[] = {
498 	"Subpacket Header", 	"AAR0",		"AAR1",
499 	"AAR2",			"AAR3",		"P0_SCTL",
500 	"P0_GPCTL",		"P0_APCTL",	"P1_SCTL",
501 	"P1_GPCTL",		"P1_SCTL",	NULL
502 };
503 
504 static struct el_subpacket_annotation el_titan_annotations[] = {
505 	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
506 			     EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED,
507 			     1,
508 			     "Titan PChip 0 Extended Frame",
509 			     el_titan_pchip0_extended_annotation),
510 	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
511 			     EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED,
512 			     1,
513 			     "Titan PChip 1 Extended Frame",
514 			     el_titan_pchip1_extended_annotation),
515 	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
516 			     EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED,
517 			     1,
518 			     "Titan Memory Extended Frame",
519 			     el_titan_memory_extended_annotation),
520 	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
521 			     EL_TYPE__TERMINATION__TERMINATION,
522 			     1,
523 			     "Termination Subpacket",
524 			     NULL)
525 };
526 
527 static struct el_subpacket *
528 el_process_regatta_subpacket(struct el_subpacket *header)
529 {
530 	int status;
531 
532 	if (header->class != EL_CLASS__REGATTA_FAMILY) {
533 		printk("%s  ** Unexpected header CLASS %d TYPE %d, aborting\n",
534 		       err_print_prefix,
535 		       header->class, header->type);
536 		return NULL;
537 	}
538 
539 	switch(header->type) {
540 	case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME:
541 	case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME:
542 	case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME:
543 	case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT:
544 	case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT:
545 		printk("%s  ** Occurred on CPU %d:\n",
546 		       err_print_prefix,
547 		       (int)header->by_type.regatta_frame.cpuid);
548 		status = privateer_process_logout_frame((struct el_common *)
549 			header->by_type.regatta_frame.data_start, 1);
550 		break;
551 	default:
552 		printk("%s  ** REGATTA TYPE %d SUBPACKET\n",
553 		       err_print_prefix, header->type);
554 		el_annotate_subpacket(header);
555 		break;
556 	}
557 
558 
559 	return (struct el_subpacket *)((unsigned long)header + header->length);
560 }
561 
562 static struct el_subpacket_handler titan_subpacket_handler =
563 	SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY,
564 			       el_process_regatta_subpacket);
565 
566 void
567 titan_register_error_handlers(void)
568 {
569 	size_t i;
570 
571 	for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++)
572 		cdl_register_subpacket_annotation(&el_titan_annotations[i]);
573 
574 	cdl_register_subpacket_handler(&titan_subpacket_handler);
575 
576 	ev6_register_error_handlers();
577 }
578 
579 
580 /*
581  * Privateer
582  */
583 
584 static int
585 privateer_process_680_frame(struct el_common *mchk_header, int print)
586 {
587 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
588 #ifdef CONFIG_VERBOSE_MCHECK
589 	struct el_PRIVATEER_envdata_mcheck *emchk =
590 		(struct el_PRIVATEER_envdata_mcheck *)
591 		((unsigned long)mchk_header + mchk_header->sys_offset);
592 
593 	/* TODO - catagorize errors, for now, no error */
594 
595 	if (!print)
596 		return status;
597 
598 	/* TODO - decode instead of just dumping... */
599 	printk("%s  Summary Flags:         %016lx\n"
600  	         "  CChip DIRx:            %016lx\n"
601 		 "  System Management IR:  %016lx\n"
602 		 "  CPU IR:                %016lx\n"
603 		 "  Power Supply IR:       %016lx\n"
604 		 "  LM78 Fault Status:     %016lx\n"
605 		 "  System Doors:          %016lx\n"
606 		 "  Temperature Warning:   %016lx\n"
607 		 "  Fan Control:           %016lx\n"
608 		 "  Fatal Power Down Code: %016lx\n",
609 	       err_print_prefix,
610 	       emchk->summary,
611 	       emchk->c_dirx,
612 	       emchk->smir,
613 	       emchk->cpuir,
614 	       emchk->psir,
615 	       emchk->fault,
616 	       emchk->sys_doors,
617 	       emchk->temp_warn,
618 	       emchk->fan_ctrl,
619 	       emchk->code);
620 #endif /* CONFIG_VERBOSE_MCHECK */
621 
622 	return status;
623 }
624 
625 int
626 privateer_process_logout_frame(struct el_common *mchk_header, int print)
627 {
628 	struct el_common_EV6_mcheck *ev6mchk =
629 		(struct el_common_EV6_mcheck *)mchk_header;
630 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
631 
632 	/*
633 	 * Machine check codes
634 	 */
635 #define PRIVATEER_MCHK__CORR_ECC		0x86	/* 630 */
636 #define PRIVATEER_MCHK__DC_TAG_PERR		0x9E	/* 630 */
637 #define PRIVATEER_MCHK__PAL_BUGCHECK		0x8E	/* 670 */
638 #define PRIVATEER_MCHK__OS_BUGCHECK		0x90	/* 670 */
639 #define PRIVATEER_MCHK__PROC_HRD_ERR		0x98	/* 670 */
640 #define PRIVATEER_MCHK__ISTREAM_CMOV_PRX	0xA0	/* 670 */
641 #define PRIVATEER_MCHK__ISTREAM_CMOV_FLT	0xA2	/* 670 */
642 #define PRIVATEER_MCHK__SYS_HRD_ERR		0x202	/* 660 */
643 #define PRIVATEER_MCHK__SYS_CORR_ERR		0x204	/* 620 */
644 #define PRIVATEER_MCHK__SYS_ENVIRON		0x206	/* 680 */
645 
646 	switch(ev6mchk->MCHK_Code) {
647 	/*
648 	 * Vector 630 - Processor, Correctable
649 	 */
650 	case PRIVATEER_MCHK__CORR_ECC:
651 	case PRIVATEER_MCHK__DC_TAG_PERR:
652 		/*
653 		 * Fall through to vector 670 for processing...
654 		 */
655 	/*
656 	 * Vector 670 - Processor, Uncorrectable
657 	 */
658 	case PRIVATEER_MCHK__PAL_BUGCHECK:
659 	case PRIVATEER_MCHK__OS_BUGCHECK:
660 	case PRIVATEER_MCHK__PROC_HRD_ERR:
661 	case PRIVATEER_MCHK__ISTREAM_CMOV_PRX:
662 	case PRIVATEER_MCHK__ISTREAM_CMOV_FLT:
663 		status |= ev6_process_logout_frame(mchk_header, print);
664 		break;
665 
666 	/*
667 	 * Vector 620 - System, Correctable
668 	 */
669 	case PRIVATEER_MCHK__SYS_CORR_ERR:
670 		/*
671 		 * Fall through to vector 660 for processing...
672 		 */
673 	/*
674 	 * Vector 660 - System, Uncorrectable
675 	 */
676 	case PRIVATEER_MCHK__SYS_HRD_ERR:
677 		status |= titan_process_logout_frame(mchk_header, print);
678 		break;
679 
680 	/*
681 	 * Vector 680 - System, Environmental
682 	 */
683 	case PRIVATEER_MCHK__SYS_ENVIRON:	/* System, Environmental */
684 		status |= privateer_process_680_frame(mchk_header, print);
685 		break;
686 
687 	/*
688 	 * Unknown
689 	 */
690 	default:
691 		status |= MCHK_DISPOSITION_REPORT;
692 		if (print) {
693 			printk("%s** Unknown Error, frame follows\n",
694 			       err_print_prefix);
695 			mchk_dump_logout_frame(mchk_header);
696 		}
697 
698 	}
699 
700 	return status;
701 }
702 
703 void
704 privateer_machine_check(u64 vector, u64 la_ptr)
705 {
706 	struct el_common *mchk_header = (struct el_common *)la_ptr;
707 	struct el_TITAN_sysdata_mcheck *tmchk =
708 		(struct el_TITAN_sysdata_mcheck *)
709 		(la_ptr + mchk_header->sys_offset);
710 	u64 irqmask;
711 	char *saved_err_prefix = err_print_prefix;
712 
713 #define PRIVATEER_680_INTERRUPT_MASK		(0xE00UL)
714 #define PRIVATEER_HOTPLUG_INTERRUPT_MASK	(0xE00UL)
715 
716 	/*
717 	 * Sync the processor.
718 	 */
719 	mb();
720 	draina();
721 
722 	/*
723 	 * Only handle system events here.
724 	 */
725 	if (vector != SCB_Q_SYSEVENT)
726 		return titan_machine_check(vector, la_ptr);
727 
728 	/*
729 	 * Report the event - System Events should be reported even if no
730 	 * error is indicated since the event could indicate the return
731 	 * to normal status.
732 	 */
733 	err_print_prefix = KERN_CRIT;
734 	printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n",
735 	       err_print_prefix,
736 	       (unsigned int)vector, (int)smp_processor_id());
737 	privateer_process_680_frame(mchk_header, 1);
738 	err_print_prefix = saved_err_prefix;
739 
740 	/*
741 	 * Convert any pending interrupts which report as 680 machine
742 	 * checks to interrupts.
743 	 */
744 	irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK;
745 
746 	/*
747 	 * Dispatch the interrupt(s).
748 	 */
749 	titan_dispatch_irqs(irqmask);
750 
751 	/*
752 	 * Release the logout frame.
753 	 */
754 	wrmces(0x7);
755 	mb();
756 }
757