x86: fixes LAPIC unmasking
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 27 Mar 2014 21:44:24 +0000 (14:44 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 29 Mar 2014 01:17:05 +0000 (18:17 -0700)
Was off by 0x320, not that it really had an effect.

kern/arch/x86/apic.c
kern/arch/x86/trap.c

index f9aa04f..b830ffe 100644 (file)
@@ -24,6 +24,10 @@ bool core_id_ready = FALSE;
 
 bool lapic_check_spurious(int trap_nr)
 {
+#ifndef CONFIG_ENABLE_MPTABLES
+       /* no MP tables doesn't use the new spurious vec */
+       return FALSE;
+#endif
        /* FYI: lapic_spurious is 255 on qemu and 15 on the nehalem..  We actually
         * can set bits 4-7, and P6s have 0-3 hardwired to 0.  YMMV.  NxM seems to
         * say the lower 3 bits are usually 1.  We'll see if the assert trips.
@@ -97,7 +101,7 @@ void lapic_unmask_irq(int apic_vector)
                warn("Bad apic vector %d\n", apic_vector);
                return;
        }
-       mm_reg = LAPIC_BASE + (apic_vector - IdtLAPIC) * 0x10;
+       mm_reg = LAPIC_BASE + 0x320 + (apic_vector - IdtLAPIC) * 0x10;
        write_mmreg32(mm_reg, read_mmreg32(mm_reg) & ~LAPIC_LVT_MASK);
 }
 
@@ -128,7 +132,7 @@ void __lapic_set_timer(uint32_t ticks, uint8_t vec, bool periodic, uint8_t div)
        // clears bottom bit and then set divider
        write_mmreg32(LAPIC_TIMER_DIVIDE, (read_mmreg32(LAPIC_TIMER_DIVIDE) &~0xf) |
                      (div & 0xf));
-       // set LVT with interrupt handling information
+       // set LVT with interrupt handling information.  also unmasks.
        write_mmreg32(LAPIC_LVT_TIMER, vec | (periodic << 17));
        write_mmreg32(LAPIC_TIMER_INIT, ticks);
        // For debugging when we expand this
index 92b81ee..6d8edbe 100644 (file)
@@ -523,8 +523,9 @@ int register_irq(int irq, isr_t handler, void *irq_arg, uint32_t tbdf)
        irq_handlers[vector] = irq_h;
        spin_unlock_irqsave(&irq_handler_wlock);
        /* Most IRQs other than the BusIPI should need their irq unmasked.
-        * Might need to pass the irq_h, in case unmask needs more info */
-       if (irq_h->unmask)
+        * Might need to pass the irq_h, in case unmask needs more info.
+        * The lapic IRQs need to be unmasked on a per-core basis */
+       if (irq_h->unmask && strcmp(irq_h->type, "lapic"))
                irq_h->unmask(vector);
        return 0;
 }