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?
This commit is contained in:
Bananymous 2023-01-25 22:15:32 +02:00
parent 9c31790359
commit e87026f01d
4 changed files with 36 additions and 11 deletions

View File

@ -74,7 +74,7 @@ namespace IDT
static IDTR s_idtr; static IDTR s_idtr;
static GateDescriptor* s_idt = nullptr; static GateDescriptor* s_idt = nullptr;
static void (**s_irq_handlers)(); static void(**s_irq_handlers)();
INTERRUPT_HANDLER____(0x00, "Division Error") INTERRUPT_HANDLER____(0x00, "Division Error")
INTERRUPT_HANDLER____(0x01, "Debug") INTERRUPT_HANDLER____(0x01, "Debug")
@ -137,7 +137,19 @@ namespace IDT
if (s_irq_handlers[irq]) if (s_irq_handlers[irq])
s_irq_handlers[irq](); s_irq_handlers[irq]();
else 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); InterruptController::Get().EOI(irq);
} }
@ -165,7 +177,7 @@ namespace IDT
asm volatile("lidt %0"::"m"(s_idtr)); 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]; GateDescriptor& descriptor = s_idt[index];
descriptor.offset1 = (uint32_t)f & 0xFFFF; descriptor.offset1 = (uint32_t)f & 0xFFFF;
@ -176,7 +188,7 @@ namespace IDT
descriptor.offset2 = (uint32_t)f >> 16; 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; s_irq_handlers[IRQ_VECTOR_BASE + irq] = f;
register_interrupt_handler(IRQ_VECTOR_BASE + irq, handle_irq_common); register_interrupt_handler(IRQ_VECTOR_BASE + irq, handle_irq_common);

View File

@ -30,7 +30,7 @@ namespace IDT
static IDTR s_idtr; static IDTR s_idtr;
static GateDescriptor* s_idt = nullptr; static GateDescriptor* s_idt = nullptr;
static void (*s_irq_handlers[0x10])() { nullptr }; static void(*s_irq_handlers[0x10])() { nullptr };
static const char* isr_exceptions[] = static const char* isr_exceptions[] =
{ {
@ -95,7 +95,19 @@ namespace IDT
if (s_irq_handlers[irq]) if (s_irq_handlers[irq])
s_irq_handlers[irq](); s_irq_handlers[irq]();
else 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); dprintln("no handler for irq 0x{2H}\n", irq);
}
InterruptController::Get().EOI(irq); InterruptController::Get().EOI(irq);
} }
@ -105,7 +117,7 @@ namespace IDT
asm volatile("lidt %0"::"m"(s_idtr)); 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]; GateDescriptor& descriptor = s_idt[index];
descriptor.offset1 = (uint16_t)((uint64_t)f >> 0); descriptor.offset1 = (uint16_t)((uint64_t)f >> 0);
@ -117,7 +129,7 @@ namespace IDT
descriptor.flags = 0x8E; 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; s_irq_handlers[irq] = f;
} }

View File

@ -8,6 +8,6 @@ namespace IDT
{ {
void initialize(); void initialize();
void register_irq_handler(uint8_t irq, void (*f)()); void register_irq_handler(uint8_t irq, void(*f)());
} }

View File

@ -11,7 +11,8 @@
#define PIC2_COMMAND PIC2 #define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1) #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_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ #define ICW1_SINGLE 0x02 /* Single (cascade) mode */
@ -100,8 +101,8 @@ void PIC::EnableIrq(uint8_t irq)
void PIC::GetISR(uint32_t out[8]) void PIC::GetISR(uint32_t out[8])
{ {
memset(out, 0, 8 * sizeof(uint32_t)); memset(out, 0, 8 * sizeof(uint32_t));
IO::outb(PIC1_COMMAND, 0x0b); IO::outb(PIC1_COMMAND, PIC_READ_ISR);
IO::outb(PIC2_COMMAND, 0x0b); IO::outb(PIC2_COMMAND, PIC_READ_ISR);
uint16_t isr0 = IO::inb(PIC1_COMMAND); uint16_t isr0 = IO::inb(PIC1_COMMAND);
uint16_t isr1 = IO::inb(PIC2_COMMAND); uint16_t isr1 = IO::inb(PIC2_COMMAND);