Improve IRQ system

Pass some data that is forwarded to the handler
This commit is contained in:
Baptiste Wicht 2016-07-07 09:54:50 +02:00
parent e6a2cf0b95
commit 53a2a07784
6 changed files with 18 additions and 20 deletions

View File

@ -52,7 +52,7 @@ struct syscall_regs {
void setup_interrupts(); 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*)); void register_syscall_handler(size_t irq, void (*handler)(syscall_regs*));
} //end of interrupt namespace } //end of interrupt namespace

View File

@ -69,7 +69,7 @@ volatile bool secondary_invoked = false;
//TODO In the future, the wait for IRQs, could //TODO In the future, the wait for IRQs, could
//be done with a semaphore //be done with a semaphore
void primary_controller_handler(interrupt::syscall_regs*){ void primary_controller_handler(interrupt::syscall_regs*, void*){
if(scheduler::is_started()){ if(scheduler::is_started()){
primary_lock.release(); primary_lock.release();
} else { } 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()){ if(scheduler::is_started()){
secondary_lock.release(); secondary_lock.release();
} else { } else {
@ -387,8 +387,8 @@ void ata::detect_disks(){
out_byte(ATA_PRIMARY + ATA_DEV_CTL, 0); out_byte(ATA_PRIMARY + ATA_DEV_CTL, 0);
out_byte(ATA_SECONDARY + ATA_DEV_CTL, 0); out_byte(ATA_SECONDARY + ATA_DEV_CTL, 0);
interrupt::register_irq_handler(14, primary_controller_handler); interrupt::register_irq_handler(14, primary_controller_handler, nullptr);
interrupt::register_irq_handler(15, secondary_controller_handler); interrupt::register_irq_handler(15, secondary_controller_handler, nullptr);
} }
uint8_t ata::number_of_disks(){ uint8_t ata::number_of_disks(){

View File

@ -14,7 +14,7 @@
namespace { namespace {
void timer_handler(interrupt::syscall_regs*){ void timer_handler(interrupt::syscall_regs*, void*){
timer::tick(); timer::tick();
} }
@ -27,5 +27,5 @@ void pit::install(){
out_byte(0x40, static_cast<uint8_t>(divisor)); out_byte(0x40, static_cast<uint8_t>(divisor));
out_byte(0x40, static_cast<uint8_t>(divisor >> 8)); out_byte(0x40, static_cast<uint8_t>(divisor >> 8));
interrupt::register_irq_handler(0, timer_handler); interrupt::register_irq_handler(0, timer_handler, nullptr);
} }

View File

@ -49,7 +49,8 @@ struct idtr {
idt_entry idt_64[64]; idt_entry idt_64[64];
idtr idtr_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 (*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){ 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 //Clear the IRQ handlers
std::fill_n(irq_handlers, 16, nullptr); std::fill_n(irq_handlers, 16, nullptr);
std::fill_n(irq_handler_data, 16, nullptr);
//Give the IDTR address to the CPU //Give the IDTR address to the CPU
asm volatile("lidt [%0]" : : "m" (idtr_64)); 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 there is an handler, call it
if(irq_handlers[regs->code]){ 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" } //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_handlers[irq] = handler;
irq_handler_data[irq] = data;
} }
void interrupt::register_syscall_handler(size_t syscall, void (*handler)(interrupt::syscall_regs*)){ void interrupt::register_syscall_handler(size_t syscall, void (*handler)(interrupt::syscall_regs*)){

View File

@ -90,7 +90,7 @@ char shifted_qwertz[128] = {
0, /* All other keys are undefined */ 0, /* All other keys are undefined */
}; };
void keyboard_handler(interrupt::syscall_regs*){ void keyboard_handler(interrupt::syscall_regs*, void*){
auto key = static_cast<char>(in_byte(0x60)); auto key = static_cast<char>(in_byte(0x60));
stdio::get_active_terminal().send_input(key); stdio::get_active_terminal().send_input(key);
@ -99,7 +99,7 @@ void keyboard_handler(interrupt::syscall_regs*){
} //end of anonymous namespace } //end of anonymous namespace
void keyboard::install_driver(){ 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 // At this point, we need to clear the keyboard buffer
// Otherwise, all the following events will be lost // Otherwise, all the following events will be lost

View File

@ -56,14 +56,10 @@ struct rtl8139_t {
uint64_t cur_rx; //Index inside the buffer 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 void packet_handler(interrupt::syscall_regs*, void* data){
volatile rtl8139_t* saved_desc;
void packet_handler(interrupt::syscall_regs*){
logging::logf(logging::log_level::TRACE, "rtl8139: Packet Received\n"); logging::logf(logging::log_level::TRACE, "rtl8139: Packet Received\n");
auto& desc = *saved_desc; auto& desc = *static_cast<rtl8139_t*>(data);
// Get the interrupt status // Get the interrupt status
auto status = in_word(desc.iobase + ISR); 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(); rtl8139_t* desc = new rtl8139_t();
interface.driver_data = desc; interface.driver_data = desc;
saved_desc = desc;
// 1. Enable PCI Bus Mastering (allows DMA) // 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 // 6. Register IRQ handler
auto irq = pci::read_config_dword(pci_device.bus, pci_device.device, pci_device.function, 0x3c) & 0xFF; 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 // 7. Set IMR + ISR