mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-23 01:29:33 +00:00
x86: Add a fake IRQ7 handler to avoid spurious interrupts
The 8259a PIC has a well known problem of generating flaky IRQ7 interrupts. The correct solution is to always check if an IRQ7 interrupt is real or not by probing the PIC's ISR register. This check is only mandatory if the IRQ7 is actually being used by the system. More importantly, the handler should NEVER send and EOI if the interrupt was spurious. This patch addresses this issue by implementing a fake empty handler for this IRQ and, as stated, NOT sending the EOI.
This commit is contained in:
parent
afd9b5b0b7
commit
3b01e04379
@ -34,12 +34,28 @@
|
|||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
|
||||||
|
#define IRQ7_INT PIC_INT(7)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
double_fault_handler(struct interrupt_context context)
|
double_fault_handler(struct interrupt_context context)
|
||||||
{
|
{
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
spurious_irq7_handler(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NOTE: Originally IRQ7 was used for the parallel port interrupts. Nowadays,
|
||||||
|
* though, it is only used if some other IRQ (i.e.: a PCIx interrupt) is
|
||||||
|
* mapped to it. In this case we will have to check the PIC ISR register in
|
||||||
|
* order to confirm this was a real interrupt.
|
||||||
|
*
|
||||||
|
* In case of a spurious interrupt, we should NEVER send an EOI here so the PIC
|
||||||
|
* doesn't trigger the next queued interrupt.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
cpu_init(void)
|
cpu_init(void)
|
||||||
{
|
{
|
||||||
@ -52,4 +68,9 @@ cpu_init(void)
|
|||||||
SET_INTERRUPT_HANDLER(8, 1, double_fault_handler);
|
SET_INTERRUPT_HANDLER(8, 1, double_fault_handler);
|
||||||
|
|
||||||
pic_init();
|
pic_init();
|
||||||
|
|
||||||
|
/* Set a 'fake' handler for the Spurious IRQ7 interrupts.
|
||||||
|
* Refer to http://wiki.osdev.org/PIC .
|
||||||
|
*/
|
||||||
|
SET_INTERRUPT_HANDLER(IRQ7_INT, 0, spurious_irq7_handler);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user