linux/arch/alpha/kernel/err_titan.c
<<
>>
Prefs
   1/*
   2 *      linux/arch/alpha/kernel/err_titan.c
   3 *
   4 *      Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
   5 *
   6 *      Error handling code supporting TITAN systems
   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/core_titan.h>
  15#include <asm/hwrpb.h>
  16#include <asm/smp.h>
  17#include <asm/err_common.h>
  18#include <asm/err_ev6.h>
  19#include <asm/irq_regs.h>
  20
  21#include "err_impl.h"
  22#include "proto.h"
  23
  24
  25static int
  26titan_parse_c_misc(u64 c_misc, int print)
  27{
  28#ifdef CONFIG_VERBOSE_MCHECK
  29        char *src;
  30        int nxs = 0;
  31#endif
  32        int status = MCHK_DISPOSITION_REPORT;
  33
  34#define TITAN__CCHIP_MISC__NXM          (1UL << 28)
  35#define TITAN__CCHIP_MISC__NXS__S       (29)
  36#define TITAN__CCHIP_MISC__NXS__M       (0x7)
  37
  38        if (!(c_misc & TITAN__CCHIP_MISC__NXM))
  39                return MCHK_DISPOSITION_UNKNOWN_ERROR;
  40
  41#ifdef CONFIG_VERBOSE_MCHECK
  42        if (!print)
  43                return status;
  44
  45        nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS);
  46        switch(nxs) {
  47        case 0: /* CPU 0 */
  48        case 1: /* CPU 1 */
  49        case 2: /* CPU 2 */
  50        case 3: /* CPU 3 */
  51                src = "CPU";
  52                /* num is already the CPU number */
  53                break;
  54        case 4: /* Pchip 0 */
  55        case 5: /* Pchip 1 */
  56                src = "Pchip";
  57                nxs -= 4;
  58                break;
  59        default:/* reserved */
  60                src = "Unknown, NXS =";
  61                /* leave num untouched */
  62                break;
  63        }
  64
  65        printk("%s    Non-existent memory access from: %s %d\n", 
  66               err_print_prefix, src, nxs);
  67#endif /* CONFIG_VERBOSE_MCHECK */
  68
  69        return status;
  70}
  71
  72static int
  73titan_parse_p_serror(int which, u64 serror, int print)
  74{
  75        int status = MCHK_DISPOSITION_REPORT;
  76
  77#ifdef CONFIG_VERBOSE_MCHECK
  78        static const char * const serror_src[] = {
  79                "GPCI", "APCI", "AGP HP", "AGP LP"
  80        };
  81        static const char * const serror_cmd[] = {
  82                "DMA Read", "DMA RMW", "SGTE Read", "Reserved"
  83        };
  84#endif /* CONFIG_VERBOSE_MCHECK */
  85
  86#define TITAN__PCHIP_SERROR__LOST_UECC  (1UL << 0)
  87#define TITAN__PCHIP_SERROR__UECC       (1UL << 1)
  88#define TITAN__PCHIP_SERROR__CRE        (1UL << 2)
  89#define TITAN__PCHIP_SERROR__NXIO       (1UL << 3)
  90#define TITAN__PCHIP_SERROR__LOST_CRE   (1UL << 4)
  91#define TITAN__PCHIP_SERROR__ECCMASK    (TITAN__PCHIP_SERROR__UECC |      \
  92                                         TITAN__PCHIP_SERROR__CRE)
  93#define TITAN__PCHIP_SERROR__ERRMASK    (TITAN__PCHIP_SERROR__LOST_UECC | \
  94                                         TITAN__PCHIP_SERROR__UECC |      \
  95                                         TITAN__PCHIP_SERROR__CRE |       \
  96                                         TITAN__PCHIP_SERROR__NXIO |      \
  97                                         TITAN__PCHIP_SERROR__LOST_CRE)
  98#define TITAN__PCHIP_SERROR__SRC__S     (52)
  99#define TITAN__PCHIP_SERROR__SRC__M     (0x3)
 100#define TITAN__PCHIP_SERROR__CMD__S     (54)
 101#define TITAN__PCHIP_SERROR__CMD__M     (0x3)
 102#define TITAN__PCHIP_SERROR__SYN__S     (56)
 103#define TITAN__PCHIP_SERROR__SYN__M     (0xff)
 104#define TITAN__PCHIP_SERROR__ADDR__S    (15)
 105#define TITAN__PCHIP_SERROR__ADDR__M    (0xffffffffUL)
 106
 107        if (!(serror & TITAN__PCHIP_SERROR__ERRMASK))
 108                return MCHK_DISPOSITION_UNKNOWN_ERROR;
 109
 110#ifdef CONFIG_VERBOSE_MCHECK
 111        if (!print)
 112                return status;
 113
 114        printk("%s  PChip %d SERROR: %016llx\n",
 115               err_print_prefix, which, serror);
 116        if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
 117                printk("%s    %sorrectable ECC Error:\n"
 118                       "      Source: %-6s  Command: %-8s  Syndrome: 0x%08x\n"
 119                       "      Address: 0x%llx\n",
 120                       err_print_prefix,
 121                       (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
 122                       serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
 123                       serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)],
 124                       (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN),
 125                       EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR));
 126        }
 127        if (serror & TITAN__PCHIP_SERROR__NXIO)
 128                printk("%s    Non Existent I/O Error\n", err_print_prefix);
 129        if (serror & TITAN__PCHIP_SERROR__LOST_UECC)
 130                printk("%s    Lost Uncorrectable ECC Error\n", 
 131                       err_print_prefix);
 132        if (serror & TITAN__PCHIP_SERROR__LOST_CRE)
 133                printk("%s    Lost Correctable ECC Error\n", err_print_prefix);
 134#endif /* CONFIG_VERBOSE_MCHECK */
 135
 136        return status;
 137}
 138
 139static int 
 140titan_parse_p_perror(int which, int port, u64 perror, int print)
 141{
 142        int cmd;
 143        unsigned long addr;
 144        int status = MCHK_DISPOSITION_REPORT;
 145
 146#ifdef CONFIG_VERBOSE_MCHECK
 147        static const char * const perror_cmd[] = {
 148                "Interrupt Acknowledge", "Special Cycle",
 149                "I/O Read",             "I/O Write",
 150                "Reserved",             "Reserved",
 151                "Memory Read",          "Memory Write",
 152                "Reserved",             "Reserved",
 153                "Configuration Read",   "Configuration Write",
 154                "Memory Read Multiple", "Dual Address Cycle",
 155                "Memory Read Line",     "Memory Write and Invalidate"
 156        };
 157#endif /* CONFIG_VERBOSE_MCHECK */
 158
 159#define TITAN__PCHIP_PERROR__LOST       (1UL << 0)
 160#define TITAN__PCHIP_PERROR__SERR       (1UL << 1)
 161#define TITAN__PCHIP_PERROR__PERR       (1UL << 2)
 162#define TITAN__PCHIP_PERROR__DCRTO      (1UL << 3)
 163#define TITAN__PCHIP_PERROR__SGE        (1UL << 4)
 164#define TITAN__PCHIP_PERROR__APE        (1UL << 5)
 165#define TITAN__PCHIP_PERROR__TA         (1UL << 6)
 166#define TITAN__PCHIP_PERROR__DPE        (1UL << 7)
 167#define TITAN__PCHIP_PERROR__NDS        (1UL << 8)
 168#define TITAN__PCHIP_PERROR__IPTPR      (1UL << 9)
 169#define TITAN__PCHIP_PERROR__IPTPW      (1UL << 10)
 170#define TITAN__PCHIP_PERROR__ERRMASK    (TITAN__PCHIP_PERROR__LOST |    \
 171                                         TITAN__PCHIP_PERROR__SERR |    \
 172                                         TITAN__PCHIP_PERROR__PERR |    \
 173                                         TITAN__PCHIP_PERROR__DCRTO |   \
 174                                         TITAN__PCHIP_PERROR__SGE |     \
 175                                         TITAN__PCHIP_PERROR__APE |     \
 176                                         TITAN__PCHIP_PERROR__TA |      \
 177                                         TITAN__PCHIP_PERROR__DPE |     \
 178                                         TITAN__PCHIP_PERROR__NDS |     \
 179                                         TITAN__PCHIP_PERROR__IPTPR |   \
 180                                         TITAN__PCHIP_PERROR__IPTPW)
 181#define TITAN__PCHIP_PERROR__DAC        (1UL << 47)
 182#define TITAN__PCHIP_PERROR__MWIN       (1UL << 48)
 183#define TITAN__PCHIP_PERROR__CMD__S     (52)
 184#define TITAN__PCHIP_PERROR__CMD__M     (0x0f)
 185#define TITAN__PCHIP_PERROR__ADDR__S    (14)
 186#define TITAN__PCHIP_PERROR__ADDR__M    (0x1fffffffful)
 187
 188        if (!(perror & TITAN__PCHIP_PERROR__ERRMASK))
 189                return MCHK_DISPOSITION_UNKNOWN_ERROR;
 190
 191        cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD);
 192        addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2;
 193
 194        /*
 195         * Initializing the BIOS on a video card on a bus without
 196         * a south bridge (subtractive decode agent) can result in 
 197         * master aborts as the BIOS probes the capabilities of the
 198         * card. XFree86 does such initialization. If the error
 199         * is a master abort (No DevSel as PCI Master) and the command
 200         * is an I/O read or write below the address where we start
 201         * assigning PCI I/O spaces (SRM uses 0x1000), then mark the
 202         * error as dismissable so starting XFree86 doesn't result
 203         * in a series of uncorrectable errors being reported. Also
 204         * dismiss master aborts to VGA frame buffer space
 205         * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000)
 206         * for the same reason.
 207         *
 208         * Also mark the error dismissible if it looks like the right
 209         * error but only the Lost bit is set. Since the BIOS initialization
 210         * can cause multiple master aborts and the error interrupt can
 211         * be handled on a different CPU than the BIOS code is run on,
 212         * it is possible for a second master abort to occur between the
 213         * time the PALcode reads PERROR and the time it writes PERROR
 214         * to acknowledge the error. If this timing happens, a second
 215         * error will be signalled after the first, and if no additional
 216         * errors occur, will look like a Lost error with no additional 
 217         * errors on the same transaction as the previous error.
 218         */
 219        if (((perror & TITAN__PCHIP_PERROR__NDS) || 
 220             ((perror & TITAN__PCHIP_PERROR__ERRMASK) == 
 221              TITAN__PCHIP_PERROR__LOST)) &&
 222            ((((cmd & 0xE) == 2) && (addr < 0x1000)) ||
 223             (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) {
 224                status = MCHK_DISPOSITION_DISMISS;
 225        }
 226
 227#ifdef CONFIG_VERBOSE_MCHECK
 228        if (!print) 
 229                return status;
 230
 231        printk("%s  PChip %d %cPERROR: %016llx\n",
 232               err_print_prefix, which, 
 233               port ? 'A' : 'G', perror);
 234        if (perror & TITAN__PCHIP_PERROR__IPTPW)
 235                printk("%s    Invalid Peer-to-Peer Write\n", err_print_prefix);
 236        if (perror & TITAN__PCHIP_PERROR__IPTPR)
 237                printk("%s    Invalid Peer-to-Peer Read\n", err_print_prefix);
 238        if (perror & TITAN__PCHIP_PERROR__NDS)
 239                printk("%s    No DEVSEL as PCI Master [Master Abort]\n",
 240                       err_print_prefix);
 241        if (perror & TITAN__PCHIP_PERROR__DPE)
 242                printk("%s    Data Parity Error\n", err_print_prefix);
 243        if (perror & TITAN__PCHIP_PERROR__TA)
 244                printk("%s    Target Abort\n", err_print_prefix);
 245        if (perror & TITAN__PCHIP_PERROR__APE)
 246                printk("%s    Address Parity Error\n", err_print_prefix);
 247        if (perror & TITAN__PCHIP_PERROR__SGE)
 248                printk("%s    Scatter-Gather Error, Invalid PTE\n", 
 249                       err_print_prefix);
 250        if (perror & TITAN__PCHIP_PERROR__DCRTO)
 251                printk("%s    Delayed-Completion Retry Timeout\n", 
 252                       err_print_prefix);
 253        if (perror & TITAN__PCHIP_PERROR__PERR)
 254                printk("%s    PERR Asserted\n", err_print_prefix);
 255        if (perror & TITAN__PCHIP_PERROR__SERR)
 256                printk("%s    SERR Asserted\n", err_print_prefix);
 257        if (perror & TITAN__PCHIP_PERROR__LOST)
 258                printk("%s    Lost Error\n", err_print_prefix);
 259        printk("%s      Command: 0x%x - %s\n"
 260                 "      Address: 0x%lx\n",
 261               err_print_prefix,
 262               cmd, perror_cmd[cmd],
 263               addr);
 264        if (perror & TITAN__PCHIP_PERROR__DAC)
 265                printk("%s      Dual Address Cycle\n", err_print_prefix);
 266        if (perror & TITAN__PCHIP_PERROR__MWIN)
 267                printk("%s      Hit in Monster Window\n", err_print_prefix);
 268#endif /* CONFIG_VERBOSE_MCHECK */
 269
 270        return status;
 271}
 272
 273static int
 274titan_parse_p_agperror(int which, u64 agperror, int print)
 275{
 276        int status = MCHK_DISPOSITION_REPORT;
 277#ifdef CONFIG_VERBOSE_MCHECK
 278        int cmd, len;
 279        unsigned long addr;
 280
 281        static const char * const agperror_cmd[] = {
 282                "Read (low-priority)",  "Read (high-priority)",
 283                "Write (low-priority)", "Write (high-priority)",
 284                "Reserved",             "Reserved",
 285                "Flush",                "Fence"
 286        };
 287#endif /* CONFIG_VERBOSE_MCHECK */
 288
 289#define TITAN__PCHIP_AGPERROR__LOST     (1UL << 0)
 290#define TITAN__PCHIP_AGPERROR__LPQFULL  (1UL << 1)
 291#define TITAN__PCHIP_AGPERROR__HPQFULL  (1UL << 2)
 292#define TITAN__PCHIP_AGPERROR__RESCMD   (1UL << 3)
 293#define TITAN__PCHIP_AGPERROR__IPTE     (1UL << 4)
 294#define TITAN__PCHIP_AGPERROR__PTP      (1UL << 5)
 295#define TITAN__PCHIP_AGPERROR__NOWINDOW (1UL << 6)
 296#define TITAN__PCHIP_AGPERROR__ERRMASK  (TITAN__PCHIP_AGPERROR__LOST |    \
 297                                         TITAN__PCHIP_AGPERROR__LPQFULL | \
 298                                         TITAN__PCHIP_AGPERROR__HPQFULL | \
 299                                         TITAN__PCHIP_AGPERROR__RESCMD |  \
 300                                         TITAN__PCHIP_AGPERROR__IPTE |    \
 301                                         TITAN__PCHIP_AGPERROR__PTP |     \
 302                                         TITAN__PCHIP_AGPERROR__NOWINDOW)
 303#define TITAN__PCHIP_AGPERROR__DAC      (1UL << 48)
 304#define TITAN__PCHIP_AGPERROR__MWIN     (1UL << 49)
 305#define TITAN__PCHIP_AGPERROR__FENCE    (1UL << 59)
 306#define TITAN__PCHIP_AGPERROR__CMD__S   (50)
 307#define TITAN__PCHIP_AGPERROR__CMD__M   (0x07)
 308#define TITAN__PCHIP_AGPERROR__ADDR__S  (15)
 309#define TITAN__PCHIP_AGPERROR__ADDR__M  (0xffffffffUL)
 310#define TITAN__PCHIP_AGPERROR__LEN__S   (53)
 311#define TITAN__PCHIP_AGPERROR__LEN__M   (0x3f)
 312
 313        if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK))
 314                return MCHK_DISPOSITION_UNKNOWN_ERROR;
 315
 316#ifdef CONFIG_VERBOSE_MCHECK
 317        if (!print)
 318                return status;
 319
 320        cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD);
 321        addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
 322        len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
 323
 324        printk("%s  PChip %d AGPERROR: %016llx\n", err_print_prefix,
 325               which, agperror);
 326        if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
 327                printk("%s    No Window\n", err_print_prefix);
 328        if (agperror & TITAN__PCHIP_AGPERROR__PTP)
 329                printk("%s    Peer-to-Peer set\n", err_print_prefix);
 330        if (agperror & TITAN__PCHIP_AGPERROR__IPTE)
 331                printk("%s    Invalid PTE\n", err_print_prefix);
 332        if (agperror & TITAN__PCHIP_AGPERROR__RESCMD)
 333                printk("%s    Reserved Command\n", err_print_prefix);
 334        if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL)
 335                printk("%s    HP Transaction Received while Queue Full\n", 
 336                       err_print_prefix);
 337        if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL)
 338                printk("%s    LP Transaction Received while Queue Full\n", 
 339                       err_print_prefix);
 340        if (agperror & TITAN__PCHIP_AGPERROR__LOST)
 341                printk("%s    Lost Error\n", err_print_prefix);
 342        printk("%s      Command: 0x%x - %s, %d Quadwords%s\n"
 343                 "      Address: 0x%lx\n",
 344               err_print_prefix, cmd, agperror_cmd[cmd], len,
 345               (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "",
 346               addr);
 347        if (agperror & TITAN__PCHIP_AGPERROR__DAC)
 348                printk("%s      Dual Address Cycle\n", err_print_prefix);
 349        if (agperror & TITAN__PCHIP_AGPERROR__MWIN)
 350                printk("%s      Hit in Monster Window\n", err_print_prefix);
 351#endif /* CONFIG_VERBOSE_MCHECK */
 352
 353        return status;
 354}       
 355
 356static int
 357titan_parse_p_chip(int which, u64 serror, u64 gperror, 
 358                   u64 aperror, u64 agperror, int print)
 359{
 360        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 361        status |= titan_parse_p_serror(which, serror, print);
 362        status |= titan_parse_p_perror(which, 0, gperror, print);
 363        status |= titan_parse_p_perror(which, 1, aperror, print);
 364        status |= titan_parse_p_agperror(which, agperror, print);
 365        return status;
 366}
 367
 368int
 369titan_process_logout_frame(struct el_common *mchk_header, int print)
 370{
 371        struct el_TITAN_sysdata_mcheck *tmchk =
 372                (struct el_TITAN_sysdata_mcheck *)
 373                ((unsigned long)mchk_header + mchk_header->sys_offset);
 374        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 375
 376        status |= titan_parse_c_misc(tmchk->c_misc, print);
 377        status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror,
 378                                     tmchk->p0_aperror, tmchk->p0_agperror, 
 379                                     print);
 380        status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror,
 381                                     tmchk->p1_aperror, tmchk->p1_agperror, 
 382                                     print);
 383
 384        return status;
 385}
 386
 387void
 388titan_machine_check(unsigned long vector, unsigned long la_ptr)
 389{
 390        struct el_common *mchk_header = (struct el_common *)la_ptr;
 391        struct el_TITAN_sysdata_mcheck *tmchk =
 392                (struct el_TITAN_sysdata_mcheck *)
 393                ((unsigned long)mchk_header + mchk_header->sys_offset);
 394        u64 irqmask;
 395
 396        /*
 397         * Mask of Titan interrupt sources which are reported as machine checks
 398         *
 399         * 63 - CChip Error
 400         * 62 - PChip 0 H_Error
 401         * 61 - PChip 1 H_Error
 402         * 60 - PChip 0 C_Error
 403         * 59 - PChip 1 C_Error
 404         */
 405#define TITAN_MCHECK_INTERRUPT_MASK     0xF800000000000000UL
 406
 407        /*
 408         * Sync the processor
 409         */
 410        mb();
 411        draina();
 412        
 413        /*
 414         * Only handle system errors here 
 415         */
 416        if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) {
 417                ev6_machine_check(vector, la_ptr);
 418                return;
 419        }
 420
 421        /* 
 422         * It's a system error, handle it here
 423         *
 424         * The PALcode has already cleared the error, so just parse it
 425         */
 426        
 427        /* 
 428         * Parse the logout frame without printing first. If the only error(s)
 429         * found are classified as "dismissable", then just dismiss them and
 430         * don't print any message
 431         */
 432        if (titan_process_logout_frame(mchk_header, 0) != 
 433            MCHK_DISPOSITION_DISMISS) {
 434                char *saved_err_prefix = err_print_prefix;
 435                err_print_prefix = KERN_CRIT;
 436
 437                /*
 438                 * Either a nondismissable error was detected or no
 439                 * recognized error was detected  in the logout frame 
 440                 * -- report the error in either case
 441                 */
 442                printk("%s"
 443                       "*System %s Error (Vector 0x%x) reported on CPU %d:\n", 
 444                       err_print_prefix,
 445                       (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable",
 446                       (unsigned int)vector, (int)smp_processor_id());
 447                
 448#ifdef CONFIG_VERBOSE_MCHECK
 449                titan_process_logout_frame(mchk_header, alpha_verbose_mcheck);
 450                if (alpha_verbose_mcheck)
 451                        dik_show_regs(get_irq_regs(), NULL);
 452#endif /* CONFIG_VERBOSE_MCHECK */
 453
 454                err_print_prefix = saved_err_prefix;
 455
 456                /*
 457                 * Convert any pending interrupts which report as system
 458                 * machine checks to interrupts
 459                 */
 460                irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK;
 461                titan_dispatch_irqs(irqmask);
 462        }       
 463
 464
 465        /* 
 466         * Release the logout frame 
 467         */
 468        wrmces(0x7);
 469        mb();
 470}
 471
 472/*
 473 * Subpacket Annotations
 474 */
 475static char *el_titan_pchip0_extended_annotation[] = {
 476        "Subpacket Header",     "P0_SCTL",      "P0_SERREN",
 477        "P0_APCTL",             "P0_APERREN",   "P0_AGPERREN",
 478        "P0_ASPRST",            "P0_AWSBA0",    "P0_AWSBA1",
 479        "P0_AWSBA2",            "P0_AWSBA3",    "P0_AWSM0",
 480        "P0_AWSM1",             "P0_AWSM2",     "P0_AWSM3",
 481        "P0_ATBA0",             "P0_ATBA1",     "P0_ATBA2",
 482        "P0_ATBA3",             "P0_GPCTL",     "P0_GPERREN",
 483        "P0_GSPRST",            "P0_GWSBA0",    "P0_GWSBA1",
 484        "P0_GWSBA2",            "P0_GWSBA3",    "P0_GWSM0",
 485        "P0_GWSM1",             "P0_GWSM2",     "P0_GWSM3",
 486        "P0_GTBA0",             "P0_GTBA1",     "P0_GTBA2",
 487        "P0_GTBA3",             NULL 
 488};
 489static char *el_titan_pchip1_extended_annotation[] = {
 490        "Subpacket Header",     "P1_SCTL",      "P1_SERREN",
 491        "P1_APCTL",             "P1_APERREN",   "P1_AGPERREN",
 492        "P1_ASPRST",            "P1_AWSBA0",    "P1_AWSBA1",
 493        "P1_AWSBA2",            "P1_AWSBA3",    "P1_AWSM0",
 494        "P1_AWSM1",             "P1_AWSM2",     "P1_AWSM3",
 495        "P1_ATBA0",             "P1_ATBA1",     "P1_ATBA2",
 496        "P1_ATBA3",             "P1_GPCTL",     "P1_GPERREN",
 497        "P1_GSPRST",            "P1_GWSBA0",    "P1_GWSBA1",
 498        "P1_GWSBA2",            "P1_GWSBA3",    "P1_GWSM0",
 499        "P1_GWSM1",             "P1_GWSM2",     "P1_GWSM3",
 500        "P1_GTBA0",             "P1_GTBA1",     "P1_GTBA2",
 501        "P1_GTBA3",             NULL 
 502};
 503static char *el_titan_memory_extended_annotation[] = {
 504        "Subpacket Header",     "AAR0",         "AAR1",
 505        "AAR2",                 "AAR3",         "P0_SCTL",
 506        "P0_GPCTL",             "P0_APCTL",     "P1_SCTL",
 507        "P1_GPCTL",             "P1_SCTL",      NULL 
 508};
 509
 510static struct el_subpacket_annotation el_titan_annotations[] = {
 511        SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
 512                             EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED,
 513                             1,
 514                             "Titan PChip 0 Extended Frame",
 515                             el_titan_pchip0_extended_annotation),
 516        SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
 517                             EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED,
 518                             1,
 519                             "Titan PChip 1 Extended Frame",
 520                             el_titan_pchip1_extended_annotation),
 521        SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
 522                             EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED,
 523                             1,
 524                             "Titan Memory Extended Frame",
 525                             el_titan_memory_extended_annotation),
 526        SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
 527                             EL_TYPE__TERMINATION__TERMINATION,
 528                             1,
 529                             "Termination Subpacket",
 530                             NULL)
 531};
 532
 533static struct el_subpacket *
 534el_process_regatta_subpacket(struct el_subpacket *header)
 535{
 536        if (header->class != EL_CLASS__REGATTA_FAMILY) {
 537                printk("%s  ** Unexpected header CLASS %d TYPE %d, aborting\n",
 538                       err_print_prefix,
 539                       header->class, header->type);
 540                return NULL;
 541        }
 542
 543        switch(header->type) {
 544        case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME:
 545        case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME:
 546        case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME:
 547        case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT:
 548        case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT:
 549                printk("%s  ** Occurred on CPU %d:\n", 
 550                       err_print_prefix,
 551                       (int)header->by_type.regatta_frame.cpuid);
 552                privateer_process_logout_frame((struct el_common *)
 553                        header->by_type.regatta_frame.data_start, 1);
 554                break;
 555        default:
 556                printk("%s  ** REGATTA TYPE %d SUBPACKET\n", 
 557                       err_print_prefix, header->type);
 558                el_annotate_subpacket(header);
 559                break;
 560        }
 561
 562
 563        return (struct el_subpacket *)((unsigned long)header + header->length);
 564} 
 565
 566static struct el_subpacket_handler titan_subpacket_handler = 
 567        SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY, 
 568                               el_process_regatta_subpacket);
 569
 570void __init
 571titan_register_error_handlers(void)
 572{
 573        size_t i;
 574
 575        for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++)
 576                cdl_register_subpacket_annotation(&el_titan_annotations[i]);
 577
 578        cdl_register_subpacket_handler(&titan_subpacket_handler);
 579
 580        ev6_register_error_handlers();
 581}
 582
 583
 584/*
 585 * Privateer
 586 */
 587
 588static int
 589privateer_process_680_frame(struct el_common *mchk_header, int print)
 590{
 591        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 592#ifdef CONFIG_VERBOSE_MCHECK
 593        struct el_PRIVATEER_envdata_mcheck *emchk =
 594                (struct el_PRIVATEER_envdata_mcheck *)
 595                ((unsigned long)mchk_header + mchk_header->sys_offset);
 596
 597        /* TODO - categorize errors, for now, no error */
 598
 599        if (!print)
 600                return status;
 601
 602        /* TODO - decode instead of just dumping... */
 603        printk("%s  Summary Flags:         %016llx\n"
 604                 "  CChip DIRx:            %016llx\n"
 605                 "  System Management IR:  %016llx\n"
 606                 "  CPU IR:                %016llx\n"
 607                 "  Power Supply IR:       %016llx\n"
 608                 "  LM78 Fault Status:     %016llx\n"
 609                 "  System Doors:          %016llx\n"
 610                 "  Temperature Warning:   %016llx\n"
 611                 "  Fan Control:           %016llx\n"
 612                 "  Fatal Power Down Code: %016llx\n",
 613               err_print_prefix,
 614               emchk->summary,
 615               emchk->c_dirx,
 616               emchk->smir,
 617               emchk->cpuir,
 618               emchk->psir,
 619               emchk->fault,
 620               emchk->sys_doors,
 621               emchk->temp_warn,
 622               emchk->fan_ctrl,
 623               emchk->code);
 624#endif /* CONFIG_VERBOSE_MCHECK */
 625
 626        return status;
 627}
 628
 629int
 630privateer_process_logout_frame(struct el_common *mchk_header, int print)
 631{
 632        struct el_common_EV6_mcheck *ev6mchk = 
 633                (struct el_common_EV6_mcheck *)mchk_header;
 634        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 635
 636        /*
 637         * Machine check codes
 638         */
 639#define PRIVATEER_MCHK__CORR_ECC                0x86    /* 630 */
 640#define PRIVATEER_MCHK__DC_TAG_PERR             0x9E    /* 630 */
 641#define PRIVATEER_MCHK__PAL_BUGCHECK            0x8E    /* 670 */
 642#define PRIVATEER_MCHK__OS_BUGCHECK             0x90    /* 670 */
 643#define PRIVATEER_MCHK__PROC_HRD_ERR            0x98    /* 670 */
 644#define PRIVATEER_MCHK__ISTREAM_CMOV_PRX        0xA0    /* 670 */
 645#define PRIVATEER_MCHK__ISTREAM_CMOV_FLT        0xA2    /* 670 */
 646#define PRIVATEER_MCHK__SYS_HRD_ERR             0x202   /* 660 */
 647#define PRIVATEER_MCHK__SYS_CORR_ERR            0x204   /* 620 */
 648#define PRIVATEER_MCHK__SYS_ENVIRON             0x206   /* 680 */
 649
 650        switch(ev6mchk->MCHK_Code) {
 651        /*
 652         * Vector 630 - Processor, Correctable
 653         */
 654        case PRIVATEER_MCHK__CORR_ECC:
 655        case PRIVATEER_MCHK__DC_TAG_PERR:
 656                /*
 657                 * Fall through to vector 670 for processing...
 658                 */
 659        /*
 660         * Vector 670 - Processor, Uncorrectable
 661         */
 662        case PRIVATEER_MCHK__PAL_BUGCHECK:
 663        case PRIVATEER_MCHK__OS_BUGCHECK:
 664        case PRIVATEER_MCHK__PROC_HRD_ERR:
 665        case PRIVATEER_MCHK__ISTREAM_CMOV_PRX:
 666        case PRIVATEER_MCHK__ISTREAM_CMOV_FLT:
 667                status |= ev6_process_logout_frame(mchk_header, print);
 668                break;
 669
 670        /*
 671         * Vector 620 - System, Correctable
 672         */
 673        case PRIVATEER_MCHK__SYS_CORR_ERR:
 674                /*
 675                 * Fall through to vector 660 for processing...
 676                 */
 677        /*
 678         * Vector 660 - System, Uncorrectable
 679         */
 680        case PRIVATEER_MCHK__SYS_HRD_ERR:
 681                status |= titan_process_logout_frame(mchk_header, print);
 682                break;
 683
 684        /* 
 685         * Vector 680 - System, Environmental
 686         */
 687        case PRIVATEER_MCHK__SYS_ENVIRON:       /* System, Environmental */
 688                status |= privateer_process_680_frame(mchk_header, print);
 689                break;
 690
 691        /* 
 692         * Unknown
 693         */
 694        default:
 695                status |= MCHK_DISPOSITION_REPORT;
 696                if (print) {
 697                        printk("%s** Unknown Error, frame follows\n", 
 698                               err_print_prefix);
 699                        mchk_dump_logout_frame(mchk_header);
 700                }
 701
 702        }
 703
 704        return status;
 705}
 706
 707void
 708privateer_machine_check(unsigned long vector, unsigned long la_ptr)
 709{
 710        struct el_common *mchk_header = (struct el_common *)la_ptr;
 711        struct el_TITAN_sysdata_mcheck *tmchk =
 712                (struct el_TITAN_sysdata_mcheck *)
 713                (la_ptr + mchk_header->sys_offset);
 714        u64 irqmask;
 715        char *saved_err_prefix = err_print_prefix;
 716
 717#define PRIVATEER_680_INTERRUPT_MASK            (0xE00UL)
 718#define PRIVATEER_HOTPLUG_INTERRUPT_MASK        (0xE00UL)
 719
 720        /*
 721         * Sync the processor.
 722         */
 723        mb();
 724        draina();
 725
 726        /* 
 727         * Only handle system events here.
 728         */
 729        if (vector != SCB_Q_SYSEVENT) 
 730                return titan_machine_check(vector, la_ptr);
 731
 732        /*
 733         * Report the event - System Events should be reported even if no
 734         * error is indicated since the event could indicate the return
 735         * to normal status.
 736         */
 737        err_print_prefix = KERN_CRIT;
 738        printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n", 
 739               err_print_prefix,
 740               (unsigned int)vector, (int)smp_processor_id());
 741        privateer_process_680_frame(mchk_header, 1);
 742        err_print_prefix = saved_err_prefix;
 743        
 744        /* 
 745         * Convert any pending interrupts which report as 680 machine
 746         * checks to interrupts.
 747         */
 748        irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK;
 749
 750        /*
 751         * Dispatch the interrupt(s).
 752         */
 753        titan_dispatch_irqs(irqmask);
 754
 755        /* 
 756         * Release the logout frame.
 757         */
 758        wrmces(0x7);
 759        mb();
 760}
 761