11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/alpha/kernel/err_titan.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation) 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Error handling code supporting TITAN systems 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #include <linux/init.h> 101da177e4SLinus Torvalds #include <linux/pci.h> 111da177e4SLinus Torvalds #include <linux/sched.h> 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds #include <asm/io.h> 141da177e4SLinus Torvalds #include <asm/core_titan.h> 151da177e4SLinus Torvalds #include <asm/hwrpb.h> 161da177e4SLinus Torvalds #include <asm/smp.h> 171da177e4SLinus Torvalds #include <asm/err_common.h> 181da177e4SLinus Torvalds #include <asm/err_ev6.h> 19*1b75b05bSIvan Kokshaysky #include <asm/irq_regs.h> 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #include "err_impl.h" 221da177e4SLinus Torvalds #include "proto.h" 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds static int 261da177e4SLinus Torvalds titan_parse_c_misc(u64 c_misc, int print) 271da177e4SLinus Torvalds { 281da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 291da177e4SLinus Torvalds char *src; 301da177e4SLinus Torvalds int nxs = 0; 311da177e4SLinus Torvalds #endif 321da177e4SLinus Torvalds int status = MCHK_DISPOSITION_REPORT; 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #define TITAN__CCHIP_MISC__NXM (1UL << 28) 351da177e4SLinus Torvalds #define TITAN__CCHIP_MISC__NXS__S (29) 361da177e4SLinus Torvalds #define TITAN__CCHIP_MISC__NXS__M (0x7) 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds if (!(c_misc & TITAN__CCHIP_MISC__NXM)) 391da177e4SLinus Torvalds return MCHK_DISPOSITION_UNKNOWN_ERROR; 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 421da177e4SLinus Torvalds if (!print) 431da177e4SLinus Torvalds return status; 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS); 461da177e4SLinus Torvalds switch(nxs) { 471da177e4SLinus Torvalds case 0: /* CPU 0 */ 481da177e4SLinus Torvalds case 1: /* CPU 1 */ 491da177e4SLinus Torvalds case 2: /* CPU 2 */ 501da177e4SLinus Torvalds case 3: /* CPU 3 */ 511da177e4SLinus Torvalds src = "CPU"; 521da177e4SLinus Torvalds /* num is already the CPU number */ 531da177e4SLinus Torvalds break; 541da177e4SLinus Torvalds case 4: /* Pchip 0 */ 551da177e4SLinus Torvalds case 5: /* Pchip 1 */ 561da177e4SLinus Torvalds src = "Pchip"; 571da177e4SLinus Torvalds nxs -= 4; 581da177e4SLinus Torvalds break; 591da177e4SLinus Torvalds default:/* reserved */ 601da177e4SLinus Torvalds src = "Unknown, NXS ="; 611da177e4SLinus Torvalds /* leave num untouched */ 621da177e4SLinus Torvalds break; 631da177e4SLinus Torvalds } 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds printk("%s Non-existent memory access from: %s %d\n", 661da177e4SLinus Torvalds err_print_prefix, src, nxs); 671da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds return status; 701da177e4SLinus Torvalds } 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds static int 731da177e4SLinus Torvalds titan_parse_p_serror(int which, u64 serror, int print) 741da177e4SLinus Torvalds { 751da177e4SLinus Torvalds int status = MCHK_DISPOSITION_REPORT; 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 781da177e4SLinus Torvalds char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; 791da177e4SLinus Torvalds char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; 801da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) 831da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__UECC (1UL << 1) 841da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__CRE (1UL << 2) 851da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__NXIO (1UL << 3) 861da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__LOST_CRE (1UL << 4) 871da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__ECCMASK (TITAN__PCHIP_SERROR__UECC | \ 881da177e4SLinus Torvalds TITAN__PCHIP_SERROR__CRE) 891da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__ERRMASK (TITAN__PCHIP_SERROR__LOST_UECC | \ 901da177e4SLinus Torvalds TITAN__PCHIP_SERROR__UECC | \ 911da177e4SLinus Torvalds TITAN__PCHIP_SERROR__CRE | \ 921da177e4SLinus Torvalds TITAN__PCHIP_SERROR__NXIO | \ 931da177e4SLinus Torvalds TITAN__PCHIP_SERROR__LOST_CRE) 941da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__SRC__S (52) 951da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__SRC__M (0x3) 961da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__CMD__S (54) 971da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__CMD__M (0x3) 981da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__SYN__S (56) 991da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__SYN__M (0xff) 1001da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__ADDR__S (15) 1011da177e4SLinus Torvalds #define TITAN__PCHIP_SERROR__ADDR__M (0xffffffffUL) 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds if (!(serror & TITAN__PCHIP_SERROR__ERRMASK)) 1041da177e4SLinus Torvalds return MCHK_DISPOSITION_UNKNOWN_ERROR; 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 1071da177e4SLinus Torvalds if (!print) 1081da177e4SLinus Torvalds return status; 1091da177e4SLinus Torvalds 1101da177e4SLinus Torvalds printk("%s PChip %d SERROR: %016lx\n", 1111da177e4SLinus Torvalds err_print_prefix, which, serror); 1121da177e4SLinus Torvalds if (serror & TITAN__PCHIP_SERROR__ECCMASK) { 1131da177e4SLinus Torvalds printk("%s %sorrectable ECC Error:\n" 1141da177e4SLinus Torvalds " Source: %-6s Command: %-8s Syndrome: 0x%08x\n" 1151da177e4SLinus Torvalds " Address: 0x%lx\n", 1161da177e4SLinus Torvalds err_print_prefix, 1171da177e4SLinus Torvalds (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", 1181da177e4SLinus Torvalds serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], 1191da177e4SLinus Torvalds serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)], 1201da177e4SLinus Torvalds (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN), 1211da177e4SLinus Torvalds EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR)); 1221da177e4SLinus Torvalds } 1231da177e4SLinus Torvalds if (serror & TITAN__PCHIP_SERROR__NXIO) 1241da177e4SLinus Torvalds printk("%s Non Existent I/O Error\n", err_print_prefix); 1251da177e4SLinus Torvalds if (serror & TITAN__PCHIP_SERROR__LOST_UECC) 1261da177e4SLinus Torvalds printk("%s Lost Uncorrectable ECC Error\n", 1271da177e4SLinus Torvalds err_print_prefix); 1281da177e4SLinus Torvalds if (serror & TITAN__PCHIP_SERROR__LOST_CRE) 1291da177e4SLinus Torvalds printk("%s Lost Correctable ECC Error\n", err_print_prefix); 1301da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds return status; 1331da177e4SLinus Torvalds } 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds static int 1361da177e4SLinus Torvalds titan_parse_p_perror(int which, int port, u64 perror, int print) 1371da177e4SLinus Torvalds { 1381da177e4SLinus Torvalds int cmd; 1391da177e4SLinus Torvalds unsigned long addr; 1401da177e4SLinus Torvalds int status = MCHK_DISPOSITION_REPORT; 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 1431da177e4SLinus Torvalds char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", 1441da177e4SLinus Torvalds "I/O Read", "I/O Write", 1451da177e4SLinus Torvalds "Reserved", "Reserved", 1461da177e4SLinus Torvalds "Memory Read", "Memory Write", 1471da177e4SLinus Torvalds "Reserved", "Reserved", 1481da177e4SLinus Torvalds "Configuration Read", "Configuration Write", 1491da177e4SLinus Torvalds "Memory Read Multiple", "Dual Address Cycle", 1501da177e4SLinus Torvalds "Memory Read Line","Memory Write and Invalidate" 1511da177e4SLinus Torvalds }; 1521da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__LOST (1UL << 0) 1551da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__SERR (1UL << 1) 1561da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__PERR (1UL << 2) 1571da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__DCRTO (1UL << 3) 1581da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__SGE (1UL << 4) 1591da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__APE (1UL << 5) 1601da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__TA (1UL << 6) 1611da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__DPE (1UL << 7) 1621da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__NDS (1UL << 8) 1631da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__IPTPR (1UL << 9) 1641da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__IPTPW (1UL << 10) 1651da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__ERRMASK (TITAN__PCHIP_PERROR__LOST | \ 1661da177e4SLinus Torvalds TITAN__PCHIP_PERROR__SERR | \ 1671da177e4SLinus Torvalds TITAN__PCHIP_PERROR__PERR | \ 1681da177e4SLinus Torvalds TITAN__PCHIP_PERROR__DCRTO | \ 1691da177e4SLinus Torvalds TITAN__PCHIP_PERROR__SGE | \ 1701da177e4SLinus Torvalds TITAN__PCHIP_PERROR__APE | \ 1711da177e4SLinus Torvalds TITAN__PCHIP_PERROR__TA | \ 1721da177e4SLinus Torvalds TITAN__PCHIP_PERROR__DPE | \ 1731da177e4SLinus Torvalds TITAN__PCHIP_PERROR__NDS | \ 1741da177e4SLinus Torvalds TITAN__PCHIP_PERROR__IPTPR | \ 1751da177e4SLinus Torvalds TITAN__PCHIP_PERROR__IPTPW) 1761da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__DAC (1UL << 47) 1771da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__MWIN (1UL << 48) 1781da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__CMD__S (52) 1791da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__CMD__M (0x0f) 1801da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__ADDR__S (14) 1811da177e4SLinus Torvalds #define TITAN__PCHIP_PERROR__ADDR__M (0x1fffffffful) 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds if (!(perror & TITAN__PCHIP_PERROR__ERRMASK)) 1841da177e4SLinus Torvalds return MCHK_DISPOSITION_UNKNOWN_ERROR; 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD); 1871da177e4SLinus Torvalds addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2; 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds /* 1901da177e4SLinus Torvalds * Initializing the BIOS on a video card on a bus without 1911da177e4SLinus Torvalds * a south bridge (subtractive decode agent) can result in 1921da177e4SLinus Torvalds * master aborts as the BIOS probes the capabilities of the 1931da177e4SLinus Torvalds * card. XFree86 does such initialization. If the error 1941da177e4SLinus Torvalds * is a master abort (No DevSel as PCI Master) and the command 1951da177e4SLinus Torvalds * is an I/O read or write below the address where we start 1961da177e4SLinus Torvalds * assigning PCI I/O spaces (SRM uses 0x1000), then mark the 1971da177e4SLinus Torvalds * error as dismissable so starting XFree86 doesn't result 1981da177e4SLinus Torvalds * in a series of uncorrectable errors being reported. Also 1991da177e4SLinus Torvalds * dismiss master aborts to VGA frame buffer space 2001da177e4SLinus Torvalds * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000) 2011da177e4SLinus Torvalds * for the same reason. 2021da177e4SLinus Torvalds * 2031da177e4SLinus Torvalds * Also mark the error dismissible if it looks like the right 2041da177e4SLinus Torvalds * error but only the Lost bit is set. Since the BIOS initialization 2051da177e4SLinus Torvalds * can cause multiple master aborts and the error interrupt can 2061da177e4SLinus Torvalds * be handled on a different CPU than the BIOS code is run on, 2071da177e4SLinus Torvalds * it is possible for a second master abort to occur between the 2081da177e4SLinus Torvalds * time the PALcode reads PERROR and the time it writes PERROR 2091da177e4SLinus Torvalds * to acknowledge the error. If this timing happens, a second 2101da177e4SLinus Torvalds * error will be signalled after the first, and if no additional 2111da177e4SLinus Torvalds * errors occur, will look like a Lost error with no additional 2121da177e4SLinus Torvalds * errors on the same transaction as the previous error. 2131da177e4SLinus Torvalds */ 2141da177e4SLinus Torvalds if (((perror & TITAN__PCHIP_PERROR__NDS) || 2151da177e4SLinus Torvalds ((perror & TITAN__PCHIP_PERROR__ERRMASK) == 2161da177e4SLinus Torvalds TITAN__PCHIP_PERROR__LOST)) && 2171da177e4SLinus Torvalds ((((cmd & 0xE) == 2) && (addr < 0x1000)) || 2181da177e4SLinus Torvalds (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) { 2191da177e4SLinus Torvalds status = MCHK_DISPOSITION_DISMISS; 2201da177e4SLinus Torvalds } 2211da177e4SLinus Torvalds 2221da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 2231da177e4SLinus Torvalds if (!print) 2241da177e4SLinus Torvalds return status; 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds printk("%s PChip %d %cPERROR: %016lx\n", 2271da177e4SLinus Torvalds err_print_prefix, which, 2281da177e4SLinus Torvalds port ? 'A' : 'G', perror); 2291da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__IPTPW) 2301da177e4SLinus Torvalds printk("%s Invalid Peer-to-Peer Write\n", err_print_prefix); 2311da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__IPTPR) 2321da177e4SLinus Torvalds printk("%s Invalid Peer-to-Peer Read\n", err_print_prefix); 2331da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__NDS) 2341da177e4SLinus Torvalds printk("%s No DEVSEL as PCI Master [Master Abort]\n", 2351da177e4SLinus Torvalds err_print_prefix); 2361da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__DPE) 2371da177e4SLinus Torvalds printk("%s Data Parity Error\n", err_print_prefix); 2381da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__TA) 2391da177e4SLinus Torvalds printk("%s Target Abort\n", err_print_prefix); 2401da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__APE) 2411da177e4SLinus Torvalds printk("%s Address Parity Error\n", err_print_prefix); 2421da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__SGE) 2431da177e4SLinus Torvalds printk("%s Scatter-Gather Error, Invalid PTE\n", 2441da177e4SLinus Torvalds err_print_prefix); 2451da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__DCRTO) 2461da177e4SLinus Torvalds printk("%s Delayed-Completion Retry Timeout\n", 2471da177e4SLinus Torvalds err_print_prefix); 2481da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__PERR) 2491da177e4SLinus Torvalds printk("%s PERR Asserted\n", err_print_prefix); 2501da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__SERR) 2511da177e4SLinus Torvalds printk("%s SERR Asserted\n", err_print_prefix); 2521da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__LOST) 2531da177e4SLinus Torvalds printk("%s Lost Error\n", err_print_prefix); 2541da177e4SLinus Torvalds printk("%s Command: 0x%x - %s\n" 2551da177e4SLinus Torvalds " Address: 0x%lx\n", 2561da177e4SLinus Torvalds err_print_prefix, 2571da177e4SLinus Torvalds cmd, perror_cmd[cmd], 2581da177e4SLinus Torvalds addr); 2591da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__DAC) 2601da177e4SLinus Torvalds printk("%s Dual Address Cycle\n", err_print_prefix); 2611da177e4SLinus Torvalds if (perror & TITAN__PCHIP_PERROR__MWIN) 2621da177e4SLinus Torvalds printk("%s Hit in Monster Window\n", err_print_prefix); 2631da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds return status; 2661da177e4SLinus Torvalds } 2671da177e4SLinus Torvalds 2681da177e4SLinus Torvalds static int 2691da177e4SLinus Torvalds titan_parse_p_agperror(int which, u64 agperror, int print) 2701da177e4SLinus Torvalds { 2711da177e4SLinus Torvalds int status = MCHK_DISPOSITION_REPORT; 2721da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 2731da177e4SLinus Torvalds int cmd, len; 2741da177e4SLinus Torvalds unsigned long addr; 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", 2771da177e4SLinus Torvalds "Write (low-priority)", 2781da177e4SLinus Torvalds "Write (high-priority)", 2791da177e4SLinus Torvalds "Reserved", "Reserved", 2801da177e4SLinus Torvalds "Flush", "Fence" 2811da177e4SLinus Torvalds }; 2821da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__LOST (1UL << 0) 2851da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__LPQFULL (1UL << 1) 2861da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__HPQFULL (1UL << 2) 2871da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__RESCMD (1UL << 3) 2881da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__IPTE (1UL << 4) 2891da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__PTP (1UL << 5) 2901da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__NOWINDOW (1UL << 6) 2911da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__ERRMASK (TITAN__PCHIP_AGPERROR__LOST | \ 2921da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__LPQFULL | \ 2931da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__HPQFULL | \ 2941da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__RESCMD | \ 2951da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__IPTE | \ 2961da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__PTP | \ 2971da177e4SLinus Torvalds TITAN__PCHIP_AGPERROR__NOWINDOW) 2981da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__DAC (1UL << 48) 2991da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__MWIN (1UL << 49) 3001da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__FENCE (1UL << 59) 3011da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__CMD__S (50) 3021da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__CMD__M (0x07) 3031da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__ADDR__S (15) 3041da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__ADDR__M (0xffffffffUL) 3051da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__LEN__S (53) 3061da177e4SLinus Torvalds #define TITAN__PCHIP_AGPERROR__LEN__M (0x3f) 3071da177e4SLinus Torvalds 3081da177e4SLinus Torvalds if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK)) 3091da177e4SLinus Torvalds return MCHK_DISPOSITION_UNKNOWN_ERROR; 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 3121da177e4SLinus Torvalds if (!print) 3131da177e4SLinus Torvalds return status; 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD); 3161da177e4SLinus Torvalds addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; 3171da177e4SLinus Torvalds len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix, 3201da177e4SLinus Torvalds which, agperror); 3211da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) 3221da177e4SLinus Torvalds printk("%s No Window\n", err_print_prefix); 3231da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__PTP) 3241da177e4SLinus Torvalds printk("%s Peer-to-Peer set\n", err_print_prefix); 3251da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__IPTE) 3261da177e4SLinus Torvalds printk("%s Invalid PTE\n", err_print_prefix); 3271da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__RESCMD) 3281da177e4SLinus Torvalds printk("%s Reserved Command\n", err_print_prefix); 3291da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL) 3301da177e4SLinus Torvalds printk("%s HP Transaction Received while Queue Full\n", 3311da177e4SLinus Torvalds err_print_prefix); 3321da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL) 3331da177e4SLinus Torvalds printk("%s LP Transaction Received while Queue Full\n", 3341da177e4SLinus Torvalds err_print_prefix); 3351da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__LOST) 3361da177e4SLinus Torvalds printk("%s Lost Error\n", err_print_prefix); 3371da177e4SLinus Torvalds printk("%s Command: 0x%x - %s, %d Quadwords%s\n" 3381da177e4SLinus Torvalds " Address: 0x%lx\n", 3391da177e4SLinus Torvalds err_print_prefix, cmd, agperror_cmd[cmd], len, 3401da177e4SLinus Torvalds (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "", 3411da177e4SLinus Torvalds addr); 3421da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__DAC) 3431da177e4SLinus Torvalds printk("%s Dual Address Cycle\n", err_print_prefix); 3441da177e4SLinus Torvalds if (agperror & TITAN__PCHIP_AGPERROR__MWIN) 3451da177e4SLinus Torvalds printk("%s Hit in Monster Window\n", err_print_prefix); 3461da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds return status; 3491da177e4SLinus Torvalds } 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvalds static int 3521da177e4SLinus Torvalds titan_parse_p_chip(int which, u64 serror, u64 gperror, 3531da177e4SLinus Torvalds u64 aperror, u64 agperror, int print) 3541da177e4SLinus Torvalds { 3551da177e4SLinus Torvalds int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 3561da177e4SLinus Torvalds status |= titan_parse_p_serror(which, serror, print); 3571da177e4SLinus Torvalds status |= titan_parse_p_perror(which, 0, gperror, print); 3581da177e4SLinus Torvalds status |= titan_parse_p_perror(which, 1, aperror, print); 3591da177e4SLinus Torvalds status |= titan_parse_p_agperror(which, agperror, print); 3601da177e4SLinus Torvalds return status; 3611da177e4SLinus Torvalds } 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds int 3641da177e4SLinus Torvalds titan_process_logout_frame(struct el_common *mchk_header, int print) 3651da177e4SLinus Torvalds { 3661da177e4SLinus Torvalds struct el_TITAN_sysdata_mcheck *tmchk = 3671da177e4SLinus Torvalds (struct el_TITAN_sysdata_mcheck *) 3681da177e4SLinus Torvalds ((unsigned long)mchk_header + mchk_header->sys_offset); 3691da177e4SLinus Torvalds int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds status |= titan_parse_c_misc(tmchk->c_misc, print); 3721da177e4SLinus Torvalds status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror, 3731da177e4SLinus Torvalds tmchk->p0_aperror, tmchk->p0_agperror, 3741da177e4SLinus Torvalds print); 3751da177e4SLinus Torvalds status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror, 3761da177e4SLinus Torvalds tmchk->p1_aperror, tmchk->p1_agperror, 3771da177e4SLinus Torvalds print); 3781da177e4SLinus Torvalds 3791da177e4SLinus Torvalds return status; 3801da177e4SLinus Torvalds } 3811da177e4SLinus Torvalds 3821da177e4SLinus Torvalds void 3834fa1970aSAl Viro titan_machine_check(u64 vector, u64 la_ptr) 3841da177e4SLinus Torvalds { 3851da177e4SLinus Torvalds struct el_common *mchk_header = (struct el_common *)la_ptr; 3861da177e4SLinus Torvalds struct el_TITAN_sysdata_mcheck *tmchk = 3871da177e4SLinus Torvalds (struct el_TITAN_sysdata_mcheck *) 3881da177e4SLinus Torvalds ((unsigned long)mchk_header + mchk_header->sys_offset); 3891da177e4SLinus Torvalds u64 irqmask; 3901da177e4SLinus Torvalds 3911da177e4SLinus Torvalds /* 3921da177e4SLinus Torvalds * Mask of Titan interrupt sources which are reported as machine checks 3931da177e4SLinus Torvalds * 3941da177e4SLinus Torvalds * 63 - CChip Error 3951da177e4SLinus Torvalds * 62 - PChip 0 H_Error 3961da177e4SLinus Torvalds * 61 - PChip 1 H_Error 3971da177e4SLinus Torvalds * 60 - PChip 0 C_Error 3981da177e4SLinus Torvalds * 59 - PChip 1 C_Error 3991da177e4SLinus Torvalds */ 4001da177e4SLinus Torvalds #define TITAN_MCHECK_INTERRUPT_MASK 0xF800000000000000UL 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvalds /* 4031da177e4SLinus Torvalds * Sync the processor 4041da177e4SLinus Torvalds */ 4051da177e4SLinus Torvalds mb(); 4061da177e4SLinus Torvalds draina(); 4071da177e4SLinus Torvalds 4081da177e4SLinus Torvalds /* 4091da177e4SLinus Torvalds * Only handle system errors here 4101da177e4SLinus Torvalds */ 4111da177e4SLinus Torvalds if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) { 4124fa1970aSAl Viro ev6_machine_check(vector, la_ptr); 4131da177e4SLinus Torvalds return; 4141da177e4SLinus Torvalds } 4151da177e4SLinus Torvalds 4161da177e4SLinus Torvalds /* 4171da177e4SLinus Torvalds * It's a system error, handle it here 4181da177e4SLinus Torvalds * 4191da177e4SLinus Torvalds * The PALcode has already cleared the error, so just parse it 4201da177e4SLinus Torvalds */ 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvalds /* 4231da177e4SLinus Torvalds * Parse the logout frame without printing first. If the only error(s) 4241da177e4SLinus Torvalds * found are classified as "dismissable", then just dismiss them and 4251da177e4SLinus Torvalds * don't print any message 4261da177e4SLinus Torvalds */ 4271da177e4SLinus Torvalds if (titan_process_logout_frame(mchk_header, 0) != 4281da177e4SLinus Torvalds MCHK_DISPOSITION_DISMISS) { 4291da177e4SLinus Torvalds char *saved_err_prefix = err_print_prefix; 4301da177e4SLinus Torvalds err_print_prefix = KERN_CRIT; 4311da177e4SLinus Torvalds 4321da177e4SLinus Torvalds /* 4331da177e4SLinus Torvalds * Either a nondismissable error was detected or no 4341da177e4SLinus Torvalds * recognized error was detected in the logout frame 4351da177e4SLinus Torvalds * -- report the error in either case 4361da177e4SLinus Torvalds */ 4371da177e4SLinus Torvalds printk("%s" 4381da177e4SLinus Torvalds "*System %s Error (Vector 0x%x) reported on CPU %d:\n", 4391da177e4SLinus Torvalds err_print_prefix, 4401da177e4SLinus Torvalds (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable", 4411da177e4SLinus Torvalds (unsigned int)vector, (int)smp_processor_id()); 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 4441da177e4SLinus Torvalds titan_process_logout_frame(mchk_header, alpha_verbose_mcheck); 4451da177e4SLinus Torvalds if (alpha_verbose_mcheck) 4464fa1970aSAl Viro dik_show_regs(get_irq_regs(), NULL); 4471da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 4481da177e4SLinus Torvalds 4491da177e4SLinus Torvalds err_print_prefix = saved_err_prefix; 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds /* 4521da177e4SLinus Torvalds * Convert any pending interrupts which report as system 4531da177e4SLinus Torvalds * machine checks to interrupts 4541da177e4SLinus Torvalds */ 4551da177e4SLinus Torvalds irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK; 4562f116cbfSAl Viro titan_dispatch_irqs(irqmask); 4571da177e4SLinus Torvalds } 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds 4601da177e4SLinus Torvalds /* 4611da177e4SLinus Torvalds * Release the logout frame 4621da177e4SLinus Torvalds */ 4631da177e4SLinus Torvalds wrmces(0x7); 4641da177e4SLinus Torvalds mb(); 4651da177e4SLinus Torvalds } 4661da177e4SLinus Torvalds 4671da177e4SLinus Torvalds /* 4681da177e4SLinus Torvalds * Subpacket Annotations 4691da177e4SLinus Torvalds */ 4701da177e4SLinus Torvalds static char *el_titan_pchip0_extended_annotation[] = { 4711da177e4SLinus Torvalds "Subpacket Header", "P0_SCTL", "P0_SERREN", 4721da177e4SLinus Torvalds "P0_APCTL", "P0_APERREN", "P0_AGPERREN", 4731da177e4SLinus Torvalds "P0_ASPRST", "P0_AWSBA0", "P0_AWSBA1", 4741da177e4SLinus Torvalds "P0_AWSBA2", "P0_AWSBA3", "P0_AWSM0", 4751da177e4SLinus Torvalds "P0_AWSM1", "P0_AWSM2", "P0_AWSM3", 4761da177e4SLinus Torvalds "P0_ATBA0", "P0_ATBA1", "P0_ATBA2", 4771da177e4SLinus Torvalds "P0_ATBA3", "P0_GPCTL", "P0_GPERREN", 4781da177e4SLinus Torvalds "P0_GSPRST", "P0_GWSBA0", "P0_GWSBA1", 4791da177e4SLinus Torvalds "P0_GWSBA2", "P0_GWSBA3", "P0_GWSM0", 4801da177e4SLinus Torvalds "P0_GWSM1", "P0_GWSM2", "P0_GWSM3", 4811da177e4SLinus Torvalds "P0_GTBA0", "P0_GTBA1", "P0_GTBA2", 4821da177e4SLinus Torvalds "P0_GTBA3", NULL 4831da177e4SLinus Torvalds }; 4841da177e4SLinus Torvalds static char *el_titan_pchip1_extended_annotation[] = { 4851da177e4SLinus Torvalds "Subpacket Header", "P1_SCTL", "P1_SERREN", 4861da177e4SLinus Torvalds "P1_APCTL", "P1_APERREN", "P1_AGPERREN", 4871da177e4SLinus Torvalds "P1_ASPRST", "P1_AWSBA0", "P1_AWSBA1", 4881da177e4SLinus Torvalds "P1_AWSBA2", "P1_AWSBA3", "P1_AWSM0", 4891da177e4SLinus Torvalds "P1_AWSM1", "P1_AWSM2", "P1_AWSM3", 4901da177e4SLinus Torvalds "P1_ATBA0", "P1_ATBA1", "P1_ATBA2", 4911da177e4SLinus Torvalds "P1_ATBA3", "P1_GPCTL", "P1_GPERREN", 4921da177e4SLinus Torvalds "P1_GSPRST", "P1_GWSBA0", "P1_GWSBA1", 4931da177e4SLinus Torvalds "P1_GWSBA2", "P1_GWSBA3", "P1_GWSM0", 4941da177e4SLinus Torvalds "P1_GWSM1", "P1_GWSM2", "P1_GWSM3", 4951da177e4SLinus Torvalds "P1_GTBA0", "P1_GTBA1", "P1_GTBA2", 4961da177e4SLinus Torvalds "P1_GTBA3", NULL 4971da177e4SLinus Torvalds }; 4981da177e4SLinus Torvalds static char *el_titan_memory_extended_annotation[] = { 4991da177e4SLinus Torvalds "Subpacket Header", "AAR0", "AAR1", 5001da177e4SLinus Torvalds "AAR2", "AAR3", "P0_SCTL", 5011da177e4SLinus Torvalds "P0_GPCTL", "P0_APCTL", "P1_SCTL", 5021da177e4SLinus Torvalds "P1_GPCTL", "P1_SCTL", NULL 5031da177e4SLinus Torvalds }; 5041da177e4SLinus Torvalds 5051da177e4SLinus Torvalds static struct el_subpacket_annotation el_titan_annotations[] = { 5061da177e4SLinus Torvalds SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 5071da177e4SLinus Torvalds EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED, 5081da177e4SLinus Torvalds 1, 5091da177e4SLinus Torvalds "Titan PChip 0 Extended Frame", 5101da177e4SLinus Torvalds el_titan_pchip0_extended_annotation), 5111da177e4SLinus Torvalds SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 5121da177e4SLinus Torvalds EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED, 5131da177e4SLinus Torvalds 1, 5141da177e4SLinus Torvalds "Titan PChip 1 Extended Frame", 5151da177e4SLinus Torvalds el_titan_pchip1_extended_annotation), 5161da177e4SLinus Torvalds SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 5171da177e4SLinus Torvalds EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED, 5181da177e4SLinus Torvalds 1, 5191da177e4SLinus Torvalds "Titan Memory Extended Frame", 5201da177e4SLinus Torvalds el_titan_memory_extended_annotation), 5211da177e4SLinus Torvalds SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY, 5221da177e4SLinus Torvalds EL_TYPE__TERMINATION__TERMINATION, 5231da177e4SLinus Torvalds 1, 5241da177e4SLinus Torvalds "Termination Subpacket", 5251da177e4SLinus Torvalds NULL) 5261da177e4SLinus Torvalds }; 5271da177e4SLinus Torvalds 5281da177e4SLinus Torvalds static struct el_subpacket * 5291da177e4SLinus Torvalds el_process_regatta_subpacket(struct el_subpacket *header) 5301da177e4SLinus Torvalds { 5311da177e4SLinus Torvalds int status; 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds if (header->class != EL_CLASS__REGATTA_FAMILY) { 5341da177e4SLinus Torvalds printk("%s ** Unexpected header CLASS %d TYPE %d, aborting\n", 5351da177e4SLinus Torvalds err_print_prefix, 5361da177e4SLinus Torvalds header->class, header->type); 5371da177e4SLinus Torvalds return NULL; 5381da177e4SLinus Torvalds } 5391da177e4SLinus Torvalds 5401da177e4SLinus Torvalds switch(header->type) { 5411da177e4SLinus Torvalds case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME: 5421da177e4SLinus Torvalds case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME: 5431da177e4SLinus Torvalds case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME: 5441da177e4SLinus Torvalds case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT: 5451da177e4SLinus Torvalds case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT: 5461da177e4SLinus Torvalds printk("%s ** Occurred on CPU %d:\n", 5471da177e4SLinus Torvalds err_print_prefix, 5481da177e4SLinus Torvalds (int)header->by_type.regatta_frame.cpuid); 5491da177e4SLinus Torvalds status = privateer_process_logout_frame((struct el_common *) 5501da177e4SLinus Torvalds header->by_type.regatta_frame.data_start, 1); 5511da177e4SLinus Torvalds break; 5521da177e4SLinus Torvalds default: 5531da177e4SLinus Torvalds printk("%s ** REGATTA TYPE %d SUBPACKET\n", 5541da177e4SLinus Torvalds err_print_prefix, header->type); 5551da177e4SLinus Torvalds el_annotate_subpacket(header); 5561da177e4SLinus Torvalds break; 5571da177e4SLinus Torvalds } 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds 5601da177e4SLinus Torvalds return (struct el_subpacket *)((unsigned long)header + header->length); 5611da177e4SLinus Torvalds } 5621da177e4SLinus Torvalds 5631da177e4SLinus Torvalds static struct el_subpacket_handler titan_subpacket_handler = 5641da177e4SLinus Torvalds SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY, 5651da177e4SLinus Torvalds el_process_regatta_subpacket); 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds void 5681da177e4SLinus Torvalds titan_register_error_handlers(void) 5691da177e4SLinus Torvalds { 5701da177e4SLinus Torvalds size_t i; 5711da177e4SLinus Torvalds 5721da177e4SLinus Torvalds for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++) 5731da177e4SLinus Torvalds cdl_register_subpacket_annotation(&el_titan_annotations[i]); 5741da177e4SLinus Torvalds 5751da177e4SLinus Torvalds cdl_register_subpacket_handler(&titan_subpacket_handler); 5761da177e4SLinus Torvalds 5771da177e4SLinus Torvalds ev6_register_error_handlers(); 5781da177e4SLinus Torvalds } 5791da177e4SLinus Torvalds 5801da177e4SLinus Torvalds 5811da177e4SLinus Torvalds /* 5821da177e4SLinus Torvalds * Privateer 5831da177e4SLinus Torvalds */ 5841da177e4SLinus Torvalds 5851da177e4SLinus Torvalds static int 5861da177e4SLinus Torvalds privateer_process_680_frame(struct el_common *mchk_header, int print) 5871da177e4SLinus Torvalds { 5881da177e4SLinus Torvalds int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 5891da177e4SLinus Torvalds #ifdef CONFIG_VERBOSE_MCHECK 5901da177e4SLinus Torvalds struct el_PRIVATEER_envdata_mcheck *emchk = 5911da177e4SLinus Torvalds (struct el_PRIVATEER_envdata_mcheck *) 5921da177e4SLinus Torvalds ((unsigned long)mchk_header + mchk_header->sys_offset); 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds /* TODO - catagorize errors, for now, no error */ 5951da177e4SLinus Torvalds 5961da177e4SLinus Torvalds if (!print) 5971da177e4SLinus Torvalds return status; 5981da177e4SLinus Torvalds 5991da177e4SLinus Torvalds /* TODO - decode instead of just dumping... */ 6001da177e4SLinus Torvalds printk("%s Summary Flags: %016lx\n" 6011da177e4SLinus Torvalds " CChip DIRx: %016lx\n" 6021da177e4SLinus Torvalds " System Management IR: %016lx\n" 6031da177e4SLinus Torvalds " CPU IR: %016lx\n" 6041da177e4SLinus Torvalds " Power Supply IR: %016lx\n" 6051da177e4SLinus Torvalds " LM78 Fault Status: %016lx\n" 6061da177e4SLinus Torvalds " System Doors: %016lx\n" 6071da177e4SLinus Torvalds " Temperature Warning: %016lx\n" 6081da177e4SLinus Torvalds " Fan Control: %016lx\n" 6091da177e4SLinus Torvalds " Fatal Power Down Code: %016lx\n", 6101da177e4SLinus Torvalds err_print_prefix, 6111da177e4SLinus Torvalds emchk->summary, 6121da177e4SLinus Torvalds emchk->c_dirx, 6131da177e4SLinus Torvalds emchk->smir, 6141da177e4SLinus Torvalds emchk->cpuir, 6151da177e4SLinus Torvalds emchk->psir, 6161da177e4SLinus Torvalds emchk->fault, 6171da177e4SLinus Torvalds emchk->sys_doors, 6181da177e4SLinus Torvalds emchk->temp_warn, 6191da177e4SLinus Torvalds emchk->fan_ctrl, 6201da177e4SLinus Torvalds emchk->code); 6211da177e4SLinus Torvalds #endif /* CONFIG_VERBOSE_MCHECK */ 6221da177e4SLinus Torvalds 6231da177e4SLinus Torvalds return status; 6241da177e4SLinus Torvalds } 6251da177e4SLinus Torvalds 6261da177e4SLinus Torvalds int 6271da177e4SLinus Torvalds privateer_process_logout_frame(struct el_common *mchk_header, int print) 6281da177e4SLinus Torvalds { 6291da177e4SLinus Torvalds struct el_common_EV6_mcheck *ev6mchk = 6301da177e4SLinus Torvalds (struct el_common_EV6_mcheck *)mchk_header; 6311da177e4SLinus Torvalds int status = MCHK_DISPOSITION_UNKNOWN_ERROR; 6321da177e4SLinus Torvalds 6331da177e4SLinus Torvalds /* 6341da177e4SLinus Torvalds * Machine check codes 6351da177e4SLinus Torvalds */ 6361da177e4SLinus Torvalds #define PRIVATEER_MCHK__CORR_ECC 0x86 /* 630 */ 6371da177e4SLinus Torvalds #define PRIVATEER_MCHK__DC_TAG_PERR 0x9E /* 630 */ 6381da177e4SLinus Torvalds #define PRIVATEER_MCHK__PAL_BUGCHECK 0x8E /* 670 */ 6391da177e4SLinus Torvalds #define PRIVATEER_MCHK__OS_BUGCHECK 0x90 /* 670 */ 6401da177e4SLinus Torvalds #define PRIVATEER_MCHK__PROC_HRD_ERR 0x98 /* 670 */ 6411da177e4SLinus Torvalds #define PRIVATEER_MCHK__ISTREAM_CMOV_PRX 0xA0 /* 670 */ 6421da177e4SLinus Torvalds #define PRIVATEER_MCHK__ISTREAM_CMOV_FLT 0xA2 /* 670 */ 6431da177e4SLinus Torvalds #define PRIVATEER_MCHK__SYS_HRD_ERR 0x202 /* 660 */ 6441da177e4SLinus Torvalds #define PRIVATEER_MCHK__SYS_CORR_ERR 0x204 /* 620 */ 6451da177e4SLinus Torvalds #define PRIVATEER_MCHK__SYS_ENVIRON 0x206 /* 680 */ 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds switch(ev6mchk->MCHK_Code) { 6481da177e4SLinus Torvalds /* 6491da177e4SLinus Torvalds * Vector 630 - Processor, Correctable 6501da177e4SLinus Torvalds */ 6511da177e4SLinus Torvalds case PRIVATEER_MCHK__CORR_ECC: 6521da177e4SLinus Torvalds case PRIVATEER_MCHK__DC_TAG_PERR: 6531da177e4SLinus Torvalds /* 6541da177e4SLinus Torvalds * Fall through to vector 670 for processing... 6551da177e4SLinus Torvalds */ 6561da177e4SLinus Torvalds /* 6571da177e4SLinus Torvalds * Vector 670 - Processor, Uncorrectable 6581da177e4SLinus Torvalds */ 6591da177e4SLinus Torvalds case PRIVATEER_MCHK__PAL_BUGCHECK: 6601da177e4SLinus Torvalds case PRIVATEER_MCHK__OS_BUGCHECK: 6611da177e4SLinus Torvalds case PRIVATEER_MCHK__PROC_HRD_ERR: 6621da177e4SLinus Torvalds case PRIVATEER_MCHK__ISTREAM_CMOV_PRX: 6631da177e4SLinus Torvalds case PRIVATEER_MCHK__ISTREAM_CMOV_FLT: 6641da177e4SLinus Torvalds status |= ev6_process_logout_frame(mchk_header, print); 6651da177e4SLinus Torvalds break; 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds /* 6681da177e4SLinus Torvalds * Vector 620 - System, Correctable 6691da177e4SLinus Torvalds */ 6701da177e4SLinus Torvalds case PRIVATEER_MCHK__SYS_CORR_ERR: 6711da177e4SLinus Torvalds /* 6721da177e4SLinus Torvalds * Fall through to vector 660 for processing... 6731da177e4SLinus Torvalds */ 6741da177e4SLinus Torvalds /* 6751da177e4SLinus Torvalds * Vector 660 - System, Uncorrectable 6761da177e4SLinus Torvalds */ 6771da177e4SLinus Torvalds case PRIVATEER_MCHK__SYS_HRD_ERR: 6781da177e4SLinus Torvalds status |= titan_process_logout_frame(mchk_header, print); 6791da177e4SLinus Torvalds break; 6801da177e4SLinus Torvalds 6811da177e4SLinus Torvalds /* 6821da177e4SLinus Torvalds * Vector 680 - System, Environmental 6831da177e4SLinus Torvalds */ 6841da177e4SLinus Torvalds case PRIVATEER_MCHK__SYS_ENVIRON: /* System, Environmental */ 6851da177e4SLinus Torvalds status |= privateer_process_680_frame(mchk_header, print); 6861da177e4SLinus Torvalds break; 6871da177e4SLinus Torvalds 6881da177e4SLinus Torvalds /* 6891da177e4SLinus Torvalds * Unknown 6901da177e4SLinus Torvalds */ 6911da177e4SLinus Torvalds default: 6921da177e4SLinus Torvalds status |= MCHK_DISPOSITION_REPORT; 6931da177e4SLinus Torvalds if (print) { 6941da177e4SLinus Torvalds printk("%s** Unknown Error, frame follows\n", 6951da177e4SLinus Torvalds err_print_prefix); 6961da177e4SLinus Torvalds mchk_dump_logout_frame(mchk_header); 6971da177e4SLinus Torvalds } 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds } 7001da177e4SLinus Torvalds 7011da177e4SLinus Torvalds return status; 7021da177e4SLinus Torvalds } 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds void 7054fa1970aSAl Viro privateer_machine_check(u64 vector, u64 la_ptr) 7061da177e4SLinus Torvalds { 7071da177e4SLinus Torvalds struct el_common *mchk_header = (struct el_common *)la_ptr; 7081da177e4SLinus Torvalds struct el_TITAN_sysdata_mcheck *tmchk = 7091da177e4SLinus Torvalds (struct el_TITAN_sysdata_mcheck *) 7101da177e4SLinus Torvalds (la_ptr + mchk_header->sys_offset); 7111da177e4SLinus Torvalds u64 irqmask; 7121da177e4SLinus Torvalds char *saved_err_prefix = err_print_prefix; 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds #define PRIVATEER_680_INTERRUPT_MASK (0xE00UL) 7151da177e4SLinus Torvalds #define PRIVATEER_HOTPLUG_INTERRUPT_MASK (0xE00UL) 7161da177e4SLinus Torvalds 7171da177e4SLinus Torvalds /* 7181da177e4SLinus Torvalds * Sync the processor. 7191da177e4SLinus Torvalds */ 7201da177e4SLinus Torvalds mb(); 7211da177e4SLinus Torvalds draina(); 7221da177e4SLinus Torvalds 7231da177e4SLinus Torvalds /* 7241da177e4SLinus Torvalds * Only handle system events here. 7251da177e4SLinus Torvalds */ 7261da177e4SLinus Torvalds if (vector != SCB_Q_SYSEVENT) 7274fa1970aSAl Viro return titan_machine_check(vector, la_ptr); 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds /* 7301da177e4SLinus Torvalds * Report the event - System Events should be reported even if no 7311da177e4SLinus Torvalds * error is indicated since the event could indicate the return 7321da177e4SLinus Torvalds * to normal status. 7331da177e4SLinus Torvalds */ 7341da177e4SLinus Torvalds err_print_prefix = KERN_CRIT; 7351da177e4SLinus Torvalds printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n", 7361da177e4SLinus Torvalds err_print_prefix, 7371da177e4SLinus Torvalds (unsigned int)vector, (int)smp_processor_id()); 7381da177e4SLinus Torvalds privateer_process_680_frame(mchk_header, 1); 7391da177e4SLinus Torvalds err_print_prefix = saved_err_prefix; 7401da177e4SLinus Torvalds 7411da177e4SLinus Torvalds /* 7421da177e4SLinus Torvalds * Convert any pending interrupts which report as 680 machine 7431da177e4SLinus Torvalds * checks to interrupts. 7441da177e4SLinus Torvalds */ 7451da177e4SLinus Torvalds irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK; 7461da177e4SLinus Torvalds 7471da177e4SLinus Torvalds /* 7481da177e4SLinus Torvalds * Dispatch the interrupt(s). 7491da177e4SLinus Torvalds */ 7502f116cbfSAl Viro titan_dispatch_irqs(irqmask); 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds /* 7531da177e4SLinus Torvalds * Release the logout frame. 7541da177e4SLinus Torvalds */ 7551da177e4SLinus Torvalds wrmces(0x7); 7561da177e4SLinus Torvalds mb(); 7571da177e4SLinus Torvalds } 758