- Peter Anvin: more P4 configuration parsing
[davej-history.git] / arch / i386 / kernel / bluesmoke.c
blob59826db68388802b135424f533bb9001706b60f8
1 /*
2 * Machine Check Handler For PII/PIII
3 */
5 #include <linux/types.h>
6 #include <linux/kernel.h>
7 #include <linux/sched.h>
8 #include <asm/processor.h>
9 #include <asm/msr.h>
11 static int banks;
13 void do_machine_check(struct pt_regs * regs, long error_code)
15 int recover=1;
16 u32 alow, ahigh, high, low;
17 u32 mcgstl, mcgsth;
18 int i;
20 rdmsr(0x17a, mcgstl, mcgsth);
21 if(mcgstl&(1<<0)) /* Recoverable ? */
22 recover=0;
24 printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl);
26 for(i=0;i<banks;i++)
28 rdmsr(0x401+i*4,low, high);
29 if(high&(1<<31))
31 if(high&(1<<29))
32 recover|=1;
33 if(high&(1<<25))
34 recover|=2;
35 printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low);
36 high&=~(1<<31);
37 if(high&(1<<27))
39 rdmsr(0x402+i*4, alow, ahigh);
40 printk("[%08x%08x]", alow, ahigh);
42 if(high&(1<<26))
44 rdmsr(0x402+i*4, alow, ahigh);
45 printk(" at %08x%08x",
46 high, low);
48 /* Clear it */
49 wrmsr(0x401+i*4, 0UL, 0UL);
50 /* Serialize */
51 wmb();
55 if(recover&2)
56 panic("CPU context corrupt");
57 if(recover&1)
58 panic("Unable to continue");
59 printk(KERN_EMERG "Attempting to continue.\n");
60 mcgstl&=~(1<<2);
61 wrmsr(0x17a,mcgstl, mcgsth);
66 * This has to be run for each processor
69 void mcheck_init(struct cpuinfo_x86 *c)
71 u32 l, h;
72 int i;
73 static int done;
75 if( c->x86_vendor != X86_VENDOR_INTEL )
76 return;
78 if( !test_bit(X86_FEATURE_TSC, &c->x86_capability) )
79 return;
81 if( !test_bit(X86_FEATURE_MCA, &c->x86_capability) )
82 return;
84 /* Ok machine check is available */
86 if(done==0)
87 printk(KERN_INFO "Intel machine check architecture supported.\n");
88 rdmsr(0x179, l, h);
89 if(l&(1<<8))
90 wrmsr(0x17b, 0xffffffff, 0xffffffff);
91 banks = l&0xff;
92 for(i=1;i<banks;i++)
94 wrmsr(0x400+4*i, 0xffffffff, 0xffffffff);
96 for(i=0;i<banks;i++)
98 wrmsr(0x401+4*i, 0x0, 0x0);
100 __asm__ __volatile__ (
101 "movl %%cr4, %%eax\n\t"
102 "orl $0x40, %%eax\n\t"
103 "movl %%eax, %%cr4\n\t" : : : "eax");
104 printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
105 done=1;