This is forwardport of Alan's 2.2.17/18 Machine Check Architecture support for PII/PIII. It's based on 2.2.18p6. Works ok on mine Mendocino. -- Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
--- linux-2.4.0-test8/arch/i386/kernel/Makefile Sat Aug 26 00:01:34 2000 +++ linux/arch/i386/kernel/Makefile Thu Sep 14 20:17:09 2000 @@ -18,7 +18,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o + pci-dma.o i386_ksyms.o i387.o bluesmoke.o ifdef CONFIG_PCI --- linux-2.4.0-test8/arch/i386/kernel/bluesmoke.c Thu Sep 14 20:27:41 2000 +++ linux/arch/i386/kernel/bluesmoke.c Thu Sep 14 20:13:11 2000 @@ -0,0 +1,110 @@ +/* + * Machine Check Handler For PII/PIII + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <asm/processor.h> +#include <asm/msr.h> + +static int banks = 0; + +void mcheck_fault(void) +{ + int recover=1; + u32 alow, ahigh, high, low; + u32 mcgstl, mcgsth; + int i; + + rdmsr(0x17a, 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;i<banks;i++) + { + rdmsr(0x401+i*4,low, high); + if(high&(1<<31)) + { + 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(0x402+i*4, alow, ahigh); + printk("[%08x%08x]", alow, ahigh); + } + if(high&(1<<26)) + { + rdmsr(0x402+i*4, alow, ahigh); + printk(" at %08x%08x", + high, low); + } + /* Clear it */ + wrmsr(0x401+i*4, 0UL, 0UL); + /* Serialize */ + wmb(); + } + } + + 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(0x17a,mcgstl, mcgsth); +} + + +/* + * This has to be run for each processor + */ + +void mcheck_init(void) +{ + u32 l, h; + int i; + struct cpuinfo_x86 *c; + static int done=0; + + c=cpu_data+smp_processor_id(); + + if(c->x86_vendor!=X86_VENDOR_INTEL) + return; + + if(!(c->x86_capability&X86_FEATURE_MCE)) + return; + + if(!(c->x86_capability&X86_FEATURE_MCA)) + return; + + /* Ok machine check is available */ + + if(done==0) + printk(KERN_INFO "Intel machine check architecture supported.\n"); + rdmsr(0x179, l, h); + if(l&(1<<8)) + wrmsr(0x17b, 0xffffffff, 0xffffffff); + banks = l&0xff; + for(i=1;i<banks;i++) + { + wrmsr(0x400+4*i, 0xffffffff, 0xffffffff); + } + for(i=0;i<banks;i++) + { + wrmsr(0x401+4*i, 0x0, 0x0); + } + __asm__ __volatile__ ( + "movl %%cr4, %%eax\n\t" + "orl $0x40, %%eax\n\t" + "movl %%eax, %%cr4\n\t" : : : "eax"); + printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", +smp_processor_id()); + done=1; +} --- linux-2.4.0-test8/arch/i386/kernel/entry.S Sat Aug 26 00:09:04 2000 +++ linux/arch/i386/kernel/entry.S Thu Sep 14 20:21:17 2000 @@ -414,6 +414,11 @@ pushl $ SYMBOL_NAME(do_page_fault) jmp error_code +ENTRY(machine_check) + pushl $0 + pushl $ SYMBOL_NAME(mcheck_fault) + jmp error_code + ENTRY(spurious_interrupt_bug) pushl $0 pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) --- linux-2.4.0-test8/arch/i386/kernel/setup.c Sun Sep 10 12:54:35 2000 +++ linux/arch/i386/kernel/setup.c Thu Sep 14 20:26:09 2000 @@ -1439,6 +1439,7 @@ { int i=0; char *p = NULL; + extern void mcheck_init(void); c->loops_per_sec = loops_per_sec; c->x86_cache_size = -1; @@ -1475,9 +1476,10 @@ return; case X86_VENDOR_INTEL: - + squash_the_stupid_serial_number(c); - + mcheck_init(); + if (c->cpuid_level > 1) { /* supports eax=2 call */ int edx, dummy;