Page 2 of 2

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 3:34 pm
by Brendan
Hi,
onlyonemac wrote:Should I assume that the higher-order interrupts thus take priority over the lower-order ones? In other words, if I get a second interrupt before I've returned from the first, may I assume that it is a higher-order interrupt? Another way to word this is: if I get an interrupt and I haven't yet sent an EOI, may I assume that only higher-order interrupts will be passed to the CPU and that lower-order ones will be discarded/queued until the first interrupt is handled? (Sorry for asking this so many different ways but I'm wanting to make sure that I'm clear on this because accessible documentation on the topic seems scant.)
Normally; yes you can assume that only higher priority IRQs can interrupt lower priority interrupt handlers. However note that IRQ priorities go in an "awkward" order for historical reasons - e.g. from highest priority to lowest, it's "IRQ0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, 6, IRQ7".

Abnormally; the PIC has various modes that are almost never used on PCs ("auto-EOI", "rotating priority mode", etc) that break this. In addition it's possible for a kernel's IRQ handler to mask the IRQ and send EOI initially, then handle the interrupt, then unmask the IRQ. This breaks the PIC's priority scheme, and I doubt there's ever a sane reason to do this (but I'm sure there's at least one kernel I've seen in the past that does this - possibly an old version of MINIX).

Finally; the PIC's spurious IRQs are a little strange, and it's best to just assume they ignore the PIC's IRQ priority scheme.


Cheers,

Brendan

Re: Queuing interrupts

Posted: Tue Feb 02, 2016 3:07 am
by onlyonemac
I just masked the IRQ 7 because I don't use the printer port.

Re: Queuing interrupts

Posted: Tue Feb 02, 2016 4:47 am
by Brendan
Hi,
onlyonemac wrote:I just masked the IRQ 7 because I don't use the printer port.
I mask all IRQs early during boot; then (later during boot) decide if I'm using PIC or IO APIC, then (even later) unmask an IRQ (in PIC or IO APIC) if/when I install a device driver that needs it.

Of course you still need to handle spurious IRQs - they can't be masked.

The only way to correctly handle spurious IRQs from PIC is to have 2 interrupt handlers (one for IRQ7 and one for IRQ15) that check if the PIC sent a real IRQ or not (by reading the PIC's "In Service Register" so that you don't need to care if the IRQ itself is masked or not at some point in the future). If it was "spurious IRQ7" (from master PIC) you have to return without sending EOI. If it was "spurious IRQ15" you still need to send EOI to the master PIC (but don't send EOI to the slave PIC).

I'd also recommend having a counter for each type of spurious IRQ (one for master PIC, one for slave PIC and one for local APIC) and incrementing it if/when a spurious IRQ occurs; because an excessive number of spurious IRQs can indicate hardware problems.


Cheers,

Brendan

Re: Queuing interrupts

Posted: Tue Feb 02, 2016 6:14 am
by onlyonemac
Brendan wrote:Of course you still need to handle spurious IRQs - they can't be masked.
I thought it was too good to be true that I had discovered a really elegant way of handling spurious IRQs that nobody had mentioned before :-( . Oh well, with the information you've given me about spurious IRQs it should be a simple matter to handle them nevertheless, and I should be able to build that functionality into my operating system quite easily :-) .