linux/arch/alpha/kernel/err_marvel.c
<<
>>
Prefs
   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}
1162