aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/apic.c')
-rw-r--r--arch/i386/kernel/apic.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index cf45bed96d08..93df90bbb87e 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -211,7 +211,7 @@ void __init connect_bsp_APIC(void)
211 enable_apic_mode(); 211 enable_apic_mode();
212} 212}
213 213
214void disconnect_bsp_APIC(void) 214void disconnect_bsp_APIC(int virt_wire_setup)
215{ 215{
216 if (pic_mode) { 216 if (pic_mode) {
217 /* 217 /*
@@ -225,6 +225,42 @@ void disconnect_bsp_APIC(void)
225 outb(0x70, 0x22); 225 outb(0x70, 0x22);
226 outb(0x00, 0x23); 226 outb(0x00, 0x23);
227 } 227 }
228 else {
229 /* Go back to Virtual Wire compatibility mode */
230 unsigned long value;
231
232 /* For the spurious interrupt use vector F, and enable it */
233 value = apic_read(APIC_SPIV);
234 value &= ~APIC_VECTOR_MASK;
235 value |= APIC_SPIV_APIC_ENABLED;
236 value |= 0xf;
237 apic_write_around(APIC_SPIV, value);
238
239 if (!virt_wire_setup) {
240 /* For LVT0 make it edge triggered, active high, external and enabled */
241 value = apic_read(APIC_LVT0);
242 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
243 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
244 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
245 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
246 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
247 apic_write_around(APIC_LVT0, value);
248 }
249 else {
250 /* Disable LVT0 */
251 apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
252 }
253
254 /* For LVT1 make it edge triggered, active high, nmi and enabled */
255 value = apic_read(APIC_LVT1);
256 value &= ~(
257 APIC_MODE_MASK | APIC_SEND_PENDING |
258 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
259 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
260 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
261 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
262 apic_write_around(APIC_LVT1, value);
263 }
228} 264}
229 265
230void disable_local_APIC(void) 266void disable_local_APIC(void)