diff --git a/arch/x86/core/i386_sysV_abi/intstub.S b/arch/x86/core/i386_sysV_abi/intstub.S index 10bab505fe3..644f43441cc 100644 --- a/arch/x86/core/i386_sysV_abi/intstub.S +++ b/arch/x86/core/i386_sysV_abi/intstub.S @@ -30,12 +30,13 @@ #include #include /* nanokernel structure offset definitions */ #include /* _NANO_ERR_SPURIOUS_INT */ - +#include /* LOAPIC_EOI */ /* exports (internal APIs) */ GTEXT(_IntEnt) + GTEXT(_IntExitWithEoi) GTEXT(_IntExit) GTEXT(_SpuriousIntNoErrCodeHandler) GTEXT(_SpuriousIntHandler) @@ -224,6 +225,29 @@ BRANCH_LABEL(_HandleIdle) jmp *%eax /* "return" back to stub */ #endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */ +/** + * @brief Perform EOI, clean up stack, and do interrupt exit + * + * This is used by the interrupt stubs, which all leave the stack in + * a particular state and need to poke the interrupt controller. + * Prior to running the logic in _IntExit, the ISR parameter is popped off + * the stack and EOI is set to the LOAPIC. + */ +SECTION_FUNC(TEXT, _IntExitWithEoi) + popl %eax /* Pushed onto stack by stub */ +#if CONFIG_EOI_FORWARDING_BUG + call _lakemont_eoi +#endif + xorl %eax, %eax /* zeroes eax */ + /* TODO not great to have hard-coded LOAPIC stuff here. When + * we get around to introducing the interrupt controller abstraction + * layer, the in-use IRQ controller code will define an ASM macro + * with a specific name which does the correct thing for the particular + * controller. + */ + loapic_eoi_reg = (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) + movl %eax, loapic_eoi_reg /* tell LOAPIC the IRQ is handled */ + /* fall through to _IntExit */ /** * @@ -247,7 +271,7 @@ BRANCH_LABEL(_HandleIdle) * * void _IntExit (void); */ -SECTION_FUNC(TEXT, _IntExit) +BRANCH_LABEL(_IntExit) cli /* disable interrupts */ #ifdef CONFIG_INT_LATENCY_BENCHMARK @@ -456,10 +480,8 @@ BRANCH_LABEL(callFatalHandler) #if ALL_DYN_IRQ_STUBS > 0 BRANCH_LABEL(_DynIntStubCommon) call _common_dynamic_irq_handler - /* Cleanse the stack of stub_num */ - pop %eax /* Clean up and call IRET */ - jmp _IntExit + jmp _IntExitWithEoi /* Create all the dynamic IRQ stubs * diff --git a/arch/x86/core/intconnect.c b/arch/x86/core/intconnect.c index 532c706006c..b345e4257d0 100644 --- a/arch/x86/core/intconnect.c +++ b/arch/x86/core/intconnect.c @@ -43,7 +43,6 @@ #include #include #include -#include #include extern void _SpuriousIntHandler(void *); @@ -260,11 +259,6 @@ int irq_connect(unsigned int irq, unsigned int priority, void _common_dynamic_irq_handler(uint32_t stub_idx) { dyn_irq_list[stub_idx].handler(dyn_irq_list[stub_idx].param); - /* - * Tell the APIC we're done servicing the interrupt.LOAPIC will notify - * the IOAPIC if necessary - */ - _loapic_eoi(); } /** diff --git a/include/drivers/loapic.h b/include/drivers/loapic.h index a19244ebc7f..ec4f9034a4b 100644 --- a/include/drivers/loapic.h +++ b/include/drivers/loapic.h @@ -64,13 +64,7 @@ SECTION_FUNC(TEXT, _\()\device\()_\()\isr\()_stub) call _IntEnt /* Inform kernel interrupt has begun */ pushl \context /* Push context parameter */ call \isr /* Call actual interrupt handler */ - popl %eax /* Clean-up stack from push above */ -#if CONFIG_EOI_FORWARDING_BUG - call _lakemont_eoi -#endif - xorl %eax, %eax - movl %eax, loapic_eoi /* Inform loapic interrupt is done */ - jmp _IntExit /* Inform kernel interrupt is done */ + jmp _IntExitWithEoi /* Inform kernel interrupt is done */ .endm #else /* _ASMLANGUAGE */