[PATCH] x86_64: Fix VSMP build
[linux-2.6/pdupreez.git] / arch / x86_64 / kernel / mce_intel.c
blob8f533d2c40cbdf3e25114206ee85c5362eec74c1
1 /*
2 * Intel specific MCE features.
3 * Copyright 2004 Zwane Mwaikambo <zwane@linuxpower.ca>
4 */
6 #include <linux/init.h>
7 #include <linux/interrupt.h>
8 #include <linux/percpu.h>
9 #include <asm/processor.h>
10 #include <asm/msr.h>
11 #include <asm/mce.h>
12 #include <asm/hw_irq.h>
13 #include <asm/idle.h>
15 static DEFINE_PER_CPU(unsigned long, next_check);
17 asmlinkage void smp_thermal_interrupt(void)
19 struct mce m;
21 ack_APIC_irq();
23 exit_idle();
24 irq_enter();
25 if (time_before(jiffies, __get_cpu_var(next_check)))
26 goto done;
28 __get_cpu_var(next_check) = jiffies + HZ*300;
29 memset(&m, 0, sizeof(m));
30 m.cpu = smp_processor_id();
31 m.bank = MCE_THERMAL_BANK;
32 rdtscll(m.tsc);
33 rdmsrl(MSR_IA32_THERM_STATUS, m.status);
34 if (m.status & 0x1) {
35 printk(KERN_EMERG
36 "CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu);
37 add_taint(TAINT_MACHINE_CHECK);
38 } else {
39 printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu);
42 mce_log(&m);
43 done:
44 irq_exit();
47 static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c)
49 u32 l, h;
50 int tm2 = 0;
51 unsigned int cpu = smp_processor_id();
53 if (!cpu_has(c, X86_FEATURE_ACPI))
54 return;
56 if (!cpu_has(c, X86_FEATURE_ACC))
57 return;
59 /* first check if TM1 is already enabled by the BIOS, in which
60 * case there might be some SMM goo which handles it, so we can't even
61 * put a handler since it might be delivered via SMI already.
63 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
64 h = apic_read(APIC_LVTTHMR);
65 if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
66 printk(KERN_DEBUG
67 "CPU%d: Thermal monitoring handled by SMI\n", cpu);
68 return;
71 if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
72 tm2 = 1;
74 if (h & APIC_VECTOR_MASK) {
75 printk(KERN_DEBUG
76 "CPU%d: Thermal LVT vector (%#x) already "
77 "installed\n", cpu, (h & APIC_VECTOR_MASK));
78 return;
81 h = THERMAL_APIC_VECTOR;
82 h |= (APIC_DM_FIXED | APIC_LVT_MASKED);
83 apic_write(APIC_LVTTHMR, h);
85 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
86 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
88 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
89 wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
91 l = apic_read(APIC_LVTTHMR);
92 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
93 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
94 cpu, tm2 ? "TM2" : "TM1");
95 return;
98 void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c)
100 intel_init_thermal(c);