quark_se: make EOI operations atomic
Some issues have been noted with nested interrupts on quark SE. In particular, the wrong vector # being sent to the IOAPIC EOI register. Now when doing EOI, we lock interrupts so that the act of reading the current vector being serviced, and sending EOI to both controllers happens atomically. Change-Id: Id9ad992740e197bb9d4638764952b04a27c4af61 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
813923e63c
commit
af085b8edf
3 changed files with 14 additions and 4 deletions
|
@ -288,7 +288,7 @@ SECTION_FUNC(TEXT, _IntExitWithEoi)
|
|||
#endif
|
||||
#if CONFIG_EOI_FORWARDING_BUG
|
||||
call _lakemont_eoi
|
||||
#endif
|
||||
#else
|
||||
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
|
||||
|
@ -298,6 +298,7 @@ SECTION_FUNC(TEXT, _IntExitWithEoi)
|
|||
*/
|
||||
loapic_eoi_reg = (CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI)
|
||||
movl %eax, loapic_eoi_reg /* tell LOAPIC the IRQ is handled */
|
||||
#endif
|
||||
/* fall through to _IntExit */
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,13 +32,21 @@
|
|||
|
||||
void _lakemont_eoi(void)
|
||||
{
|
||||
int vector = _loapic_isr_vector_get();
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
|
||||
/* It is difficult to know whether the IRQ being serviced is
|
||||
* a level interrupt handled by the IOAPIC; the only information
|
||||
* we have is the vector # in the IDT. So unconditionally
|
||||
* write to IOAPIC_EOI for every interrupt
|
||||
*/
|
||||
sys_write32(vector, CONFIG_IOAPIC_BASE_ADDRESS + IOAPIC_EOI);
|
||||
sys_write32(_loapic_isr_vector_get(), CONFIG_IOAPIC_BASE_ADDRESS +
|
||||
IOAPIC_EOI);
|
||||
|
||||
/* Send EOI to the LOAPIC as well */
|
||||
sys_write32(0, CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI);
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,8 +80,9 @@ static inline void _loapic_eoi(void)
|
|||
{
|
||||
#if CONFIG_EOI_FORWARDING_BUG
|
||||
_lakemont_eoi();
|
||||
#endif
|
||||
#else
|
||||
*(volatile int *)(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_EOI) = 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue