[SOLVED] Issues programming the local/IO APIC
Posted: Wed Oct 04, 2017 8:09 am
Hey,
I've been working on implementing the local APIC and IO APIC in my kernel recently, as I was previously using the 8259 PIC but felt like it'd be nice to support both. However, despite setting things up properly, when I enable interrupts with sti, I don't get any interrupts. My setup process is as follows:
(the whole process can be seen in kmain here)
- Load and initialize a 256 gate IDT
- Initialize ACPI tables and parse them.
- If an IO APIC is found in the ACPI tables then map it into virtual memory, and mask all the redirection entries
- Setup the master and slave PIC
- If ACPI parsing was successful and the APIC was supported then disable PIC, then enable the local APIC by getting it's base address from the MSR, loading it back in with the enable bit to enable it, mapping it into memory, creating a spurious interrupt in the IDT and enabling it in the local APIC, setting the TPR to 0, setting destination format to flat mode, and the logical destination to CPU0, then I enable 16 IRQs in the IO APIC, mapping IRQ0 -> interrupt 0x20, IRQ1 -> interrupt 0x21, etc..
- I then proceed to enable the PIT which is connected to my clock system which is connected to my scheduler. I don't link these all because they work under the PIC, just not under the APIC.
What should I do to continue debugging this? I've been hitting my head against the wall trying to figure out why I'm not getting any interrupts when I call sti (as verified through enabling QEMU's interrupt logging). Are there any common mistakes made while implementing the local APIC?
Thanks.
edit: some additional notes, interrupts are definitely enabled since my NMI handler gets triggered on a divide by zero. I tried to build qemu with IOAPIC debugging enabled but wasn't able to completely compile it due to macOS being weird (stdlib.h not found when compiling an objc file?). Also, the complete output of running the kernel can be found here. I've also tried this under VirtualBox, it still doesn't work.
I've been working on implementing the local APIC and IO APIC in my kernel recently, as I was previously using the 8259 PIC but felt like it'd be nice to support both. However, despite setting things up properly, when I enable interrupts with sti, I don't get any interrupts. My setup process is as follows:
(the whole process can be seen in kmain here)
- Load and initialize a 256 gate IDT
- Initialize ACPI tables and parse them.
- If an IO APIC is found in the ACPI tables then map it into virtual memory, and mask all the redirection entries
- Setup the master and slave PIC
- If ACPI parsing was successful and the APIC was supported then disable PIC, then enable the local APIC by getting it's base address from the MSR, loading it back in with the enable bit to enable it, mapping it into memory, creating a spurious interrupt in the IDT and enabling it in the local APIC, setting the TPR to 0, setting destination format to flat mode, and the logical destination to CPU0, then I enable 16 IRQs in the IO APIC, mapping IRQ0 -> interrupt 0x20, IRQ1 -> interrupt 0x21, etc..
- I then proceed to enable the PIT which is connected to my clock system which is connected to my scheduler. I don't link these all because they work under the PIC, just not under the APIC.
What should I do to continue debugging this? I've been hitting my head against the wall trying to figure out why I'm not getting any interrupts when I call sti (as verified through enabling QEMU's interrupt logging). Are there any common mistakes made while implementing the local APIC?
Thanks.
edit: some additional notes, interrupts are definitely enabled since my NMI handler gets triggered on a divide by zero. I tried to build qemu with IOAPIC debugging enabled but wasn't able to completely compile it due to macOS being weird (stdlib.h not found when compiling an objc file?). Also, the complete output of running the kernel can be found here. I've also tried this under VirtualBox, it still doesn't work.