Add ATA drive support #27
@ -29,7 +29,7 @@ namespace CPU
|
|||||||
|
|
||||||
u16 get_processor_id();
|
u16 get_processor_id();
|
||||||
|
|
||||||
bool register_interrupt(u8 interrupt, void (*handler)(Registers*));
|
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,15 @@ extern void setup_idt();
|
|||||||
|
|
||||||
static Thread* g_io_thread;
|
static Thread* g_io_thread;
|
||||||
|
|
||||||
typedef void (*interrupt_handler_t)(Registers*);
|
typedef void (*interrupt_handler_t)(Registers*, void*);
|
||||||
|
|
||||||
static interrupt_handler_t irq_handlers[16];
|
struct InterruptHandler
|
||||||
|
{
|
||||||
|
interrupt_handler_t function;
|
||||||
|
void* context;
|
||||||
|
};
|
||||||
|
|
||||||
|
static InterruptHandler irq_handlers[16];
|
||||||
|
|
||||||
void FPData::save()
|
void FPData::save()
|
||||||
{
|
{
|
||||||
@ -154,13 +160,13 @@ void io_thread()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timer_interrupt(Registers* regs)
|
static void timer_interrupt(Registers* regs, void*)
|
||||||
{
|
{
|
||||||
Timer::tick();
|
Timer::tick();
|
||||||
if (should_invoke_scheduler()) Scheduler::invoke(regs);
|
if (should_invoke_scheduler()) Scheduler::invoke(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_interrupt(Registers*)
|
static void keyboard_interrupt(Registers*, void*)
|
||||||
{
|
{
|
||||||
u8 scancode = IO::inb(0x60);
|
u8 scancode = IO::inb(0x60);
|
||||||
scancode_queue.try_push(scancode);
|
scancode_queue.try_push(scancode);
|
||||||
@ -174,14 +180,14 @@ extern "C" void arch_interrupt_entry(Registers* regs)
|
|||||||
else if (regs->isr >= 32 && regs->isr < 48) // IRQ from the PIC
|
else if (regs->isr >= 32 && regs->isr < 48) // IRQ from the PIC
|
||||||
{
|
{
|
||||||
u64 irq = regs->error;
|
u64 irq = regs->error;
|
||||||
interrupt_handler_t handler = irq_handlers[irq];
|
auto handler = irq_handlers[irq];
|
||||||
if (!handler)
|
if (!handler.function)
|
||||||
{
|
{
|
||||||
kwarnln("Unhandled IRQ catched! Halting.");
|
kwarnln("Unhandled IRQ catched! Halting.");
|
||||||
CPU::efficient_halt();
|
CPU::efficient_halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
handler(regs);
|
handler.function(regs, handler.context);
|
||||||
pic_eoi(regs);
|
pic_eoi(regs);
|
||||||
}
|
}
|
||||||
else if (regs->isr == 66) // System call
|
else if (regs->isr == 66) // System call
|
||||||
@ -252,8 +258,8 @@ namespace CPU
|
|||||||
setup_idt();
|
setup_idt();
|
||||||
|
|
||||||
memset(irq_handlers, 0, sizeof(irq_handlers));
|
memset(irq_handlers, 0, sizeof(irq_handlers));
|
||||||
register_interrupt(0, timer_interrupt);
|
register_interrupt(0, timer_interrupt, nullptr);
|
||||||
register_interrupt(1, keyboard_interrupt);
|
register_interrupt(1, keyboard_interrupt, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform_finish_init()
|
void platform_finish_init()
|
||||||
@ -375,11 +381,11 @@ namespace CPU
|
|||||||
return (u16)(ebx >> 24);
|
return (u16)(ebx >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool register_interrupt(u8 interrupt, interrupt_handler_t handler)
|
bool register_interrupt(u8 interrupt, interrupt_handler_t handler, void* context)
|
||||||
{
|
{
|
||||||
if (irq_handlers[interrupt]) return false;
|
if (irq_handlers[interrupt].function) return false;
|
||||||
|
|
||||||
irq_handlers[interrupt] = handler;
|
irq_handlers[interrupt] = { handler, context };
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user