mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-11 21:44:37 -04:00
Improve IRQ system
Pass some data that is forwarded to the handler
This commit is contained in:
parent
e6a2cf0b95
commit
53a2a07784
@ -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
|
||||||
|
@ -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(){
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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*)){
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user