Linux Audio

Check our new training course

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