[HELP] PIT or PIC does not generate hardware interrupts (64 bit, Limine)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
CubikCubovich
Posts: 1
Joined: Fri Mar 27, 2026 9:03 am
GitHub: https://github.com/Cubik-Cubovich

[HELP] PIT or PIC does not generate hardware interrupts (64 bit, Limine)

Post by CubikCubovich »

Problem
My kernel is loaded by Limine in 64-bit mode. IDT is set up, software interrupts (`int $0x32`) work. PIC is initialized, IRQ0 unmasked, PIT configured. However, hardware interrupts from PIT never arrive.

What works
- IDT loaded (verified via SIDT)
- Software interrupt `int $0x32` triggers the handler (prints characters)
- PIT counter changes (verified via `inb`)
- CPL = 0 (Ring 0)

What doesn't work
- Hardware interrupts from PIT never arrive
- Tried disabling APIC with `-cpu qemu64,-apic` — didn't help

Code (simplified)

IDT:

Code: Select all

void idt_set_gate(uint8_t vector, void *handler, uint8_t type_attr) {
    uint64_t addr = (uint64_t)handler;
    idt[vector].base_low = addr & 0xFFFF;
    idt[vector].selector = 0x28;  // CS=0x28 from GDT. This is the correct selector that has determined itself
    idt[vector].type_attr = type_attr;
    idt[vector].base_mid = (addr >> 16) & 0xFFFF;
    idt[vector].base_high = (addr >> 32) & 0xFFFFFFFF;
}
PIC:

Code: Select all

outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0xFC);  // IRQ0 and IRQ1 unmasked
outb(0xA1, 0xFF);
PIT:

Code: Select all

outb(0x43, 0x34);  // mode 2
outb(0x40, divisor & 0xFF);
outb(0x40, (divisor >> 8) & 0xFF);
Environment
QEMU 10.0.7

Bootloader: Limine (64-bit)

Launch command: qemu-system-x86_64 -cdrom template-x86_64.iso -debugcon stdio

Questions
How do I determine which I/O APIC input the PIT is connected to?

Do I need to completely disable PIC if I want to use APIC?

Is there a simple way to make PIT work with APIC without ACPI?

Should I just switch to the Local APIC Timer instead?

Notes:

I used a translator, so there may be mistakes. I'm new to OSDev and this is my first kernel that got this far. Any help is appreciated!

Full code on https://github.com/Cubik-Cubovich/CAMFOS
Octocontrabass
Member
Member
Posts: 6249
Joined: Mon Mar 25, 2013 7:01 pm

Re: [HELP] PIT or PIC does not generate hardware interrupts (64 bit, Limine)

Post by Octocontrabass »

CubikCubovich wrote: Fri Mar 27, 2026 9:27 am- Software interrupt `int $0x32` triggers the handler (prints characters)
But your PIT handler should be triggered by "int $32", not "int $0x32".
CubikCubovich wrote: Fri Mar 27, 2026 9:27 am- Hardware interrupts from PIT never arrive
Have you verified this with QEMU's interrupt log? (Run QEMU with "-d int".) Have you checked the PIC configuration using "info pic" in the QEMU monitor? Have you used a debugger to see what the CPU is doing while it waits for timer interrupts?
CubikCubovich wrote: Fri Mar 27, 2026 9:27 amHow do I determine which I/O APIC input the PIT is connected to?
Parse the ACPI MADT.
CubikCubovich wrote: Fri Mar 27, 2026 9:27 amDo I need to completely disable PIC if I want to use APIC?
Yes.
CubikCubovich wrote: Fri Mar 27, 2026 9:27 amIs there a simple way to make PIT work with APIC without ACPI?
Parse the MP Configuration Table.
CubikCubovich wrote: Fri Mar 27, 2026 9:27 amShould I just switch to the Local APIC Timer instead?
Ignoring the problem will not fix the problem.
Post Reply