From e87026f01dc20838eb1e04a1b3521ad4902d00fa Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 25 Jan 2023 22:15:32 +0200 Subject: [PATCH] Kernel: I have no idea what this commit does I had committed a change in IDT but reverted it now. This propably only adds a spurious interrupt detection to common cpp interrupt handler? --- kernel/arch/i386/IDT.cpp | 20 ++++++++++++++++---- kernel/arch/x86_64/IDT.cpp | 18 +++++++++++++++--- kernel/include/kernel/IDT.h | 2 +- kernel/kernel/PIC.cpp | 7 ++++--- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/kernel/arch/i386/IDT.cpp b/kernel/arch/i386/IDT.cpp index c1681ede..d9460b98 100644 --- a/kernel/arch/i386/IDT.cpp +++ b/kernel/arch/i386/IDT.cpp @@ -74,7 +74,7 @@ namespace IDT static IDTR s_idtr; static GateDescriptor* s_idt = nullptr; - static void (**s_irq_handlers)(); + static void(**s_irq_handlers)(); INTERRUPT_HANDLER____(0x00, "Division Error") INTERRUPT_HANDLER____(0x01, "Debug") @@ -137,7 +137,19 @@ namespace IDT if (s_irq_handlers[irq]) s_irq_handlers[irq](); else - Kernel::Panic("no handler for irq 0x{2H}\n", irq); + { + uint32_t isr_byte = irq / 32; + uint32_t isr_bit = irq % 32; + + uint32_t isr[8]; + InterruptController::Get().GetISR(isr); + if (!(isr[isr_byte] & (1 << isr_bit))) + { + dprintln("spurious irq 0x{2H}", irq); + return; + } + dprintln("no handler for irq 0x{2H}\n", irq); + } InterruptController::Get().EOI(irq); } @@ -165,7 +177,7 @@ namespace IDT asm volatile("lidt %0"::"m"(s_idtr)); } - static void register_interrupt_handler(uint8_t index, void (*f)()) + static void register_interrupt_handler(uint8_t index, void(*f)()) { GateDescriptor& descriptor = s_idt[index]; descriptor.offset1 = (uint32_t)f & 0xFFFF; @@ -176,7 +188,7 @@ namespace IDT descriptor.offset2 = (uint32_t)f >> 16; } - void register_irq_handler(uint8_t irq, void (*f)()) + void register_irq_handler(uint8_t irq, void(*f)()) { s_irq_handlers[IRQ_VECTOR_BASE + irq] = f; register_interrupt_handler(IRQ_VECTOR_BASE + irq, handle_irq_common); diff --git a/kernel/arch/x86_64/IDT.cpp b/kernel/arch/x86_64/IDT.cpp index eee4663d..bb8a62fe 100644 --- a/kernel/arch/x86_64/IDT.cpp +++ b/kernel/arch/x86_64/IDT.cpp @@ -30,7 +30,7 @@ namespace IDT static IDTR s_idtr; static GateDescriptor* s_idt = nullptr; - static void (*s_irq_handlers[0x10])() { nullptr }; + static void(*s_irq_handlers[0x10])() { nullptr }; static const char* isr_exceptions[] = { @@ -95,7 +95,19 @@ namespace IDT if (s_irq_handlers[irq]) s_irq_handlers[irq](); else + { + uint32_t isr_byte = irq / 32; + uint32_t isr_bit = irq % 32; + + uint32_t isr[8]; + InterruptController::Get().GetISR(isr); + if (!(isr[isr_byte] & (1 << isr_bit))) + { + dprintln("spurious irq 0x{2H}", irq); + return; + } dprintln("no handler for irq 0x{2H}\n", irq); + } InterruptController::Get().EOI(irq); } @@ -105,7 +117,7 @@ namespace IDT asm volatile("lidt %0"::"m"(s_idtr)); } - static void register_interrupt_handler(uint8_t index, void (*f)()) + static void register_interrupt_handler(uint8_t index, void(*f)()) { GateDescriptor& descriptor = s_idt[index]; descriptor.offset1 = (uint16_t)((uint64_t)f >> 0); @@ -117,7 +129,7 @@ namespace IDT descriptor.flags = 0x8E; } - void register_irq_handler(uint8_t irq, void (*f)()) + void register_irq_handler(uint8_t irq, void(*f)()) { s_irq_handlers[irq] = f; } diff --git a/kernel/include/kernel/IDT.h b/kernel/include/kernel/IDT.h index 946d956e..f69fb91a 100644 --- a/kernel/include/kernel/IDT.h +++ b/kernel/include/kernel/IDT.h @@ -8,6 +8,6 @@ namespace IDT { void initialize(); - void register_irq_handler(uint8_t irq, void (*f)()); + void register_irq_handler(uint8_t irq, void(*f)()); } \ No newline at end of file diff --git a/kernel/kernel/PIC.cpp b/kernel/kernel/PIC.cpp index f0c34d80..cc98eb65 100644 --- a/kernel/kernel/PIC.cpp +++ b/kernel/kernel/PIC.cpp @@ -11,7 +11,8 @@ #define PIC2_COMMAND PIC2 #define PIC2_DATA (PIC2+1) -#define PIC_EOI 0x20 /* End-of-interrupt command code */ +#define PIC_READ_ISR 0x0B +#define PIC_EOI 0x20 #define ICW1_ICW4 0x01 /* ICW4 (not) needed */ #define ICW1_SINGLE 0x02 /* Single (cascade) mode */ @@ -100,8 +101,8 @@ void PIC::EnableIrq(uint8_t irq) void PIC::GetISR(uint32_t out[8]) { memset(out, 0, 8 * sizeof(uint32_t)); - IO::outb(PIC1_COMMAND, 0x0b); - IO::outb(PIC2_COMMAND, 0x0b); + IO::outb(PIC1_COMMAND, PIC_READ_ISR); + IO::outb(PIC2_COMMAND, PIC_READ_ISR); uint16_t isr0 = IO::inb(PIC1_COMMAND); uint16_t isr1 = IO::inb(PIC2_COMMAND);