diff --git a/Kernel/Arch/aarch64/Interrupts.cpp b/Kernel/Arch/aarch64/Interrupts.cpp index 65a3a7278d9..e28802c0c79 100644 --- a/Kernel/Arch/aarch64/Interrupts.cpp +++ b/Kernel/Arch/aarch64/Interrupts.cpp @@ -214,11 +214,6 @@ void register_generic_interrupt_handler(InterruptNumber interrupt_number, Generi return; } if (!handler_slot->is_shared_handler()) { - if (handler_slot->type() == HandlerType::SpuriousInterruptHandler) { - // FIXME: Add support for spurious interrupts on aarch64 - TODO_AARCH64(); - } - VERIFY(handler_slot->type() == HandlerType::IRQHandler); auto& previous_handler = *handler_slot; diff --git a/Kernel/Arch/riscv64/Interrupts.cpp b/Kernel/Arch/riscv64/Interrupts.cpp index c6473f58a46..dc035559e69 100644 --- a/Kernel/Arch/riscv64/Interrupts.cpp +++ b/Kernel/Arch/riscv64/Interrupts.cpp @@ -215,11 +215,6 @@ void register_generic_interrupt_handler(InterruptNumber interrupt_number, Generi return; } if (!handler_slot->is_shared_handler()) { - if (handler_slot->type() == HandlerType::SpuriousInterruptHandler) { - // FIXME: Add support for spurious interrupts on riscv64 - TODO_RISCV64(); - } - VERIFY(handler_slot->type() == HandlerType::IRQHandler); auto& previous_handler = *handler_slot; diff --git a/Kernel/Arch/x86_64/InterruptManagement.cpp b/Kernel/Arch/x86_64/InterruptManagement.cpp index c19cb9286a7..da9db92136d 100644 --- a/Kernel/Arch/x86_64/InterruptManagement.cpp +++ b/Kernel/Arch/x86_64/InterruptManagement.cpp @@ -11,11 +11,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -138,8 +138,8 @@ UNMAP_AFTER_INIT void InterruptManagement::switch_to_pic_mode() dmesgln("Interrupts: Switch to Legacy PIC mode"); InterruptDisabler disabler; m_interrupt_controllers.try_append(adopt_lock_ref(*new PIC())).release_value_but_fixme_should_propagate_errors(); - SpuriousInterruptHandler::initialize(7); - SpuriousInterruptHandler::initialize(15); + PICSpuriousInterruptHandler::initialize(7); + PICSpuriousInterruptHandler::initialize(15); dbgln("Interrupts: Detected {}", m_interrupt_controllers[0]->model()); } @@ -169,8 +169,8 @@ UNMAP_AFTER_INIT void InterruptManagement::switch_to_ioapic_mode() if (irq_controller->type() == IRQControllerType::i8259) { irq_controller->hard_disable(); dbgln("Interrupts: Detected {} - Disabled", irq_controller->model()); - SpuriousInterruptHandler::initialize_for_disabled_master_pic(); - SpuriousInterruptHandler::initialize_for_disabled_slave_pic(); + PICSpuriousInterruptHandler::initialize_for_disabled_master_pic(); + PICSpuriousInterruptHandler::initialize_for_disabled_slave_pic(); } else { dbgln("Interrupts: Detected {}", irq_controller->model()); } diff --git a/Kernel/Arch/x86_64/Interrupts.cpp b/Kernel/Arch/x86_64/Interrupts.cpp index 00503345490..84198654edd 100644 --- a/Kernel/Arch/x86_64/Interrupts.cpp +++ b/Kernel/Arch/x86_64/Interrupts.cpp @@ -9,11 +9,12 @@ #include #include +#include #include +#include #include #include #include -#include #include #include #include @@ -429,7 +430,12 @@ void register_generic_interrupt_handler(InterruptNumber interrupt_number, Generi } if (!handler_slot->is_shared_handler()) { if (handler_slot->type() == HandlerType::SpuriousInterruptHandler) { - static_cast(handler_slot)->register_handler(handler); + auto controller = InterruptManagement::the().get_responsible_irq_controller(interrupt_number); + + // Only PICs should ever have spurious interrupts that are shared with real interrupts. + VERIFY(controller->type() == IRQControllerType::i8259); + static_cast(handler_slot)->register_handler(handler); + return; } diff --git a/Kernel/Interrupts/SpuriousInterruptHandler.cpp b/Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.cpp similarity index 66% rename from Kernel/Interrupts/SpuriousInterruptHandler.cpp rename to Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.cpp index 32d4da1ce0f..77832f3870e 100644 --- a/Kernel/Interrupts/SpuriousInterruptHandler.cpp +++ b/Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.cpp @@ -6,42 +6,42 @@ #include #include -#include +#include #include namespace Kernel { -UNMAP_AFTER_INIT void SpuriousInterruptHandler::initialize(InterruptNumber interrupt_number) +UNMAP_AFTER_INIT void PICSpuriousInterruptHandler::initialize(InterruptNumber interrupt_number) { - auto* handler = new SpuriousInterruptHandler(interrupt_number); + auto* handler = new PICSpuriousInterruptHandler(interrupt_number); handler->register_interrupt_handler(); } -void SpuriousInterruptHandler::initialize_for_disabled_master_pic() +void PICSpuriousInterruptHandler::initialize_for_disabled_master_pic() { - auto* handler = new SpuriousInterruptHandler(7); + auto* handler = new PICSpuriousInterruptHandler(7); register_disabled_interrupt_handler(7, *handler); handler->enable_interrupt_vector_for_disabled_pic(); } -void SpuriousInterruptHandler::initialize_for_disabled_slave_pic() +void PICSpuriousInterruptHandler::initialize_for_disabled_slave_pic() { - auto* handler = new SpuriousInterruptHandler(15); + auto* handler = new PICSpuriousInterruptHandler(15); register_disabled_interrupt_handler(15, *handler); handler->enable_interrupt_vector_for_disabled_pic(); } -void SpuriousInterruptHandler::register_handler(GenericInterruptHandler& handler) +void PICSpuriousInterruptHandler::register_handler(GenericInterruptHandler& handler) { VERIFY(!m_real_handler); m_real_handler = adopt_own_if_nonnull(&handler); } -void SpuriousInterruptHandler::unregister_handler(GenericInterruptHandler&) +void PICSpuriousInterruptHandler::unregister_handler(GenericInterruptHandler&) { TODO(); } -bool SpuriousInterruptHandler::eoi() +bool PICSpuriousInterruptHandler::eoi() { // Actually check if IRQ7 or IRQ15 are spurious, and if not, call EOI with the correct interrupt number. if (m_real_irq) { @@ -53,22 +53,22 @@ bool SpuriousInterruptHandler::eoi() return false; } -StringView SpuriousInterruptHandler::purpose() const +StringView PICSpuriousInterruptHandler::purpose() const { if (!m_real_handler) return "Spurious Interrupt Handler"sv; return m_real_handler->purpose(); } -SpuriousInterruptHandler::SpuriousInterruptHandler(InterruptNumber irq) +PICSpuriousInterruptHandler::PICSpuriousInterruptHandler(InterruptNumber irq) : GenericInterruptHandler(irq) , m_responsible_irq_controller(InterruptManagement::the().get_responsible_irq_controller(irq)) { } -SpuriousInterruptHandler::~SpuriousInterruptHandler() = default; +PICSpuriousInterruptHandler::~PICSpuriousInterruptHandler() = default; -bool SpuriousInterruptHandler::handle_interrupt() +bool PICSpuriousInterruptHandler::handle_interrupt() { // Actually check if IRQ7 or IRQ15 are spurious, and if not, call the real handler to handle the IRQ. if (m_responsible_irq_controller->get_isr() & (1 << interrupt_number().value())) { @@ -83,13 +83,13 @@ bool SpuriousInterruptHandler::handle_interrupt() return true; } -void SpuriousInterruptHandler::enable_interrupt_vector_for_disabled_pic() +void PICSpuriousInterruptHandler::enable_interrupt_vector_for_disabled_pic() { m_enabled = true; m_responsible_irq_controller = InterruptManagement::the().get_responsible_irq_controller(IRQControllerType::i8259, interrupt_number()); } -void SpuriousInterruptHandler::enable_interrupt_vector() +void PICSpuriousInterruptHandler::enable_interrupt_vector() { if (m_enabled) return; @@ -97,7 +97,7 @@ void SpuriousInterruptHandler::enable_interrupt_vector() m_responsible_irq_controller->enable(*this); } -void SpuriousInterruptHandler::disable_interrupt_vector() +void PICSpuriousInterruptHandler::disable_interrupt_vector() { VERIFY(!m_real_irq); // this flag should not be set when we call this method if (!m_enabled) @@ -106,7 +106,7 @@ void SpuriousInterruptHandler::disable_interrupt_vector() m_responsible_irq_controller->disable(*this); } -StringView SpuriousInterruptHandler::controller() const +StringView PICSpuriousInterruptHandler::controller() const { if (m_responsible_irq_controller->type() == IRQControllerType::i82093AA) return ""sv; diff --git a/Kernel/Interrupts/SpuriousInterruptHandler.h b/Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.h similarity index 87% rename from Kernel/Interrupts/SpuriousInterruptHandler.h rename to Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.h index 9e455a1c2ff..e63ea5206c0 100644 --- a/Kernel/Interrupts/SpuriousInterruptHandler.h +++ b/Kernel/Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.h @@ -13,12 +13,12 @@ namespace Kernel { -class SpuriousInterruptHandler final : public GenericInterruptHandler { +class PICSpuriousInterruptHandler final : public GenericInterruptHandler { public: static void initialize(InterruptNumber interrupt_number); static void initialize_for_disabled_master_pic(); static void initialize_for_disabled_slave_pic(); - virtual ~SpuriousInterruptHandler(); + virtual ~PICSpuriousInterruptHandler(); virtual bool handle_interrupt() override; void register_handler(GenericInterruptHandler&); @@ -38,7 +38,7 @@ public: private: void enable_interrupt_vector(); void disable_interrupt_vector(); - explicit SpuriousInterruptHandler(InterruptNumber interrupt_number); + explicit PICSpuriousInterruptHandler(InterruptNumber interrupt_number); bool m_enabled { false }; bool m_real_irq { false }; NonnullLockRefPtr m_responsible_irq_controller; diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index ee15103f364..6bc7875a4b5 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -428,6 +428,7 @@ if ("${SERENITY_ARCH}" STREQUAL "x86_64") Arch/x86_64/Interrupts/APIC.cpp Arch/x86_64/Interrupts/IOAPIC.cpp Arch/x86_64/Interrupts/PIC.cpp + Arch/x86_64/Interrupts/PICSpuriousInterruptHandler.cpp Arch/x86_64/Time/APICTimer.cpp Arch/x86_64/Time/HPET.cpp Arch/x86_64/Time/HPETComparator.cpp @@ -446,9 +447,6 @@ if ("${SERENITY_ARCH}" STREQUAL "x86_64") Arch/x86_64/RTC.cpp Arch/x86_64/Shutdown.cpp Arch/x86_64/SmapDisabler.cpp - - # TODO: Share this with the aarch64 build - Interrupts/SpuriousInterruptHandler.cpp ) set(KERNEL_SOURCES diff --git a/Kernel/Interrupts/GenericInterruptHandler.h b/Kernel/Interrupts/GenericInterruptHandler.h index 9346784d28b..62f757bb978 100644 --- a/Kernel/Interrupts/GenericInterruptHandler.h +++ b/Kernel/Interrupts/GenericInterruptHandler.h @@ -17,7 +17,9 @@ enum class HandlerType : u8 { IRQHandler = 1, SharedIRQHandler = 2, UnhandledInterruptHandler = 3, +#if ARCH(X86_64) SpuriousInterruptHandler = 4 +#endif }; class GenericInterruptHandler {