mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 22:37:35 +00:00
Kernel/Interrupts: Initialize two spurious handlers when PIC is disabled
Even if the PIC was disabled it can still generate noise (spurious IRQs) so we need to register two handlers for handling such cases. Also, we declare interrupt service routine offset 0x20 to 0x2f as reserved, so when the PIC is disabled, we can handle spurious IRQs from the PIC at separate handlers.
This commit is contained in:
parent
7028a64997
commit
88c5992e0b
8 changed files with 169 additions and 5 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <AK/Types.h>
|
||||
|
||||
#include <Kernel/Interrupts/GenericInterruptHandler.h>
|
||||
#include <Kernel/Interrupts/PIC.h>
|
||||
#include <Kernel/Interrupts/SharedIRQHandler.h>
|
||||
#include <Kernel/Interrupts/SpuriousInterruptHandler.h>
|
||||
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
|
||||
|
@ -42,6 +43,7 @@ READONLY_AFTER_INIT static DescriptorTablePointer s_idtr;
|
|||
READONLY_AFTER_INIT static IDTEntry s_idt[256];
|
||||
|
||||
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
|
||||
static GenericInterruptHandler* s_disabled_interrupt_handler[2];
|
||||
|
||||
static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interrupts };
|
||||
|
||||
|
@ -496,10 +498,24 @@ void handle_interrupt(TrapFrame* trap)
|
|||
{
|
||||
clac();
|
||||
auto& regs = *trap->regs;
|
||||
VERIFY(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
|
||||
u8 irq = (u8)(regs.isr_number - 0x50);
|
||||
s_entropy_source_interrupts.add_random_event(irq);
|
||||
auto* handler = s_interrupt_handler[irq];
|
||||
|
||||
GenericInterruptHandler* handler = nullptr;
|
||||
// Note: we declare interrupt service routine offset 0x20 to 0x2f as
|
||||
// reserved for when the PIC is disabled, so we can still route spurious
|
||||
// IRQs to a different interrupt handlers at different location.
|
||||
if (regs.isr_number >= pic_disabled_vector_base && regs.isr_number <= pic_disabled_vector_end) {
|
||||
u8 irq = (u8)(regs.isr_number - pic_disabled_vector_base);
|
||||
if (irq == 7) {
|
||||
handler = s_disabled_interrupt_handler[0];
|
||||
} else if (irq == 15) {
|
||||
handler = s_disabled_interrupt_handler[1];
|
||||
}
|
||||
} else {
|
||||
VERIFY(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
|
||||
u8 irq = (u8)(regs.isr_number - IRQ_VECTOR_BASE);
|
||||
s_entropy_source_interrupts.add_random_event(irq);
|
||||
handler = s_interrupt_handler[irq];
|
||||
}
|
||||
VERIFY(handler);
|
||||
handler->increment_invoking_counter();
|
||||
handler->handle_interrupt(regs);
|
||||
|
@ -529,6 +545,18 @@ static void revert_to_unused_handler(u8 interrupt_number)
|
|||
handler->register_interrupt_handler();
|
||||
}
|
||||
|
||||
void register_disabled_interrupt_handler(u8 number, GenericInterruptHandler& handler)
|
||||
{
|
||||
if (number == 15) {
|
||||
s_disabled_interrupt_handler[0] = &handler;
|
||||
return;
|
||||
} else if (number == 7) {
|
||||
s_disabled_interrupt_handler[1] = &handler;
|
||||
return;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
|
||||
{
|
||||
VERIFY(interrupt_number < GENERIC_INTERRUPT_HANDLERS_COUNT);
|
||||
|
@ -637,10 +665,58 @@ UNMAP_AFTER_INIT void idt_init()
|
|||
register_interrupt_handler(0x0f, _exception15);
|
||||
register_interrupt_handler(0x10, _exception16);
|
||||
|
||||
for (u8 i = 0x11; i < 0x50; i++)
|
||||
for (u8 i = 0x11; i < 0x20; i++)
|
||||
register_interrupt_handler(i, unimp_trap);
|
||||
|
||||
dbgln("Initializing unhandled interrupt handlers");
|
||||
register_interrupt_handler(0x20, interrupt_32_asm_entry);
|
||||
register_interrupt_handler(0x21, interrupt_33_asm_entry);
|
||||
register_interrupt_handler(0x22, interrupt_34_asm_entry);
|
||||
register_interrupt_handler(0x23, interrupt_35_asm_entry);
|
||||
register_interrupt_handler(0x24, interrupt_36_asm_entry);
|
||||
register_interrupt_handler(0x25, interrupt_37_asm_entry);
|
||||
register_interrupt_handler(0x26, interrupt_38_asm_entry);
|
||||
register_interrupt_handler(0x27, interrupt_39_asm_entry);
|
||||
register_interrupt_handler(0x28, interrupt_40_asm_entry);
|
||||
register_interrupt_handler(0x29, interrupt_41_asm_entry);
|
||||
register_interrupt_handler(0x2a, interrupt_42_asm_entry);
|
||||
register_interrupt_handler(0x2b, interrupt_43_asm_entry);
|
||||
register_interrupt_handler(0x2c, interrupt_44_asm_entry);
|
||||
register_interrupt_handler(0x2d, interrupt_45_asm_entry);
|
||||
register_interrupt_handler(0x2e, interrupt_46_asm_entry);
|
||||
register_interrupt_handler(0x2f, interrupt_47_asm_entry);
|
||||
register_interrupt_handler(0x30, interrupt_48_asm_entry);
|
||||
register_interrupt_handler(0x31, interrupt_49_asm_entry);
|
||||
register_interrupt_handler(0x32, interrupt_50_asm_entry);
|
||||
register_interrupt_handler(0x33, interrupt_51_asm_entry);
|
||||
register_interrupt_handler(0x34, interrupt_52_asm_entry);
|
||||
register_interrupt_handler(0x35, interrupt_53_asm_entry);
|
||||
register_interrupt_handler(0x36, interrupt_54_asm_entry);
|
||||
register_interrupt_handler(0x37, interrupt_55_asm_entry);
|
||||
register_interrupt_handler(0x38, interrupt_56_asm_entry);
|
||||
register_interrupt_handler(0x39, interrupt_57_asm_entry);
|
||||
register_interrupt_handler(0x3a, interrupt_58_asm_entry);
|
||||
register_interrupt_handler(0x3b, interrupt_59_asm_entry);
|
||||
register_interrupt_handler(0x3c, interrupt_60_asm_entry);
|
||||
register_interrupt_handler(0x3d, interrupt_61_asm_entry);
|
||||
register_interrupt_handler(0x3e, interrupt_62_asm_entry);
|
||||
register_interrupt_handler(0x3f, interrupt_63_asm_entry);
|
||||
register_interrupt_handler(0x40, interrupt_64_asm_entry);
|
||||
register_interrupt_handler(0x41, interrupt_65_asm_entry);
|
||||
register_interrupt_handler(0x42, interrupt_66_asm_entry);
|
||||
register_interrupt_handler(0x43, interrupt_67_asm_entry);
|
||||
register_interrupt_handler(0x44, interrupt_68_asm_entry);
|
||||
register_interrupt_handler(0x45, interrupt_69_asm_entry);
|
||||
register_interrupt_handler(0x46, interrupt_70_asm_entry);
|
||||
register_interrupt_handler(0x47, interrupt_71_asm_entry);
|
||||
register_interrupt_handler(0x48, interrupt_72_asm_entry);
|
||||
register_interrupt_handler(0x49, interrupt_73_asm_entry);
|
||||
register_interrupt_handler(0x4a, interrupt_74_asm_entry);
|
||||
register_interrupt_handler(0x4b, interrupt_75_asm_entry);
|
||||
register_interrupt_handler(0x4c, interrupt_76_asm_entry);
|
||||
register_interrupt_handler(0x4d, interrupt_77_asm_entry);
|
||||
register_interrupt_handler(0x4e, interrupt_78_asm_entry);
|
||||
register_interrupt_handler(0x4f, interrupt_79_asm_entry);
|
||||
register_interrupt_handler(0x50, interrupt_80_asm_entry);
|
||||
register_interrupt_handler(0x51, interrupt_81_asm_entry);
|
||||
register_interrupt_handler(0x52, interrupt_82_asm_entry);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue