kernel: Actually register interrupt handlers properly

This commit is contained in:
apio 2023-05-14 15:24:46 +02:00
parent 82db0e39ea
commit a99c5e325d
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 79 additions and 1 deletions

View File

@ -22,6 +22,9 @@ namespace CPU
void disable_interrupts();
void wait_for_interrupt();
bool save_interrupts();
void restore_interrupts(bool saved);
void get_stack_trace(void (*callback)(u64, void*), void* arg);
void print_stack_trace();
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
@ -30,6 +33,7 @@ namespace CPU
u16 get_processor_id();
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
void sync_interrupts();
void pause();
}

View File

@ -22,6 +22,7 @@ extern "C" void enable_nx();
extern void setup_gdt();
extern void remap_pic();
extern void change_pic_masks(u8 pic1_mask, u8 pic2_mask);
extern void pic_eoi(unsigned char irq);
extern void pic_eoi(Registers* regs);
extern void setup_idt();
@ -268,6 +269,8 @@ namespace CPU
.expect_value("Could not create the IO background thread!");
remap_pic();
sync_interrupts();
}
void enable_interrupts()
@ -280,6 +283,20 @@ namespace CPU
asm volatile("cli");
}
bool save_interrupts()
{
u64 flags;
asm volatile("pushfq; pop %0" : "=r"(flags));
return flags & 0x200;
}
void restore_interrupts(bool saved)
{
if (saved) enable_interrupts();
else
disable_interrupts();
}
void wait_for_interrupt()
{
asm volatile("hlt");
@ -387,8 +404,28 @@ namespace CPU
irq_handlers[interrupt] = { handler, context };
sync_interrupts();
return true;
}
void sync_interrupts()
{
u8 pic1_mask, pic2_mask;
pic1_mask = pic2_mask = 0b11111111;
for (int i = 0; i < 8; i++)
{
if (irq_handlers[i].function) pic1_mask &= (u8)(~(1 << i));
if (irq_handlers[i + 8].function) pic2_mask &= (u8)(~(1 << i));
}
if (pic2_mask != 0b11111111) pic1_mask &= 0b11111011;
auto val = CPU::save_interrupts();
CPU::disable_interrupts();
change_pic_masks(pic1_mask, pic2_mask);
CPU::restore_interrupts(val);
}
}
// called by kernel_yield

View File

@ -84,6 +84,20 @@ INT(20);
INT(21);
INT(32);
INT(33);
INT(34);
INT(35);
INT(36);
INT(37);
INT(38);
INT(39);
INT(40);
INT(41);
INT(42);
INT(43);
INT(44);
INT(45);
INT(46);
INT(47);
INT(66);
void setup_idt()
@ -112,6 +126,20 @@ void setup_idt()
TRAP(21);
IRQ(32);
IRQ(33);
IRQ(34);
IRQ(35);
IRQ(36);
IRQ(37);
IRQ(38);
IRQ(39);
IRQ(40);
IRQ(41);
IRQ(42);
IRQ(43);
IRQ(44);
IRQ(45);
IRQ(46);
IRQ(47);
SYS(66);
static IDTR idtr;

View File

@ -36,9 +36,18 @@ void remap_pic()
IO::outb(PIC2_DATA, ICW4_8086);
io_delay();
IO::outb(PIC1_DATA, 0b11111100);
IO::outb(PIC1_DATA, 0b11111111);
io_delay();
IO::outb(PIC2_DATA, 0b11111111);
io_delay();
}
void change_pic_masks(u8 pic1_mask, u8 pic2_mask)
{
IO::outb(PIC1_DATA, pic1_mask);
io_delay();
IO::outb(PIC2_DATA, pic2_mask);
io_delay();
}
void pic_eoi(unsigned char irq)