linux/arch/alpha/kernel/err_marvel.c
<<
>>
Prefs
   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 %ld%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: %ld - Dest PID: %ld - 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): %ld:%ld:%ld\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        char *pcix_cmd[] = { "Interrupt Acknowledge",
 593                             "Special Cycle",
 594                             "I/O Read",
 595                             "I/O Write",
 596                             "Reserved",
 597                             "Reserved / Device ID Message",
 598                             "Memory Read",
 599                             "Memory Write",
 600                             "Reserved / Alias to Memory Read Block",
 601                             "Reserved / Alias to Memory Write Block",
 602                             "Configuration Read",
 603                             "Configuration Write",
 604                             "Memory Read Multiple / Split Completion",
 605                             "Dual Address Cycle",
 606                             "Memory Read Line / Memory Read Block",
 607                             "Memory Write and Invalidate / Memory Write Block"
 608        };
 609
 610#define IO7__POX_TRANSUM__PCI_ADDR__S           (0)
 611#define IO7__POX_TRANSUM__PCI_ADDR__M           (0x3fffffffffffful)
 612#define IO7__POX_TRANSUM__DAC                   (1UL << 50)
 613#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S   (52)
 614#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M   (0xf)
 615#define IO7__POX_TRANSUM__PCIX_CMD__S           (56)
 616#define IO7__POX_TRANSUM__PCIX_CMD__M           (0xf)
 617#define IO7__POX_TRANSUM__ERR_VALID             (1UL << 63)
 618
 619        if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
 620                return;
 621
 622        printk("%s      Transaction Summary:\n"
 623               "%s        Command: 0x%llx - %s\n"
 624               "%s        Address: 0x%016llx%s\n"
 625               "%s        PCI-X Master Slot: 0x%llx\n",
 626               err_print_prefix, 
 627               err_print_prefix, 
 628               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
 629               pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
 630               err_print_prefix,
 631               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
 632               (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
 633               err_print_prefix,
 634               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
 635}
 636
 637static void
 638marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
 639{
 640#define IO7__POX_ERRSUM__AGP_REQQ_OVFL    (1UL <<  4)
 641#define IO7__POX_ERRSUM__AGP_SYNC_ERR     (1UL <<  5)
 642#define IO7__POX_ERRSUM__MRETRY_TO        (1UL <<  6)
 643#define IO7__POX_ERRSUM__PCIX_UX_SPL      (1UL <<  7)
 644#define IO7__POX_ERRSUM__PCIX_SPLIT_TO    (1UL <<  8)
 645#define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL <<  9)
 646#define IO7__POX_ERRSUM__DMA_RD_TO        (1UL << 10)
 647#define IO7__POX_ERRSUM__CSR_NXM_RD       (1UL << 11)
 648#define IO7__POX_ERRSUM__CSR_NXM_WR       (1UL << 12)
 649#define IO7__POX_ERRSUM__DMA_TO           (1UL << 13)
 650#define IO7__POX_ERRSUM__ALL_MABORTS      (1UL << 14)
 651#define IO7__POX_ERRSUM__MABORT           (1UL << 15)
 652#define IO7__POX_ERRSUM__MABORT_MASK      (IO7__POX_ERRSUM__ALL_MABORTS|\
 653                                           IO7__POX_ERRSUM__MABORT)
 654#define IO7__POX_ERRSUM__PT_TABORT        (1UL << 16)
 655#define IO7__POX_ERRSUM__PM_TABORT        (1UL << 17)
 656#define IO7__POX_ERRSUM__TABORT_MASK      (IO7__POX_ERRSUM__PT_TABORT | \
 657                                           IO7__POX_ERRSUM__PM_TABORT)
 658#define IO7__POX_ERRSUM__SERR             (1UL << 18)
 659#define IO7__POX_ERRSUM__ADDRERR_STB      (1UL << 19)
 660#define IO7__POX_ERRSUM__DETECTED_SERR    (1UL << 20)
 661#define IO7__POX_ERRSUM__PERR             (1UL << 21)
 662#define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
 663#define IO7__POX_ERRSUM__DETECTED_PERR    (1UL << 23)
 664#define IO7__POX_ERRSUM__PM_PERR          (1UL << 24)
 665#define IO7__POX_ERRSUM__PT_SCERROR       (1UL << 26)
 666#define IO7__POX_ERRSUM__HUNG_BUS         (1UL << 28)
 667#define IO7__POX_ERRSUM__UPE_ERROR__S     (51)
 668#define IO7__POX_ERRSUM__UPE_ERROR__M     (0xffUL)
 669#define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
 670#define IO7__POX_ERRSUM__TLB_ERR          (1UL << 59)
 671#define IO7__POX_ERRSUM__ERR_VALID        (1UL << 63)
 672
 673#define IO7__POX_ERRSUM__TRANS_SUM__MASK  (IO7__POX_ERRSUM__MRETRY_TO |       \
 674                                           IO7__POX_ERRSUM__PCIX_UX_SPL |     \
 675                                           IO7__POX_ERRSUM__PCIX_SPLIT_TO |   \
 676                                           IO7__POX_ERRSUM__DMA_TO |          \
 677                                           IO7__POX_ERRSUM__MABORT_MASK |     \
 678                                           IO7__POX_ERRSUM__TABORT_MASK |     \
 679                                           IO7__POX_ERRSUM__SERR |            \
 680                                           IO7__POX_ERRSUM__ADDRERR_STB |     \
 681                                           IO7__POX_ERRSUM__PERR |            \
 682                                           IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
 683                                           IO7__POX_ERRSUM__DETECTED_PERR |   \
 684                                           IO7__POX_ERRSUM__PM_PERR |         \
 685                                           IO7__POX_ERRSUM__PT_SCERROR |      \
 686                                           IO7__POX_ERRSUM__UPE_ERROR)
 687
 688        if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
 689                return;
 690
 691        /*
 692         * First the transaction summary errors
 693         */
 694        if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
 695                printk("%s    IO7 Master Retry Timeout expired\n",
 696                       err_print_prefix);
 697        if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
 698                printk("%s    Unexpected Split Completion\n",
 699                       err_print_prefix);
 700        if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
 701                printk("%s    IO7 Split Completion Timeout expired\n",
 702                       err_print_prefix);
 703        if (err_sum & IO7__POX_ERRSUM__DMA_TO)
 704                printk("%s    Hung bus during DMA transaction\n",
 705                       err_print_prefix);
 706        if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
 707                printk("%s    Master Abort\n", err_print_prefix);
 708        if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
 709                printk("%s    IO7 Asserted Target Abort\n", err_print_prefix);
 710        if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
 711                printk("%s    IO7 Received Target Abort\n", err_print_prefix);
 712        if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
 713                printk("%s    Address or PCI-X Attribute Parity Error\n", 
 714                       err_print_prefix);
 715                if (err_sum & IO7__POX_ERRSUM__SERR)
 716                        printk("%s     IO7 Asserted SERR\n", err_print_prefix);
 717        }
 718        if (err_sum & IO7__POX_ERRSUM__PERR) {
 719                if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
 720                        printk("%s    IO7 Detected Data Parity Error\n",
 721                               err_print_prefix);
 722                else
 723                        printk("%s    Split Completion Response with "
 724                               "Parity Error\n", err_print_prefix);
 725        }
 726        if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
 727                printk("%s    PERR detected\n", err_print_prefix);
 728        if (err_sum & IO7__POX_ERRSUM__PM_PERR)
 729                printk("%s    PERR while IO7 is master\n", err_print_prefix);
 730        if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
 731                printk("%s    IO7 Received Split Completion Error message\n",
 732                       err_print_prefix);
 733                marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
 734        }
 735        if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
 736                unsigned int upe_error = EXTRACT(err_sum,
 737                                                 IO7__POX_ERRSUM__UPE_ERROR);
 738                int i;
 739                static char *upe_errors[] = {
 740                        "Parity Error on MSI write data",
 741                        "MSI read (MSI window is write only",
 742                        "TLB - Invalid WR transaction",
 743                        "TLB - Invalid RD transaction",
 744                        "DMA - WR error (see north port)",
 745                        "DMA - RD error (see north port)",
 746                        "PPR - WR error (see north port)",
 747                        "PPR - RD error (see north port)"
 748                };
 749
 750                printk("%s    UPE Error:\n", err_print_prefix);
 751                for (i = 0; i < 8; i++) {
 752                        if (upe_error & (1 << i))
 753                                printk("%s      %s\n", err_print_prefix,
 754                                       upe_errors[i]);
 755                }
 756        }
 757
 758        /*
 759         * POx_TRANS_SUM, if appropriate.
 760         */
 761        if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK) 
 762                marvel_print_pox_trans_sum(port->pox_trans_sum);
 763
 764        /*
 765         * Then TLB_ERR.
 766         */
 767        if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
 768                printk("%s    TLB ERROR\n", err_print_prefix);
 769                marvel_print_pox_tlb_err(port->pox_tlb_err);
 770        }
 771
 772        /*
 773         * And the single bit status errors.
 774         */
 775        if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
 776                printk("%s    AGP Request Queue Overflow\n", err_print_prefix);
 777        if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
 778                printk("%s    AGP Sync Error\n", err_print_prefix);
 779        if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
 780                printk("%s    Discarded split completion\n", err_print_prefix);
 781        if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
 782                printk("%s    DMA Read Timeout\n", err_print_prefix);
 783        if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
 784                printk("%s    CSR NXM READ\n", err_print_prefix);
 785        if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
 786                printk("%s    CSR NXM WRITE\n", err_print_prefix);
 787        if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
 788                printk("%s    SERR detected\n", err_print_prefix);
 789        if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
 790                printk("%s    HUNG BUS detected\n", err_print_prefix);
 791}
 792
 793#endif /* CONFIG_VERBOSE_MCHECK */
 794
 795static struct ev7_pal_io_subpacket *
 796marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
 797{
 798        struct ev7_pal_io_subpacket *io = lf_subpackets->io;
 799        struct io7 *io7;
 800        int i;
 801
 802        /*
 803         * Caller must provide the packet to fill
 804         */
 805        if (!io)
 806                return NULL;
 807
 808        /*
 809         * Fill the subpacket with the console's standard fill pattern
 810         */
 811        memset(io, 0x55, sizeof(*io));
 812
 813        for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) {
 814                unsigned long err_sum = 0;
 815
 816                err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
 817                for (i = 0; i < IO7_NUM_PORTS; i++) {
 818                        if (!io7->ports[i].enabled)
 819                                continue;
 820                        err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
 821                }
 822
 823                /*
 824                 * Is there at least one error? 
 825                 */
 826                if (err_sum & (1UL << 63))
 827                        break;
 828        }
 829
 830        /*
 831         * Did we find an IO7 with an error?
 832         */
 833        if (!io7)
 834                return NULL;
 835
 836        /*
 837         * We have an IO7 with an error. 
 838         *
 839         * Fill in the IO subpacket.
 840         */
 841        io->io_asic_rev   = io7->csrs->IO_ASIC_REV.csr;
 842        io->io_sys_rev    = io7->csrs->IO_SYS_REV.csr;
 843        io->io7_uph       = io7->csrs->IO7_UPH.csr;
 844        io->hpi_ctl       = io7->csrs->HPI_CTL.csr;
 845        io->crd_ctl       = io7->csrs->CRD_CTL.csr;
 846        io->hei_ctl       = io7->csrs->HEI_CTL.csr;
 847        io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
 848        io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
 849        io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
 850        io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
 851        io->po7_err_pkt0  = io7->csrs->PO7_ERR_PKT[0].csr;
 852        io->po7_err_pkt1  = io7->csrs->PO7_ERR_PKT[1].csr;
 853        
 854        for (i = 0; i < IO7_NUM_PORTS; i++) {
 855                io7_ioport_csrs *csrs = io7->ports[i].csrs;
 856
 857                if (!io7->ports[i].enabled)
 858                        continue;
 859
 860                io->ports[i].pox_err_sum   = csrs->POx_ERR_SUM.csr;
 861                io->ports[i].pox_tlb_err   = csrs->POx_TLB_ERR.csr;
 862                io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
 863                io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
 864                io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
 865                io->ports[i].pox_mult_err  = csrs->POx_MULT_ERR.csr;
 866                io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
 867                io->ports[i].pox_dm_dest   = csrs->POx_DM_DEST.csr;
 868                io->ports[i].pox_dm_size   = csrs->POx_DM_SIZE.csr;
 869                io->ports[i].pox_dm_ctrl   = csrs->POx_DM_CTRL.csr;
 870
 871                /*
 872                 * Ack this port's errors, if any. POx_ERR_SUM must be last.
 873                 *
 874                 * Most of the error registers get cleared and unlocked when
 875                 * the associated bits in POx_ERR_SUM are cleared (by writing
 876                 * 1). POx_TLB_ERR is an exception and must be explicitly 
 877                 * cleared.
 878                 */
 879                csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
 880                csrs->POx_ERR_SUM.csr = io->ports[i].pox_err_sum;
 881                mb();
 882                csrs->POx_ERR_SUM.csr;          
 883        }
 884
 885        /*
 886         * Ack any port 7 error(s).
 887         */
 888        io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
 889        mb();
 890        io7->csrs->PO7_ERROR_SUM.csr;
 891        
 892        /*
 893         * Correct the io7_pid.
 894         */
 895        lf_subpackets->io_pid = io7->pe;
 896
 897        return io;
 898}
 899
 900static int
 901marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
 902{
 903        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 904
 905#ifdef CONFIG_VERBOSE_MCHECK
 906        struct ev7_pal_io_subpacket *io = lf_subpackets->io;
 907        int i;
 908#endif /* CONFIG_VERBOSE_MCHECK */
 909
 910#define MARVEL_IO_ERR_VALID(x)  ((x) & (1UL << 63))
 911
 912        if (!lf_subpackets->logout || !lf_subpackets->io)
 913                return status;
 914
 915        /*
 916         * The PALcode only builds an IO subpacket if there is a 
 917         * locally connected IO7. In the cases of
 918         *      1) a uniprocessor kernel
 919         *      2) an mp kernel before the local secondary has called in
 920         * error interrupts are all directed to the primary processor.
 921         * In that case, we may not have an IO subpacket at all and, event
 922         * if we do, it may not be the right now. 
 923         *
 924         * If the RBOX indicates an I/O error interrupt, make sure we have
 925         * the correct IO7 information. If we don't have an IO subpacket
 926         * or it's the wrong one, try to find the right one.
 927         *
 928         * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
 929         * RBOX_INT<10>.
 930         */
 931        if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
 932            ((lf_subpackets->io->po7_error_sum        |
 933              lf_subpackets->io->ports[0].pox_err_sum |
 934              lf_subpackets->io->ports[1].pox_err_sum |
 935              lf_subpackets->io->ports[2].pox_err_sum |
 936              lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
 937                /*
 938                 * Either we have no IO subpacket or no error is
 939                 * indicated in the one we do have. Try find the
 940                 * one with the error.
 941                 */
 942                if (!marvel_find_io7_with_error(lf_subpackets))
 943                        return status;
 944        }
 945
 946        /*
 947         * We have an IO7 indicating an error - we're going to report it
 948         */
 949        status = MCHK_DISPOSITION_REPORT;
 950
 951#ifdef CONFIG_VERBOSE_MCHECK
 952
 953        if (!print)
 954                return status;
 955
 956        printk("%s*Error occurred on IO7 at PID %u\n", 
 957               err_print_prefix, lf_subpackets->io_pid);
 958
 959        /*
 960         * Check port 7 first
 961         */
 962        if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
 963                marvel_print_po7_err_sum(io);
 964
 965#if 0
 966                printk("%s  PORT 7 ERROR:\n"
 967                       "%s    PO7_ERROR_SUM: %016llx\n"
 968                       "%s    PO7_UNCRR_SYM: %016llx\n"
 969                       "%s    PO7_CRRCT_SYM: %016llx\n"
 970                       "%s    PO7_UGBGE_SYM: %016llx\n"
 971                       "%s    PO7_ERR_PKT0:  %016llx\n"
 972                       "%s    PO7_ERR_PKT1:  %016llx\n",
 973                       err_print_prefix,
 974                       err_print_prefix, io->po7_error_sum,
 975                       err_print_prefix, io->po7_uncrr_sym,
 976                       err_print_prefix, io->po7_crrct_sym,
 977                       err_print_prefix, io->po7_ugbge_sym,
 978                       err_print_prefix, io->po7_err_pkt0,
 979                       err_print_prefix, io->po7_err_pkt1);
 980#endif
 981        }
 982
 983        /*
 984         * Then loop through the ports
 985         */
 986        for (i = 0; i < IO7_NUM_PORTS; i++) {
 987                if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
 988                        continue;
 989
 990                printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
 991                       err_print_prefix, 
 992                       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
 993                marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
 994
 995                printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
 996                       err_print_prefix, io->ports[i].pox_first_err);
 997                marvel_print_pox_err(io->ports[i].pox_first_err, 
 998                                     &io->ports[i]);
 999
1000        }
1001
1002
1003#endif /* CONFIG_VERBOSE_MCHECK */
1004
1005        return status;
1006}
1007
1008static int
1009marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
1010{
1011        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
1012
1013        /*
1014         * I/O error? 
1015         */
1016#define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
1017        if (lf_subpackets->logout &&
1018            (lf_subpackets->logout->rbox_int & 0x20000400ul))
1019                status = marvel_process_io_error(lf_subpackets, print);
1020
1021        /*
1022         * Probing behind PCI-X bridges can cause machine checks on
1023         * Marvel when the probe is handled by the bridge as a split
1024         * completion transaction. The symptom is an ERROR_RESPONSE 
1025         * to a CONFIG address. Since these errors will happen in
1026         * normal operation, dismiss them.
1027         *
1028         * Dismiss if:
1029         *      C_STAT          = 0x14          (Error Reponse)
1030         *      C_STS<3>        = 0             (C_ADDR valid)
1031         *      C_ADDR<42>      = 1             (I/O)
1032         *      C_ADDR<31:22>   = 111110xxb     (PCI Config space)
1033         */
1034        if (lf_subpackets->ev7 &&
1035            (lf_subpackets->ev7->c_stat == 0x14) &&
1036            !(lf_subpackets->ev7->c_sts & 0x8) &&
1037            ((lf_subpackets->ev7->c_addr & 0x400ff000000ul) 
1038             == 0x400fe000000ul))
1039                status = MCHK_DISPOSITION_DISMISS;
1040
1041        return status;
1042}
1043
1044void
1045marvel_machine_check(unsigned long vector, unsigned long la_ptr)
1046{
1047        struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
1048        int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
1049        struct ev7_lf_subpackets subpacket_collection = { NULL, };
1050        struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
1051        struct ev7_lf_subpackets *lf_subpackets = NULL;
1052        int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
1053        char *saved_err_prefix = err_print_prefix;
1054        char *error_type = NULL;
1055
1056        /*
1057         * Sync the processor
1058         */
1059        mb();
1060        draina();
1061
1062        switch(vector) {
1063        case SCB_Q_SYSEVENT:
1064                process_frame = marvel_process_680_frame;
1065                error_type = "System Event";
1066                break;
1067
1068        case SCB_Q_SYSMCHK:
1069                process_frame = marvel_process_logout_frame;
1070                error_type = "System Uncorrectable Error";
1071                break;
1072
1073        case SCB_Q_SYSERR:
1074                process_frame = marvel_process_logout_frame;
1075                error_type = "System Correctable Error";
1076                break;
1077
1078        default:
1079                /* Don't know it - pass it up.  */
1080                ev7_machine_check(vector, la_ptr);
1081                return;
1082        }       
1083
1084        /*
1085         * A system event or error has occurred, handle it here.
1086         *
1087         * Any errors in the logout frame have already been cleared by the
1088         * PALcode, so just parse it.
1089         */
1090        err_print_prefix = KERN_CRIT;
1091
1092        /* 
1093         * Parse the logout frame without printing first. If the only error(s)
1094         * found are classified as "dismissable", then just dismiss them and
1095         * don't print any message
1096         */
1097        lf_subpackets = 
1098                ev7_collect_logout_frame_subpackets(el_ptr,
1099                                                    &subpacket_collection);
1100        if (process_frame && lf_subpackets && lf_subpackets->logout) {
1101                /*
1102                 * We might not have the correct (or any) I/O subpacket.
1103                 * [ See marvel_process_io_error() for explanation. ]
1104                 * If we don't have one, point the io subpacket in
1105                 * lf_subpackets at scratch_io_packet so that 
1106                 * marvel_find_io7_with_error() will have someplace to
1107                 * store the info.
1108                 */
1109                if (!lf_subpackets->io)
1110                        lf_subpackets->io = &scratch_io_packet;
1111
1112                /*
1113                 * Default io_pid to the processor reporting the error
1114                 * [this will get changed in marvel_find_io7_with_error()
1115                 * if a different one is needed]
1116                 */
1117                lf_subpackets->io_pid = lf_subpackets->logout->whami;
1118
1119                /*
1120                 * Evaluate the frames.
1121                 */
1122                disposition = process_frame(lf_subpackets, 0);
1123        }
1124        switch(disposition) {
1125        case MCHK_DISPOSITION_DISMISS:
1126                /* Nothing to do. */
1127                break;
1128
1129        case MCHK_DISPOSITION_REPORT:
1130                /* Recognized error, report it. */
1131                printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1132                       err_print_prefix, error_type,
1133                       (unsigned int)vector, (int)smp_processor_id());
1134                el_print_timestamp(&lf_subpackets->logout->timestamp);
1135                process_frame(lf_subpackets, 1);
1136                break;
1137
1138        default:
1139                /* Unknown - dump the annotated subpackets. */
1140                printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1141                       err_print_prefix, error_type,
1142                       (unsigned int)vector, (int)smp_processor_id());
1143                el_process_subpacket(el_ptr);
1144                break;
1145
1146        }
1147
1148        err_print_prefix = saved_err_prefix;
1149
1150        /* Release the logout frame.  */
1151        wrmces(0x7);
1152        mb();
1153}
1154
1155void __init
1156marvel_register_error_handlers(void)
1157{
1158        ev7_register_error_handlers();
1159}
1160