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 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

View File

@ -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(){

View File

@ -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<uint8_t>(divisor));
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];
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*)){

View File

@ -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<char>(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

View File

@ -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<rtl8139_t*>(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