Code: Select all
uint32_t *regsel = (uint32_t*) 0xFFFF808000002000;
uint32_t *iowin = (uint32_t*) 0xFFFF808000002010;
kprintf("APIC ID: %d\n", apic->id);
int i;
for (i=0; i<16; i++)
{
*regsel = (0x10+2*i);
__sync_synchronize();
uint64_t entry = (uint64_t)(i+32) | ((uint64_t)(apic->id) << 56);
*iowin = (uint32_t)(entry);
__sync_synchronize();
*regsel = (0x10+2*i+1);
__sync_synchronize();
*iowin = (uint32_t)(entry >> 32);
__sync_synchronize();
};
When I enable interrupts, I immediately get interrupt 34. When it returns, it goes back to an infinite while loop right after the "sti" instruction, executes "jmp $" twice, then, randomly, interrupt 8 is thrown. When returning from its interrupt handler, the "iretq" instruction throws a page fault (non-present, read, kernel) at address 0x240.
The interrupt handlers worked perfectly when I used the legacy PIC. I presume a possible cause is that I am misinterpreting the "ioapicbase" in the ACPI table, or just misunderstanding the datasheet?
Bochs does not show any diagnostic messages when I'm remapping the IRQs (I don't know if it should, but it does show a message when I initialize the local APIC). Also, Bochs is not showing any diagnostic message when the iretq instruction is executed.
Has this happened to anyone else?