#include #include #include #include #include #include static int mce_disabled __initdata = 0; /* * Machine Check Handler For PII/PIII */ static int banks; static void intel_machine_check(struct pt_regs * regs, long error_code) { int recover=1; u32 alow, ahigh, high, low; u32 mcgstl, mcgsth; int i; rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); if(mcgstl&(1<<0)) /* Recoverable ? */ recover=0; printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); for(i=0;ix86_capability) ) return; /* * Pentium machine check */ if(c->x86 == 5) { /* Default P5 to off as its often misconnected */ if(mce_disabled != -1) return; machine_check_vector = pentium_machine_check; wmb(); /* Read registers before enabling */ rdmsr(MSR_IA32_P5_MC_ADDR, l, h); rdmsr(MSR_IA32_P5_MC_TYPE, l, h); if(done==0) printk(KERN_INFO "Intel old style machine check architecture supported.\n"); /* Enable MCE */ set_in_cr4(X86_CR4_MCE); printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id()); return; } /* * Check for PPro style MCA */ if( !test_bit(X86_FEATURE_MCA, &c->x86_capability) ) return; /* Ok machine check is available */ machine_check_vector = intel_machine_check; wmb(); if(done==0) printk(KERN_INFO "Intel machine check architecture supported.\n"); rdmsr(MSR_IA32_MCG_CAP, l, h); if(l&(1<<8)) wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); banks = l&0xff; for(i=1;ix86 != 5) return; /* Winchip C6 */ machine_check_vector = winchip_machine_check; wmb(); rdmsr(MSR_IDT_FCR1, lo, hi); lo|= (1<<2); /* Enable EIERRINT (int 18 MCE) */ lo&= ~(1<<4); /* Enable MCE */ wrmsr(MSR_IDT_FCR1, lo, hi); set_in_cr4(X86_CR4_MCE); printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id()); } /* * This has to be run for each processor */ void __init mcheck_init(struct cpuinfo_x86 *c) { if(mce_disabled==1) return; switch(c->x86_vendor) { case X86_VENDOR_AMD: /* * AMD K7 machine check is Intel like */ if(c->x86 == 6) intel_mcheck_init(c); break; case X86_VENDOR_INTEL: intel_mcheck_init(c); break; case X86_VENDOR_CENTAUR: winchip_mcheck_init(c); break; default: break; } } static int __init mcheck_disable(char *str) { mce_disabled = 1; return 0; } static int __init mcheck_enable(char *str) { mce_disabled = -1; return 0; } __setup("nomce", mcheck_disable); __setup("mce", mcheck_enable);