Techflash wrote:
Perhaps I should fill out the entire rest of the IDT with stub entries instead of just zeroes?
That is generally a good idea. Between IOAPIC, local APIC, and MSI, you can generally not know how many interrupts you will have ahead of time these days. Filling the entire IDT can be done as simply as:
Code:
.align 8
.global external_interrupt
external_interrupt:
.set interrupt,32
.rept 256-32
pushq interrupt-128
jmpq interrupt_common
.align 8
.set interrupt, interrupt+1
.endr
This defines a new symbol, "external interrupt", that handles interrupt 32. You need to define your own function "interrupt_common". It is entered with an IRET frame and the interrupt number less 128 on the stack. The encoding is chosen such that for all possible values of "interrupt", the encoding of the push instruction is the short encoding. This means that all interrupt handlers are exactly 8 bytes apart from one another (you have 2 bytes for the push and at most 5 for the jump, makes 7 in total, aligned to
. So now you can define in C:
Code:
extern const char external_interrupt[];
for (int i = 0; i < 256-32; i++)
set_idt_entry(i + 32, external_interrupt + 8 * i);
Your "interrupt_common" function will then need to save all registers, probably fix up the interrupt number on stack, then call whatever interrupt handler you need to. Then restore registers and do whatever work is required when returning from interrupt.