aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-04-08 06:31:23 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-05-28 12:24:10 -0400
commita65d086235208a3b3546e209d2210048549099b2 (patch)
tree73a402994453de2e1c977826b163d4999b74226a
parent6cc6f3ebd19fea722c19630af5ad68af7f51d493 (diff)
x86, mce: unify Intel thermal init
Mechanic unification. No change in code. [ Impact: cleanup, 32-bit / 64-bit unification ] Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/kernel/cpu/mcheck/Makefile3
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.h11
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c73
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel_64.c61
-rw-r--r--arch/x86/kernel/cpu/mcheck/p4.c59
5 files changed, 89 insertions, 118 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile
index b2f89829bbe8..6def76942bf2 100644
--- a/arch/x86/kernel/cpu/mcheck/Makefile
+++ b/arch/x86/kernel/cpu/mcheck/Makefile
@@ -1,7 +1,8 @@
1obj-y = mce_$(BITS).o therm_throt.o 1obj-y = mce_$(BITS).o therm_throt.o
2 2
3obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o 3obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o
4obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o 4obj-$(CONFIG_X86_MCE_P4THERMAL) += mce_intel.o
5obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o mce_intel.o
5obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o 6obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o
6obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o 7obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o
7obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o 8obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
diff --git a/arch/x86/kernel/cpu/mcheck/mce.h b/arch/x86/kernel/cpu/mcheck/mce.h
index ae9f628838f1..2d1a54bdadfc 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.h
+++ b/arch/x86/kernel/cpu/mcheck/mce.h
@@ -1,6 +1,8 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <asm/mce.h> 2#include <asm/mce.h>
3 3
4#ifdef CONFIG_X86_32
5
4void amd_mcheck_init(struct cpuinfo_x86 *c); 6void amd_mcheck_init(struct cpuinfo_x86 *c);
5void intel_p4_mcheck_init(struct cpuinfo_x86 *c); 7void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
6void intel_p5_mcheck_init(struct cpuinfo_x86 *c); 8void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
@@ -12,3 +14,12 @@ extern void (*machine_check_vector)(struct pt_regs *, long error_code);
12 14
13extern int nr_mce_banks; 15extern int nr_mce_banks;
14 16
17void intel_set_thermal_handler(void);
18
19#else
20
21static inline void intel_set_thermal_handler(void) { }
22
23#endif
24
25void intel_init_thermal(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
new file mode 100644
index 000000000000..bad3cbb0e566
--- /dev/null
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -0,0 +1,73 @@
1/*
2 * Common code for Intel machine checks
3 */
4#include <linux/interrupt.h>
5#include <linux/kernel.h>
6#include <linux/types.h>
7#include <linux/init.h>
8#include <linux/smp.h>
9
10#include <asm/therm_throt.h>
11#include <asm/processor.h>
12#include <asm/system.h>
13#include <asm/apic.h>
14#include <asm/msr.h>
15
16#include "mce.h"
17
18void intel_init_thermal(struct cpuinfo_x86 *c)
19{
20 unsigned int cpu = smp_processor_id();
21 int tm2 = 0;
22 u32 l, h;
23
24 /* Thermal monitoring depends on ACPI and clock modulation*/
25 if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
26 return;
27
28 /*
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:
32 */
33 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
34 h = apic_read(APIC_LVTTHMR);
35 if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
36 printk(KERN_DEBUG
37 "CPU%d: Thermal monitoring handled by SMI\n", cpu);
38 return;
39 }
40
41 if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
42 tm2 = 1;
43
44 /* Check whether a vector already exists */
45 if (h & APIC_VECTOR_MASK) {
46 printk(KERN_DEBUG
47 "CPU%d: Thermal LVT vector (%#x) already installed\n",
48 cpu, (h & APIC_VECTOR_MASK));
49 return;
50 }
51
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);
55
56 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
57 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
58
59 intel_set_thermal_handler();
60
61 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
62 wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
63
64 /* Unmask the thermal vector: */
65 l = apic_read(APIC_LVTTHMR);
66 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
67
68 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
69 cpu, tm2 ? "TM2" : "TM1");
70
71 /* enable thermal throttle processing */
72 atomic_set(&therm_throt_en, 1);
73}
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index b85d0c107c84..38f9632306fa 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -17,6 +17,8 @@
17#include <asm/therm_throt.h> 17#include <asm/therm_throt.h>
18#include <asm/apic.h> 18#include <asm/apic.h>
19 19
20#include "mce.h"
21
20asmlinkage void smp_thermal_interrupt(void) 22asmlinkage void smp_thermal_interrupt(void)
21{ 23{
22 __u64 msr_val; 24 __u64 msr_val;
@@ -34,65 +36,6 @@ asmlinkage void smp_thermal_interrupt(void)
34 irq_exit(); 36 irq_exit();
35} 37}
36 38
37static inline void intel_set_thermal_handler(void) { }
38
39static void intel_init_thermal(struct cpuinfo_x86 *c)
40{
41 unsigned int cpu = smp_processor_id();
42 int tm2 = 0;
43 u32 l, h;
44
45 /* Thermal monitoring depends on ACPI and clock modulation*/
46 if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
47 return;
48
49 /*
50 * First check if its enabled already, in which case there might
51 * be some SMM goo which handles it, so we can't even put a handler
52 * since it might be delivered via SMI already:
53 */
54 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
55 h = apic_read(APIC_LVTTHMR);
56 if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
57 printk(KERN_DEBUG
58 "CPU%d: Thermal monitoring handled by SMI\n", cpu);
59 return;
60 }
61
62 if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
63 tm2 = 1;
64
65 /* Check whether a vector already exists */
66 if (h & APIC_VECTOR_MASK) {
67 printk(KERN_DEBUG
68 "CPU%d: Thermal LVT vector (%#x) already installed\n",
69 cpu, (h & APIC_VECTOR_MASK));
70 return;
71 }
72
73 /* We'll mask the thermal vector in the lapic till we're ready: */
74 h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
75 apic_write(APIC_LVTTHMR, h);
76
77 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
78 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
79
80 intel_set_thermal_handler();
81
82 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
83 wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
84
85 /* Unmask the thermal vector: */
86 l = apic_read(APIC_LVTTHMR);
87 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
88
89 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
90 cpu, tm2 ? "TM2" : "TM1");
91
92 /* enable thermal throttle processing */
93 atomic_set(&therm_throt_en, 1);
94}
95
96/* 39/*
97 * Support for Intel Correct Machine Check Interrupts. This allows 40 * Support for Intel Correct Machine Check Interrupts. This allows
98 * the CPU to raise an interrupt when a corrected machine check happened. 41 * the CPU to raise an interrupt when a corrected machine check happened.
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
index f70753a443bb..f979ffea330b 100644
--- a/arch/x86/kernel/cpu/mcheck/p4.c
+++ b/arch/x86/kernel/cpu/mcheck/p4.c
@@ -66,68 +66,11 @@ void smp_thermal_interrupt(struct pt_regs *regs)
66 irq_exit(); 66 irq_exit();
67} 67}
68 68
69static void intel_set_thermal_handler(void) 69void intel_set_thermal_handler(void)
70{ 70{
71 vendor_thermal_interrupt = intel_thermal_interrupt; 71 vendor_thermal_interrupt = intel_thermal_interrupt;
72} 72}
73 73
74/* P4/Xeon Thermal regulation detect and init: */
75static void intel_init_thermal(struct cpuinfo_x86 *c)
76{
77 unsigned int cpu = smp_processor_id();
78 int tm2 = 0;
79 u32 l, h;
80
81 /* Thermal monitoring depends on ACPI and clock modulation*/
82 if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC))
83 return;
84
85 /*
86 * First check if its enabled already, in which case there might
87 * be some SMM goo which handles it, so we can't even put a handler
88 * since it might be delivered via SMI already:
89 */
90 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
91 h = apic_read(APIC_LVTTHMR);
92 if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
93 printk(KERN_DEBUG
94 "CPU%d: Thermal monitoring handled by SMI\n", cpu);
95 return;
96 }
97
98 if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
99 tm2 = 1;
100
101 /* Check whether a vector already exists */
102 if (h & APIC_VECTOR_MASK) {
103 printk(KERN_DEBUG
104 "CPU%d: Thermal LVT vector (%#x) already installed\n",
105 cpu, (h & APIC_VECTOR_MASK));
106 return;
107 }
108
109 /* We'll mask the thermal vector in the lapic till we're ready: */
110 h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
111 apic_write(APIC_LVTTHMR, h);
112
113 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
114 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
115
116 intel_set_thermal_handler();
117
118 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
119 wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
120
121 /* Unmask the thermal vector: */
122 l = apic_read(APIC_LVTTHMR);
123 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
124
125 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
126 cpu, tm2 ? "TM2" : "TM1");
127
128 /* enable thermal throttle processing */
129 atomic_set(&therm_throt_en, 1);
130}
131#endif /* CONFIG_X86_MCE_P4THERMAL */ 74#endif /* CONFIG_X86_MCE_P4THERMAL */
132 75
133/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */ 76/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */