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