diff --git a/kernel/include/interrupts.hpp b/kernel/include/interrupts.hpp index 4d0f2f69..18eca851 100644 --- a/kernel/include/interrupts.hpp +++ b/kernel/include/interrupts.hpp @@ -52,7 +52,7 @@ struct syscall_regs { void setup_interrupts(); -void register_irq_handler(size_t irq, void (*handler)(syscall_regs*)); +void register_irq_handler(size_t irq, void (*handler)(syscall_regs*, void*), void* data); void register_syscall_handler(size_t irq, void (*handler)(syscall_regs*)); } //end of interrupt namespace diff --git a/kernel/src/ata.cpp b/kernel/src/ata.cpp index ecbb2747..dba784f0 100644 --- a/kernel/src/ata.cpp +++ b/kernel/src/ata.cpp @@ -69,7 +69,7 @@ volatile bool secondary_invoked = false; //TODO In the future, the wait for IRQs, could //be done with a semaphore -void primary_controller_handler(interrupt::syscall_regs*){ +void primary_controller_handler(interrupt::syscall_regs*, void*){ if(scheduler::is_started()){ primary_lock.release(); } else { @@ -77,7 +77,7 @@ void primary_controller_handler(interrupt::syscall_regs*){ } } -void secondary_controller_handler(interrupt::syscall_regs*){ +void secondary_controller_handler(interrupt::syscall_regs*, void*){ if(scheduler::is_started()){ secondary_lock.release(); } else { @@ -387,8 +387,8 @@ void ata::detect_disks(){ out_byte(ATA_PRIMARY + ATA_DEV_CTL, 0); out_byte(ATA_SECONDARY + ATA_DEV_CTL, 0); - interrupt::register_irq_handler(14, primary_controller_handler); - interrupt::register_irq_handler(15, secondary_controller_handler); + interrupt::register_irq_handler(14, primary_controller_handler, nullptr); + interrupt::register_irq_handler(15, secondary_controller_handler, nullptr); } uint8_t ata::number_of_disks(){ diff --git a/kernel/src/drivers/pit.cpp b/kernel/src/drivers/pit.cpp index 81bc536f..a8de11f7 100644 --- a/kernel/src/drivers/pit.cpp +++ b/kernel/src/drivers/pit.cpp @@ -14,7 +14,7 @@ namespace { -void timer_handler(interrupt::syscall_regs*){ +void timer_handler(interrupt::syscall_regs*, void*){ timer::tick(); } @@ -27,5 +27,5 @@ void pit::install(){ out_byte(0x40, static_cast(divisor)); out_byte(0x40, static_cast(divisor >> 8)); - interrupt::register_irq_handler(0, timer_handler); + interrupt::register_irq_handler(0, timer_handler, nullptr); } diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index 97bef00e..dd435a11 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -49,7 +49,8 @@ struct idtr { idt_entry idt_64[64]; idtr idtr_64; -void (*irq_handlers[16])(interrupt::syscall_regs*); +void (*irq_handlers[16])(interrupt::syscall_regs*, void*); +void* irq_handler_data[16]; void (*syscall_handlers[interrupt::SYSCALL_MAX])(interrupt::syscall_regs*); void idt_set_gate(size_t gate, void (*function)(void), uint16_t gdt_selector, idt_flags flags){ @@ -88,6 +89,7 @@ void install_idt(){ //Clear the IRQ handlers std::fill_n(irq_handlers, 16, nullptr); + std::fill_n(irq_handler_data, 16, nullptr); //Give the IDTR address to the CPU asm volatile("lidt [%0]" : : "m" (idtr_64)); @@ -258,7 +260,7 @@ void _irq_handler(interrupt::syscall_regs* regs){ //If there is an handler, call it if(irq_handlers[regs->code]){ - irq_handlers[regs->code](regs); + irq_handlers[regs->code](regs, irq_handler_data[regs->code]); } } @@ -273,8 +275,9 @@ void _syscall_handler(interrupt::syscall_regs* regs){ } //end of extern "C" -void interrupt::register_irq_handler(size_t irq, void (*handler)(interrupt::syscall_regs*)){ +void interrupt::register_irq_handler(size_t irq, void (*handler)(interrupt::syscall_regs*, void*), void* data){ irq_handlers[irq] = handler; + irq_handler_data[irq] = data; } void interrupt::register_syscall_handler(size_t syscall, void (*handler)(interrupt::syscall_regs*)){ diff --git a/kernel/src/keyboard.cpp b/kernel/src/keyboard.cpp index f340a7fe..224af290 100644 --- a/kernel/src/keyboard.cpp +++ b/kernel/src/keyboard.cpp @@ -90,7 +90,7 @@ char shifted_qwertz[128] = { 0, /* All other keys are undefined */ }; -void keyboard_handler(interrupt::syscall_regs*){ +void keyboard_handler(interrupt::syscall_regs*, void*){ auto key = static_cast(in_byte(0x60)); stdio::get_active_terminal().send_input(key); @@ -99,7 +99,7 @@ void keyboard_handler(interrupt::syscall_regs*){ } //end of anonymous namespace void keyboard::install_driver(){ - interrupt::register_irq_handler(1, keyboard_handler); + interrupt::register_irq_handler(1, keyboard_handler, nullptr); // At this point, we need to clear the keyboard buffer // Otherwise, all the following events will be lost diff --git a/kernel/src/rtl8139.cpp b/kernel/src/rtl8139.cpp index e08dfbc0..e69ef224 100644 --- a/kernel/src/rtl8139.cpp +++ b/kernel/src/rtl8139.cpp @@ -56,14 +56,10 @@ struct rtl8139_t { uint64_t cur_rx; //Index inside the buffer }; -//TODO Add a way so that the interrupt handler is able to pass a void ptr to the handler - -volatile rtl8139_t* saved_desc; - -void packet_handler(interrupt::syscall_regs*){ +void packet_handler(interrupt::syscall_regs*, void* data){ logging::logf(logging::log_level::TRACE, "rtl8139: Packet Received\n"); - auto& desc = *saved_desc; + auto& desc = *static_cast(data); // Get the interrupt status auto status = in_word(desc.iobase + ISR); @@ -126,7 +122,6 @@ void rtl8139::init_driver(network::interface_descriptor& interface, pci::device_ rtl8139_t* desc = new rtl8139_t(); interface.driver_data = desc; - saved_desc = desc; // 1. Enable PCI Bus Mastering (allows DMA) @@ -174,7 +169,7 @@ void rtl8139::init_driver(network::interface_descriptor& interface, pci::device_ // 6. Register IRQ handler auto irq = pci::read_config_dword(pci_device.bus, pci_device.device, pci_device.function, 0x3c) & 0xFF; - interrupt::register_irq_handler(irq, packet_handler); + interrupt::register_irq_handler(irq, packet_handler, desc); // 7. Set IMR + ISR