Irq 7 is special. It is not just the parallel port. It can also be a
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 28 Sep 2006 17:45:27 +0000 (17:45 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 28 Sep 2006 17:45:27 +0000 (17:45 +0000)
commit4b519bb1fe59f22cf3208cb5fa4cca6b454aed5c
tree9a08fd1730e2de18c4d23277ad61c41e4f79c3e8
parenta80035a1b261b5bdd8afa60e5fb8332f528fa53f
Irq 7 is special.  It is not just the parallel port.  It can also be a
"spurious" irq, one that is not associated with any particular device.
Real hardware can generate spurious irqs for various reasons (try
Google for details), but it never occurred to me that simulated
hardware would ever do so.

However, it can, at least under Bochs.  Pintos programs the PIT to
interrupt at 100 Hz.  The PIT does so by generating a output signal
that stays high most of the time but drops low for a single clock
cycle 100 times per second.  The low-to-high transition causes the
timer interrupt.

The problem occurs when we've been doing work with interrupts
disabled, causing a timer interrupt to be delayed.  If we enable
interrupts on the same clock cycle as the PIT's high-to-low
transition, we will still get an interrupt, because the interrupt
controller latched the presence of an interrupt.  However, when the
CPU attempts to determine the irq number, the interrupt controller
sees that all of its incoming interrupt lines are low.  Thus, it
reports irq 7 to the CPU, and we end up with an interrupt 0x27.

It doesn't happen very often, because there's only a 1-cycle window,
and it requires that we do a good deal of work with interrupts off,
and it can only happen if no other interrupts (e.g. serial) are
pending.  But it's darned annoying when it happens.

Here's a filtered excerpt from a Bochs log with debugging enabled
where you can see the problem.  The first interrupt (32 or 0x20) is
properly a timer interrupt, because irq line 0 is high.  The second
interrupt (39 or 0x27) is the spurious one; you can see that irq line
0 went low on the same cycle.

00080033515d[PIC  ] IRQ line 4 now low
00080033827d[PIC  ] IRQ line 4 now high
00080033970d[PIC  ] IRQ line 0 now low
00080033971d[PIC  ] IRQ line 0 now high
00080033989d[PIC  ] IRQ line 4 now low
00080034068d[CPU  ] interrupt(): vector = 32, INT = 0, EXT = 1
00080043970d[PIC  ] IRQ line 0 now low
00080043971d[PIC  ] IRQ line 0 now high
00080053971d[PIC  ] IRQ line 0 now low
00080053971d[PIC  ] IRQ line 0 now high
00080063971d[PIC  ] IRQ line 0 now low
00080063972d[PIC  ] IRQ line 0 now high
00080073971d[PIC  ] IRQ line 0 now low
00080073972d[PIC  ] IRQ line 0 now high
00080083971d[PIC  ] IRQ line 0 now low
00080083971d[CPU  ] interrupt(): vector = 39, INT = 0, EXT = 1
00080083972d[PIC  ] IRQ line 0 now high
00080084538d[PIC  ] IRQ line 4 now high

This change causes irqs 7 and 15 (0x27 and 0x2f) to be ignored when no
handler is provided.

Problem reported by Godmar Back.
src/threads/interrupt.c