aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2008-01-30 07:30:40 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:30:40 -0500
commit7b83dae7aa31db4f6d6e78c3c6d490a7ac58699c (patch)
tree58196045602928d11c2688eda321738eab1dc8bc /arch/x86/kernel
parent739f33b38bf88312447e38ae8b7ac3acdbb72a6b (diff)
x86: extended interrupt LVT support for AMD Barcelona
Also macro definitions in apicdef.h has been updated. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/apic_64.c26
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c10
2 files changed, 27 insertions, 9 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 */
192void 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
199static 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
207u8 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
213u8 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 }