xref: /linux-6.15/arch/alpha/kernel/err_marvel.c (revision 1ffb1c0c)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *	linux/arch/alpha/kernel/err_marvel.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *	Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation)
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #include <linux/init.h>
91da177e4SLinus Torvalds #include <linux/pci.h>
101da177e4SLinus Torvalds #include <linux/sched.h>
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <asm/io.h>
131da177e4SLinus Torvalds #include <asm/console.h>
141da177e4SLinus Torvalds #include <asm/core_marvel.h>
151da177e4SLinus Torvalds #include <asm/hwrpb.h>
161da177e4SLinus Torvalds #include <asm/smp.h>
171da177e4SLinus Torvalds #include <asm/err_common.h>
181da177e4SLinus Torvalds #include <asm/err_ev7.h>
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds #include "err_impl.h"
211da177e4SLinus Torvalds #include "proto.h"
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds static void
241da177e4SLinus Torvalds marvel_print_680_frame(struct ev7_lf_subpackets *lf_subpackets)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
271da177e4SLinus Torvalds 	struct ev7_pal_environmental_subpacket *env;
281da177e4SLinus Torvalds 	struct { int type; char *name; } ev_packets[] = {
291da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE,
301da177e4SLinus Torvalds 		  "Ambient Temperature" },
311da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__AIRMOVER_FAN,
321da177e4SLinus Torvalds 		  "AirMover / Fan" },
331da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__VOLTAGE,
341da177e4SLinus Torvalds 		  "Voltage" },
351da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__INTRUSION,
361da177e4SLinus Torvalds 		  "Intrusion" },
371da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__POWER_SUPPLY,
381da177e4SLinus Torvalds 		  "Power Supply" },
391da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__LAN,
401da177e4SLinus Torvalds 		  "LAN" },
411da177e4SLinus Torvalds 		{ EL_TYPE__PAL__ENV__HOT_PLUG,
421da177e4SLinus Torvalds 		  "Hot Plug" },
431da177e4SLinus Torvalds 		{ 0, NULL }
441da177e4SLinus Torvalds 	};
451da177e4SLinus Torvalds 	int i;
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds 	for (i = 0; ev_packets[i].type != 0; i++) {
481da177e4SLinus Torvalds 		env = lf_subpackets->env[ev7_lf_env_index(ev_packets[i].type)];
491da177e4SLinus Torvalds 		if (!env)
501da177e4SLinus Torvalds 			continue;
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds 		printk("%s**%s event (cabinet %d, drawer %d)\n",
531da177e4SLinus Torvalds 		       err_print_prefix,
541da177e4SLinus Torvalds 		       ev_packets[i].name,
551da177e4SLinus Torvalds 		       env->cabinet,
561da177e4SLinus Torvalds 		       env->drawer);
571da177e4SLinus Torvalds 		printk("%s   Module Type: 0x%x - Unit ID 0x%x - "
581da177e4SLinus Torvalds 		       "Condition 0x%x\n",
591da177e4SLinus Torvalds 		       err_print_prefix,
601da177e4SLinus Torvalds 		       env->module_type,
611da177e4SLinus Torvalds 		       env->unit_id,
621da177e4SLinus Torvalds 		       env->condition);
631da177e4SLinus Torvalds 	}
641da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
651da177e4SLinus Torvalds }
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds static int
681da177e4SLinus Torvalds marvel_process_680_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
691da177e4SLinus Torvalds {
701da177e4SLinus Torvalds 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
711da177e4SLinus Torvalds 	int i;
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds 	for (i = ev7_lf_env_index(EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE);
741da177e4SLinus Torvalds 	     i <= ev7_lf_env_index(EL_TYPE__PAL__ENV__HOT_PLUG);
751da177e4SLinus Torvalds 	     i++) {
761da177e4SLinus Torvalds 		if (lf_subpackets->env[i])
771da177e4SLinus Torvalds 			status = MCHK_DISPOSITION_REPORT;
781da177e4SLinus Torvalds 	}
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds 	if (print)
811da177e4SLinus Torvalds 		marvel_print_680_frame(lf_subpackets);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	return status;
841da177e4SLinus Torvalds }
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds static void
891da177e4SLinus Torvalds marvel_print_err_cyc(u64 err_cyc)
901da177e4SLinus Torvalds {
911da177e4SLinus Torvalds 	static char *packet_desc[] = {
921da177e4SLinus Torvalds 		"No Error",
931da177e4SLinus Torvalds 		"UNKNOWN",
941da177e4SLinus Torvalds 		"1 cycle (1 or 2 flit packet)",
951da177e4SLinus Torvalds 		"2 cycles (3 flit packet)",
961da177e4SLinus Torvalds 		"9 cycles (18 flit packet)",
971da177e4SLinus Torvalds 		"10 cycles (19 flit packet)",
981da177e4SLinus Torvalds 		"UNKNOWN",
991da177e4SLinus Torvalds 		"UNKNOWN",
1001da177e4SLinus Torvalds 		"UNKNOWN"
1011da177e4SLinus Torvalds 	};
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds #define IO7__ERR_CYC__ODD_FLT	(1UL <<  0)
1041da177e4SLinus Torvalds #define IO7__ERR_CYC__EVN_FLT	(1UL <<  1)
1051da177e4SLinus Torvalds #define IO7__ERR_CYC__PACKET__S	(6)
1061da177e4SLinus Torvalds #define IO7__ERR_CYC__PACKET__M	(0x7)
1071da177e4SLinus Torvalds #define IO7__ERR_CYC__LOC	(1UL <<  5)
1081da177e4SLinus Torvalds #define IO7__ERR_CYC__CYCLE__S	(2)
1091da177e4SLinus Torvalds #define IO7__ERR_CYC__CYCLE__M	(0x7)
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds 	printk("%s        Packet In Error: %s\n"
1121da177e4SLinus Torvalds 	       "%s        Error in %s, cycle %ld%s%s\n",
1131da177e4SLinus Torvalds 	       err_print_prefix,
1141da177e4SLinus Torvalds 	       packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
1151da177e4SLinus Torvalds 	       err_print_prefix,
1161da177e4SLinus Torvalds 	       (err_cyc & IO7__ERR_CYC__LOC) ? "DATA" : "HEADER",
1171da177e4SLinus Torvalds 	       EXTRACT(err_cyc, IO7__ERR_CYC__CYCLE),
1181da177e4SLinus Torvalds 	       (err_cyc & IO7__ERR_CYC__ODD_FLT) ? " [ODD Flit]": "",
1191da177e4SLinus Torvalds 	       (err_cyc & IO7__ERR_CYC__EVN_FLT) ? " [Even Flit]": "");
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds static void
1231da177e4SLinus Torvalds marvel_print_po7_crrct_sym(u64 crrct_sym)
1241da177e4SLinus Torvalds {
1251da177e4SLinus Torvalds #define IO7__PO7_CRRCT_SYM__SYN__S	(0)
1261da177e4SLinus Torvalds #define IO7__PO7_CRRCT_SYM__SYN__M	(0x7f)
1271da177e4SLinus Torvalds #define IO7__PO7_CRRCT_SYM__ERR_CYC__S	(7)   /* ERR_CYC + ODD_FLT + EVN_FLT */
1281da177e4SLinus Torvalds #define IO7__PO7_CRRCT_SYM__ERR_CYC__M	(0x1ff)
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds 	printk("%s      Correctable Error Symptoms:\n"
1325f0e3da6SRandy Dunlap 	       "%s        Syndrome: 0x%llx\n",
1331da177e4SLinus Torvalds 	       err_print_prefix,
1341da177e4SLinus Torvalds 	       err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
1351da177e4SLinus Torvalds 	marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
1361da177e4SLinus Torvalds }
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds static void
1391da177e4SLinus Torvalds marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
1401da177e4SLinus Torvalds {
1411da177e4SLinus Torvalds 	static char *clk_names[] = { "_h[0]", "_h[1]", "_n[0]", "_n[1]" };
1421da177e4SLinus Torvalds 	static char *clk_decode[] = {
1431da177e4SLinus Torvalds 		"No Error",
1441da177e4SLinus Torvalds 		"One extra rising edge",
1451da177e4SLinus Torvalds 		"Two extra rising edges",
1461da177e4SLinus Torvalds 		"Lost one clock"
1471da177e4SLinus Torvalds 	};
1481da177e4SLinus Torvalds 	static char *port_names[] = { "Port 0", 	"Port 1",
1491da177e4SLinus Torvalds 				      "Port 2", 	"Port 3",
1501da177e4SLinus Torvalds 				      "Unknown Port",	"Unknown Port",
1511da177e4SLinus Torvalds 				      "Unknown Port",	"Port 7" };
1521da177e4SLinus Torvalds 	int scratch, i;
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__SYN__S	    (0)
1551da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__SYN__M	    (0x7f)
1561da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__ERR_CYC__S	    (7)      /* ERR_CYC + ODD_FLT... */
1571da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__ERR_CYC__M	    (0x1ff)  /* ... + EVN_FLT        */
1581da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CLK__S	    (16)
1591da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CLK__M	    (0xff)
1601da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ (1UL << 24)
1611da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO (1UL << 25)
1621da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO (1UL << 26)
1631da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK (1UL << 27)
1641da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK (1UL << 28)
1651da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__OVF__READIO	    (1UL << 29)
1661da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__OVF__WRITEIO    (1UL << 30)
1671da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__OVF__FWD        (1UL << 31)
1681da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__VICTIM_SP__S    (32)
1691da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__VICTIM_SP__M    (0xff)
1701da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__DETECT_SP__S    (40)
1711da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__DETECT_SP__M    (0xff)
1721da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__STRV_VTR__S     (48)
1731da177e4SLinus Torvalds #define IO7__PO7_UNCRR_SYM__STRV_VTR__M     (0x3ff)
1741da177e4SLinus Torvalds 
1751da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__INTX__S	    (0)
1761da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__INTX__M	    (0x3)
1771da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__SLOT__S	    (2)
1781da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__SLOT__M	    (0x7)
1791da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__BUS__S	    (5)
1801da177e4SLinus Torvalds #define IO7__STRV_VTR__LSI__BUS__M	    (0x3)
1811da177e4SLinus Torvalds #define IO7__STRV_VTR__MSI__INTNUM__S	    (0)
1821da177e4SLinus Torvalds #define IO7__STRV_VTR__MSI__INTNUM__M	    (0x1ff)
1831da177e4SLinus Torvalds #define IO7__STRV_VTR__IS_MSI		    (1UL << 9)
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	printk("%s      Uncorrectable Error Symptoms:\n", err_print_prefix);
1861da177e4SLinus Torvalds 	uncrr_sym &= valid_mask;
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
1895f0e3da6SRandy Dunlap 		printk("%s        Syndrome: 0x%llx\n",
1901da177e4SLinus Torvalds 		       err_print_prefix,
1911da177e4SLinus Torvalds 		       EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
1921da177e4SLinus Torvalds 
1931da177e4SLinus Torvalds 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__ERR_CYC))
1941da177e4SLinus Torvalds 		marvel_print_err_cyc(EXTRACT(uncrr_sym,
1951da177e4SLinus Torvalds 					     IO7__PO7_UNCRR_SYM__ERR_CYC));
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds 	scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__CLK);
1981da177e4SLinus Torvalds 	for (i = 0; i < 4; i++, scratch >>= 2) {
1991da177e4SLinus Torvalds 		if (scratch & 0x3)
2001da177e4SLinus Torvalds 			printk("%s        Clock %s: %s\n",
2011da177e4SLinus Torvalds 			       err_print_prefix,
2021da177e4SLinus Torvalds 			       clk_names[i], clk_decode[scratch & 0x3]);
2031da177e4SLinus Torvalds 	}
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ)
2061da177e4SLinus Torvalds 		printk("%s       REQ Credit Timeout or Overflow\n",
2071da177e4SLinus Torvalds 		       err_print_prefix);
2081da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO)
2091da177e4SLinus Torvalds 		printk("%s       RIO Credit Timeout or Overflow\n",
2101da177e4SLinus Torvalds 		       err_print_prefix);
2111da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO)
2121da177e4SLinus Torvalds 		printk("%s       WIO Credit Timeout or Overflow\n",
2131da177e4SLinus Torvalds 		       err_print_prefix);
2141da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK)
2151da177e4SLinus Torvalds 		printk("%s       BLK Credit Timeout or Overflow\n",
2161da177e4SLinus Torvalds 		       err_print_prefix);
2171da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK)
2181da177e4SLinus Torvalds 		printk("%s       NBK Credit Timeout or Overflow\n",
2191da177e4SLinus Torvalds 		       err_print_prefix);
2201da177e4SLinus Torvalds 
2211da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__READIO)
2221da177e4SLinus Torvalds 		printk("%s       Read I/O Buffer Overflow\n",
2231da177e4SLinus Torvalds 		       err_print_prefix);
2241da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__WRITEIO)
2251da177e4SLinus Torvalds 		printk("%s       Write I/O Buffer Overflow\n",
2261da177e4SLinus Torvalds 		       err_print_prefix);
2271da177e4SLinus Torvalds 	if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__FWD)
2281da177e4SLinus Torvalds 		printk("%s       FWD Buffer Overflow\n",
2291da177e4SLinus Torvalds 		       err_print_prefix);
2301da177e4SLinus Torvalds 
2311da177e4SLinus Torvalds 	if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__VICTIM_SP))) {
2321da177e4SLinus Torvalds 		int lost = scratch & (1UL << 4);
2331da177e4SLinus Torvalds 		scratch &= ~lost;
2341da177e4SLinus Torvalds 		for (i = 0; i < 8; i++, scratch >>= 1) {
2351da177e4SLinus Torvalds 			if (!(scratch & 1))
2361da177e4SLinus Torvalds 				continue;
2371da177e4SLinus Torvalds 			printk("%s        Error Response sent to %s",
2381da177e4SLinus Torvalds 			       err_print_prefix, port_names[i]);
2391da177e4SLinus Torvalds 		}
2401da177e4SLinus Torvalds 		if (lost)
2411da177e4SLinus Torvalds 			printk("%s        Lost Error sent somewhere else\n",
2421da177e4SLinus Torvalds 			       err_print_prefix);
2431da177e4SLinus Torvalds 	}
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds 	if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__DETECT_SP))) {
2461da177e4SLinus Torvalds 		for (i = 0; i < 8; i++, scratch >>= 1) {
2471da177e4SLinus Torvalds 			if (!(scratch & 1))
2481da177e4SLinus Torvalds 				continue;
2491da177e4SLinus Torvalds 			printk("%s        Error Reported by %s",
2501da177e4SLinus Torvalds 			       err_print_prefix, port_names[i]);
2511da177e4SLinus Torvalds 		}
2521da177e4SLinus Torvalds 	}
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__STRV_VTR)) {
2551da177e4SLinus Torvalds 		char starvation_message[80];
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 		scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__STRV_VTR);
2581da177e4SLinus Torvalds 		if (scratch & IO7__STRV_VTR__IS_MSI)
2591da177e4SLinus Torvalds 			sprintf(starvation_message,
2601da177e4SLinus Torvalds 				"MSI Interrupt 0x%x",
2611da177e4SLinus Torvalds 				EXTRACT(scratch, IO7__STRV_VTR__MSI__INTNUM));
2621da177e4SLinus Torvalds 		else
2631da177e4SLinus Torvalds 			sprintf(starvation_message,
2641da177e4SLinus Torvalds 				"LSI INT%c for Bus:Slot (%d:%d)\n",
2651da177e4SLinus Torvalds 				'A' + EXTRACT(scratch,
2661da177e4SLinus Torvalds 					      IO7__STRV_VTR__LSI__INTX),
2671da177e4SLinus Torvalds 				EXTRACT(scratch, IO7__STRV_VTR__LSI__BUS),
2681da177e4SLinus Torvalds 				EXTRACT(scratch, IO7__STRV_VTR__LSI__SLOT));
2691da177e4SLinus Torvalds 
2701da177e4SLinus Torvalds 		printk("%s        Starvation Int Trigger By: %s\n",
2711da177e4SLinus Torvalds 		       err_print_prefix, starvation_message);
2721da177e4SLinus Torvalds 	}
2731da177e4SLinus Torvalds }
2741da177e4SLinus Torvalds 
2751da177e4SLinus Torvalds static void
2761da177e4SLinus Torvalds marvel_print_po7_ugbge_sym(u64 ugbge_sym)
2771da177e4SLinus Torvalds {
2781da177e4SLinus Torvalds 	char opcode_str[10];
2791da177e4SLinus Torvalds 
2801da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__S	(6)
2811da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__M	(0xfffffffful)
2821da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__S	(40)
2831da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_OPCODE__M	(0xff)
2841da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__S	(48)
2851da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__M	(0xf)
2861da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__S	(52)
2871da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__M	(0x7ff)
2881da177e4SLinus Torvalds #define IO7__PO7_UGBGE_SYM__VALID		(1UL << 63)
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds 	if (!(ugbge_sym & IO7__PO7_UGBGE_SYM__VALID))
2911da177e4SLinus Torvalds 		return;
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	switch(EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) {
2941da177e4SLinus Torvalds 	case 0x51:
2951da177e4SLinus Torvalds 		sprintf(opcode_str, "Wr32");
2961da177e4SLinus Torvalds 		break;
2971da177e4SLinus Torvalds 	case 0x50:
2981da177e4SLinus Torvalds 		sprintf(opcode_str, "WrQW");
2991da177e4SLinus Torvalds 		break;
3001da177e4SLinus Torvalds 	case 0x54:
3011da177e4SLinus Torvalds 		sprintf(opcode_str, "WrIPR");
3021da177e4SLinus Torvalds 		break;
3031da177e4SLinus Torvalds 	case 0xD8:
3041da177e4SLinus Torvalds 		sprintf(opcode_str, "Victim");
3051da177e4SLinus Torvalds 		break;
3061da177e4SLinus Torvalds 	case 0xC5:
3071da177e4SLinus Torvalds 		sprintf(opcode_str, "BlkIO");
3081da177e4SLinus Torvalds 		break;
3091da177e4SLinus Torvalds 	default:
3105f0e3da6SRandy Dunlap 		sprintf(opcode_str, "0x%llx\n",
3111da177e4SLinus Torvalds 			EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
3121da177e4SLinus Torvalds 		break;
3131da177e4SLinus Torvalds 	}
3141da177e4SLinus Torvalds 
3151da177e4SLinus Torvalds 	printk("%s      Up Hose Garbage Symptom:\n"
3161da177e4SLinus Torvalds 	       "%s        Source Port: %ld - Dest PID: %ld - OpCode: %s\n",
3171da177e4SLinus Torvalds 	       err_print_prefix,
3181da177e4SLinus Torvalds 	       err_print_prefix,
3191da177e4SLinus Torvalds 	       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
3201da177e4SLinus Torvalds 	       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_DEST_PID),
3211da177e4SLinus Torvalds 	       opcode_str);
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds 	if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
3245f0e3da6SRandy Dunlap 		printk("%s        Packet Offset 0x%08llx\n",
3251da177e4SLinus Torvalds 		       err_print_prefix,
3261da177e4SLinus Torvalds 		       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
3271da177e4SLinus Torvalds }
3281da177e4SLinus Torvalds 
3291da177e4SLinus Torvalds static void
3301da177e4SLinus Torvalds marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
3311da177e4SLinus Torvalds {
3321da177e4SLinus Torvalds 	u64	uncrr_sym_valid = 0;
3331da177e4SLinus Torvalds 
3341da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_SBE		(1UL << 32)
3351da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_SBE2	(1UL << 33)
3361da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_PIO_WBYTE	(1UL << 34)
3371da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_CSR_NXM	(1UL << 35)
3381da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_RPID_ACV	(1UL << 36)
3391da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_RSP_NXM	(1UL << 37)
3401da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_ERR_RESP	(1UL << 38)
3411da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_CLK_DERR	(1UL << 39)
3421da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_DAT_DBE	(1UL << 40)
3431da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CR_DAT_GRBG	(1UL << 41)
3441da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__MAF_TO		(1UL << 42)
3451da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__UGBGE		(1UL << 43)
3461da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__UN_MAF_LOST	(1UL << 44)
3471da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__UN_PKT_OVF	(1UL << 45)
3481da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__UN_CDT_OVF	(1UL << 46)
3491da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__UN_DEALLOC	(1UL << 47)
3501da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_CDT_TO	(1UL << 51)
3511da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_CLK_HDR	(1UL << 52)
3521da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_DBE_HDR	(1UL << 53)
3531da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_GBG_HDR	(1UL << 54)
3541da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_BAD_CMD	(1UL << 55)
3551da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__HLT_INT	(1UL << 56)
3561da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__HP_INT		(1UL << 57)
3571da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__CRD_INT	(1UL << 58)
3581da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__STV_INT	(1UL << 59)
3591da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__HRD_INT	(1UL << 60)
3601da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__BH_SUM		(1UL << 61)
3611da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__ERR_LST	(1UL << 62)
3621da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__ERR_VALID	(1UL << 63)
3631da177e4SLinus Torvalds 
3641da177e4SLinus Torvalds #define IO7__PO7_ERRSUM__ERR_MASK	(IO7__PO7_ERRSUM__ERR_VALID |	\
3651da177e4SLinus Torvalds 					 IO7__PO7_ERRSUM__CR_SBE)
3661da177e4SLinus Torvalds 
3671da177e4SLinus Torvalds 	/*
3681da177e4SLinus Torvalds 	 * Single bit errors aren't covered by ERR_VALID.
3691da177e4SLinus Torvalds 	 */
3701da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE) {
3711da177e4SLinus Torvalds 		printk("%s    %sSingle Bit Error(s) detected/corrected\n",
3721da177e4SLinus Torvalds 		       err_print_prefix,
3731da177e4SLinus Torvalds 		       (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE2)
3741da177e4SLinus Torvalds 		       ? "Multiple " : "");
3751da177e4SLinus Torvalds 		marvel_print_po7_crrct_sym(io->po7_crrct_sym);
3761da177e4SLinus Torvalds 	}
3771da177e4SLinus Torvalds 
3781da177e4SLinus Torvalds 	/*
3791da177e4SLinus Torvalds 	 * Neither are the interrupt status bits
3801da177e4SLinus Torvalds 	 */
3811da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HLT_INT)
3821da177e4SLinus Torvalds 		printk("%s    Halt Interrupt posted", err_print_prefix);
3831da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HP_INT) {
3841da177e4SLinus Torvalds 		printk("%s    Hot Plug Event Interrupt posted",
3851da177e4SLinus Torvalds 		       err_print_prefix);
3861da177e4SLinus Torvalds 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
3871da177e4SLinus Torvalds 	}
3881da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CRD_INT)
3891da177e4SLinus Torvalds 		printk("%s    Correctable Error Interrupt posted",
3901da177e4SLinus Torvalds 		       err_print_prefix);
3911da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__STV_INT) {
3921da177e4SLinus Torvalds 		printk("%s    Starvation Interrupt posted", err_print_prefix);
3931da177e4SLinus Torvalds 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__STRV_VTR);
3941da177e4SLinus Torvalds 	}
3951da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__HRD_INT) {
3961da177e4SLinus Torvalds 		printk("%s    Hard Error Interrupt posted", err_print_prefix);
3971da177e4SLinus Torvalds 		uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
3981da177e4SLinus Torvalds 	}
3991da177e4SLinus Torvalds 
4001da177e4SLinus Torvalds 	/*
4011da177e4SLinus Torvalds 	 * Everything else is valid only with ERR_VALID, so skip to the end
4021da177e4SLinus Torvalds 	 * (uncrr_sym check) unless ERR_VALID is set.
4031da177e4SLinus Torvalds 	 */
4041da177e4SLinus Torvalds 	if (!(io->po7_error_sum & IO7__PO7_ERRSUM__ERR_VALID))
4051da177e4SLinus Torvalds 		goto check_uncrr_sym;
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds 	/*
4081da177e4SLinus Torvalds 	 * Since ERR_VALID is set, VICTIM_SP in uncrr_sym is valid.
4091da177e4SLinus Torvalds 	 * For bits [29:0] to also be valid, the following bits must
4101da177e4SLinus Torvalds 	 * not be set:
4111da177e4SLinus Torvalds 	 *	CR_PIO_WBYTE	CR_CSR_NXM	CR_RSP_NXM
4121da177e4SLinus Torvalds 	 *	CR_ERR_RESP	MAF_TO
4131da177e4SLinus Torvalds 	 */
4141da177e4SLinus Torvalds 	uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__VICTIM_SP);
4151da177e4SLinus Torvalds 	if (!(io->po7_error_sum & (IO7__PO7_ERRSUM__CR_PIO_WBYTE |
4161da177e4SLinus Torvalds 				   IO7__PO7_ERRSUM__CR_CSR_NXM |
4171da177e4SLinus Torvalds 				   IO7__PO7_ERRSUM__CR_RSP_NXM |
4181da177e4SLinus Torvalds 				   IO7__PO7_ERRSUM__CR_ERR_RESP |
4191da177e4SLinus Torvalds 				   IO7__PO7_ERRSUM__MAF_TO)))
4201da177e4SLinus Torvalds 		uncrr_sym_valid |= 0x3ffffffful;
4211da177e4SLinus Torvalds 
4221da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_PIO_WBYTE)
4231da177e4SLinus Torvalds 		printk("%s    Write byte into IO7 CSR\n", err_print_prefix);
4241da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CSR_NXM)
4251da177e4SLinus Torvalds 		printk("%s    PIO to non-existent CSR\n", err_print_prefix);
4261da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RPID_ACV)
4271da177e4SLinus Torvalds 		printk("%s    Bus Requester PID (Access Violation)\n",
4281da177e4SLinus Torvalds 		       err_print_prefix);
4291da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RSP_NXM)
4301da177e4SLinus Torvalds 		printk("%s    Received NXM response from EV7\n",
4311da177e4SLinus Torvalds 		       err_print_prefix);
4321da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_ERR_RESP)
4331da177e4SLinus Torvalds 		printk("%s    Received ERROR RESPONSE\n", err_print_prefix);
4341da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CLK_DERR)
4351da177e4SLinus Torvalds 		printk("%s    Clock error on data flit\n", err_print_prefix);
4361da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_DBE)
4371da177e4SLinus Torvalds 		printk("%s    Double Bit Error Data Error Detected\n",
4381da177e4SLinus Torvalds 		       err_print_prefix);
4391da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_GRBG)
4401da177e4SLinus Torvalds 		printk("%s    Garbage Encoding Detected on the data\n",
4411da177e4SLinus Torvalds 		       err_print_prefix);
4421da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UGBGE) {
4431da177e4SLinus Torvalds 		printk("%s    Garbage Encoding sent up hose\n",
4441da177e4SLinus Torvalds 		       err_print_prefix);
4451da177e4SLinus Torvalds 		marvel_print_po7_ugbge_sym(io->po7_ugbge_sym);
4461da177e4SLinus Torvalds 	}
4471da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_MAF_LOST)
4481da177e4SLinus Torvalds 		printk("%s    Orphan response (unexpected response)\n",
4491da177e4SLinus Torvalds 		       err_print_prefix);
4501da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_PKT_OVF)
4511da177e4SLinus Torvalds 		printk("%s    Down hose packet overflow\n", err_print_prefix);
4521da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_CDT_OVF)
4531da177e4SLinus Torvalds 		printk("%s    Down hose credit overflow\n", err_print_prefix);
4541da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_DEALLOC)
4551da177e4SLinus Torvalds 		printk("%s    Unexpected or bad dealloc field\n",
4561da177e4SLinus Torvalds 		       err_print_prefix);
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds 	/*
4591da177e4SLinus Torvalds 	 * The black hole events.
4601da177e4SLinus Torvalds 	 */
4611da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__MAF_TO)
4621da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Timeout for all responses\n",
4631da177e4SLinus Torvalds 		       err_print_prefix);
4641da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CDT_TO)
4651da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Credit Timeout\n", err_print_prefix);
4661da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CLK_HDR)
4671da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Clock check on header\n",
4681da177e4SLinus Torvalds 		       err_print_prefix);
4691da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_DBE_HDR)
4701da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Uncorrectable Error on header\n",
4711da177e4SLinus Torvalds 		       err_print_prefix);
4721da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_GBG_HDR)
4731da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Garbage on header\n",
4741da177e4SLinus Torvalds 		       err_print_prefix);
4751da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_BAD_CMD)
4761da177e4SLinus Torvalds 		printk("%s    BLACK HOLE: Bad EV7 command\n",
4771da177e4SLinus Torvalds 		       err_print_prefix);
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds 	if (io->po7_error_sum & IO7__PO7_ERRSUM__ERR_LST)
4801da177e4SLinus Torvalds 		printk("%s    Lost Error\n", err_print_prefix);
4811da177e4SLinus Torvalds 
4821da177e4SLinus Torvalds 	printk("%s    Failing Packet:\n"
4835f0e3da6SRandy Dunlap 	       "%s      Cycle 1: %016llx\n"
4845f0e3da6SRandy Dunlap 	       "%s      Cycle 2: %016llx\n",
4851da177e4SLinus Torvalds 	       err_print_prefix,
4861da177e4SLinus Torvalds 	       err_print_prefix, io->po7_err_pkt0,
4871da177e4SLinus Torvalds 	       err_print_prefix, io->po7_err_pkt1);
4881da177e4SLinus Torvalds 	/*
4891da177e4SLinus Torvalds 	 * If there are any valid bits in UNCRR sym for this err,
4901da177e4SLinus Torvalds 	 * print UNCRR_SYM as well.
4911da177e4SLinus Torvalds 	 */
4921da177e4SLinus Torvalds check_uncrr_sym:
4931da177e4SLinus Torvalds 	if (uncrr_sym_valid)
4941da177e4SLinus Torvalds 		marvel_print_po7_uncrr_sym(io->po7_uncrr_sym, uncrr_sym_valid);
4951da177e4SLinus Torvalds }
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds static void
4981da177e4SLinus Torvalds marvel_print_pox_tlb_err(u64 tlb_err)
4991da177e4SLinus Torvalds {
5001da177e4SLinus Torvalds 	static char *tlb_errors[] = {
5011da177e4SLinus Torvalds 		"No Error",
5021da177e4SLinus Torvalds 		"North Port Signaled Error fetching TLB entry",
5031da177e4SLinus Torvalds 		"PTE invalid or UCC or GBG error on this entry",
5041da177e4SLinus Torvalds 		"Address did not hit any DMA window"
5051da177e4SLinus Torvalds 	};
5061da177e4SLinus Torvalds 
5071da177e4SLinus Torvalds #define IO7__POX_TLBERR__ERR_VALID		(1UL << 63)
5081da177e4SLinus Torvalds #define IO7__POX_TLBERR__ERRCODE__S		(0)
5091da177e4SLinus Torvalds #define IO7__POX_TLBERR__ERRCODE__M		(0x3)
5101da177e4SLinus Torvalds #define IO7__POX_TLBERR__ERR_TLB_PTR__S		(3)
5111da177e4SLinus Torvalds #define IO7__POX_TLBERR__ERR_TLB_PTR__M		(0x7)
5121da177e4SLinus Torvalds #define IO7__POX_TLBERR__FADDR__S		(6)
5131da177e4SLinus Torvalds #define IO7__POX_TLBERR__FADDR__M		(0x3fffffffffful)
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds 	if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
5161da177e4SLinus Torvalds 		return;
5171da177e4SLinus Torvalds 
5185f0e3da6SRandy Dunlap 	printk("%s      TLB Error on index 0x%llx:\n"
5191da177e4SLinus Torvalds 	       "%s        - %s\n"
5205f0e3da6SRandy Dunlap 	       "%s        - Addr: 0x%016llx\n",
5211da177e4SLinus Torvalds 	       err_print_prefix,
5221da177e4SLinus Torvalds 	       EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
5231da177e4SLinus Torvalds 	       err_print_prefix,
5241da177e4SLinus Torvalds 	       tlb_errors[EXTRACT(tlb_err, IO7__POX_TLBERR__ERRCODE)],
5251da177e4SLinus Torvalds 	       err_print_prefix,
5261da177e4SLinus Torvalds 	       EXTRACT(tlb_err, IO7__POX_TLBERR__FADDR) << 6);
5271da177e4SLinus Torvalds }
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds static  void
5301da177e4SLinus Torvalds marvel_print_pox_spl_cmplt(u64 spl_cmplt)
5311da177e4SLinus Torvalds {
5321da177e4SLinus Torvalds 	char message[80];
5331da177e4SLinus Torvalds 
5341da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MESSAGE__S		(0)
5351da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MESSAGE__M		(0x0fffffffful)
5361da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_BUS__S	(40)
5371da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_BUS__M	(0xfful)
5381da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_DEV__S	(35)
5391da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_DEV__M	(0x1ful)
5401da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_FUNC__S	(32)
5411da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__SOURCE_FUNC__M	(0x07ul)
5421da177e4SLinus Torvalds 
5431da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_CLASS__S		(28)
5441da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_CLASS__M		(0xf)
5451da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_INDEX__S		(20)
5461da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_INDEX__M		(0xff)
5471da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__S	(20)
5481da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__M    (0xfff)
5491da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__S	(12)
5501da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__M	(0x7f)
5511da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__S	(0)
5521da177e4SLinus Torvalds #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M	(0xfff)
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds 	printk("%s      Split Completion Error:\n"
5551da177e4SLinus Torvalds 	       "%s         Source (Bus:Dev:Func): %ld:%ld:%ld\n",
5561da177e4SLinus Torvalds 	       err_print_prefix,
5571da177e4SLinus Torvalds 	       err_print_prefix,
5581da177e4SLinus Torvalds 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
5591da177e4SLinus Torvalds 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_DEV),
5601da177e4SLinus Torvalds 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_FUNC));
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds 	switch(EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MSG_CLASSINDEX)) {
5631da177e4SLinus Torvalds 	case 0x000:
5641da177e4SLinus Torvalds 		sprintf(message, "Normal completion");
5651da177e4SLinus Torvalds 		break;
5661da177e4SLinus Torvalds 	case 0x100:
5671da177e4SLinus Torvalds 		sprintf(message, "Bridge - Master Abort");
5681da177e4SLinus Torvalds 		break;
5691da177e4SLinus Torvalds 	case 0x101:
5701da177e4SLinus Torvalds 		sprintf(message, "Bridge - Target Abort");
5711da177e4SLinus Torvalds 		break;
5721da177e4SLinus Torvalds 	case 0x102:
5731da177e4SLinus Torvalds 		sprintf(message, "Bridge - Uncorrectable Write Data Error");
5741da177e4SLinus Torvalds 		break;
5751da177e4SLinus Torvalds 	case 0x200:
5761da177e4SLinus Torvalds 		sprintf(message, "Byte Count Out of Range");
5771da177e4SLinus Torvalds 		break;
5781da177e4SLinus Torvalds 	case 0x201:
5791da177e4SLinus Torvalds 		sprintf(message, "Uncorrectable Split Write Data Error");
5801da177e4SLinus Torvalds 		break;
5811da177e4SLinus Torvalds 	default:
5825f0e3da6SRandy Dunlap 		sprintf(message, "%08llx\n",
5831da177e4SLinus Torvalds 			EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
5841da177e4SLinus Torvalds 		break;
5851da177e4SLinus Torvalds 	}
5861da177e4SLinus Torvalds 	printk("%s	   Message: %s\n", err_print_prefix, message);
5871da177e4SLinus Torvalds }
5881da177e4SLinus Torvalds 
5891da177e4SLinus Torvalds static void
5901da177e4SLinus Torvalds marvel_print_pox_trans_sum(u64 trans_sum)
5911da177e4SLinus Torvalds {
5921da177e4SLinus Torvalds 	char *pcix_cmd[] = { "Interrupt Acknowledge",
5931da177e4SLinus Torvalds 			     "Special Cycle",
5941da177e4SLinus Torvalds 			     "I/O Read",
5951da177e4SLinus Torvalds 			     "I/O Write",
5961da177e4SLinus Torvalds 			     "Reserved",
5971da177e4SLinus Torvalds 			     "Reserved / Device ID Message",
5981da177e4SLinus Torvalds 			     "Memory Read",
5991da177e4SLinus Torvalds 			     "Memory Write",
6001da177e4SLinus Torvalds 			     "Reserved / Alias to Memory Read Block",
6011da177e4SLinus Torvalds 			     "Reserved / Alias to Memory Write Block",
6021da177e4SLinus Torvalds 			     "Configuration Read",
6031da177e4SLinus Torvalds 			     "Configuration Write",
6041da177e4SLinus Torvalds 			     "Memory Read Multiple / Split Completion",
6051da177e4SLinus Torvalds 			     "Dual Address Cycle",
6061da177e4SLinus Torvalds 			     "Memory Read Line / Memory Read Block",
6071da177e4SLinus Torvalds 			     "Memory Write and Invalidate / Memory Write Block"
6081da177e4SLinus Torvalds 	};
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCI_ADDR__S		(0)
6111da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCI_ADDR__M		(0x3fffffffffffful)
6121da177e4SLinus Torvalds #define IO7__POX_TRANSUM__DAC			(1UL << 50)
6131da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S	(52)
6141da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M	(0xf)
6151da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_CMD__S		(56)
6161da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_CMD__M		(0xf)
6171da177e4SLinus Torvalds #define IO7__POX_TRANSUM__ERR_VALID		(1UL << 63)
6181da177e4SLinus Torvalds 
6191da177e4SLinus Torvalds 	if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
6201da177e4SLinus Torvalds 		return;
6211da177e4SLinus Torvalds 
6221da177e4SLinus Torvalds 	printk("%s      Transaction Summary:\n"
6235f0e3da6SRandy Dunlap 	       "%s        Command: 0x%llx - %s\n"
6245f0e3da6SRandy Dunlap 	       "%s        Address: 0x%016llx%s\n"
6255f0e3da6SRandy Dunlap 	       "%s        PCI-X Master Slot: 0x%llx\n",
6261da177e4SLinus Torvalds 	       err_print_prefix,
6271da177e4SLinus Torvalds 	       err_print_prefix,
6281da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
6291da177e4SLinus Torvalds 	       pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
6301da177e4SLinus Torvalds 	       err_print_prefix,
6311da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
6321da177e4SLinus Torvalds 	       (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
6331da177e4SLinus Torvalds 	       err_print_prefix,
6341da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
6351da177e4SLinus Torvalds }
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds static void
6381da177e4SLinus Torvalds marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
6391da177e4SLinus Torvalds {
6401da177e4SLinus Torvalds #define IO7__POX_ERRSUM__AGP_REQQ_OVFL    (1UL <<  4)
6411da177e4SLinus Torvalds #define IO7__POX_ERRSUM__AGP_SYNC_ERR     (1UL <<  5)
6421da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MRETRY_TO        (1UL <<  6)
6431da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_UX_SPL      (1UL <<  7)
6441da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_SPLIT_TO    (1UL <<  8)
6451da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL <<  9)
6461da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DMA_RD_TO        (1UL << 10)
6471da177e4SLinus Torvalds #define IO7__POX_ERRSUM__CSR_NXM_RD       (1UL << 11)
6481da177e4SLinus Torvalds #define IO7__POX_ERRSUM__CSR_NXM_WR       (1UL << 12)
6491da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DMA_TO           (1UL << 13)
6501da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ALL_MABORTS      (1UL << 14)
6511da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MABORT		  (1UL << 15)
6521da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MABORT_MASK	  (IO7__POX_ERRSUM__ALL_MABORTS|\
6531da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__MABORT)
6541da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PT_TABORT        (1UL << 16)
6551da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PM_TABORT        (1UL << 17)
6561da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TABORT_MASK      (IO7__POX_ERRSUM__PT_TABORT | \
6571da177e4SLinus Torvalds                                            IO7__POX_ERRSUM__PM_TABORT)
6581da177e4SLinus Torvalds #define IO7__POX_ERRSUM__SERR             (1UL << 18)
6591da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ADDRERR_STB      (1UL << 19)
6601da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DETECTED_SERR    (1UL << 20)
6611da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PERR             (1UL << 21)
6621da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
6631da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DETECTED_PERR    (1UL << 23)
6641da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PM_PERR          (1UL << 24)
6651da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PT_SCERROR       (1UL << 26)
6661da177e4SLinus Torvalds #define IO7__POX_ERRSUM__HUNG_BUS         (1UL << 28)
6671da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR__S     (51)
6681da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR__M     (0xffUL)
6691da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
6701da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TLB_ERR          (1UL << 59)
6711da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ERR_VALID        (1UL << 63)
6721da177e4SLinus Torvalds 
6731da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TRANS_SUM__MASK  (IO7__POX_ERRSUM__MRETRY_TO |       \
6741da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PCIX_UX_SPL |     \
6751da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PCIX_SPLIT_TO |   \
6761da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DMA_TO |          \
6771da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__MABORT_MASK |     \
6781da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__TABORT_MASK |     \
6791da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__SERR |            \
6801da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__ADDRERR_STB |     \
6811da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PERR |            \
6821da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
6831da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DETECTED_PERR |   \
6841da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PM_PERR |         \
6851da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PT_SCERROR |      \
6861da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__UPE_ERROR)
6871da177e4SLinus Torvalds 
6881da177e4SLinus Torvalds 	if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
6891da177e4SLinus Torvalds 		return;
6901da177e4SLinus Torvalds 
6911da177e4SLinus Torvalds 	/*
6921da177e4SLinus Torvalds 	 * First the transaction summary errors
6931da177e4SLinus Torvalds 	 */
6941da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
6951da177e4SLinus Torvalds 		printk("%s    IO7 Master Retry Timeout expired\n",
6961da177e4SLinus Torvalds 		       err_print_prefix);
6971da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
6981da177e4SLinus Torvalds 		printk("%s    Unexpected Split Completion\n",
6991da177e4SLinus Torvalds 		       err_print_prefix);
7001da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
7011da177e4SLinus Torvalds 		printk("%s    IO7 Split Completion Timeout expired\n",
7021da177e4SLinus Torvalds 		       err_print_prefix);
7031da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DMA_TO)
7041da177e4SLinus Torvalds 		printk("%s    Hung bus during DMA transaction\n",
7051da177e4SLinus Torvalds 		       err_print_prefix);
7061da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
7071da177e4SLinus Torvalds 		printk("%s    Master Abort\n", err_print_prefix);
7081da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
7091da177e4SLinus Torvalds 		printk("%s    IO7 Asserted Target Abort\n", err_print_prefix);
7101da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
7111da177e4SLinus Torvalds 		printk("%s    IO7 Received Target Abort\n", err_print_prefix);
7121da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
7131da177e4SLinus Torvalds 		printk("%s    Address or PCI-X Attribute Parity Error\n",
7141da177e4SLinus Torvalds 		       err_print_prefix);
7151da177e4SLinus Torvalds 		if (err_sum & IO7__POX_ERRSUM__SERR)
7161da177e4SLinus Torvalds 			printk("%s     IO7 Asserted SERR\n", err_print_prefix);
7171da177e4SLinus Torvalds 	}
7181da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PERR) {
7191da177e4SLinus Torvalds 		if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
7201da177e4SLinus Torvalds 			printk("%s    IO7 Detected Data Parity Error\n",
7211da177e4SLinus Torvalds 			       err_print_prefix);
7221da177e4SLinus Torvalds 		else
7231da177e4SLinus Torvalds 			printk("%s    Split Completion Response with "
7241da177e4SLinus Torvalds 			       "Parity Error\n", err_print_prefix);
7251da177e4SLinus Torvalds 	}
7261da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
7271da177e4SLinus Torvalds 		printk("%s    PERR detected\n", err_print_prefix);
7281da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PM_PERR)
7291da177e4SLinus Torvalds 		printk("%s    PERR while IO7 is master\n", err_print_prefix);
7301da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
7311da177e4SLinus Torvalds 		printk("%s    IO7 Received Split Completion Error message\n",
7321da177e4SLinus Torvalds 		       err_print_prefix);
7331da177e4SLinus Torvalds 		marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
7341da177e4SLinus Torvalds 	}
7351da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
7361da177e4SLinus Torvalds 		unsigned int upe_error = EXTRACT(err_sum,
7371da177e4SLinus Torvalds 						 IO7__POX_ERRSUM__UPE_ERROR);
7381da177e4SLinus Torvalds 		int i;
7391da177e4SLinus Torvalds 		static char *upe_errors[] = {
7401da177e4SLinus Torvalds 			"Parity Error on MSI write data",
7411da177e4SLinus Torvalds 			"MSI read (MSI window is write only",
7421da177e4SLinus Torvalds 			"TLB - Invalid WR transaction",
7431da177e4SLinus Torvalds 			"TLB - Invalid RD transaction",
7441da177e4SLinus Torvalds 			"DMA - WR error (see north port)",
7451da177e4SLinus Torvalds 			"DMA - RD error (see north port)",
7461da177e4SLinus Torvalds 			"PPR - WR error (see north port)",
7471da177e4SLinus Torvalds 			"PPR - RD error (see north port)"
7481da177e4SLinus Torvalds 		};
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 		printk("%s    UPE Error:\n", err_print_prefix);
7511da177e4SLinus Torvalds 		for (i = 0; i < 8; i++) {
7521da177e4SLinus Torvalds 			if (upe_error & (1 << i))
7531da177e4SLinus Torvalds 				printk("%s      %s\n", err_print_prefix,
7541da177e4SLinus Torvalds 				       upe_errors[i]);
7551da177e4SLinus Torvalds 		}
7561da177e4SLinus Torvalds 	}
7571da177e4SLinus Torvalds 
7581da177e4SLinus Torvalds 	/*
7591da177e4SLinus Torvalds 	 * POx_TRANS_SUM, if appropriate.
7601da177e4SLinus Torvalds 	 */
7611da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK)
7621da177e4SLinus Torvalds 		marvel_print_pox_trans_sum(port->pox_trans_sum);
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 	/*
7651da177e4SLinus Torvalds 	 * Then TLB_ERR.
7661da177e4SLinus Torvalds 	 */
7671da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
7681da177e4SLinus Torvalds 		printk("%s    TLB ERROR\n", err_print_prefix);
7691da177e4SLinus Torvalds 		marvel_print_pox_tlb_err(port->pox_tlb_err);
7701da177e4SLinus Torvalds 	}
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	/*
7731da177e4SLinus Torvalds 	 * And the single bit status errors.
7741da177e4SLinus Torvalds 	 */
7751da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
7761da177e4SLinus Torvalds 		printk("%s    AGP Request Queue Overflow\n", err_print_prefix);
7771da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
7781da177e4SLinus Torvalds 		printk("%s    AGP Sync Error\n", err_print_prefix);
7791da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
7801da177e4SLinus Torvalds 		printk("%s    Discarded split completion\n", err_print_prefix);
7811da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
7821da177e4SLinus Torvalds 		printk("%s    DMA Read Timeout\n", err_print_prefix);
7831da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
7841da177e4SLinus Torvalds 		printk("%s    CSR NXM READ\n", err_print_prefix);
7851da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
7861da177e4SLinus Torvalds 		printk("%s    CSR NXM WRITE\n", err_print_prefix);
7871da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
7881da177e4SLinus Torvalds 		printk("%s    SERR detected\n", err_print_prefix);
7891da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
7901da177e4SLinus Torvalds 		printk("%s    HUNG BUS detected\n", err_print_prefix);
7911da177e4SLinus Torvalds }
7921da177e4SLinus Torvalds 
7931da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds static struct ev7_pal_io_subpacket *
7961da177e4SLinus Torvalds marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
7971da177e4SLinus Torvalds {
7981da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
7991da177e4SLinus Torvalds 	struct io7 *io7;
8001da177e4SLinus Torvalds 	int i;
8011da177e4SLinus Torvalds 
8021da177e4SLinus Torvalds 	/*
8031da177e4SLinus Torvalds 	 * Caller must provide the packet to fill
8041da177e4SLinus Torvalds 	 */
8051da177e4SLinus Torvalds 	if (!io)
8061da177e4SLinus Torvalds 		return NULL;
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	/*
8091da177e4SLinus Torvalds 	 * Fill the subpacket with the console's standard fill pattern
8101da177e4SLinus Torvalds 	 */
8111da177e4SLinus Torvalds 	memset(io, 0x55, sizeof(*io));
8121da177e4SLinus Torvalds 
8131da177e4SLinus Torvalds 	for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) {
8141da177e4SLinus Torvalds 		unsigned long err_sum = 0;
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds 		err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
8171da177e4SLinus Torvalds 		for (i = 0; i < IO7_NUM_PORTS; i++) {
8181da177e4SLinus Torvalds 			if (!io7->ports[i].enabled)
8191da177e4SLinus Torvalds 				continue;
8201da177e4SLinus Torvalds 			err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
8211da177e4SLinus Torvalds 		}
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds 		/*
8241da177e4SLinus Torvalds 		 * Is there at least one error?
8251da177e4SLinus Torvalds 		 */
8261da177e4SLinus Torvalds 		if (err_sum & (1UL << 63))
8271da177e4SLinus Torvalds 			break;
8281da177e4SLinus Torvalds 	}
8291da177e4SLinus Torvalds 
8301da177e4SLinus Torvalds 	/*
8311da177e4SLinus Torvalds 	 * Did we find an IO7 with an error?
8321da177e4SLinus Torvalds 	 */
8331da177e4SLinus Torvalds 	if (!io7)
8341da177e4SLinus Torvalds 		return NULL;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	/*
8371da177e4SLinus Torvalds 	 * We have an IO7 with an error.
8381da177e4SLinus Torvalds 	 *
8391da177e4SLinus Torvalds 	 * Fill in the IO subpacket.
8401da177e4SLinus Torvalds 	 */
8411da177e4SLinus Torvalds 	io->io_asic_rev   = io7->csrs->IO_ASIC_REV.csr;
8421da177e4SLinus Torvalds 	io->io_sys_rev    = io7->csrs->IO_SYS_REV.csr;
8431da177e4SLinus Torvalds 	io->io7_uph       = io7->csrs->IO7_UPH.csr;
8441da177e4SLinus Torvalds 	io->hpi_ctl       = io7->csrs->HPI_CTL.csr;
8451da177e4SLinus Torvalds 	io->crd_ctl       = io7->csrs->CRD_CTL.csr;
8461da177e4SLinus Torvalds 	io->hei_ctl       = io7->csrs->HEI_CTL.csr;
8471da177e4SLinus Torvalds 	io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
8481da177e4SLinus Torvalds 	io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
8491da177e4SLinus Torvalds 	io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
8501da177e4SLinus Torvalds 	io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
8511da177e4SLinus Torvalds 	io->po7_err_pkt0  = io7->csrs->PO7_ERR_PKT[0].csr;
8521da177e4SLinus Torvalds 	io->po7_err_pkt1  = io7->csrs->PO7_ERR_PKT[1].csr;
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds 	for (i = 0; i < IO7_NUM_PORTS; i++) {
8551da177e4SLinus Torvalds 		io7_ioport_csrs *csrs = io7->ports[i].csrs;
8561da177e4SLinus Torvalds 
8571da177e4SLinus Torvalds 		if (!io7->ports[i].enabled)
8581da177e4SLinus Torvalds 			continue;
8591da177e4SLinus Torvalds 
8601da177e4SLinus Torvalds 		io->ports[i].pox_err_sum   = csrs->POx_ERR_SUM.csr;
8611da177e4SLinus Torvalds 		io->ports[i].pox_tlb_err   = csrs->POx_TLB_ERR.csr;
8621da177e4SLinus Torvalds 		io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
8631da177e4SLinus Torvalds 		io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
8641da177e4SLinus Torvalds 		io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
8651da177e4SLinus Torvalds 		io->ports[i].pox_mult_err  = csrs->POx_MULT_ERR.csr;
8661da177e4SLinus Torvalds 		io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
8671da177e4SLinus Torvalds 		io->ports[i].pox_dm_dest   = csrs->POx_DM_DEST.csr;
8681da177e4SLinus Torvalds 		io->ports[i].pox_dm_size   = csrs->POx_DM_SIZE.csr;
8691da177e4SLinus Torvalds 		io->ports[i].pox_dm_ctrl   = csrs->POx_DM_CTRL.csr;
8701da177e4SLinus Torvalds 
8711da177e4SLinus Torvalds 		/*
8721da177e4SLinus Torvalds 		 * Ack this port's errors, if any. POx_ERR_SUM must be last.
8731da177e4SLinus Torvalds 		 *
8741da177e4SLinus Torvalds 		 * Most of the error registers get cleared and unlocked when
8751da177e4SLinus Torvalds 		 * the associated bits in POx_ERR_SUM are cleared (by writing
8761da177e4SLinus Torvalds 		 * 1). POx_TLB_ERR is an exception and must be explicitly
8771da177e4SLinus Torvalds 		 * cleared.
8781da177e4SLinus Torvalds 		 */
8791da177e4SLinus Torvalds 		csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
8801da177e4SLinus Torvalds 		csrs->POx_ERR_SUM.csr =	io->ports[i].pox_err_sum;
8811da177e4SLinus Torvalds 		mb();
8821da177e4SLinus Torvalds 		csrs->POx_ERR_SUM.csr;
8831da177e4SLinus Torvalds 	}
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	/*
8861da177e4SLinus Torvalds 	 * Ack any port 7 error(s).
8871da177e4SLinus Torvalds 	 */
8881da177e4SLinus Torvalds 	io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
8891da177e4SLinus Torvalds 	mb();
8901da177e4SLinus Torvalds 	io7->csrs->PO7_ERROR_SUM.csr;
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds 	/*
8931da177e4SLinus Torvalds 	 * Correct the io7_pid.
8941da177e4SLinus Torvalds 	 */
8951da177e4SLinus Torvalds 	lf_subpackets->io_pid = io7->pe;
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds 	return io;
8981da177e4SLinus Torvalds }
8991da177e4SLinus Torvalds 
9001da177e4SLinus Torvalds static int
9011da177e4SLinus Torvalds marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
9021da177e4SLinus Torvalds {
9031da177e4SLinus Torvalds 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
9041da177e4SLinus Torvalds 
9051da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
9061da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
9071da177e4SLinus Torvalds 	int i;
9081da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds #define MARVEL_IO_ERR_VALID(x)  ((x) & (1UL << 63))
9111da177e4SLinus Torvalds 
9121da177e4SLinus Torvalds 	if (!lf_subpackets->logout || !lf_subpackets->io)
9131da177e4SLinus Torvalds 		return status;
9141da177e4SLinus Torvalds 
9151da177e4SLinus Torvalds 	/*
9161da177e4SLinus Torvalds 	 * The PALcode only builds an IO subpacket if there is a
9171da177e4SLinus Torvalds 	 * locally connected IO7. In the cases of
9181da177e4SLinus Torvalds 	 *	1) a uniprocessor kernel
9191da177e4SLinus Torvalds 	 *	2) an mp kernel before the local secondary has called in
9201da177e4SLinus Torvalds 	 * error interrupts are all directed to the primary processor.
9211da177e4SLinus Torvalds 	 * In that case, we may not have an IO subpacket at all and, event
9221da177e4SLinus Torvalds 	 * if we do, it may not be the right now.
9231da177e4SLinus Torvalds 	 *
9241da177e4SLinus Torvalds 	 * If the RBOX indicates an I/O error interrupt, make sure we have
9251da177e4SLinus Torvalds 	 * the correct IO7 information. If we don't have an IO subpacket
9261da177e4SLinus Torvalds 	 * or it's the wrong one, try to find the right one.
9271da177e4SLinus Torvalds 	 *
9281da177e4SLinus Torvalds 	 * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
9291da177e4SLinus Torvalds 	 * RBOX_INT<10>.
9301da177e4SLinus Torvalds 	 */
9311da177e4SLinus Torvalds 	if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
9321da177e4SLinus Torvalds 	    ((lf_subpackets->io->po7_error_sum        |
9331da177e4SLinus Torvalds 	      lf_subpackets->io->ports[0].pox_err_sum |
9341da177e4SLinus Torvalds 	      lf_subpackets->io->ports[1].pox_err_sum |
9351da177e4SLinus Torvalds 	      lf_subpackets->io->ports[2].pox_err_sum |
9361da177e4SLinus Torvalds 	      lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
9371da177e4SLinus Torvalds 		/*
9381da177e4SLinus Torvalds 		 * Either we have no IO subpacket or no error is
9391da177e4SLinus Torvalds 		 * indicated in the one we do have. Try find the
9401da177e4SLinus Torvalds 		 * one with the error.
9411da177e4SLinus Torvalds 		 */
9421da177e4SLinus Torvalds 		if (!marvel_find_io7_with_error(lf_subpackets))
9431da177e4SLinus Torvalds 			return status;
9441da177e4SLinus Torvalds 	}
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	/*
9471da177e4SLinus Torvalds 	 * We have an IO7 indicating an error - we're going to report it
9481da177e4SLinus Torvalds 	 */
9491da177e4SLinus Torvalds 	status = MCHK_DISPOSITION_REPORT;
9501da177e4SLinus Torvalds 
9511da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	if (!print)
9541da177e4SLinus Torvalds 		return status;
9551da177e4SLinus Torvalds 
9561da177e4SLinus Torvalds 	printk("%s*Error occurred on IO7 at PID %u\n",
9571da177e4SLinus Torvalds 	       err_print_prefix, lf_subpackets->io_pid);
9581da177e4SLinus Torvalds 
9591da177e4SLinus Torvalds 	/*
9601da177e4SLinus Torvalds 	 * Check port 7 first
9611da177e4SLinus Torvalds 	 */
9621da177e4SLinus Torvalds 	if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
9631da177e4SLinus Torvalds 		marvel_print_po7_err_sum(io);
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds #if 0
9661da177e4SLinus Torvalds 		printk("%s  PORT 7 ERROR:\n"
9675f0e3da6SRandy Dunlap 		       "%s    PO7_ERROR_SUM: %016llx\n"
9685f0e3da6SRandy Dunlap 		       "%s    PO7_UNCRR_SYM: %016llx\n"
9695f0e3da6SRandy Dunlap 		       "%s    PO7_CRRCT_SYM: %016llx\n"
9705f0e3da6SRandy Dunlap 		       "%s    PO7_UGBGE_SYM: %016llx\n"
9715f0e3da6SRandy Dunlap 		       "%s    PO7_ERR_PKT0:  %016llx\n"
9725f0e3da6SRandy Dunlap 		       "%s    PO7_ERR_PKT1:  %016llx\n",
9731da177e4SLinus Torvalds 		       err_print_prefix,
9741da177e4SLinus Torvalds 		       err_print_prefix, io->po7_error_sum,
9751da177e4SLinus Torvalds 		       err_print_prefix, io->po7_uncrr_sym,
9761da177e4SLinus Torvalds 		       err_print_prefix, io->po7_crrct_sym,
9771da177e4SLinus Torvalds 		       err_print_prefix, io->po7_ugbge_sym,
9781da177e4SLinus Torvalds 		       err_print_prefix, io->po7_err_pkt0,
9791da177e4SLinus Torvalds 		       err_print_prefix, io->po7_err_pkt1);
9801da177e4SLinus Torvalds #endif
9811da177e4SLinus Torvalds 	}
9821da177e4SLinus Torvalds 
9831da177e4SLinus Torvalds 	/*
9841da177e4SLinus Torvalds 	 * Then loop through the ports
9851da177e4SLinus Torvalds 	 */
9861da177e4SLinus Torvalds 	for (i = 0; i < IO7_NUM_PORTS; i++) {
9871da177e4SLinus Torvalds 		if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
9881da177e4SLinus Torvalds 			continue;
9891da177e4SLinus Torvalds 
9905f0e3da6SRandy Dunlap 		printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
9911da177e4SLinus Torvalds 		       err_print_prefix,
9921da177e4SLinus Torvalds 		       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
9931da177e4SLinus Torvalds 		marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
9941da177e4SLinus Torvalds 
9955f0e3da6SRandy Dunlap 		printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
9961da177e4SLinus Torvalds 		       err_print_prefix, io->ports[i].pox_first_err);
9971da177e4SLinus Torvalds 		marvel_print_pox_err(io->ports[i].pox_first_err,
9981da177e4SLinus Torvalds 				     &io->ports[i]);
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds 	}
10011da177e4SLinus Torvalds 
10021da177e4SLinus Torvalds 
10031da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds 	return status;
10061da177e4SLinus Torvalds }
10071da177e4SLinus Torvalds 
10081da177e4SLinus Torvalds static int
10091da177e4SLinus Torvalds marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
10101da177e4SLinus Torvalds {
10111da177e4SLinus Torvalds 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
10121da177e4SLinus Torvalds 
10131da177e4SLinus Torvalds 	/*
10141da177e4SLinus Torvalds 	 * I/O error?
10151da177e4SLinus Torvalds 	 */
10161da177e4SLinus Torvalds #define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
10171da177e4SLinus Torvalds 	if (lf_subpackets->logout &&
10181da177e4SLinus Torvalds 	    (lf_subpackets->logout->rbox_int & 0x20000400ul))
10191da177e4SLinus Torvalds 		status = marvel_process_io_error(lf_subpackets, print);
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds 	/*
10221da177e4SLinus Torvalds 	 * Probing behind PCI-X bridges can cause machine checks on
10231da177e4SLinus Torvalds 	 * Marvel when the probe is handled by the bridge as a split
10241da177e4SLinus Torvalds 	 * completion transaction. The symptom is an ERROR_RESPONSE
10251da177e4SLinus Torvalds 	 * to a CONFIG address. Since these errors will happen in
10261da177e4SLinus Torvalds 	 * normal operation, dismiss them.
10271da177e4SLinus Torvalds 	 *
10281da177e4SLinus Torvalds 	 * Dismiss if:
10291da177e4SLinus Torvalds 	 *	C_STAT		= 0x14 		(Error Reponse)
10301da177e4SLinus Torvalds 	 *	C_STS<3>	= 0    		(C_ADDR valid)
10311da177e4SLinus Torvalds 	 *	C_ADDR<42>	= 1    		(I/O)
10321da177e4SLinus Torvalds 	 *	C_ADDR<31:22>	= 111110xxb	(PCI Config space)
10331da177e4SLinus Torvalds 	 */
10341da177e4SLinus Torvalds 	if (lf_subpackets->ev7 &&
10351da177e4SLinus Torvalds 	    (lf_subpackets->ev7->c_stat == 0x14) &&
10361da177e4SLinus Torvalds 	    !(lf_subpackets->ev7->c_sts & 0x8) &&
10371da177e4SLinus Torvalds 	    ((lf_subpackets->ev7->c_addr & 0x400ff000000ul)
10381da177e4SLinus Torvalds 	     == 0x400fe000000ul))
10391da177e4SLinus Torvalds 		status = MCHK_DISPOSITION_DISMISS;
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds 	return status;
10421da177e4SLinus Torvalds }
10431da177e4SLinus Torvalds 
10441da177e4SLinus Torvalds void
1045*1ffb1c0cSIvan Kokshaysky marvel_machine_check(unsigned long vector, unsigned long la_ptr)
10461da177e4SLinus Torvalds {
10471da177e4SLinus Torvalds 	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
10481da177e4SLinus Torvalds 	int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
10491da177e4SLinus Torvalds 	struct ev7_lf_subpackets subpacket_collection = { NULL, };
10501da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
10511da177e4SLinus Torvalds 	struct ev7_lf_subpackets *lf_subpackets = NULL;
10521da177e4SLinus Torvalds 	int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
10531da177e4SLinus Torvalds 	char *saved_err_prefix = err_print_prefix;
10541da177e4SLinus Torvalds 	char *error_type = NULL;
10551da177e4SLinus Torvalds 
10561da177e4SLinus Torvalds 	/*
10571da177e4SLinus Torvalds 	 * Sync the processor
10581da177e4SLinus Torvalds 	 */
10591da177e4SLinus Torvalds 	mb();
10601da177e4SLinus Torvalds 	draina();
10611da177e4SLinus Torvalds 
10621da177e4SLinus Torvalds 	switch(vector) {
10631da177e4SLinus Torvalds 	case SCB_Q_SYSEVENT:
10641da177e4SLinus Torvalds 		process_frame = marvel_process_680_frame;
10651da177e4SLinus Torvalds 		error_type = "System Event";
10661da177e4SLinus Torvalds 		break;
10671da177e4SLinus Torvalds 
10681da177e4SLinus Torvalds 	case SCB_Q_SYSMCHK:
10691da177e4SLinus Torvalds 		process_frame = marvel_process_logout_frame;
10701da177e4SLinus Torvalds 		error_type = "System Uncorrectable Error";
10711da177e4SLinus Torvalds 		break;
10721da177e4SLinus Torvalds 
10731da177e4SLinus Torvalds 	case SCB_Q_SYSERR:
10741da177e4SLinus Torvalds 		process_frame = marvel_process_logout_frame;
10751da177e4SLinus Torvalds 		error_type = "System Correctable Error";
10761da177e4SLinus Torvalds 		break;
10771da177e4SLinus Torvalds 
10781da177e4SLinus Torvalds 	default:
10791da177e4SLinus Torvalds 		/* Don't know it - pass it up.  */
10804fa1970aSAl Viro 		ev7_machine_check(vector, la_ptr);
10811da177e4SLinus Torvalds 		return;
10821da177e4SLinus Torvalds 	}
10831da177e4SLinus Torvalds 
10841da177e4SLinus Torvalds 	/*
1085c3a2ddeeSSimon Arlott 	 * A system event or error has occurred, handle it here.
10861da177e4SLinus Torvalds 	 *
10871da177e4SLinus Torvalds 	 * Any errors in the logout frame have already been cleared by the
10881da177e4SLinus Torvalds 	 * PALcode, so just parse it.
10891da177e4SLinus Torvalds 	 */
10901da177e4SLinus Torvalds 	err_print_prefix = KERN_CRIT;
10911da177e4SLinus Torvalds 
10921da177e4SLinus Torvalds 	/*
10931da177e4SLinus Torvalds 	 * Parse the logout frame without printing first. If the only error(s)
10941da177e4SLinus Torvalds 	 * found are classified as "dismissable", then just dismiss them and
10951da177e4SLinus Torvalds 	 * don't print any message
10961da177e4SLinus Torvalds 	 */
10971da177e4SLinus Torvalds 	lf_subpackets =
10981da177e4SLinus Torvalds 		ev7_collect_logout_frame_subpackets(el_ptr,
10991da177e4SLinus Torvalds 						    &subpacket_collection);
11001da177e4SLinus Torvalds 	if (process_frame && lf_subpackets && lf_subpackets->logout) {
11011da177e4SLinus Torvalds 		/*
11021da177e4SLinus Torvalds 		 * We might not have the correct (or any) I/O subpacket.
11031da177e4SLinus Torvalds 		 * [ See marvel_process_io_error() for explanation. ]
11041da177e4SLinus Torvalds 		 * If we don't have one, point the io subpacket in
11051da177e4SLinus Torvalds 		 * lf_subpackets at scratch_io_packet so that
11061da177e4SLinus Torvalds 		 * marvel_find_io7_with_error() will have someplace to
11071da177e4SLinus Torvalds 		 * store the info.
11081da177e4SLinus Torvalds 		 */
11091da177e4SLinus Torvalds 		if (!lf_subpackets->io)
11101da177e4SLinus Torvalds 			lf_subpackets->io = &scratch_io_packet;
11111da177e4SLinus Torvalds 
11121da177e4SLinus Torvalds 		/*
11131da177e4SLinus Torvalds 		 * Default io_pid to the processor reporting the error
11141da177e4SLinus Torvalds 		 * [this will get changed in marvel_find_io7_with_error()
11151da177e4SLinus Torvalds 		 * if a different one is needed]
11161da177e4SLinus Torvalds 		 */
11171da177e4SLinus Torvalds 		lf_subpackets->io_pid = lf_subpackets->logout->whami;
11181da177e4SLinus Torvalds 
11191da177e4SLinus Torvalds 		/*
11201da177e4SLinus Torvalds 		 * Evaluate the frames.
11211da177e4SLinus Torvalds 		 */
11221da177e4SLinus Torvalds 		disposition = process_frame(lf_subpackets, 0);
11231da177e4SLinus Torvalds 	}
11241da177e4SLinus Torvalds 	switch(disposition) {
11251da177e4SLinus Torvalds 	case MCHK_DISPOSITION_DISMISS:
11261da177e4SLinus Torvalds 		/* Nothing to do. */
11271da177e4SLinus Torvalds 		break;
11281da177e4SLinus Torvalds 
11291da177e4SLinus Torvalds 	case MCHK_DISPOSITION_REPORT:
11301da177e4SLinus Torvalds 		/* Recognized error, report it. */
11311da177e4SLinus Torvalds 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
11321da177e4SLinus Torvalds 		       err_print_prefix, error_type,
11331da177e4SLinus Torvalds 		       (unsigned int)vector, (int)smp_processor_id());
11341da177e4SLinus Torvalds 		el_print_timestamp(&lf_subpackets->logout->timestamp);
11351da177e4SLinus Torvalds 		process_frame(lf_subpackets, 1);
11361da177e4SLinus Torvalds 		break;
11371da177e4SLinus Torvalds 
11381da177e4SLinus Torvalds 	default:
11391da177e4SLinus Torvalds 		/* Unknown - dump the annotated subpackets. */
11401da177e4SLinus Torvalds 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
11411da177e4SLinus Torvalds 		       err_print_prefix, error_type,
11421da177e4SLinus Torvalds 		       (unsigned int)vector, (int)smp_processor_id());
11431da177e4SLinus Torvalds 		el_process_subpacket(el_ptr);
11441da177e4SLinus Torvalds 		break;
11451da177e4SLinus Torvalds 
11461da177e4SLinus Torvalds 	}
11471da177e4SLinus Torvalds 
11481da177e4SLinus Torvalds 	err_print_prefix = saved_err_prefix;
11491da177e4SLinus Torvalds 
11501da177e4SLinus Torvalds         /* Release the logout frame.  */
11511da177e4SLinus Torvalds 	wrmces(0x7);
11521da177e4SLinus Torvalds 	mb();
11531da177e4SLinus Torvalds }
11541da177e4SLinus Torvalds 
11559548b209SIvan Kokshaysky void __init
11561da177e4SLinus Torvalds marvel_register_error_handlers(void)
11571da177e4SLinus Torvalds {
11581da177e4SLinus Torvalds 	ev7_register_error_handlers();
11591da177e4SLinus Torvalds }
1160