Hi,
Post by Rod PembertonPost by BrendanThis would cause a flood of IRQs because PCI IRQs are level triggered
- as soon as the PIC receives the EOI it'll send another IRQ6 to the
CPU because the device's IRQ line will still be active.
Interesting...
You seem to be saying that the clearing the EOI via a PIC won't clear the
IRQ for a PCI device. Yes?
Yes.
Note: For the following, I can't remember if level triggered (for PCI)
is active low or active high, or if "edge triggered" (for ISA) is
detected on a rising edge or on a falling edge. There's a 50% chance
I've got the polarities around the wrong way in each case, but this
shouldn't effect the point I'm trying to make and I just got home from
work (I'm too lazy to look it up at the moment)...
Post by Rod PembertonIf so, how do you clear the IRQ for a PCI device? APIC? (No, can't be that
since not all cpu's and MB's support it...)
The same as you do for ISA devices - clear the condition that is
causing the interrupt. For some simple examples, for a "byte received"
IRQ from the serial port you must read the byte from the serial port,
for a "byte received" IRQ from the PS/2 controller you must read the
byte from the PS/2 controller, for a RTC/CMOS periodic IRQ you need to
read the status register, etc. Almost all devices are like this
(except for the PIT, which is too simple to care).
One reason you may not have noticed is that ISA devices are edge
triggered. When the device wants to generate an IRQ it's "IRQ output"
line changes (e.g. from low to high) and the PIC notices the change in
state. Now, if you send an EOI to the PIC while the device's "IRQ
output" line is still in the "high" state, then there is no edge for
the PIC to notice, and there is no IRQ flood. The other reason you may
not have noticed is that ISA devices (usually) don't share IRQ lines,
and usually the thing you need to do to clear a device's IRQ output is
something you need to do anyway (e.g. for a keyboard device driver to
work you know you need to get a received byte, so you write code to
get the received byte without caring if this action is necessary to
clear the IRQ condition or not).
The problem with edge triggered IRQ's is that you can't tell if 2 or
more devices (that are sharing the same IRQ line) generate IRQs at the
same time. To get around this problem, if edge triggered IRQs are
shared, you need to check all devices that are sharing the IRQ line
every time the IRQ occurs. This is "crappy" for 2 reasons. First, it
can be more efficient to only check one device. For example, if a high
speed ethernet card generates lots of IRQs and shares an IRQ line with
a USB controller that isn't even being used, then it'd be more
efficient to check if the ethernet card generated the IRQ first and
only check if the USB card generated the IRQ if you know the ethernet
card didn't.
Secondly (and most importantly), it's usually impossible to check if 2
or more devices generated the same IRQ without introducing major
problems with race conditions. For example, an USB controller could
generate an IRQ, and the OS could check if the ethernet card generated
the IRQ (it didn't) and then check if the USB controller generated the
IRQ (it did), but the ethernet card could generate it's own IRQ before
the first EOI is sent. In this case the IRQ line is still in the same
state (no second rising edge for "edge triggered" to detect), no
second IRQ is sent and you miss the second IRQ (and the ethernet
driver stops working because it waits forever for it's IRQ to be
handled). For the same example, using level triggered interrupts, you
send the EOI after handling the USB controller's IRQ and the IRQ line
will still be at the "high" state (because of the ethernet card), so
the PIC sends a new IRQ to the CPU (no IRQ is lost).
Note: This is why edge triggered interrupts are not (normally) shared,
and also why it can be complicated to reliably handle serial ports
(which typically do share edge triggered IRQ lines when there's 3 or
more serial ports).
Of course the PIC doesn't know how many devices are connected to each
(level triggered) IRQ line - it just knows that the line is still
"high", so if you don't handle the device's IRQ the PIC just keeps
sending IRQs to the CPU.
Post by Rod PembertonFYI, the reason I said I find it "Interesting..." is that nearly every
device on the highly integrated motherboard I'm developing my OS on is PCI
and I haven't done squat for PCI. So, far my PIC's, IRQ's, etc. all work...
What sort of devices are you handling, and are they all in "ISA
compatability" mode?
Again, Maxim is (mostly) correct. PCI devices are normally in their
default "disabled/ignore everything" state and will not generate an
IRQ without being asked to generate an IRQ. This isn't always the case
though - e.g. PCI devices emulating legacy ISA devices, and PCI
devices that are/were being used by the BIOS (however, even though
these devices aren't in their default "disabled/ignore everything"
state they still usually won't generate an IRQ without being asked to
generate an IRQ).
Post by Rod PembertonPost by BrendanI'm wondering if the IRQ comes from the floppy drive controller (which
is usually IRQ 6) or the PCI device that does have a device driver.
I'm wondering if he has a bug (especially since he hasn't posted any
code...), or higher priority interrupt not being serviced properly (i.e.,
enabled timer or mouse IRQ but has no EOI code?).
My Magic 8-Ball says "Reply hazy, try again"... :-)
Cheers,
Brendan