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