APIC fails on real hardware
APIC fails on real hardware
I've just switched from PIC to APIC and everything works just fine in QEMU, but on real hardware it's a real mess:
- Sometimes I get an interrupt 2, which I don't expect.
- I never get any interrupt from my keyboard or mouse.
- If I enable the PIT (and allow it's overridden interrupt source in the IOAPIC), I get loads of interrupt 39, despite mapping it to vector 34 (as per the IO APIC interrupt source override from the ACPI table)
What I am doing to setup APIC:
- Masking all interrupts in the PIC
- Disabling the PIC routing (if hardware supports it) by writing 0x70 to port 0x22 and 0x01 to port 0x23
- Setting the spurious interrupt to 0xFF and enabling the LAPIC by writing 1 to bit 8 of the SVR
- I configure the LVT_ERR to vector 0xFE
- I set LINT 0 and LINT 1 flags as specified in the lapic non maskable interrupt source entry in the ACPI table
- I mask LINT 0 and LINT 1 in the LAPIC LVT
- I write 0 to the LAPIC_TPR register
- I read all the IOApic Interrupt Source Overrides and set the flags in the IOAPICs IOREDTBL (but of course don't unmask them)
- When I allow an IOAPIC interrupt, I lookup in the interrupt source overrides if the irq should be remapped and remap it accordingly
I hope anybody could help me.
- Sometimes I get an interrupt 2, which I don't expect.
- I never get any interrupt from my keyboard or mouse.
- If I enable the PIT (and allow it's overridden interrupt source in the IOAPIC), I get loads of interrupt 39, despite mapping it to vector 34 (as per the IO APIC interrupt source override from the ACPI table)
What I am doing to setup APIC:
- Masking all interrupts in the PIC
- Disabling the PIC routing (if hardware supports it) by writing 0x70 to port 0x22 and 0x01 to port 0x23
- Setting the spurious interrupt to 0xFF and enabling the LAPIC by writing 1 to bit 8 of the SVR
- I configure the LVT_ERR to vector 0xFE
- I set LINT 0 and LINT 1 flags as specified in the lapic non maskable interrupt source entry in the ACPI table
- I mask LINT 0 and LINT 1 in the LAPIC LVT
- I write 0 to the LAPIC_TPR register
- I read all the IOApic Interrupt Source Overrides and set the flags in the IOAPICs IOREDTBL (but of course don't unmask them)
- When I allow an IOAPIC interrupt, I lookup in the interrupt source overrides if the irq should be remapped and remap it accordingly
I hope anybody could help me.
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: APIC fails on real hardware
Does it arrive during a specific part of your code?
Do you have USB drivers? Some firmware's "USB legacy support" doesn't work properly with APIC.
It's hard to say what's going on here without more specifics. What does the interrupt source override say? What value are you writing and which IOAPIC register are you writing it to?
How are you determining that the IMCR exists?
Are these separate steps, or are you masking them with the same writes that set the rest of the flags?
Re: APIC fails on real hardware
Hi,
Interrupt 2 arrives at random times, often right when I enable interrupts in the CPU.
I do not have USB drivers yet, but my mouse is connected via a PS2 port on the mainboard and both peripherals worked under the PIC.
Interrupt source override sais: Bus 0, irq 0, global system interrupt 2, flags 0.
I also have similar ones for irq 9 to gsi 9, irq 10 to gsi 10 and irq 11 to gsi 11.
I am writing to IO Apic register 0x10 + 2 * 2 and 0x10 + 2 * 2 + 1 for the keyboard. The value I write is 0x22 I believe, but I've tried all flag combinations.
Currently I am not yet determining if the IMCR exists, I am just testing it with and without the code for writing to it. I will do this properly once everything works.
I mask them with the same writes and just to be sure I do it again later.
Interestingly enough: I seem to get MSI interrupts just fine on real hardware (just enabled them out of curiosity).
As a trade off, I now also get interrupt 15 sometimes.
Interrupt 2 arrives at random times, often right when I enable interrupts in the CPU.
I do not have USB drivers yet, but my mouse is connected via a PS2 port on the mainboard and both peripherals worked under the PIC.
Interrupt source override sais: Bus 0, irq 0, global system interrupt 2, flags 0.
I also have similar ones for irq 9 to gsi 9, irq 10 to gsi 10 and irq 11 to gsi 11.
I am writing to IO Apic register 0x10 + 2 * 2 and 0x10 + 2 * 2 + 1 for the keyboard. The value I write is 0x22 I believe, but I've tried all flag combinations.
Currently I am not yet determining if the IMCR exists, I am just testing it with and without the code for writing to it. I will do this properly once everything works.
I mask them with the same writes and just to be sure I do it again later.
Interestingly enough: I seem to get MSI interrupts just fine on real hardware (just enabled them out of curiosity).
As a trade off, I now also get interrupt 15 sometimes.
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: APIC fails on real hardware
Unfortunately, that's not a guarantee that they will continue to work with the APIC.
You mean the timer? ISA IRQ1 is connected to a different IOAPIC pin.
That sounds correct to me.
Are you sure the legacy PICs are set up properly?
Re: APIC fails on real hardware
Ah, yeah, that was the timer, I've mixed that up when I wrote xD
The keyboard is of course on pin 1 with vector 33 and the mouse on pin 12 with vector 44.
I am by no means sure about anything xD
But I am masking master and slave by writing 0xFF to master and slaves data port (in addition I never unmask them).
I've also tried removing the PIC initialization code, without any change in behavior.
The keyboard is of course on pin 1 with vector 33 and the mouse on pin 12 with vector 44.
I am by no means sure about anything xD
But I am masking master and slave by writing 0xFF to master and slaves data port (in addition I never unmask them).
I've also tried removing the PIC initialization code, without any change in behavior.
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: APIC fails on real hardware
Depending on how the PIC interrupt line is routed to the CPU, you may still receive spurious IRQs from the PICs even when all of their inputs are masked. Also, if an APIC input is mistakenly configured as ExtINT, any IRQs arriving on that input will appear to be a spurious IRQ from the PIC.
You still need to initialize the PICs so their spurious IRQ vectors don't overlap with anything else.
Re: APIC fails on real hardware
Ah ok, so I have no choice than receiving (and ignoring) them? That's sad.
But what about my peripherals not generating any interrupts?
But what about my peripherals not generating any interrupts?
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: APIC fails on real hardware
That's 41 years of backwards compatibility.
You said earlier that one of your peripherals was generating lots of interrupts - just not the interrupts you expected. If that's still happening, dump the contents of the local APIC's LVT registers and the IOAPIC's IOREDTBL and see which (if any) are unmasked.
Re: APIC fails on real hardware
The lot of (wrong) interrupts came from my PIT, not my peripherals. I've checked in the IOREDTBL that line 1 and 12 (keyboard and PS2 Mouse) are unmasked and set to the values, I expect (vector number, everything else set to 0).
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: APIC fails on real hardware
Are you getting the correct interrupts from the PIT now?
The firmware's "USB legacy support" is only intended to work with the legacy PICs. If you turn that off in the BIOS setup, your PS/2 mouse might start working, since it actually is a PS/2 device. (But you may not be able to control the BIOS setup without a PS/2 keyboard if you turn off USB legacy support!)