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