Page 1 of 1
properly masking IRQs
Posted: Sat Dec 19, 2009 3:28 pm
by NickJohnson
I'm trying to mask all IRQs except for 0, specifically IRQ 7, which is causing problems with my kernel's initialization, which requires a timer interrupt to drop to userspace. I thought I got it to work, but now I'm getting some boot problems I've traced back to spurious interrupts from IRQ 7. Can you tell me what is wrong with my PIC setup?
Code: Select all
/* Initialize 8259 PIC */
outb(0x20, 0x11); /* Initialize master */
outb(0xA0, 0x11); /* Initialize slave */
outb(0x21, 0x20); /* Master mapped to 0x20 - 0x27 */
outb(0xA1, 0x28); /* Slave mapped to 0x28 - 0x2E */
outb(0x21, 0x04); /* Master thingy */
outb(0xA1, 0x02); /* Slave thingy */
outb(0x21, 0x01); /* 8086 (standard) mode */
outb(0xA1, 0x01); /* 8086 (standard) mode */
outb(0x21, 0xFE); /* Allow only master IRQ 0 */
outb(0xA1, 0xFF); /* Allow no slave IRQs */
I get both IRQ 0 *and* 7, and it depends on optimizations which one fires first (simply because of timing: higher optimizations actually fix it, and I can tell from debug info which fired first). Interestingly, even though this bug is in the test image I posted in another thread, there were no problems with it on other people's real hardware, or in QEMU.
Re: properly masking IRQs
Posted: Sat Dec 19, 2009 6:19 pm
by Combuster
IRQ 7 doubles as the spurious interrupt. See the
FAQ.
Re: properly masking IRQs
Posted: Sat Dec 19, 2009 6:52 pm
by NickJohnson
I know IRQ 7 is used as a spurious interrupt, but shouldn't it still be able to be blocked by configuring the PIC to mask it? I also want to prevent the firing of other IRQs as well, and my code doesn't seem to be working for that either (although I haven't determined that for sure).
Re: properly masking IRQs
Posted: Sat Dec 19, 2009 7:07 pm
by ~
For what the wiki and the other posts say, it looks like that IRQ7 has little to do with the PIC configuration and the IRQ signalling passing through the PIC, or at the very least is a PIC "malfunction" that can't be prevented with anything other than:
- an interrupt routine that just returns
- an interrupt routine that does something but avoids re-entering and also do a if(inb(0x20) & 0x80) in the interrupt routine to see if bit 7 is set (if it isn't, IRQ7 was triggered spuriously and thus doesn't need an EOI to the PIC). Why bit 7? I think it is bit 7 which corresponds to IRQ7 in the MASTER PIC (it's a matter to read better the "configuration word" specifications of the PIC).
That's what the previous FAQ reference seems to say in short.
Re: properly masking IRQs
Posted: Sat Dec 19, 2009 7:25 pm
by NickJohnson
Sorry, I guess I should have read it more closely. It turns out the issue was only triggered by the spurious interrupt, not directly caused by it, so I fixed it anyway.
Re: properly masking IRQs
Posted: Sun Dec 20, 2009 8:22 pm
by bewing
Um.
I can't really say anything about your problem, because your code above looked fine to me each time I looked at it.
What was said above seems erroneous to me -- to map an IRQ into an INT requires that the IRQ be routed through the PIC. To claim that an IRQ7 could happen without it being routed through the PIC sounds impossible (unless we are talking about a complicated APIC setup) -- because the system would not know which INT to fire without the PIC mapping. So it should be maskable, just as you said.
I understand that you seem to have worked around the problem without deciphering it completely -- I was hoping for some definite answer because it sounds important, but oh well. What hardware platform are you running this test example on, to have the masking not work?
Re: properly masking IRQs
Posted: Sun Dec 20, 2009 9:12 pm
by NickJohnson
Yeah, I think my code is right, but it is impossible to mask the spurious interrupt. It is probably because the PIC actually is the origin of the interrupt (otherwise Intel would have created a dedicated exception for it - there are quite a few reserved ones), and it bypasses the masking internally. It seems like a relatively bad design, but there must have been some reason for it (even laziness).
Re: properly masking IRQs
Posted: Mon Dec 21, 2009 7:19 am
by Owen
A spurious interrupt occurs when the processor thinks an interrupt occurred, but one actually didn't; for example, if there is noise on the processor's INT pin. It asks the PIC for the interrupt, and it scratches it's head and returns the spurious one.
A possible cause is masking interrupts while the PIC is raising an interrupt to the processor. The processor will read the INT, ask the PIC for an interrupt, and the PIC will say it was spurious because interrupts are masked.
Re: properly masking IRQs
Posted: Mon Dec 21, 2009 8:14 am
by qw
From
Wikipedia:
The 8259 generates spurious interrupts in response to a number of conditions.
The first is an IRQ line being deasserted before it is acknowledged. This may occur due to noise on the IRQ lines. In edge triggered mode, the noise must maintain the line in the low state for 100nS. When the noise diminishes, a pull-up resistor returns the IRQ line to high, thus generating a false interrupt. In level triggered mode, the noise may cause a high signal level on the systems INTR line. If the system sends an acknowledgment request, the 8259 has nothing to resolve and thus sends an IRQ7 in response. This first case will generate spurious IRQ7's.
A similar case can occur when the 8259 unmask and the IRQ input deassertion are not properly synchronized. In many systems, the IRQ input is deasserted by an I/O write, and the processor doesn't wait until the write reaches the I/O device. If the processor continues and unmasks the 8259 IRQ before the IRQ input is deasserted, the 8259 will assert INTR again. By the time the processor recognizes this INTR and issues an acknowledgment to read the IRQ from the 8259, the IRQ input may be deasserted, and the 8259 returns a spurious IRQ7.
The second is the master 8259's IRQ2 is active high when the slave 8259's IRQ lines are inactive on the falling edge of an interrupt acknowledgment. This second case will generate spurious IRQ15's, but is very rare.
Re: properly masking IRQs
Posted: Mon Dec 21, 2009 8:18 am
by Owen
What I mentioned is the first one of yours, except on the INT line rather than an IRQ line. These days it's much more common than the ones you mentioned as the PIC is on the same chip as all the devices connected to it!