mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-09 12:31:06 -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 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
|
||||
|
@ -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(){
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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*)){
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user