diff options
-rw-r--r-- | arch/x86/kernel/apic_64.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 10 | ||||
-rw-r--r-- | include/asm-x86/apic.h | 4 | ||||
-rw-r--r-- | include/asm-x86/apicdef.h | 19 |
4 files changed, 41 insertions, 18 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index d341f798255c..027004262105 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -187,17 +187,35 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | /* | 189 | /* |
190 | * Setup extended LVT (K8 specific) | 190 | * Setup extended LVT, AMD specific (K8, family 10h) |
191 | * | ||
192 | * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and | ||
193 | * MCE interrupts are supported. Thus MCE offset must be set to 0. | ||
191 | */ | 194 | */ |
192 | void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, | 195 | |
193 | unsigned char msg_type, unsigned char mask) | 196 | #define APIC_EILVT_LVTOFF_MCE 0 |
197 | #define APIC_EILVT_LVTOFF_IBS 1 | ||
198 | |||
199 | static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask) | ||
194 | { | 200 | { |
195 | unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE; | 201 | unsigned long reg = (lvt_off << 4) + APIC_EILVT0; |
196 | unsigned int v = (mask << 16) | (msg_type << 8) | vector; | 202 | unsigned int v = (mask << 16) | (msg_type << 8) | vector; |
197 | 203 | ||
198 | apic_write(reg, v); | 204 | apic_write(reg, v); |
199 | } | 205 | } |
200 | 206 | ||
207 | u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask) | ||
208 | { | ||
209 | setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask); | ||
210 | return APIC_EILVT_LVTOFF_MCE; | ||
211 | } | ||
212 | |||
213 | u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask) | ||
214 | { | ||
215 | setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); | ||
216 | return APIC_EILVT_LVTOFF_IBS; | ||
217 | } | ||
218 | |||
201 | /* | 219 | /* |
202 | * Program the next event, relative to now | 220 | * Program the next event, relative to now |
203 | */ | 221 | */ |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 073afa7dd89a..550502596ca3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -118,6 +118,7 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
118 | { | 118 | { |
119 | unsigned int bank, block; | 119 | unsigned int bank, block; |
120 | unsigned int cpu = smp_processor_id(); | 120 | unsigned int cpu = smp_processor_id(); |
121 | u8 lvt_off; | ||
121 | u32 low = 0, high = 0, address = 0; | 122 | u32 low = 0, high = 0, address = 0; |
122 | 123 | ||
123 | for (bank = 0; bank < NR_BANKS; ++bank) { | 124 | for (bank = 0; bank < NR_BANKS; ++bank) { |
@@ -153,14 +154,13 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
153 | if (shared_bank[bank] && c->cpu_core_id) | 154 | if (shared_bank[bank] && c->cpu_core_id) |
154 | break; | 155 | break; |
155 | #endif | 156 | #endif |
157 | lvt_off = setup_APIC_eilvt_mce(THRESHOLD_APIC_VECTOR, | ||
158 | APIC_EILVT_MSG_FIX, 0); | ||
159 | |||
156 | high &= ~MASK_LVTOFF_HI; | 160 | high &= ~MASK_LVTOFF_HI; |
157 | high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; | 161 | high |= lvt_off << 20; |
158 | wrmsr(address, low, high); | 162 | wrmsr(address, low, high); |
159 | 163 | ||
160 | setup_APIC_extended_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, | ||
161 | THRESHOLD_APIC_VECTOR, | ||
162 | K8_APIC_EXT_INT_MSG_FIX, 0); | ||
163 | |||
164 | threshold_defaults.address = address; | 164 | threshold_defaults.address = address; |
165 | threshold_restart_bank(&threshold_defaults, 0, 0); | 165 | threshold_restart_bank(&threshold_defaults, 0, 0); |
166 | } | 166 | } |
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 5e8192d36e5a..423022759cb2 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h | |||
@@ -126,8 +126,8 @@ extern void enable_NMI_through_LVT0(void *dummy); | |||
126 | extern void setup_apic_routing(void); | 126 | extern void setup_apic_routing(void); |
127 | #endif | 127 | #endif |
128 | 128 | ||
129 | extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, | 129 | extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); |
130 | unsigned char msg_type, unsigned char mask); | 130 | extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask); |
131 | 131 | ||
132 | extern int apic_is_clustered_box(void); | 132 | extern int apic_is_clustered_box(void); |
133 | 133 | ||
diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 5f7abe9b5f87..550af7a6f88e 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h | |||
@@ -116,13 +116,18 @@ | |||
116 | #define APIC_TDR_DIV_32 0x8 | 116 | #define APIC_TDR_DIV_32 0x8 |
117 | #define APIC_TDR_DIV_64 0x9 | 117 | #define APIC_TDR_DIV_64 0x9 |
118 | #define APIC_TDR_DIV_128 0xA | 118 | #define APIC_TDR_DIV_128 0xA |
119 | 119 | #define APIC_EILVT0 0x500 | |
120 | #define K8_APIC_EXT_LVT_BASE 0x500 | 120 | #define APIC_EILVT_NR_AMD_K8 1 /* Number of extended interrupts */ |
121 | #define K8_APIC_EXT_INT_MSG_FIX 0x0 | 121 | #define APIC_EILVT_NR_AMD_10H 4 |
122 | #define K8_APIC_EXT_INT_MSG_SMI 0x2 | 122 | #define APIC_EILVT_LVTOFF(x) (((x)>>4)&0xF) |
123 | #define K8_APIC_EXT_INT_MSG_NMI 0x4 | 123 | #define APIC_EILVT_MSG_FIX 0x0 |
124 | #define K8_APIC_EXT_INT_MSG_EXT 0x7 | 124 | #define APIC_EILVT_MSG_SMI 0x2 |
125 | #define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0 | 125 | #define APIC_EILVT_MSG_NMI 0x4 |
126 | #define APIC_EILVT_MSG_EXT 0x7 | ||
127 | #define APIC_EILVT_MASKED (1<<16) | ||
128 | #define APIC_EILVT1 0x510 | ||
129 | #define APIC_EILVT2 0x520 | ||
130 | #define APIC_EILVT3 0x530 | ||
126 | 131 | ||
127 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) | 132 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) |
128 | 133 | ||