bluesmoke.c
来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 654 行 · 第 1/2 页
C
654 行
/* * Machine check handler. * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. * Additional K8 decoding and simplification Copyright 2003 Eric Morton, Newisys Inc * Rest from unknown author(s). */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/pci.h>#include <linux/timer.h>#include <linux/notifier.h>#include <asm/bluesmoke.h>#include <asm/processor.h> #include <asm/msr.h>#include <asm/kdebug.h>#include <asm/smp.h>static int mce_disabled __initdata;static unsigned long mce_cpus; /* * Machine Check Handler For PII/PIII/K7 */static int banks;static unsigned long ignored_banks, disabled_banks;struct notifier_block *mc_notifier_list = NULL;EXPORT_SYMBOL(mc_notifier_list);static void generic_machine_check(struct pt_regs * regs, long error_code){ int recover=1; u32 alow, ahigh, high, low; u32 mcgstl, mcgsth; int i; struct notifier_mc_err mc_err; rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); if(mcgstl&(1<<0)) /* Recoverable ? */ recover=0; /* Make sure unrecoverable MCEs reach the console */ if(recover & 3) oops_in_progress++; printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); if (regs && (mcgstl & 2)) printk(KERN_EMERG "RIP <%02lx>:%016lx RSP %016lx\n", regs->cs, regs->rip, regs->rsp); for(i=0;i<banks;i++) { if ((1UL<<i) & ignored_banks) continue; rdmsr(MSR_IA32_MC0_STATUS+i*4,low, high); if(high&(1<<31)) { memset(&mc_err, 0x00, sizeof(mc_err)); mc_err.cpunum = safe_smp_processor_id(); mc_err.banknum = i; mc_err.mci_status = ((u64)high << 32) | low; if(high&(1<<29)) recover|=1; if(high&(1<<25)) recover|=2; printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low); high&=~(1<<31); if(high&(1<<27)) { rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); mc_err.mci_misc = ((u64)ahigh << 32) | alow; printk("[%08x%08x]", alow, ahigh); } if(high&(1<<26)) { rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); mc_err.mci_addr = ((u64)ahigh << 32) | alow; printk(" at %08x%08x", ahigh, alow); } rdmsr(MSR_IA32_MC0_CTL+i*4, alow, ahigh); mc_err.mci_ctl = ((u64)ahigh << 32) | alow; printk("\n"); /* Clear it */ wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); /* Serialize */ wmb(); notifier_call_chain(&mc_notifier_list, X86_VENDOR_INTEL, &mc_err); } } if(recover&2) panic("CPU context corrupt"); if(recover&1) panic("Unable to continue"); printk(KERN_EMERG "Attempting to continue.\n"); mcgstl&=~(1<<2); wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);}static void unexpected_machine_check(struct pt_regs *regs, long error_code){ printk("unexpected machine check %lx\n", error_code); } /* * Call the installed machine check handler for this CPU setup. */ static void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;void do_machine_check(struct pt_regs * regs, long error_code){ notify_die(DIE_NMI, "machine check", regs, error_code, 255, SIGKILL); machine_check_vector(regs, error_code);}/* * K8 machine check. */static char *k8bank[] = { "data cache", "instruction cache", "bus unit", "load/store unit", "northbridge"};static char *transaction[] = { "instruction", "data", "generic", "reserved"}; static char *cachelevel[] = { "0", "1", "2", "generic"};static char *memtrans[] = { "generic error", "generic read", "generic write", "data read", "data write", "instruction fetch", "prefetch", "evict", "snoop", "?", "?", "?", "?", "?", "?", "?"};static char *partproc[] = { "local node origin", "local node response", "local node observed", "generic participation"};static char *timeout[] = { "request didn't time out", "request timed out"};static char *memoryio[] = { "memory", "res.", "i/o", "generic"};static char *nbextendederr[] = { "ECC error", "CRC error", "Sync error", "Master abort", "Target abort", "GART error", "RMW error", "Watchdog error", "Chipkill ECC error", "<9>","<10>","<11>","<12>", "<13>","<14>","<15>"};static char *highbits[32] = { [31] = "valid", [30] = "error overflow (multiple errors)", [29] = "error uncorrected", [28] = "error enable", [27] = "misc error valid", [26] = "error address valid", [25] = "processor context corrupt", [24] = "res24", [23] = "res23", /* 22-15 ecc syndrome bits */ [14] = "corrected ecc error", [13] = "uncorrected ecc error", [12] = "res12", [11] = "res11", [10] = "res10", [9] = "res9", [8] = "error found by scrub", [7] = "res7", /* 6-4 ht link number of error */ [3] = "res3", [2] = "res2", [1] = "err cpu1", [0] = "err cpu0",};static void decode_k8_generic_errcode(unsigned int cpunum, u64 status){ unsigned short errcode = status & 0xffff; int i; for (i=0; i<32; i++) { if (i==31 || i==28 || i==26) continue; if (highbits[i] && (status & (1UL<<(i+32)))) { printk(KERN_ERR "CPU%d: bit%d = %s\n", cpunum, i+32, highbits[i]); } } if ((errcode & 0xFFF0) == 0x0010) { printk(KERN_ERR "CPU%d: TLB error '%s transaction, level %s'\n", cpunum, transaction[(errcode >> 2) & 3], cachelevel[errcode & 3]); } else if ((errcode & 0xFF00) == 0x0100) { printk(KERN_ERR "CPU%d: memory/cache error '%s mem transaction, %s transaction, level %s'\n", cpunum, memtrans[(errcode >> 4) & 0xf], transaction[(errcode >> 2) & 3], cachelevel[errcode & 3]); } else if ((errcode & 0xF800) == 0x0800) { printk(KERN_ERR "CPU%d: bus error '%s, %s\n %s mem transaction\n %s access, level %s'\n", cpunum, partproc[(errcode >> 9) & 0x3], timeout[(errcode >> 8) & 1], memtrans[(errcode >> 4) & 0xf], memoryio[(errcode >> 2) & 0x3], cachelevel[(errcode & 0x3)]); }}static void decode_k8_dc_mc(unsigned int cpunum, u64 status){ unsigned short exterrcode = (status >> 16) & 0x0f; unsigned short errcode = status & 0xffff; if(status&(3UL<<45)) { printk(KERN_ERR "CPU%d: Data cache ECC error (syndrome %x)", cpunum, (u32) (status >> 47) & 0xff); if(status&(1UL<<40)) { printk(" found by scrubber"); } printk("\n"); } if ((errcode & 0xFFF0) == 0x0010) { printk(KERN_ERR "CPU%d: TLB parity error in %s array\n", cpunum, (exterrcode == 0) ? "physical" : "virtual"); } decode_k8_generic_errcode(cpunum, status);}static void decode_k8_ic_mc(unsigned int cpunum, u64 status){ unsigned short exterrcode = (status >> 16) & 0x0f; unsigned short errcode = status & 0xffff; if(status&(3UL<<45)) { printk(KERN_ERR "CPU%d: Instruction cache ECC error\n", cpunum); } if ((errcode & 0xFFF0) == 0x0010) { printk(KERN_ERR "CPU%d: TLB parity error in %s array\n", cpunum, (exterrcode == 0) ? "physical" : "virtual"); } decode_k8_generic_errcode(cpunum, status);}static void decode_k8_bu_mc(unsigned int cpunum, u64 status){ unsigned short exterrcode = (status >> 16) & 0x0f; if(status&(3UL<<45)) { printk(KERN_ERR "CPU%d: L2 cache ECC error\n", cpunum); } printk(KERN_ERR "CPU%d: %s array error\n", cpunum, (exterrcode == 0) ? "Bus or cache" : "Cache tag"); decode_k8_generic_errcode(cpunum, status);}static void decode_k8_ls_mc(unsigned int cpunum, u64 status){ decode_k8_generic_errcode(cpunum, status);}static void decode_k8_nb_mc(unsigned int cpunum, u64 status){ unsigned short exterrcode = (status >> 16) & 0x0f; printk(KERN_ERR "CPU%d: Northbridge %s\n", cpunum, nbextendederr[exterrcode]); switch (exterrcode) { case 0: printk(KERN_ERR "CPU%d: ECC syndrome = %x\n", cpunum, (u32) (status >> 47) & 0xff); break; case 8: printk(KERN_ERR "CPU%d: Chipkill ECC syndrome = %x\n", cpunum, (u32) ((((status >> 24) & 0xff) << 8) | ((status >> 47) & 0xff))); break; case 1: case 2: case 3: case 4: case 6: printk(KERN_ERR "CPU%d: link number = %x\n", cpunum,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?