kernel: Actually register interrupt handlers properly
This commit is contained in:
parent
57072ab0c5
commit
91b891843e
@ -22,6 +22,9 @@ namespace CPU
|
|||||||
void disable_interrupts();
|
void disable_interrupts();
|
||||||
void wait_for_interrupt();
|
void wait_for_interrupt();
|
||||||
|
|
||||||
|
bool save_interrupts();
|
||||||
|
void restore_interrupts(bool saved);
|
||||||
|
|
||||||
void get_stack_trace(void (*callback)(u64, void*), void* arg);
|
void get_stack_trace(void (*callback)(u64, void*), void* arg);
|
||||||
void print_stack_trace();
|
void print_stack_trace();
|
||||||
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
|
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
|
||||||
@ -30,6 +33,7 @@ namespace CPU
|
|||||||
u16 get_processor_id();
|
u16 get_processor_id();
|
||||||
|
|
||||||
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
|
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
|
||||||
|
void sync_interrupts();
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ extern "C" void enable_nx();
|
|||||||
|
|
||||||
extern void setup_gdt();
|
extern void setup_gdt();
|
||||||
extern void remap_pic();
|
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(unsigned char irq);
|
||||||
extern void pic_eoi(Registers* regs);
|
extern void pic_eoi(Registers* regs);
|
||||||
extern void setup_idt();
|
extern void setup_idt();
|
||||||
@ -253,6 +254,8 @@ namespace CPU
|
|||||||
.expect_value("Could not create the IO background thread!");
|
.expect_value("Could not create the IO background thread!");
|
||||||
|
|
||||||
remap_pic();
|
remap_pic();
|
||||||
|
|
||||||
|
sync_interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_interrupts()
|
void enable_interrupts()
|
||||||
@ -265,6 +268,20 @@ namespace CPU
|
|||||||
asm volatile("cli");
|
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()
|
void wait_for_interrupt()
|
||||||
{
|
{
|
||||||
asm volatile("hlt");
|
asm volatile("hlt");
|
||||||
@ -372,8 +389,28 @@ namespace CPU
|
|||||||
|
|
||||||
irq_handlers[interrupt] = { handler, context };
|
irq_handlers[interrupt] = { handler, context };
|
||||||
|
|
||||||
|
sync_interrupts();
|
||||||
|
|
||||||
return true;
|
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
|
// called by kernel_yield
|
||||||
|
@ -84,6 +84,20 @@ INT(20);
|
|||||||
INT(21);
|
INT(21);
|
||||||
INT(32);
|
INT(32);
|
||||||
INT(33);
|
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);
|
INT(66);
|
||||||
|
|
||||||
void setup_idt()
|
void setup_idt()
|
||||||
@ -112,6 +126,20 @@ void setup_idt()
|
|||||||
TRAP(21);
|
TRAP(21);
|
||||||
IRQ(32);
|
IRQ(32);
|
||||||
IRQ(33);
|
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);
|
SYS(66);
|
||||||
|
|
||||||
static IDTR idtr;
|
static IDTR idtr;
|
||||||
|
@ -36,9 +36,18 @@ void remap_pic()
|
|||||||
IO::outb(PIC2_DATA, ICW4_8086);
|
IO::outb(PIC2_DATA, ICW4_8086);
|
||||||
io_delay();
|
io_delay();
|
||||||
|
|
||||||
IO::outb(PIC1_DATA, 0b11111100);
|
IO::outb(PIC1_DATA, 0b11111111);
|
||||||
io_delay();
|
io_delay();
|
||||||
IO::outb(PIC2_DATA, 0b11111111);
|
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)
|
void pic_eoi(unsigned char irq)
|
||||||
|
Loading…
Reference in New Issue
Block a user