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");
}
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

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) {}