aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/x86/kernel/apic_64.c26
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c10
-rw-r--r--include/asm-x86/apic.h4
-rw-r--r--include/asm-x86/apicdef.h19
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 */
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 }
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);
126extern void setup_apic_routing(void); 126extern void setup_apic_routing(void);
127#endif 127#endif
128 128
129extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector, 129extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask);
130 unsigned char msg_type, unsigned char mask); 130extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask);
131 131
132extern int apic_is_clustered_box(void); 132extern 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