[SOLVED] IRQ handler never being called

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
torii
Posts: 7
Joined: Sun Feb 02, 2025 5:59 pm
GitHub: https://github.com/Toriiiiiiiiii
Contact:

[SOLVED] IRQ handler never being called

Post by torii »

I am attempting to set up IRQs using the PIC, however my IRQ handler is never being called.
I have verified that the PIC is set up properly (I am able to move the cursor around the text-mode display using it), however I am unable to then receive interrupts through it. The relevant code is here:

Code: Select all

void pic_init() {
	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, 0x0);
	outb(0xA1, 0x0);
}

void pic_install() {
    __asm__ volatile("cli");
    pic_init();

    for(uint8_t vector = 0; vector < 16; ++vector) {
        idt_set_descriptor(0x20 + vector, irq_stub_table[vector], 0x8E);
    }
    __asm__ volatile("sti");
}
My IRQ table is created in an assembly file:

Code: Select all

%macro irq_stub 1
irq_stub_%1:
    push %1
    jmp irq_common
%endmacro

global irq_common
irq_common:
    pusha               ; pushes in order: eax, ecx, edx, ebx, esp, ebp, esi, edi

    xor eax, eax        ; push ds
    mov ax, ds
    push eax

    mov ax, 0x10        ; use kernel data segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    
    push esp            ; pass pointer to stack to C, so we can access all the pushed information
    call irq_handler
    add esp, 4

    pop eax             ; restore old segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    popa                ; pop what we pushed with pusha
    add esp, 8          ; remove error code and interrupt number
    iret                ; will pop: cs, eip, eflags, ss, esp

irq_stub 0
irq_stub 1
irq_stub 2
irq_stub 3
irq_stub 4
irq_stub 5
irq_stub 6
irq_stub 7
irq_stub 8
irq_stub 9
irq_stub 10
irq_stub 11
irq_stub 12
irq_stub 13
irq_stub 14
irq_stub 15

global irq_stub_table
irq_stub_table:
%assign i 0 
%rep    16 
    dd irq_stub_%+i ; use DQ instead if targeting 64-bit
%assign i i+1 
%endrep
I have set a breakpoint on my IRQ handler, yet it does not get triggered through things that should trigger an IRQ (such as keyboard events). Any help would be appreciated! :D

UPDATE: Turns out the problem wasn't my installation code. I simply forgot that, when my kernel finishes executing code, it disables interrupts and halts. Fixed this problem by simply adding a

Code: Select all

while(1) {}
loop to the kernel.
Last edited by torii on Mon Feb 03, 2025 2:55 pm, edited 2 times in total.
Writing bad code since 2019
Image Image
Klakap
Member
Member
Posts: 308
Joined: Sat Mar 10, 2018 10:16 am

Re: IRQ handler never being called

Post by Klakap »

Can you also share your code for setting and loading IDT table?
Klakap
Member
Member
Posts: 308
Joined: Sat Mar 10, 2018 10:16 am

Re: [SOLVED] IRQ handler never being called

Post by Klakap »

torii wrote: Mon Feb 03, 2025 2:01 pm UPDATE: Turns out the problem wasn't my installation code. I simply forgot that, when my kernel finishes executing code, it disables interrupts and halts. Fixed this problem by simply adding a

Code: Select all

while(1) {}
loop to the kernel.
This can possibly overheat processor, because it executes instructions forever. It is best to add "hlt" instruction:

Code: Select all

while(1) {
 asm("hlt");
}
After hlt instruction processor halts until interrupt arrives.
Post Reply