xref: /openbmc/linux/arch/alpha/kernel/err_marvel.c (revision e3d786a3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *	linux/arch/alpha/kernel/err_marvel.c
4  *
5  *	Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation)
6  *
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/console.h>
15 #include <asm/core_marvel.h>
16 #include <asm/hwrpb.h>
17 #include <asm/smp.h>
18 #include <asm/err_common.h>
19 #include <asm/err_ev7.h>
20 
21 #include "err_impl.h"
22 #include "proto.h"
23 
24 static void
25 marvel_print_680_frame(struct ev7_lf_subpackets *lf_subpackets)
26 {
27 #ifdef CONFIG_VERBOSE_MCHECK
28 	struct ev7_pal_environmental_subpacket *env;
29 	struct { int type; char *name; } ev_packets[] = {
30 		{ EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE,
31 		  "Ambient Temperature" },
32 		{ EL_TYPE__PAL__ENV__AIRMOVER_FAN,
33 		  "AirMover / Fan" },
34 		{ EL_TYPE__PAL__ENV__VOLTAGE,
35 		  "Voltage" },
36 		{ EL_TYPE__PAL__ENV__INTRUSION,
37 		  "Intrusion" },
38 		{ EL_TYPE__PAL__ENV__POWER_SUPPLY,
39 		  "Power Supply" },
40 		{ EL_TYPE__PAL__ENV__LAN,
41 		  "LAN" },
42 		{ EL_TYPE__PAL__ENV__HOT_PLUG,
43 		  "Hot Plug" },
44 		{ 0, NULL }
45 	};
46 	int i;
47 
48 	for (i = 0; ev_packets[i].type != 0; i++) {
49 		env = lf_subpackets->env[ev7_lf_env_index(ev_packets[i].type)];
50 		if (!env)
51 			continue;
52 
53 		printk("%s**%s event (cabinet %d, drawer %d)\n",
54 		       err_print_prefix,
55 		       ev_packets[i].name,
56 		       env->cabinet,
57 		       env->drawer);
58 		printk("%s   Module Type: 0x%x - Unit ID 0x%x - "
59 		       "Condition 0x%x\n",
60 		       err_print_prefix,
61 		       env->module_type,
62 		       env->unit_id,
63 		       env->condition);
64 	}
65 #endif /* CONFIG_VERBOSE_MCHECK */
66 }
67 
68 static int
69 marvel_process_680_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
70 {
71 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
72 	int i;
73 
74 	for (i = ev7_lf_env_index(EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE);
75 	     i <= ev7_lf_env_index(EL_TYPE__PAL__ENV__HOT_PLUG);
76 	     i++) {
77 		if (lf_subpackets->env[i])
78 			status = MCHK_DISPOSITION_REPORT;
79 	}
80 
81 	if (print)
82 		marvel_print_680_frame(lf_subpackets);
83 
84 	return status;
85 }
86 
87 #ifdef CONFIG_VERBOSE_MCHECK
88 
89 static void
90 marvel_print_err_cyc(u64 err_cyc)
91 {
92 	static char *packet_desc[] = {
93 		"No Error",
94 		"UNKNOWN",
95 		"1 cycle (1 or 2 flit packet)",
96 		"2 cycles (3 flit packet)",
97 		"9 cycles (18 flit packet)",
98 		"10 cycles (19 flit packet)",
99 		"UNKNOWN",
100 		"UNKNOWN",
101 		"UNKNOWN"
102 	};
103 
104 #define IO7__ERR_CYC__ODD_FLT	(1UL <<  0)
105 #define IO7__ERR_CYC__EVN_FLT	(1UL <<  1)
106 #define IO7__ERR_CYC__PACKET__S	(6)
107 #define IO7__ERR_CYC__PACKET__M	(0x7)
108 #define IO7__ERR_CYC__LOC	(1UL <<  5)
109 #define IO7__ERR_CYC__CYCLE__S	(2)
110 #define IO7__ERR_CYC__CYCLE__M	(0x7)
111 
112 	printk("%s        Packet In Error: %s\n"
113 	       "%s        Error in %s, cycle %lld%s%s\n",
114 	       err_print_prefix,
115 	       packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
116 	       err_print_prefix,
117 	       (err_cyc & IO7__ERR_CYC__LOC) ? "DATA" : "HEADER",
118 	       EXTRACT(err_cyc, IO7__ERR_CYC__CYCLE),
119 	       (err_cyc & IO7__ERR_CYC__ODD_FLT) ? " [ODD Flit]": "",
120 	       (err_cyc & IO7__ERR_CYC__EVN_FLT) ? " [Even Flit]": "");
121 }
122 
123 static void
124 marvel_print_po7_crrct_sym(u64 crrct_sym)
125 {
126 #define IO7__PO7_CRRCT_SYM__SYN__S	(0)
127 #define IO7__PO7_CRRCT_SYM__SYN__M	(0x7f)
128 #define IO7__PO7_CRRCT_SYM__ERR_CYC__S	(7)   /* ERR_CYC + ODD_FLT + EVN_FLT */
129 #define IO7__PO7_CRRCT_SYM__ERR_CYC__M	(0x1ff)
130 
131 
132 	printk("%s      Correctable Error Symptoms:\n"
133 	       "%s        Syndrome: 0x%llx\n",
134 	       err_print_prefix,
135 	       err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
136 	marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
137 }
138 
139 static void
140 marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
141 {
142 	static char *clk_names[] = { "_h[0]", "_h[1]", "_n[0]", "_n[1]" };
143 	static char *clk_decode[] = {
144 		"No Error",
145 		"One extra rising edge",
146 		"Two extra rising edges",
147 		"Lost one clock"
148 	};
149 	static char *port_names[] = { "Port 0", 	"Port 1",
150 				      "Port 2", 	"Port 3",
151 				      "Unknown Port",	"Unknown Port",
152 				      "Unknown Port",	"Port 7" };
153 	int scratch, i;
154 
155 #define IO7__PO7_UNCRR_SYM__SYN__S	    (0)
156 #define IO7__PO7_UNCRR_SYM__SYN__M	    (0x7f)
157 #define IO7__PO7_UNCRR_SYM__ERR_CYC__S	    (7)      /* ERR_CYC + ODD_FLT... */
158 #define IO7__PO7_UNCRR_SYM__ERR_CYC__M	    (0x1ff)  /* ... + EVN_FLT        */
159 #define IO7__PO7_UNCRR_SYM__CLK__S	    (16)
160 #define IO7__PO7_UNCRR_SYM__CLK__M	    (0xff)
161 #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ (1UL << 24)
162 #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO (1UL << 25)
163 #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO (1UL << 26)
164 #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK (1UL << 27)
165 #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK (1UL << 28)
166 #define IO7__PO7_UNCRR_SYM__OVF__READIO	    (1UL << 29)
167 #define IO7__PO7_UNCRR_SYM__OVF__WRITEIO    (1UL << 30)
168 #define IO7__PO7_UNCRR_SYM__OVF__FWD        (1UL << 31)
169 #define IO7__PO7_UNCRR_SYM__VICTIM_SP__S    (32)
170 #define IO7__PO7_UNCRR_SYM__VICTIM_SP__M    (0xff)
171 #define IO7__PO7_UNCRR_SYM__DETECT_SP__S    (40)
172 #define IO7__PO7_UNCRR_SYM__DETECT_SP__M    (0xff)
173 #define IO7__PO7_UNCRR_SYM__STRV_VTR__S     (48)
174 #define IO7__PO7_UNCRR_SYM__STRV_VTR__M     (0x3ff)
175 
176 #define IO7__STRV_VTR__LSI__INTX__S	    (0)
177 #define IO7__STRV_VTR__LSI__INTX__M	    (0x3)
178 #define IO7__STRV_VTR__LSI__SLOT__S	    (2)
179 #define IO7__STRV_VTR__LSI__SLOT__M	    (0x7)
180 #define IO7__STRV_VTR__LSI__BUS__S	    (5)
181 #define IO7__STRV_VTR__LSI__BUS__M	    (0x3)
182 #define IO7__STRV_VTR__MSI__INTNUM__S	    (0)
183 #define IO7__STRV_VTR__MSI__INTNUM__M	    (0x1ff)
184 #define IO7__STRV_VTR__IS_MSI		    (1UL << 9)
185 
186 	printk("%s      Uncorrectable Error Symptoms:\n", err_print_prefix);
187 	uncrr_sym &= valid_mask;
188 
189 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
190 		printk("%s        Syndrome: 0x%llx\n",
191 		       err_print_prefix,
192 		       EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
193 
194 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__ERR_CYC))
195 		marvel_print_err_cyc(EXTRACT(uncrr_sym,
196 					     IO7__PO7_UNCRR_SYM__ERR_CYC));
197 
198 	scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__CLK);
199 	for (i = 0; i < 4; i++, scratch >>= 2) {
200 		if (scratch & 0x3)
201 			printk("%s        Clock %s: %s\n",
202 			       err_print_prefix,
203 			       clk_names[i], clk_decode[scratch & 0x3]);
204 	}
205 
206 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ)
207 		printk("%s       REQ Credit Timeout or Overflow\n",
208 		       err_print_prefix);
209 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO)
210 		printk("%s       RIO Credit Timeout or Overflow\n",
211 		       err_print_prefix);
212 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO)
213 		printk("%s       WIO Credit Timeout or Overflow\n",
214 		       err_print_prefix);
215 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK)
216 		printk("%s       BLK Credit Timeout or Overflow\n",
217 		       err_print_prefix);
218 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK)
219 		printk("%s       NBK Credit Timeout or Overflow\n",
220 		       err_print_prefix);
221 
222 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__READIO)
223 		printk("%s       Read I/O Buffer Overflow\n",
224 		       err_print_prefix);
225 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__WRITEIO)
226 		printk("%s       Write I/O Buffer Overflow\n",
227 		       err_print_prefix);
228 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__FWD)
229 		printk("%s       FWD Buffer Overflow\n",
230 		       err_print_prefix);
231 
232 	if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__VICTIM_SP))) {
233 		int lost = scratch & (1UL << 4);
234 		scratch &= ~lost;
235 		for (i = 0; i < 8; i++, scratch >>= 1) {
236 			if (!(scratch & 1))
237 				continue;
238 			printk("%s        Error Response sent to %s",
239 			       err_print_prefix, port_names[i]);
240 		}
241 		if (lost)
242 			printk("%s        Lost Error sent somewhere else\n",
243 			       err_print_prefix);
244 	}
245 
246 	if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__DETECT_SP))) {
247 		for (i = 0; i < 8; i++, scratch >>= 1) {
248 			if (!(scratch & 1))
249 				continue;
250 			printk("%s        Error Reported by %s",
251 			       err_print_prefix, port_names[i]);
252 		}
253 	}
254 
255 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__STRV_VTR)) {
256 		char starvation_message[80];
257 
258 		scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__STRV_VTR);
259 		if (scratch & IO7__STRV_VTR__IS_MSI)
260 			sprintf(starvation_message,
261 				"MSI Interrupt 0x%x",
262 				EXTRACT(scratch, IO7__STRV_VTR__MSI__INTNUM));
263 		else
264 			sprintf(starvation_message,
265 				"LSI INT%c for Bus:Slot (%d:%d)\n",
266 				'A' + EXTRACT(scratch,
267 					      IO7__STRV_VTR__LSI__INTX),
268 				EXTRACT(scratch, IO7__STRV_VTR__LSI__BUS),
269 				EXTRACT(scratch, IO7__STRV_VTR__LSI__SLOT));
270 
271 		printk("%s        Starvation Int Trigger By: %s\n",
272 		       err_print_prefix, starvation_message);
273 	}
274 }
275 
276 static void
277 marvel_print_po7_ugbge_sym(u64 ugbge_sym)
278 {
279 	char opcode_str[10];
280 
281 #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__S	(6)
282 #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__M	(0xfffffffful)
283 #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__S	(40)
284 #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__M	(0xff)
285 #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__S	(48)
286 #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__M	(0xf)
287 #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__S	(52)
288 #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__M	(0x7ff)
289 #define IO7__PO7_UGBGE_SYM__VALID		(1UL << 63)
290 
291 	if (!(ugbge_sym & IO7__PO7_UGBGE_SYM__VALID))
292 		return;
293 
294 	switch(EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) {
295 	case 0x51:
296 		sprintf(opcode_str, "Wr32");
297 		break;
298 	case 0x50:
299 		sprintf(opcode_str, "WrQW");
300 		break;
301 	case 0x54:
302 		sprintf(opcode_str, "WrIPR");
303 		break;
304 	case 0xD8:
305 		sprintf(opcode_str, "Victim");
306 		break;
307 	case 0xC5:
308 		sprintf(opcode_str, "BlkIO");
309 		break;
310 	default:
311 		sprintf(opcode_str, "0x%llx\n",
312 			EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
313 		break;
314 	}
315 
316 	printk("%s      Up Hose Garbage Symptom:\n"
317 	       "%s        Source Port: %lld - Dest PID: %lld - OpCode: %s\n",
318 	       err_print_prefix,
319 	       err_print_prefix,
320 	       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
321 	       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_DEST_PID),
322 	       opcode_str);
323 
324 	if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
325 		printk("%s        Packet Offset 0x%08llx\n",
326 		       err_print_prefix,
327 		       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
328 }
329 
330 static void
331 marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
332 {
333 	u64	uncrr_sym_valid = 0;
334 
335 #define IO7__PO7_ERRSUM__CR_SBE		(1UL << 32)
336 #define IO7__PO7_ERRSUM__CR_SBE2	(1UL << 33)
337 #define IO7__PO7_ERRSUM__CR_PIO_WBYTE	(1UL << 34)
338 #define IO7__PO7_ERRSUM__CR_CSR_NXM	(1UL << 35)
339 #define IO7__PO7_ERRSUM__CR_RPID_ACV	(1UL << 36)
340 #define IO7__PO7_ERRSUM__CR_RSP_NXM	(1UL << 37)
341 #define IO7__PO7_ERRSUM__CR_ERR_RESP	(1UL << 38)
342 #define IO7__PO7_ERRSUM__CR_CLK_DERR	(1UL << 39)
343 #define IO7__PO7_ERRSUM__CR_DAT_DBE	(1UL << 40)
344 #define IO7__PO7_ERRSUM__CR_DAT_GRBG	(1UL << 41)
345 #define IO7__PO7_ERRSUM__MAF_TO		(1UL << 42)
346 #define IO7__PO7_ERRSUM__UGBGE		(1UL << 43)
347 #define IO7__PO7_ERRSUM__UN_MAF_LOST	(1UL << 44)
348 #define IO7__PO7_ERRSUM__UN_PKT_OVF	(1UL << 45)
349 #define IO7__PO7_ERRSUM__UN_CDT_OVF	(1UL << 46)
350 #define IO7__PO7_ERRSUM__UN_DEALLOC	(1UL << 47)
351 #define IO7__PO7_ERRSUM__BH_CDT_TO	(1UL << 51)
352 #define IO7__PO7_ERRSUM__BH_CLK_HDR	(1UL << 52)
353 #define IO7__PO7_ERRSUM__BH_DBE_HDR	(1UL << 53)
354 #define IO7__PO7_ERRSUM__BH_GBG_HDR	(1UL << 54)
355 #define IO7__PO7_ERRSUM__BH_BAD_CMD	(1UL << 55)
356 #define IO7__PO7_ERRSUM__HLT_INT	(1UL << 56)
357 #define IO7__PO7_ERRSUM__HP_INT		(1UL << 57)
358 #define IO7__PO7_ERRSUM__CRD_INT	(1UL << 58)
359 #define IO7__PO7_ERRSUM__STV_INT	(1UL << 59)
360 #define IO7__PO7_ERRSUM__HRD_INT	(1UL << 60)
361 #define IO7__PO7_ERRSUM__BH_SUM		(1UL << 61)
362 #define IO7__PO7_ERRSUM__ERR_LST	(1UL << 62)
363 #define IO7__PO7_ERRSUM__ERR_VALID	(1UL << 63)
364 
365 #define IO7__PO7_ERRSUM__ERR_MASK	(IO7__PO7_ERRSUM__ERR_VALID |	\
366 					 IO7__PO7_ERRSUM__CR_SBE)
367 
368 	/*
369 	 * Single bit errors aren't covered by ERR_VALID.
370 	 */
371 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE) {
372 		printk("%s    %sSingle Bit Error(s) detected/corrected\n",
373 		       err_print_prefix,
374 		       (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE2)
375 		       ? "Multiple " : "");
376 		marvel_print_po7_crrct_sym(io->po7_crrct_sym);
377 	}
378 
379 	/*
380 	 * Neither are the interrupt status bits
381 	 */
382 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HLT_INT)
383 		printk("%s    Halt Interrupt posted", err_print_prefix);
384 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HP_INT) {
385 		printk("%s    Hot Plug Event Interrupt posted",
386 		       err_print_prefix);
387 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
388 	}
389 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CRD_INT)
390 		printk("%s    Correctable Error Interrupt posted",
391 		       err_print_prefix);
392 	if (io->po7_error_sum & IO7__PO7_ERRSUM__STV_INT) {
393 		printk("%s    Starvation Interrupt posted", err_print_prefix);
394 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__STRV_VTR);
395 	}
396 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HRD_INT) {
397 		printk("%s    Hard Error Interrupt posted", err_print_prefix);
398 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
399 	}
400 
401 	/*
402 	 * Everything else is valid only with ERR_VALID, so skip to the end
403 	 * (uncrr_sym check) unless ERR_VALID is set.
404 	 */
405 	if (!(io->po7_error_sum & IO7__PO7_ERRSUM__ERR_VALID))
406 		goto check_uncrr_sym;
407 
408 	/*
409 	 * Since ERR_VALID is set, VICTIM_SP in uncrr_sym is valid.
410 	 * For bits [29:0] to also be valid, the following bits must
411 	 * not be set:
412 	 *	CR_PIO_WBYTE	CR_CSR_NXM	CR_RSP_NXM
413 	 *	CR_ERR_RESP	MAF_TO
414 	 */
415 	uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__VICTIM_SP);
416 	if (!(io->po7_error_sum & (IO7__PO7_ERRSUM__CR_PIO_WBYTE |
417 				   IO7__PO7_ERRSUM__CR_CSR_NXM |
418 				   IO7__PO7_ERRSUM__CR_RSP_NXM |
419 				   IO7__PO7_ERRSUM__CR_ERR_RESP |
420 				   IO7__PO7_ERRSUM__MAF_TO)))
421 		uncrr_sym_valid |= 0x3ffffffful;
422 
423 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_PIO_WBYTE)
424 		printk("%s    Write byte into IO7 CSR\n", err_print_prefix);
425 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CSR_NXM)
426 		printk("%s    PIO to non-existent CSR\n", err_print_prefix);
427 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RPID_ACV)
428 		printk("%s    Bus Requester PID (Access Violation)\n",
429 		       err_print_prefix);
430 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RSP_NXM)
431 		printk("%s    Received NXM response from EV7\n",
432 		       err_print_prefix);
433 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_ERR_RESP)
434 		printk("%s    Received ERROR RESPONSE\n", err_print_prefix);
435 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CLK_DERR)
436 		printk("%s    Clock error on data flit\n", err_print_prefix);
437 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_DBE)
438 		printk("%s    Double Bit Error Data Error Detected\n",
439 		       err_print_prefix);
440 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_GRBG)
441 		printk("%s    Garbage Encoding Detected on the data\n",
442 		       err_print_prefix);
443 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UGBGE) {
444 		printk("%s    Garbage Encoding sent up hose\n",
445 		       err_print_prefix);
446 		marvel_print_po7_ugbge_sym(io->po7_ugbge_sym);
447 	}
448 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_MAF_LOST)
449 		printk("%s    Orphan response (unexpected response)\n",
450 		       err_print_prefix);
451 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_PKT_OVF)
452 		printk("%s    Down hose packet overflow\n", err_print_prefix);
453 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_CDT_OVF)
454 		printk("%s    Down hose credit overflow\n", err_print_prefix);
455 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_DEALLOC)
456 		printk("%s    Unexpected or bad dealloc field\n",
457 		       err_print_prefix);
458 
459 	/*
460 	 * The black hole events.
461 	 */
462 	if (io->po7_error_sum & IO7__PO7_ERRSUM__MAF_TO)
463 		printk("%s    BLACK HOLE: Timeout for all responses\n",
464 		       err_print_prefix);
465 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CDT_TO)
466 		printk("%s    BLACK HOLE: Credit Timeout\n", err_print_prefix);
467 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CLK_HDR)
468 		printk("%s    BLACK HOLE: Clock check on header\n",
469 		       err_print_prefix);
470 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_DBE_HDR)
471 		printk("%s    BLACK HOLE: Uncorrectable Error on header\n",
472 		       err_print_prefix);
473 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_GBG_HDR)
474 		printk("%s    BLACK HOLE: Garbage on header\n",
475 		       err_print_prefix);
476 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_BAD_CMD)
477 		printk("%s    BLACK HOLE: Bad EV7 command\n",
478 		       err_print_prefix);
479 
480 	if (io->po7_error_sum & IO7__PO7_ERRSUM__ERR_LST)
481 		printk("%s    Lost Error\n", err_print_prefix);
482 
483 	printk("%s    Failing Packet:\n"
484 	       "%s      Cycle 1: %016llx\n"
485 	       "%s      Cycle 2: %016llx\n",
486 	       err_print_prefix,
487 	       err_print_prefix, io->po7_err_pkt0,
488 	       err_print_prefix, io->po7_err_pkt1);
489 	/*
490 	 * If there are any valid bits in UNCRR sym for this err,
491 	 * print UNCRR_SYM as well.
492 	 */
493 check_uncrr_sym:
494 	if (uncrr_sym_valid)
495 		marvel_print_po7_uncrr_sym(io->po7_uncrr_sym, uncrr_sym_valid);
496 }
497 
498 static void
499 marvel_print_pox_tlb_err(u64 tlb_err)
500 {
501 	static char *tlb_errors[] = {
502 		"No Error",
503 		"North Port Signaled Error fetching TLB entry",
504 		"PTE invalid or UCC or GBG error on this entry",
505 		"Address did not hit any DMA window"
506 	};
507 
508 #define IO7__POX_TLBERR__ERR_VALID		(1UL << 63)
509 #define IO7__POX_TLBERR__ERRCODE__S		(0)
510 #define IO7__POX_TLBERR__ERRCODE__M		(0x3)
511 #define IO7__POX_TLBERR__ERR_TLB_PTR__S		(3)
512 #define IO7__POX_TLBERR__ERR_TLB_PTR__M		(0x7)
513 #define IO7__POX_TLBERR__FADDR__S		(6)
514 #define IO7__POX_TLBERR__FADDR__M		(0x3fffffffffful)
515 
516 	if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
517 		return;
518 
519 	printk("%s      TLB Error on index 0x%llx:\n"
520 	       "%s        - %s\n"
521 	       "%s        - Addr: 0x%016llx\n",
522 	       err_print_prefix,
523 	       EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
524 	       err_print_prefix,
525 	       tlb_errors[EXTRACT(tlb_err, IO7__POX_TLBERR__ERRCODE)],
526 	       err_print_prefix,
527 	       EXTRACT(tlb_err, IO7__POX_TLBERR__FADDR) << 6);
528 }
529 
530 static  void
531 marvel_print_pox_spl_cmplt(u64 spl_cmplt)
532 {
533 	char message[80];
534 
535 #define IO7__POX_SPLCMPLT__MESSAGE__S		(0)
536 #define IO7__POX_SPLCMPLT__MESSAGE__M		(0x0fffffffful)
537 #define IO7__POX_SPLCMPLT__SOURCE_BUS__S	(40)
538 #define IO7__POX_SPLCMPLT__SOURCE_BUS__M	(0xfful)
539 #define IO7__POX_SPLCMPLT__SOURCE_DEV__S	(35)
540 #define IO7__POX_SPLCMPLT__SOURCE_DEV__M	(0x1ful)
541 #define IO7__POX_SPLCMPLT__SOURCE_FUNC__S	(32)
542 #define IO7__POX_SPLCMPLT__SOURCE_FUNC__M	(0x07ul)
543 
544 #define IO7__POX_SPLCMPLT__MSG_CLASS__S		(28)
545 #define IO7__POX_SPLCMPLT__MSG_CLASS__M		(0xf)
546 #define IO7__POX_SPLCMPLT__MSG_INDEX__S		(20)
547 #define IO7__POX_SPLCMPLT__MSG_INDEX__M		(0xff)
548 #define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__S	(20)
549 #define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__M    (0xfff)
550 #define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__S	(12)
551 #define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__M	(0x7f)
552 #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__S	(0)
553 #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M	(0xfff)
554 
555 	printk("%s      Split Completion Error:\n"
556 	       "%s         Source (Bus:Dev:Func): %lld:%lld:%lld\n",
557 	       err_print_prefix,
558 	       err_print_prefix,
559 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
560 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_DEV),
561 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_FUNC));
562 
563 	switch(EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MSG_CLASSINDEX)) {
564 	case 0x000:
565 		sprintf(message, "Normal completion");
566 		break;
567 	case 0x100:
568 		sprintf(message, "Bridge - Master Abort");
569 		break;
570 	case 0x101:
571 		sprintf(message, "Bridge - Target Abort");
572 		break;
573 	case 0x102:
574 		sprintf(message, "Bridge - Uncorrectable Write Data Error");
575 		break;
576 	case 0x200:
577 		sprintf(message, "Byte Count Out of Range");
578 		break;
579 	case 0x201:
580 		sprintf(message, "Uncorrectable Split Write Data Error");
581 		break;
582 	default:
583 		sprintf(message, "%08llx\n",
584 			EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
585 		break;
586 	}
587 	printk("%s	   Message: %s\n", err_print_prefix, message);
588 }
589 
590 static void
591 marvel_print_pox_trans_sum(u64 trans_sum)
592 {
593 	static const char * const pcix_cmd[] = {
594 		"Interrupt Acknowledge",
595 		"Special Cycle",
596 		"I/O Read",
597 		"I/O Write",
598 		"Reserved",
599 		"Reserved / Device ID Message",
600 		"Memory Read",
601 		"Memory Write",
602 		"Reserved / Alias to Memory Read Block",
603 		"Reserved / Alias to Memory Write Block",
604 		"Configuration Read",
605 		"Configuration Write",
606 		"Memory Read Multiple / Split Completion",
607 		"Dual Address Cycle",
608 		"Memory Read Line / Memory Read Block",
609 		"Memory Write and Invalidate / Memory Write Block"
610 	};
611 
612 #define IO7__POX_TRANSUM__PCI_ADDR__S		(0)
613 #define IO7__POX_TRANSUM__PCI_ADDR__M		(0x3fffffffffffful)
614 #define IO7__POX_TRANSUM__DAC			(1UL << 50)
615 #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S	(52)
616 #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M	(0xf)
617 #define IO7__POX_TRANSUM__PCIX_CMD__S		(56)
618 #define IO7__POX_TRANSUM__PCIX_CMD__M		(0xf)
619 #define IO7__POX_TRANSUM__ERR_VALID		(1UL << 63)
620 
621 	if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
622 		return;
623 
624 	printk("%s      Transaction Summary:\n"
625 	       "%s        Command: 0x%llx - %s\n"
626 	       "%s        Address: 0x%016llx%s\n"
627 	       "%s        PCI-X Master Slot: 0x%llx\n",
628 	       err_print_prefix,
629 	       err_print_prefix,
630 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
631 	       pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
632 	       err_print_prefix,
633 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
634 	       (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
635 	       err_print_prefix,
636 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
637 }
638 
639 static void
640 marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
641 {
642 #define IO7__POX_ERRSUM__AGP_REQQ_OVFL    (1UL <<  4)
643 #define IO7__POX_ERRSUM__AGP_SYNC_ERR     (1UL <<  5)
644 #define IO7__POX_ERRSUM__MRETRY_TO        (1UL <<  6)
645 #define IO7__POX_ERRSUM__PCIX_UX_SPL      (1UL <<  7)
646 #define IO7__POX_ERRSUM__PCIX_SPLIT_TO    (1UL <<  8)
647 #define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL <<  9)
648 #define IO7__POX_ERRSUM__DMA_RD_TO        (1UL << 10)
649 #define IO7__POX_ERRSUM__CSR_NXM_RD       (1UL << 11)
650 #define IO7__POX_ERRSUM__CSR_NXM_WR       (1UL << 12)
651 #define IO7__POX_ERRSUM__DMA_TO           (1UL << 13)
652 #define IO7__POX_ERRSUM__ALL_MABORTS      (1UL << 14)
653 #define IO7__POX_ERRSUM__MABORT		  (1UL << 15)
654 #define IO7__POX_ERRSUM__MABORT_MASK	  (IO7__POX_ERRSUM__ALL_MABORTS|\
655 					   IO7__POX_ERRSUM__MABORT)
656 #define IO7__POX_ERRSUM__PT_TABORT        (1UL << 16)
657 #define IO7__POX_ERRSUM__PM_TABORT        (1UL << 17)
658 #define IO7__POX_ERRSUM__TABORT_MASK      (IO7__POX_ERRSUM__PT_TABORT | \
659                                            IO7__POX_ERRSUM__PM_TABORT)
660 #define IO7__POX_ERRSUM__SERR             (1UL << 18)
661 #define IO7__POX_ERRSUM__ADDRERR_STB      (1UL << 19)
662 #define IO7__POX_ERRSUM__DETECTED_SERR    (1UL << 20)
663 #define IO7__POX_ERRSUM__PERR             (1UL << 21)
664 #define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
665 #define IO7__POX_ERRSUM__DETECTED_PERR    (1UL << 23)
666 #define IO7__POX_ERRSUM__PM_PERR          (1UL << 24)
667 #define IO7__POX_ERRSUM__PT_SCERROR       (1UL << 26)
668 #define IO7__POX_ERRSUM__HUNG_BUS         (1UL << 28)
669 #define IO7__POX_ERRSUM__UPE_ERROR__S     (51)
670 #define IO7__POX_ERRSUM__UPE_ERROR__M     (0xffUL)
671 #define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
672 #define IO7__POX_ERRSUM__TLB_ERR          (1UL << 59)
673 #define IO7__POX_ERRSUM__ERR_VALID        (1UL << 63)
674 
675 #define IO7__POX_ERRSUM__TRANS_SUM__MASK  (IO7__POX_ERRSUM__MRETRY_TO |       \
676 					   IO7__POX_ERRSUM__PCIX_UX_SPL |     \
677 					   IO7__POX_ERRSUM__PCIX_SPLIT_TO |   \
678 					   IO7__POX_ERRSUM__DMA_TO |          \
679 					   IO7__POX_ERRSUM__MABORT_MASK |     \
680 					   IO7__POX_ERRSUM__TABORT_MASK |     \
681 					   IO7__POX_ERRSUM__SERR |            \
682 					   IO7__POX_ERRSUM__ADDRERR_STB |     \
683 					   IO7__POX_ERRSUM__PERR |            \
684 					   IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
685 					   IO7__POX_ERRSUM__DETECTED_PERR |   \
686 					   IO7__POX_ERRSUM__PM_PERR |         \
687 					   IO7__POX_ERRSUM__PT_SCERROR |      \
688 					   IO7__POX_ERRSUM__UPE_ERROR)
689 
690 	if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
691 		return;
692 
693 	/*
694 	 * First the transaction summary errors
695 	 */
696 	if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
697 		printk("%s    IO7 Master Retry Timeout expired\n",
698 		       err_print_prefix);
699 	if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
700 		printk("%s    Unexpected Split Completion\n",
701 		       err_print_prefix);
702 	if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
703 		printk("%s    IO7 Split Completion Timeout expired\n",
704 		       err_print_prefix);
705 	if (err_sum & IO7__POX_ERRSUM__DMA_TO)
706 		printk("%s    Hung bus during DMA transaction\n",
707 		       err_print_prefix);
708 	if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
709 		printk("%s    Master Abort\n", err_print_prefix);
710 	if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
711 		printk("%s    IO7 Asserted Target Abort\n", err_print_prefix);
712 	if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
713 		printk("%s    IO7 Received Target Abort\n", err_print_prefix);
714 	if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
715 		printk("%s    Address or PCI-X Attribute Parity Error\n",
716 		       err_print_prefix);
717 		if (err_sum & IO7__POX_ERRSUM__SERR)
718 			printk("%s     IO7 Asserted SERR\n", err_print_prefix);
719 	}
720 	if (err_sum & IO7__POX_ERRSUM__PERR) {
721 		if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
722 			printk("%s    IO7 Detected Data Parity Error\n",
723 			       err_print_prefix);
724 		else
725 			printk("%s    Split Completion Response with "
726 			       "Parity Error\n", err_print_prefix);
727 	}
728 	if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
729 		printk("%s    PERR detected\n", err_print_prefix);
730 	if (err_sum & IO7__POX_ERRSUM__PM_PERR)
731 		printk("%s    PERR while IO7 is master\n", err_print_prefix);
732 	if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
733 		printk("%s    IO7 Received Split Completion Error message\n",
734 		       err_print_prefix);
735 		marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
736 	}
737 	if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
738 		unsigned int upe_error = EXTRACT(err_sum,
739 						 IO7__POX_ERRSUM__UPE_ERROR);
740 		int i;
741 		static char *upe_errors[] = {
742 			"Parity Error on MSI write data",
743 			"MSI read (MSI window is write only",
744 			"TLB - Invalid WR transaction",
745 			"TLB - Invalid RD transaction",
746 			"DMA - WR error (see north port)",
747 			"DMA - RD error (see north port)",
748 			"PPR - WR error (see north port)",
749 			"PPR - RD error (see north port)"
750 		};
751 
752 		printk("%s    UPE Error:\n", err_print_prefix);
753 		for (i = 0; i < 8; i++) {
754 			if (upe_error & (1 << i))
755 				printk("%s      %s\n", err_print_prefix,
756 				       upe_errors[i]);
757 		}
758 	}
759 
760 	/*
761 	 * POx_TRANS_SUM, if appropriate.
762 	 */
763 	if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK)
764 		marvel_print_pox_trans_sum(port->pox_trans_sum);
765 
766 	/*
767 	 * Then TLB_ERR.
768 	 */
769 	if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
770 		printk("%s    TLB ERROR\n", err_print_prefix);
771 		marvel_print_pox_tlb_err(port->pox_tlb_err);
772 	}
773 
774 	/*
775 	 * And the single bit status errors.
776 	 */
777 	if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
778 		printk("%s    AGP Request Queue Overflow\n", err_print_prefix);
779 	if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
780 		printk("%s    AGP Sync Error\n", err_print_prefix);
781 	if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
782 		printk("%s    Discarded split completion\n", err_print_prefix);
783 	if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
784 		printk("%s    DMA Read Timeout\n", err_print_prefix);
785 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
786 		printk("%s    CSR NXM READ\n", err_print_prefix);
787 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
788 		printk("%s    CSR NXM WRITE\n", err_print_prefix);
789 	if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
790 		printk("%s    SERR detected\n", err_print_prefix);
791 	if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
792 		printk("%s    HUNG BUS detected\n", err_print_prefix);
793 }
794 
795 #endif /* CONFIG_VERBOSE_MCHECK */
796 
797 static struct ev7_pal_io_subpacket *
798 marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
799 {
800 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
801 	struct io7 *io7;
802 	int i;
803 
804 	/*
805 	 * Caller must provide the packet to fill
806 	 */
807 	if (!io)
808 		return NULL;
809 
810 	/*
811 	 * Fill the subpacket with the console's standard fill pattern
812 	 */
813 	memset(io, 0x55, sizeof(*io));
814 
815 	for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) {
816 		unsigned long err_sum = 0;
817 
818 		err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
819 		for (i = 0; i < IO7_NUM_PORTS; i++) {
820 			if (!io7->ports[i].enabled)
821 				continue;
822 			err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
823 		}
824 
825 		/*
826 		 * Is there at least one error?
827 		 */
828 		if (err_sum & (1UL << 63))
829 			break;
830 	}
831 
832 	/*
833 	 * Did we find an IO7 with an error?
834 	 */
835 	if (!io7)
836 		return NULL;
837 
838 	/*
839 	 * We have an IO7 with an error.
840 	 *
841 	 * Fill in the IO subpacket.
842 	 */
843 	io->io_asic_rev   = io7->csrs->IO_ASIC_REV.csr;
844 	io->io_sys_rev    = io7->csrs->IO_SYS_REV.csr;
845 	io->io7_uph       = io7->csrs->IO7_UPH.csr;
846 	io->hpi_ctl       = io7->csrs->HPI_CTL.csr;
847 	io->crd_ctl       = io7->csrs->CRD_CTL.csr;
848 	io->hei_ctl       = io7->csrs->HEI_CTL.csr;
849 	io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
850 	io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
851 	io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
852 	io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
853 	io->po7_err_pkt0  = io7->csrs->PO7_ERR_PKT[0].csr;
854 	io->po7_err_pkt1  = io7->csrs->PO7_ERR_PKT[1].csr;
855 
856 	for (i = 0; i < IO7_NUM_PORTS; i++) {
857 		io7_ioport_csrs *csrs = io7->ports[i].csrs;
858 
859 		if (!io7->ports[i].enabled)
860 			continue;
861 
862 		io->ports[i].pox_err_sum   = csrs->POx_ERR_SUM.csr;
863 		io->ports[i].pox_tlb_err   = csrs->POx_TLB_ERR.csr;
864 		io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
865 		io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
866 		io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
867 		io->ports[i].pox_mult_err  = csrs->POx_MULT_ERR.csr;
868 		io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
869 		io->ports[i].pox_dm_dest   = csrs->POx_DM_DEST.csr;
870 		io->ports[i].pox_dm_size   = csrs->POx_DM_SIZE.csr;
871 		io->ports[i].pox_dm_ctrl   = csrs->POx_DM_CTRL.csr;
872 
873 		/*
874 		 * Ack this port's errors, if any. POx_ERR_SUM must be last.
875 		 *
876 		 * Most of the error registers get cleared and unlocked when
877 		 * the associated bits in POx_ERR_SUM are cleared (by writing
878 		 * 1). POx_TLB_ERR is an exception and must be explicitly
879 		 * cleared.
880 		 */
881 		csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
882 		csrs->POx_ERR_SUM.csr =	io->ports[i].pox_err_sum;
883 		mb();
884 		csrs->POx_ERR_SUM.csr;
885 	}
886 
887 	/*
888 	 * Ack any port 7 error(s).
889 	 */
890 	io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
891 	mb();
892 	io7->csrs->PO7_ERROR_SUM.csr;
893 
894 	/*
895 	 * Correct the io7_pid.
896 	 */
897 	lf_subpackets->io_pid = io7->pe;
898 
899 	return io;
900 }
901 
902 static int
903 marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
904 {
905 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
906 
907 #ifdef CONFIG_VERBOSE_MCHECK
908 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
909 	int i;
910 #endif /* CONFIG_VERBOSE_MCHECK */
911 
912 #define MARVEL_IO_ERR_VALID(x)  ((x) & (1UL << 63))
913 
914 	if (!lf_subpackets->logout || !lf_subpackets->io)
915 		return status;
916 
917 	/*
918 	 * The PALcode only builds an IO subpacket if there is a
919 	 * locally connected IO7. In the cases of
920 	 *	1) a uniprocessor kernel
921 	 *	2) an mp kernel before the local secondary has called in
922 	 * error interrupts are all directed to the primary processor.
923 	 * In that case, we may not have an IO subpacket at all and, event
924 	 * if we do, it may not be the right now.
925 	 *
926 	 * If the RBOX indicates an I/O error interrupt, make sure we have
927 	 * the correct IO7 information. If we don't have an IO subpacket
928 	 * or it's the wrong one, try to find the right one.
929 	 *
930 	 * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
931 	 * RBOX_INT<10>.
932 	 */
933 	if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
934 	    ((lf_subpackets->io->po7_error_sum        |
935 	      lf_subpackets->io->ports[0].pox_err_sum |
936 	      lf_subpackets->io->ports[1].pox_err_sum |
937 	      lf_subpackets->io->ports[2].pox_err_sum |
938 	      lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
939 		/*
940 		 * Either we have no IO subpacket or no error is
941 		 * indicated in the one we do have. Try find the
942 		 * one with the error.
943 		 */
944 		if (!marvel_find_io7_with_error(lf_subpackets))
945 			return status;
946 	}
947 
948 	/*
949 	 * We have an IO7 indicating an error - we're going to report it
950 	 */
951 	status = MCHK_DISPOSITION_REPORT;
952 
953 #ifdef CONFIG_VERBOSE_MCHECK
954 
955 	if (!print)
956 		return status;
957 
958 	printk("%s*Error occurred on IO7 at PID %u\n",
959 	       err_print_prefix, lf_subpackets->io_pid);
960 
961 	/*
962 	 * Check port 7 first
963 	 */
964 	if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
965 		marvel_print_po7_err_sum(io);
966 
967 #if 0
968 		printk("%s  PORT 7 ERROR:\n"
969 		       "%s    PO7_ERROR_SUM: %016llx\n"
970 		       "%s    PO7_UNCRR_SYM: %016llx\n"
971 		       "%s    PO7_CRRCT_SYM: %016llx\n"
972 		       "%s    PO7_UGBGE_SYM: %016llx\n"
973 		       "%s    PO7_ERR_PKT0:  %016llx\n"
974 		       "%s    PO7_ERR_PKT1:  %016llx\n",
975 		       err_print_prefix,
976 		       err_print_prefix, io->po7_error_sum,
977 		       err_print_prefix, io->po7_uncrr_sym,
978 		       err_print_prefix, io->po7_crrct_sym,
979 		       err_print_prefix, io->po7_ugbge_sym,
980 		       err_print_prefix, io->po7_err_pkt0,
981 		       err_print_prefix, io->po7_err_pkt1);
982 #endif
983 	}
984 
985 	/*
986 	 * Then loop through the ports
987 	 */
988 	for (i = 0; i < IO7_NUM_PORTS; i++) {
989 		if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
990 			continue;
991 
992 		printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
993 		       err_print_prefix,
994 		       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
995 		marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
996 
997 		printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
998 		       err_print_prefix, io->ports[i].pox_first_err);
999 		marvel_print_pox_err(io->ports[i].pox_first_err,
1000 				     &io->ports[i]);
1001 
1002 	}
1003 
1004 
1005 #endif /* CONFIG_VERBOSE_MCHECK */
1006 
1007 	return status;
1008 }
1009 
1010 static int
1011 marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
1012 {
1013 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
1014 
1015 	/*
1016 	 * I/O error?
1017 	 */
1018 #define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
1019 	if (lf_subpackets->logout &&
1020 	    (lf_subpackets->logout->rbox_int & 0x20000400ul))
1021 		status = marvel_process_io_error(lf_subpackets, print);
1022 
1023 	/*
1024 	 * Probing behind PCI-X bridges can cause machine checks on
1025 	 * Marvel when the probe is handled by the bridge as a split
1026 	 * completion transaction. The symptom is an ERROR_RESPONSE
1027 	 * to a CONFIG address. Since these errors will happen in
1028 	 * normal operation, dismiss them.
1029 	 *
1030 	 * Dismiss if:
1031 	 *	C_STAT		= 0x14 		(Error Response)
1032 	 *	C_STS<3>	= 0    		(C_ADDR valid)
1033 	 *	C_ADDR<42>	= 1    		(I/O)
1034 	 *	C_ADDR<31:22>	= 111110xxb	(PCI Config space)
1035 	 */
1036 	if (lf_subpackets->ev7 &&
1037 	    (lf_subpackets->ev7->c_stat == 0x14) &&
1038 	    !(lf_subpackets->ev7->c_sts & 0x8) &&
1039 	    ((lf_subpackets->ev7->c_addr & 0x400ff000000ul)
1040 	     == 0x400fe000000ul))
1041 		status = MCHK_DISPOSITION_DISMISS;
1042 
1043 	return status;
1044 }
1045 
1046 void
1047 marvel_machine_check(unsigned long vector, unsigned long la_ptr)
1048 {
1049 	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
1050 	int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
1051 	struct ev7_lf_subpackets subpacket_collection = { NULL, };
1052 	struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
1053 	struct ev7_lf_subpackets *lf_subpackets = NULL;
1054 	int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
1055 	char *saved_err_prefix = err_print_prefix;
1056 	char *error_type = NULL;
1057 
1058 	/*
1059 	 * Sync the processor
1060 	 */
1061 	mb();
1062 	draina();
1063 
1064 	switch(vector) {
1065 	case SCB_Q_SYSEVENT:
1066 		process_frame = marvel_process_680_frame;
1067 		error_type = "System Event";
1068 		break;
1069 
1070 	case SCB_Q_SYSMCHK:
1071 		process_frame = marvel_process_logout_frame;
1072 		error_type = "System Uncorrectable Error";
1073 		break;
1074 
1075 	case SCB_Q_SYSERR:
1076 		process_frame = marvel_process_logout_frame;
1077 		error_type = "System Correctable Error";
1078 		break;
1079 
1080 	default:
1081 		/* Don't know it - pass it up.  */
1082 		ev7_machine_check(vector, la_ptr);
1083 		return;
1084 	}
1085 
1086 	/*
1087 	 * A system event or error has occurred, handle it here.
1088 	 *
1089 	 * Any errors in the logout frame have already been cleared by the
1090 	 * PALcode, so just parse it.
1091 	 */
1092 	err_print_prefix = KERN_CRIT;
1093 
1094 	/*
1095 	 * Parse the logout frame without printing first. If the only error(s)
1096 	 * found are classified as "dismissable", then just dismiss them and
1097 	 * don't print any message
1098 	 */
1099 	lf_subpackets =
1100 		ev7_collect_logout_frame_subpackets(el_ptr,
1101 						    &subpacket_collection);
1102 	if (process_frame && lf_subpackets && lf_subpackets->logout) {
1103 		/*
1104 		 * We might not have the correct (or any) I/O subpacket.
1105 		 * [ See marvel_process_io_error() for explanation. ]
1106 		 * If we don't have one, point the io subpacket in
1107 		 * lf_subpackets at scratch_io_packet so that
1108 		 * marvel_find_io7_with_error() will have someplace to
1109 		 * store the info.
1110 		 */
1111 		if (!lf_subpackets->io)
1112 			lf_subpackets->io = &scratch_io_packet;
1113 
1114 		/*
1115 		 * Default io_pid to the processor reporting the error
1116 		 * [this will get changed in marvel_find_io7_with_error()
1117 		 * if a different one is needed]
1118 		 */
1119 		lf_subpackets->io_pid = lf_subpackets->logout->whami;
1120 
1121 		/*
1122 		 * Evaluate the frames.
1123 		 */
1124 		disposition = process_frame(lf_subpackets, 0);
1125 	}
1126 	switch(disposition) {
1127 	case MCHK_DISPOSITION_DISMISS:
1128 		/* Nothing to do. */
1129 		break;
1130 
1131 	case MCHK_DISPOSITION_REPORT:
1132 		/* Recognized error, report it. */
1133 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1134 		       err_print_prefix, error_type,
1135 		       (unsigned int)vector, (int)smp_processor_id());
1136 		el_print_timestamp(&lf_subpackets->logout->timestamp);
1137 		process_frame(lf_subpackets, 1);
1138 		break;
1139 
1140 	default:
1141 		/* Unknown - dump the annotated subpackets. */
1142 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1143 		       err_print_prefix, error_type,
1144 		       (unsigned int)vector, (int)smp_processor_id());
1145 		el_process_subpacket(el_ptr);
1146 		break;
1147 
1148 	}
1149 
1150 	err_print_prefix = saved_err_prefix;
1151 
1152         /* Release the logout frame.  */
1153 	wrmces(0x7);
1154 	mb();
1155 }
1156 
1157 void __init
1158 marvel_register_error_handlers(void)
1159 {
1160 	ev7_register_error_handlers();
1161 }
1162