xref: /linux-6.15/arch/alpha/kernel/err_marvel.c (revision 25985edc)
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"
1123e073367SMichael Cree 	       "%s        Error in %s, cycle %lld%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"
3163e073367SMichael Cree 	       "%s        Source Port: %lld - Dest PID: %lld - 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"
5553e073367SMichael Cree 	       "%s         Source (Bus:Dev:Func): %lld:%lld:%lld\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 {
59231019075SJoe Perches 	static const char * const pcix_cmd[] = {
59331019075SJoe Perches 		"Interrupt Acknowledge",
5941da177e4SLinus Torvalds 		"Special Cycle",
5951da177e4SLinus Torvalds 		"I/O Read",
5961da177e4SLinus Torvalds 		"I/O Write",
5971da177e4SLinus Torvalds 		"Reserved",
5981da177e4SLinus Torvalds 		"Reserved / Device ID Message",
5991da177e4SLinus Torvalds 		"Memory Read",
6001da177e4SLinus Torvalds 		"Memory Write",
6011da177e4SLinus Torvalds 		"Reserved / Alias to Memory Read Block",
6021da177e4SLinus Torvalds 		"Reserved / Alias to Memory Write Block",
6031da177e4SLinus Torvalds 		"Configuration Read",
6041da177e4SLinus Torvalds 		"Configuration Write",
6051da177e4SLinus Torvalds 		"Memory Read Multiple / Split Completion",
6061da177e4SLinus Torvalds 		"Dual Address Cycle",
6071da177e4SLinus Torvalds 		"Memory Read Line / Memory Read Block",
6081da177e4SLinus Torvalds 		"Memory Write and Invalidate / Memory Write Block"
6091da177e4SLinus Torvalds 	};
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCI_ADDR__S		(0)
6121da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCI_ADDR__M		(0x3fffffffffffful)
6131da177e4SLinus Torvalds #define IO7__POX_TRANSUM__DAC			(1UL << 50)
6141da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S	(52)
6151da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M	(0xf)
6161da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_CMD__S		(56)
6171da177e4SLinus Torvalds #define IO7__POX_TRANSUM__PCIX_CMD__M		(0xf)
6181da177e4SLinus Torvalds #define IO7__POX_TRANSUM__ERR_VALID		(1UL << 63)
6191da177e4SLinus Torvalds 
6201da177e4SLinus Torvalds 	if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
6211da177e4SLinus Torvalds 		return;
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	printk("%s      Transaction Summary:\n"
6245f0e3da6SRandy Dunlap 	       "%s        Command: 0x%llx - %s\n"
6255f0e3da6SRandy Dunlap 	       "%s        Address: 0x%016llx%s\n"
6265f0e3da6SRandy Dunlap 	       "%s        PCI-X Master Slot: 0x%llx\n",
6271da177e4SLinus Torvalds 	       err_print_prefix,
6281da177e4SLinus Torvalds 	       err_print_prefix,
6291da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
6301da177e4SLinus Torvalds 	       pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
6311da177e4SLinus Torvalds 	       err_print_prefix,
6321da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
6331da177e4SLinus Torvalds 	       (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
6341da177e4SLinus Torvalds 	       err_print_prefix,
6351da177e4SLinus Torvalds 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
6361da177e4SLinus Torvalds }
6371da177e4SLinus Torvalds 
6381da177e4SLinus Torvalds static void
6391da177e4SLinus Torvalds marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
6401da177e4SLinus Torvalds {
6411da177e4SLinus Torvalds #define IO7__POX_ERRSUM__AGP_REQQ_OVFL    (1UL <<  4)
6421da177e4SLinus Torvalds #define IO7__POX_ERRSUM__AGP_SYNC_ERR     (1UL <<  5)
6431da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MRETRY_TO        (1UL <<  6)
6441da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_UX_SPL      (1UL <<  7)
6451da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_SPLIT_TO    (1UL <<  8)
6461da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL <<  9)
6471da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DMA_RD_TO        (1UL << 10)
6481da177e4SLinus Torvalds #define IO7__POX_ERRSUM__CSR_NXM_RD       (1UL << 11)
6491da177e4SLinus Torvalds #define IO7__POX_ERRSUM__CSR_NXM_WR       (1UL << 12)
6501da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DMA_TO           (1UL << 13)
6511da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ALL_MABORTS      (1UL << 14)
6521da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MABORT		  (1UL << 15)
6531da177e4SLinus Torvalds #define IO7__POX_ERRSUM__MABORT_MASK	  (IO7__POX_ERRSUM__ALL_MABORTS|\
6541da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__MABORT)
6551da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PT_TABORT        (1UL << 16)
6561da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PM_TABORT        (1UL << 17)
6571da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TABORT_MASK      (IO7__POX_ERRSUM__PT_TABORT | \
6581da177e4SLinus Torvalds                                            IO7__POX_ERRSUM__PM_TABORT)
6591da177e4SLinus Torvalds #define IO7__POX_ERRSUM__SERR             (1UL << 18)
6601da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ADDRERR_STB      (1UL << 19)
6611da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DETECTED_SERR    (1UL << 20)
6621da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PERR             (1UL << 21)
6631da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
6641da177e4SLinus Torvalds #define IO7__POX_ERRSUM__DETECTED_PERR    (1UL << 23)
6651da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PM_PERR          (1UL << 24)
6661da177e4SLinus Torvalds #define IO7__POX_ERRSUM__PT_SCERROR       (1UL << 26)
6671da177e4SLinus Torvalds #define IO7__POX_ERRSUM__HUNG_BUS         (1UL << 28)
6681da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR__S     (51)
6691da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR__M     (0xffUL)
6701da177e4SLinus Torvalds #define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
6711da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TLB_ERR          (1UL << 59)
6721da177e4SLinus Torvalds #define IO7__POX_ERRSUM__ERR_VALID        (1UL << 63)
6731da177e4SLinus Torvalds 
6741da177e4SLinus Torvalds #define IO7__POX_ERRSUM__TRANS_SUM__MASK  (IO7__POX_ERRSUM__MRETRY_TO |       \
6751da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PCIX_UX_SPL |     \
6761da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PCIX_SPLIT_TO |   \
6771da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DMA_TO |          \
6781da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__MABORT_MASK |     \
6791da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__TABORT_MASK |     \
6801da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__SERR |            \
6811da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__ADDRERR_STB |     \
6821da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PERR |            \
6831da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
6841da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__DETECTED_PERR |   \
6851da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PM_PERR |         \
6861da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__PT_SCERROR |      \
6871da177e4SLinus Torvalds 					   IO7__POX_ERRSUM__UPE_ERROR)
6881da177e4SLinus Torvalds 
6891da177e4SLinus Torvalds 	if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
6901da177e4SLinus Torvalds 		return;
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 	/*
6931da177e4SLinus Torvalds 	 * First the transaction summary errors
6941da177e4SLinus Torvalds 	 */
6951da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
6961da177e4SLinus Torvalds 		printk("%s    IO7 Master Retry Timeout expired\n",
6971da177e4SLinus Torvalds 		       err_print_prefix);
6981da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
6991da177e4SLinus Torvalds 		printk("%s    Unexpected Split Completion\n",
7001da177e4SLinus Torvalds 		       err_print_prefix);
7011da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
7021da177e4SLinus Torvalds 		printk("%s    IO7 Split Completion Timeout expired\n",
7031da177e4SLinus Torvalds 		       err_print_prefix);
7041da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DMA_TO)
7051da177e4SLinus Torvalds 		printk("%s    Hung bus during DMA transaction\n",
7061da177e4SLinus Torvalds 		       err_print_prefix);
7071da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
7081da177e4SLinus Torvalds 		printk("%s    Master Abort\n", err_print_prefix);
7091da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
7101da177e4SLinus Torvalds 		printk("%s    IO7 Asserted Target Abort\n", err_print_prefix);
7111da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
7121da177e4SLinus Torvalds 		printk("%s    IO7 Received Target Abort\n", err_print_prefix);
7131da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
7141da177e4SLinus Torvalds 		printk("%s    Address or PCI-X Attribute Parity Error\n",
7151da177e4SLinus Torvalds 		       err_print_prefix);
7161da177e4SLinus Torvalds 		if (err_sum & IO7__POX_ERRSUM__SERR)
7171da177e4SLinus Torvalds 			printk("%s     IO7 Asserted SERR\n", err_print_prefix);
7181da177e4SLinus Torvalds 	}
7191da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PERR) {
7201da177e4SLinus Torvalds 		if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
7211da177e4SLinus Torvalds 			printk("%s    IO7 Detected Data Parity Error\n",
7221da177e4SLinus Torvalds 			       err_print_prefix);
7231da177e4SLinus Torvalds 		else
7241da177e4SLinus Torvalds 			printk("%s    Split Completion Response with "
7251da177e4SLinus Torvalds 			       "Parity Error\n", err_print_prefix);
7261da177e4SLinus Torvalds 	}
7271da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
7281da177e4SLinus Torvalds 		printk("%s    PERR detected\n", err_print_prefix);
7291da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PM_PERR)
7301da177e4SLinus Torvalds 		printk("%s    PERR while IO7 is master\n", err_print_prefix);
7311da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
7321da177e4SLinus Torvalds 		printk("%s    IO7 Received Split Completion Error message\n",
7331da177e4SLinus Torvalds 		       err_print_prefix);
7341da177e4SLinus Torvalds 		marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
7351da177e4SLinus Torvalds 	}
7361da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
7371da177e4SLinus Torvalds 		unsigned int upe_error = EXTRACT(err_sum,
7381da177e4SLinus Torvalds 						 IO7__POX_ERRSUM__UPE_ERROR);
7391da177e4SLinus Torvalds 		int i;
7401da177e4SLinus Torvalds 		static char *upe_errors[] = {
7411da177e4SLinus Torvalds 			"Parity Error on MSI write data",
7421da177e4SLinus Torvalds 			"MSI read (MSI window is write only",
7431da177e4SLinus Torvalds 			"TLB - Invalid WR transaction",
7441da177e4SLinus Torvalds 			"TLB - Invalid RD transaction",
7451da177e4SLinus Torvalds 			"DMA - WR error (see north port)",
7461da177e4SLinus Torvalds 			"DMA - RD error (see north port)",
7471da177e4SLinus Torvalds 			"PPR - WR error (see north port)",
7481da177e4SLinus Torvalds 			"PPR - RD error (see north port)"
7491da177e4SLinus Torvalds 		};
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds 		printk("%s    UPE Error:\n", err_print_prefix);
7521da177e4SLinus Torvalds 		for (i = 0; i < 8; i++) {
7531da177e4SLinus Torvalds 			if (upe_error & (1 << i))
7541da177e4SLinus Torvalds 				printk("%s      %s\n", err_print_prefix,
7551da177e4SLinus Torvalds 				       upe_errors[i]);
7561da177e4SLinus Torvalds 		}
7571da177e4SLinus Torvalds 	}
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	/*
7601da177e4SLinus Torvalds 	 * POx_TRANS_SUM, if appropriate.
7611da177e4SLinus Torvalds 	 */
7621da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK)
7631da177e4SLinus Torvalds 		marvel_print_pox_trans_sum(port->pox_trans_sum);
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds 	/*
7661da177e4SLinus Torvalds 	 * Then TLB_ERR.
7671da177e4SLinus Torvalds 	 */
7681da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
7691da177e4SLinus Torvalds 		printk("%s    TLB ERROR\n", err_print_prefix);
7701da177e4SLinus Torvalds 		marvel_print_pox_tlb_err(port->pox_tlb_err);
7711da177e4SLinus Torvalds 	}
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds 	/*
7741da177e4SLinus Torvalds 	 * And the single bit status errors.
7751da177e4SLinus Torvalds 	 */
7761da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
7771da177e4SLinus Torvalds 		printk("%s    AGP Request Queue Overflow\n", err_print_prefix);
7781da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
7791da177e4SLinus Torvalds 		printk("%s    AGP Sync Error\n", err_print_prefix);
7801da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
7811da177e4SLinus Torvalds 		printk("%s    Discarded split completion\n", err_print_prefix);
7821da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
7831da177e4SLinus Torvalds 		printk("%s    DMA Read Timeout\n", err_print_prefix);
7841da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
7851da177e4SLinus Torvalds 		printk("%s    CSR NXM READ\n", err_print_prefix);
7861da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
7871da177e4SLinus Torvalds 		printk("%s    CSR NXM WRITE\n", err_print_prefix);
7881da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
7891da177e4SLinus Torvalds 		printk("%s    SERR detected\n", err_print_prefix);
7901da177e4SLinus Torvalds 	if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
7911da177e4SLinus Torvalds 		printk("%s    HUNG BUS detected\n", err_print_prefix);
7921da177e4SLinus Torvalds }
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds static struct ev7_pal_io_subpacket *
7971da177e4SLinus Torvalds marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
7981da177e4SLinus Torvalds {
7991da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
8001da177e4SLinus Torvalds 	struct io7 *io7;
8011da177e4SLinus Torvalds 	int i;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	/*
8041da177e4SLinus Torvalds 	 * Caller must provide the packet to fill
8051da177e4SLinus Torvalds 	 */
8061da177e4SLinus Torvalds 	if (!io)
8071da177e4SLinus Torvalds 		return NULL;
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	/*
8101da177e4SLinus Torvalds 	 * Fill the subpacket with the console's standard fill pattern
8111da177e4SLinus Torvalds 	 */
8121da177e4SLinus Torvalds 	memset(io, 0x55, sizeof(*io));
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds 	for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) {
8151da177e4SLinus Torvalds 		unsigned long err_sum = 0;
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds 		err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
8181da177e4SLinus Torvalds 		for (i = 0; i < IO7_NUM_PORTS; i++) {
8191da177e4SLinus Torvalds 			if (!io7->ports[i].enabled)
8201da177e4SLinus Torvalds 				continue;
8211da177e4SLinus Torvalds 			err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
8221da177e4SLinus Torvalds 		}
8231da177e4SLinus Torvalds 
8241da177e4SLinus Torvalds 		/*
8251da177e4SLinus Torvalds 		 * Is there at least one error?
8261da177e4SLinus Torvalds 		 */
8271da177e4SLinus Torvalds 		if (err_sum & (1UL << 63))
8281da177e4SLinus Torvalds 			break;
8291da177e4SLinus Torvalds 	}
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds 	/*
8321da177e4SLinus Torvalds 	 * Did we find an IO7 with an error?
8331da177e4SLinus Torvalds 	 */
8341da177e4SLinus Torvalds 	if (!io7)
8351da177e4SLinus Torvalds 		return NULL;
8361da177e4SLinus Torvalds 
8371da177e4SLinus Torvalds 	/*
8381da177e4SLinus Torvalds 	 * We have an IO7 with an error.
8391da177e4SLinus Torvalds 	 *
8401da177e4SLinus Torvalds 	 * Fill in the IO subpacket.
8411da177e4SLinus Torvalds 	 */
8421da177e4SLinus Torvalds 	io->io_asic_rev   = io7->csrs->IO_ASIC_REV.csr;
8431da177e4SLinus Torvalds 	io->io_sys_rev    = io7->csrs->IO_SYS_REV.csr;
8441da177e4SLinus Torvalds 	io->io7_uph       = io7->csrs->IO7_UPH.csr;
8451da177e4SLinus Torvalds 	io->hpi_ctl       = io7->csrs->HPI_CTL.csr;
8461da177e4SLinus Torvalds 	io->crd_ctl       = io7->csrs->CRD_CTL.csr;
8471da177e4SLinus Torvalds 	io->hei_ctl       = io7->csrs->HEI_CTL.csr;
8481da177e4SLinus Torvalds 	io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
8491da177e4SLinus Torvalds 	io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
8501da177e4SLinus Torvalds 	io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
8511da177e4SLinus Torvalds 	io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
8521da177e4SLinus Torvalds 	io->po7_err_pkt0  = io7->csrs->PO7_ERR_PKT[0].csr;
8531da177e4SLinus Torvalds 	io->po7_err_pkt1  = io7->csrs->PO7_ERR_PKT[1].csr;
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds 	for (i = 0; i < IO7_NUM_PORTS; i++) {
8561da177e4SLinus Torvalds 		io7_ioport_csrs *csrs = io7->ports[i].csrs;
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 		if (!io7->ports[i].enabled)
8591da177e4SLinus Torvalds 			continue;
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds 		io->ports[i].pox_err_sum   = csrs->POx_ERR_SUM.csr;
8621da177e4SLinus Torvalds 		io->ports[i].pox_tlb_err   = csrs->POx_TLB_ERR.csr;
8631da177e4SLinus Torvalds 		io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
8641da177e4SLinus Torvalds 		io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
8651da177e4SLinus Torvalds 		io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
8661da177e4SLinus Torvalds 		io->ports[i].pox_mult_err  = csrs->POx_MULT_ERR.csr;
8671da177e4SLinus Torvalds 		io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
8681da177e4SLinus Torvalds 		io->ports[i].pox_dm_dest   = csrs->POx_DM_DEST.csr;
8691da177e4SLinus Torvalds 		io->ports[i].pox_dm_size   = csrs->POx_DM_SIZE.csr;
8701da177e4SLinus Torvalds 		io->ports[i].pox_dm_ctrl   = csrs->POx_DM_CTRL.csr;
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds 		/*
8731da177e4SLinus Torvalds 		 * Ack this port's errors, if any. POx_ERR_SUM must be last.
8741da177e4SLinus Torvalds 		 *
8751da177e4SLinus Torvalds 		 * Most of the error registers get cleared and unlocked when
8761da177e4SLinus Torvalds 		 * the associated bits in POx_ERR_SUM are cleared (by writing
8771da177e4SLinus Torvalds 		 * 1). POx_TLB_ERR is an exception and must be explicitly
8781da177e4SLinus Torvalds 		 * cleared.
8791da177e4SLinus Torvalds 		 */
8801da177e4SLinus Torvalds 		csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
8811da177e4SLinus Torvalds 		csrs->POx_ERR_SUM.csr =	io->ports[i].pox_err_sum;
8821da177e4SLinus Torvalds 		mb();
8831da177e4SLinus Torvalds 		csrs->POx_ERR_SUM.csr;
8841da177e4SLinus Torvalds 	}
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds 	/*
8871da177e4SLinus Torvalds 	 * Ack any port 7 error(s).
8881da177e4SLinus Torvalds 	 */
8891da177e4SLinus Torvalds 	io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
8901da177e4SLinus Torvalds 	mb();
8911da177e4SLinus Torvalds 	io7->csrs->PO7_ERROR_SUM.csr;
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds 	/*
8941da177e4SLinus Torvalds 	 * Correct the io7_pid.
8951da177e4SLinus Torvalds 	 */
8961da177e4SLinus Torvalds 	lf_subpackets->io_pid = io7->pe;
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds 	return io;
8991da177e4SLinus Torvalds }
9001da177e4SLinus Torvalds 
9011da177e4SLinus Torvalds static int
9021da177e4SLinus Torvalds marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
9031da177e4SLinus Torvalds {
9041da177e4SLinus Torvalds 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
9071da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket *io = lf_subpackets->io;
9081da177e4SLinus Torvalds 	int i;
9091da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds #define MARVEL_IO_ERR_VALID(x)  ((x) & (1UL << 63))
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds 	if (!lf_subpackets->logout || !lf_subpackets->io)
9141da177e4SLinus Torvalds 		return status;
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds 	/*
9171da177e4SLinus Torvalds 	 * The PALcode only builds an IO subpacket if there is a
9181da177e4SLinus Torvalds 	 * locally connected IO7. In the cases of
9191da177e4SLinus Torvalds 	 *	1) a uniprocessor kernel
9201da177e4SLinus Torvalds 	 *	2) an mp kernel before the local secondary has called in
9211da177e4SLinus Torvalds 	 * error interrupts are all directed to the primary processor.
9221da177e4SLinus Torvalds 	 * In that case, we may not have an IO subpacket at all and, event
9231da177e4SLinus Torvalds 	 * if we do, it may not be the right now.
9241da177e4SLinus Torvalds 	 *
9251da177e4SLinus Torvalds 	 * If the RBOX indicates an I/O error interrupt, make sure we have
9261da177e4SLinus Torvalds 	 * the correct IO7 information. If we don't have an IO subpacket
9271da177e4SLinus Torvalds 	 * or it's the wrong one, try to find the right one.
9281da177e4SLinus Torvalds 	 *
9291da177e4SLinus Torvalds 	 * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
9301da177e4SLinus Torvalds 	 * RBOX_INT<10>.
9311da177e4SLinus Torvalds 	 */
9321da177e4SLinus Torvalds 	if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
9331da177e4SLinus Torvalds 	    ((lf_subpackets->io->po7_error_sum        |
9341da177e4SLinus Torvalds 	      lf_subpackets->io->ports[0].pox_err_sum |
9351da177e4SLinus Torvalds 	      lf_subpackets->io->ports[1].pox_err_sum |
9361da177e4SLinus Torvalds 	      lf_subpackets->io->ports[2].pox_err_sum |
9371da177e4SLinus Torvalds 	      lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
9381da177e4SLinus Torvalds 		/*
9391da177e4SLinus Torvalds 		 * Either we have no IO subpacket or no error is
9401da177e4SLinus Torvalds 		 * indicated in the one we do have. Try find the
9411da177e4SLinus Torvalds 		 * one with the error.
9421da177e4SLinus Torvalds 		 */
9431da177e4SLinus Torvalds 		if (!marvel_find_io7_with_error(lf_subpackets))
9441da177e4SLinus Torvalds 			return status;
9451da177e4SLinus Torvalds 	}
9461da177e4SLinus Torvalds 
9471da177e4SLinus Torvalds 	/*
9481da177e4SLinus Torvalds 	 * We have an IO7 indicating an error - we're going to report it
9491da177e4SLinus Torvalds 	 */
9501da177e4SLinus Torvalds 	status = MCHK_DISPOSITION_REPORT;
9511da177e4SLinus Torvalds 
9521da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds 	if (!print)
9551da177e4SLinus Torvalds 		return status;
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 	printk("%s*Error occurred on IO7 at PID %u\n",
9581da177e4SLinus Torvalds 	       err_print_prefix, lf_subpackets->io_pid);
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	/*
9611da177e4SLinus Torvalds 	 * Check port 7 first
9621da177e4SLinus Torvalds 	 */
9631da177e4SLinus Torvalds 	if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
9641da177e4SLinus Torvalds 		marvel_print_po7_err_sum(io);
9651da177e4SLinus Torvalds 
9661da177e4SLinus Torvalds #if 0
9671da177e4SLinus Torvalds 		printk("%s  PORT 7 ERROR:\n"
9685f0e3da6SRandy Dunlap 		       "%s    PO7_ERROR_SUM: %016llx\n"
9695f0e3da6SRandy Dunlap 		       "%s    PO7_UNCRR_SYM: %016llx\n"
9705f0e3da6SRandy Dunlap 		       "%s    PO7_CRRCT_SYM: %016llx\n"
9715f0e3da6SRandy Dunlap 		       "%s    PO7_UGBGE_SYM: %016llx\n"
9725f0e3da6SRandy Dunlap 		       "%s    PO7_ERR_PKT0:  %016llx\n"
9735f0e3da6SRandy Dunlap 		       "%s    PO7_ERR_PKT1:  %016llx\n",
9741da177e4SLinus Torvalds 		       err_print_prefix,
9751da177e4SLinus Torvalds 		       err_print_prefix, io->po7_error_sum,
9761da177e4SLinus Torvalds 		       err_print_prefix, io->po7_uncrr_sym,
9771da177e4SLinus Torvalds 		       err_print_prefix, io->po7_crrct_sym,
9781da177e4SLinus Torvalds 		       err_print_prefix, io->po7_ugbge_sym,
9791da177e4SLinus Torvalds 		       err_print_prefix, io->po7_err_pkt0,
9801da177e4SLinus Torvalds 		       err_print_prefix, io->po7_err_pkt1);
9811da177e4SLinus Torvalds #endif
9821da177e4SLinus Torvalds 	}
9831da177e4SLinus Torvalds 
9841da177e4SLinus Torvalds 	/*
9851da177e4SLinus Torvalds 	 * Then loop through the ports
9861da177e4SLinus Torvalds 	 */
9871da177e4SLinus Torvalds 	for (i = 0; i < IO7_NUM_PORTS; i++) {
9881da177e4SLinus Torvalds 		if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
9891da177e4SLinus Torvalds 			continue;
9901da177e4SLinus Torvalds 
9915f0e3da6SRandy Dunlap 		printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
9921da177e4SLinus Torvalds 		       err_print_prefix,
9931da177e4SLinus Torvalds 		       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
9941da177e4SLinus Torvalds 		marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
9951da177e4SLinus Torvalds 
9965f0e3da6SRandy Dunlap 		printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
9971da177e4SLinus Torvalds 		       err_print_prefix, io->ports[i].pox_first_err);
9981da177e4SLinus Torvalds 		marvel_print_pox_err(io->ports[i].pox_first_err,
9991da177e4SLinus Torvalds 				     &io->ports[i]);
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds 	}
10021da177e4SLinus Torvalds 
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	return status;
10071da177e4SLinus Torvalds }
10081da177e4SLinus Torvalds 
10091da177e4SLinus Torvalds static int
10101da177e4SLinus Torvalds marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
10111da177e4SLinus Torvalds {
10121da177e4SLinus Torvalds 	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
10131da177e4SLinus Torvalds 
10141da177e4SLinus Torvalds 	/*
10151da177e4SLinus Torvalds 	 * I/O error?
10161da177e4SLinus Torvalds 	 */
10171da177e4SLinus Torvalds #define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
10181da177e4SLinus Torvalds 	if (lf_subpackets->logout &&
10191da177e4SLinus Torvalds 	    (lf_subpackets->logout->rbox_int & 0x20000400ul))
10201da177e4SLinus Torvalds 		status = marvel_process_io_error(lf_subpackets, print);
10211da177e4SLinus Torvalds 
10221da177e4SLinus Torvalds 	/*
10231da177e4SLinus Torvalds 	 * Probing behind PCI-X bridges can cause machine checks on
10241da177e4SLinus Torvalds 	 * Marvel when the probe is handled by the bridge as a split
10251da177e4SLinus Torvalds 	 * completion transaction. The symptom is an ERROR_RESPONSE
10261da177e4SLinus Torvalds 	 * to a CONFIG address. Since these errors will happen in
10271da177e4SLinus Torvalds 	 * normal operation, dismiss them.
10281da177e4SLinus Torvalds 	 *
10291da177e4SLinus Torvalds 	 * Dismiss if:
1030*25985edcSLucas De Marchi 	 *	C_STAT		= 0x14 		(Error Response)
10311da177e4SLinus Torvalds 	 *	C_STS<3>	= 0    		(C_ADDR valid)
10321da177e4SLinus Torvalds 	 *	C_ADDR<42>	= 1    		(I/O)
10331da177e4SLinus Torvalds 	 *	C_ADDR<31:22>	= 111110xxb	(PCI Config space)
10341da177e4SLinus Torvalds 	 */
10351da177e4SLinus Torvalds 	if (lf_subpackets->ev7 &&
10361da177e4SLinus Torvalds 	    (lf_subpackets->ev7->c_stat == 0x14) &&
10371da177e4SLinus Torvalds 	    !(lf_subpackets->ev7->c_sts & 0x8) &&
10381da177e4SLinus Torvalds 	    ((lf_subpackets->ev7->c_addr & 0x400ff000000ul)
10391da177e4SLinus Torvalds 	     == 0x400fe000000ul))
10401da177e4SLinus Torvalds 		status = MCHK_DISPOSITION_DISMISS;
10411da177e4SLinus Torvalds 
10421da177e4SLinus Torvalds 	return status;
10431da177e4SLinus Torvalds }
10441da177e4SLinus Torvalds 
10451da177e4SLinus Torvalds void
10461ffb1c0cSIvan Kokshaysky marvel_machine_check(unsigned long vector, unsigned long la_ptr)
10471da177e4SLinus Torvalds {
10481da177e4SLinus Torvalds 	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
10491da177e4SLinus Torvalds 	int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
10501da177e4SLinus Torvalds 	struct ev7_lf_subpackets subpacket_collection = { NULL, };
10511da177e4SLinus Torvalds 	struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
10521da177e4SLinus Torvalds 	struct ev7_lf_subpackets *lf_subpackets = NULL;
10531da177e4SLinus Torvalds 	int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
10541da177e4SLinus Torvalds 	char *saved_err_prefix = err_print_prefix;
10551da177e4SLinus Torvalds 	char *error_type = NULL;
10561da177e4SLinus Torvalds 
10571da177e4SLinus Torvalds 	/*
10581da177e4SLinus Torvalds 	 * Sync the processor
10591da177e4SLinus Torvalds 	 */
10601da177e4SLinus Torvalds 	mb();
10611da177e4SLinus Torvalds 	draina();
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds 	switch(vector) {
10641da177e4SLinus Torvalds 	case SCB_Q_SYSEVENT:
10651da177e4SLinus Torvalds 		process_frame = marvel_process_680_frame;
10661da177e4SLinus Torvalds 		error_type = "System Event";
10671da177e4SLinus Torvalds 		break;
10681da177e4SLinus Torvalds 
10691da177e4SLinus Torvalds 	case SCB_Q_SYSMCHK:
10701da177e4SLinus Torvalds 		process_frame = marvel_process_logout_frame;
10711da177e4SLinus Torvalds 		error_type = "System Uncorrectable Error";
10721da177e4SLinus Torvalds 		break;
10731da177e4SLinus Torvalds 
10741da177e4SLinus Torvalds 	case SCB_Q_SYSERR:
10751da177e4SLinus Torvalds 		process_frame = marvel_process_logout_frame;
10761da177e4SLinus Torvalds 		error_type = "System Correctable Error";
10771da177e4SLinus Torvalds 		break;
10781da177e4SLinus Torvalds 
10791da177e4SLinus Torvalds 	default:
10801da177e4SLinus Torvalds 		/* Don't know it - pass it up.  */
10814fa1970aSAl Viro 		ev7_machine_check(vector, la_ptr);
10821da177e4SLinus Torvalds 		return;
10831da177e4SLinus Torvalds 	}
10841da177e4SLinus Torvalds 
10851da177e4SLinus Torvalds 	/*
1086c3a2ddeeSSimon Arlott 	 * A system event or error has occurred, handle it here.
10871da177e4SLinus Torvalds 	 *
10881da177e4SLinus Torvalds 	 * Any errors in the logout frame have already been cleared by the
10891da177e4SLinus Torvalds 	 * PALcode, so just parse it.
10901da177e4SLinus Torvalds 	 */
10911da177e4SLinus Torvalds 	err_print_prefix = KERN_CRIT;
10921da177e4SLinus Torvalds 
10931da177e4SLinus Torvalds 	/*
10941da177e4SLinus Torvalds 	 * Parse the logout frame without printing first. If the only error(s)
10951da177e4SLinus Torvalds 	 * found are classified as "dismissable", then just dismiss them and
10961da177e4SLinus Torvalds 	 * don't print any message
10971da177e4SLinus Torvalds 	 */
10981da177e4SLinus Torvalds 	lf_subpackets =
10991da177e4SLinus Torvalds 		ev7_collect_logout_frame_subpackets(el_ptr,
11001da177e4SLinus Torvalds 						    &subpacket_collection);
11011da177e4SLinus Torvalds 	if (process_frame && lf_subpackets && lf_subpackets->logout) {
11021da177e4SLinus Torvalds 		/*
11031da177e4SLinus Torvalds 		 * We might not have the correct (or any) I/O subpacket.
11041da177e4SLinus Torvalds 		 * [ See marvel_process_io_error() for explanation. ]
11051da177e4SLinus Torvalds 		 * If we don't have one, point the io subpacket in
11061da177e4SLinus Torvalds 		 * lf_subpackets at scratch_io_packet so that
11071da177e4SLinus Torvalds 		 * marvel_find_io7_with_error() will have someplace to
11081da177e4SLinus Torvalds 		 * store the info.
11091da177e4SLinus Torvalds 		 */
11101da177e4SLinus Torvalds 		if (!lf_subpackets->io)
11111da177e4SLinus Torvalds 			lf_subpackets->io = &scratch_io_packet;
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds 		/*
11141da177e4SLinus Torvalds 		 * Default io_pid to the processor reporting the error
11151da177e4SLinus Torvalds 		 * [this will get changed in marvel_find_io7_with_error()
11161da177e4SLinus Torvalds 		 * if a different one is needed]
11171da177e4SLinus Torvalds 		 */
11181da177e4SLinus Torvalds 		lf_subpackets->io_pid = lf_subpackets->logout->whami;
11191da177e4SLinus Torvalds 
11201da177e4SLinus Torvalds 		/*
11211da177e4SLinus Torvalds 		 * Evaluate the frames.
11221da177e4SLinus Torvalds 		 */
11231da177e4SLinus Torvalds 		disposition = process_frame(lf_subpackets, 0);
11241da177e4SLinus Torvalds 	}
11251da177e4SLinus Torvalds 	switch(disposition) {
11261da177e4SLinus Torvalds 	case MCHK_DISPOSITION_DISMISS:
11271da177e4SLinus Torvalds 		/* Nothing to do. */
11281da177e4SLinus Torvalds 		break;
11291da177e4SLinus Torvalds 
11301da177e4SLinus Torvalds 	case MCHK_DISPOSITION_REPORT:
11311da177e4SLinus Torvalds 		/* Recognized error, report it. */
11321da177e4SLinus Torvalds 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
11331da177e4SLinus Torvalds 		       err_print_prefix, error_type,
11341da177e4SLinus Torvalds 		       (unsigned int)vector, (int)smp_processor_id());
11351da177e4SLinus Torvalds 		el_print_timestamp(&lf_subpackets->logout->timestamp);
11361da177e4SLinus Torvalds 		process_frame(lf_subpackets, 1);
11371da177e4SLinus Torvalds 		break;
11381da177e4SLinus Torvalds 
11391da177e4SLinus Torvalds 	default:
11401da177e4SLinus Torvalds 		/* Unknown - dump the annotated subpackets. */
11411da177e4SLinus Torvalds 		printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
11421da177e4SLinus Torvalds 		       err_print_prefix, error_type,
11431da177e4SLinus Torvalds 		       (unsigned int)vector, (int)smp_processor_id());
11441da177e4SLinus Torvalds 		el_process_subpacket(el_ptr);
11451da177e4SLinus Torvalds 		break;
11461da177e4SLinus Torvalds 
11471da177e4SLinus Torvalds 	}
11481da177e4SLinus Torvalds 
11491da177e4SLinus Torvalds 	err_print_prefix = saved_err_prefix;
11501da177e4SLinus Torvalds 
11511da177e4SLinus Torvalds         /* Release the logout frame.  */
11521da177e4SLinus Torvalds 	wrmces(0x7);
11531da177e4SLinus Torvalds 	mb();
11541da177e4SLinus Torvalds }
11551da177e4SLinus Torvalds 
11569548b209SIvan Kokshaysky void __init
11571da177e4SLinus Torvalds marvel_register_error_handlers(void)
11581da177e4SLinus Torvalds {
11591da177e4SLinus Torvalds 	ev7_register_error_handlers();
11601da177e4SLinus Torvalds }
1161