2 * Common code for Intel machine checks
4 #include <linux/interrupt.h>
5 #include <linux/kernel.h>
6 #include <linux/types.h>
7 #include <linux/init.h>
10 #include <asm/therm_throt.h>
11 #include <asm/processor.h>
12 #include <asm/system.h>
18 void intel_init_thermal(struct cpuinfo_x86
*c
)
20 unsigned int cpu
= smp_processor_id();
24 /* Thermal monitoring depends on ACPI and clock modulation*/
25 if (!cpu_has(c
, X86_FEATURE_ACPI
) || !cpu_has(c
, X86_FEATURE_ACC
))
29 * First check if its enabled already, in which case there might
30 * be some SMM goo which handles it, so we can't even put a handler
31 * since it might be delivered via SMI already:
33 rdmsr(MSR_IA32_MISC_ENABLE
, l
, h
);
34 h
= apic_read(APIC_LVTTHMR
);
35 if ((l
& MSR_IA32_MISC_ENABLE_TM1
) && (h
& APIC_DM_SMI
)) {
37 "CPU%d: Thermal monitoring handled by SMI\n", cpu
);
41 if (cpu_has(c
, X86_FEATURE_TM2
) && (l
& MSR_IA32_MISC_ENABLE_TM2
))
44 /* Check whether a vector already exists */
45 if (h
& APIC_VECTOR_MASK
) {
47 "CPU%d: Thermal LVT vector (%#x) already installed\n",
48 cpu
, (h
& APIC_VECTOR_MASK
));
52 /* We'll mask the thermal vector in the lapic till we're ready: */
53 h
= THERMAL_APIC_VECTOR
| APIC_DM_FIXED
| APIC_LVT_MASKED
;
54 apic_write(APIC_LVTTHMR
, h
);
56 rdmsr(MSR_IA32_THERM_INTERRUPT
, l
, h
);
57 wrmsr(MSR_IA32_THERM_INTERRUPT
,
58 l
| (THERM_INT_LOW_ENABLE
| THERM_INT_HIGH_ENABLE
), h
);
60 intel_set_thermal_handler();
62 rdmsr(MSR_IA32_MISC_ENABLE
, l
, h
);
63 wrmsr(MSR_IA32_MISC_ENABLE
, l
| MSR_IA32_MISC_ENABLE_TM1
, h
);
65 /* Unmask the thermal vector: */
66 l
= apic_read(APIC_LVTTHMR
);
67 apic_write(APIC_LVTTHMR
, l
& ~APIC_LVT_MASKED
);
69 printk(KERN_INFO
"CPU%d: Thermal monitoring enabled (%s)\n",
70 cpu
, tm2
? "TM2" : "TM1");
72 /* enable thermal throttle processing */
73 atomic_set(&therm_throt_en
, 1);