Hi,
Creature wrote:You are right, I've tried acknowledging the IRQ separately after returning to protected mode, and interrupts are received again. After that, I noticed I had accidently re-enabled interrupts before performing the IRQ (some of the tutorials did it, but I was wondering why, because it isn't needed at all to perform a software interrupt, damn that faulty information).
It's working now
.
Are you sure? There's a difference between "working reliably in all situations" and "working most of the time on one computer".
If some BIOS code is running and carry is clear, and the CPU is about to do "jnc somewhere"; then if an IRQ occurs (making the BIOS execute an unsupported software interrupt handler which sets the carry flag), then how many unpredictable/random crashes could that cause? An average of one crash per 10000 video mode switches? What if the BIOS's software interrupt handler sets "AH = unsupported function"? That'd be a lot worse than just setting the carry flag - maybe an average of one crash per 1000 video mode switches?
What if the BIOS function isn't unsupported? What if, when an IRQ occurs the BIOS executes some random function? Ouch. Don't forget that one day you might want to add support for I/O APICs and MSI (message signalled interrupts) and instead of having 16 potential IRQs (e.g. interrupts 0x20 to 0x2F) you might have 100 of them (e.g. interrupts 0x20 to 0x84); plus maybe some more for multi-CPU IPIs.
Also, what if no IRQ occured while you're in real mode and you send an EOI anyway? For multi-CPU that can cause serious problems because you can't guarantee than a different CPU isn't in the middle of handling an IRQ. What if 10 IRQs occur while you're in real mode? You'd need to send 10 EOIs after you return to protected mode.
So, how do you prevent random undefined behavior (and the other problems)?
You could try to disable interrupts while running BIOS code, but that won't work. In real mode all interrupts are like "interrupt gates" in protected mode - interrupts are disabled automatically be the CPU when the interrupt is started. This means that BIOS code that takes a little time needs to enable interrupts again to avoid IRQs from being missed; so you can expect that good video cards will do "STI" before switching video modes (which does take a relatively long time).
You could try masking all the IRQs in the PIC. That will cause IRQs to be lost. It might not matter in some cases. For e.g. the PIT timer has enough drift that you wouldn't notice if a few lost PIT IRQs cause your OS to lose a few ms per day; and for PCI devices the device will just keep trying until it's IRQ is handled. For other cases (most ISA devices), if the IRQ is lost then that device won't send it's IRQ again, and you're screwed.
The way to do it properly is to install your own IRQ handlers in real mode. For example, if an IRQ does occur while you're in real mode then your IRQ handler will switch back to protected mode and execute the correct protected mode IRQ handler (then switch back to real mode after the protected mode IRQ handler has completed). No lost IRQs, no missed EOIs, no problem for I/O APICs and MSI, and no problem with multi-CPU.
Cheers,
Brendan