diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_manager.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_manager.hpp index 235ae00f2..204efd447 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_interrupt_manager.hpp @@ -85,7 +85,6 @@ namespace ams::kern::arch::arm64 { NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level); NOINLINE Result UnbindHandler(s32 irq, s32 core); - NOINLINE Result ClearInterrupt(s32 irq); NOINLINE Result ClearInterrupt(s32 irq, s32 core_id); ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp index acc72dc0d..08808ab94 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp @@ -28,9 +28,10 @@ namespace ams::kern { MESOSPHERE_AUTOOBJECT_TRAITS(KInterruptEvent, KReadableEvent); private: s32 m_interrupt_id; + s32 m_core_id; bool m_is_initialized; public: - constexpr KInterruptEvent() : m_interrupt_id(-1), m_is_initialized(false) { /* ... */ } + constexpr KInterruptEvent() : m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ } virtual ~KInterruptEvent() { /* ... */ } Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type); @@ -58,9 +59,9 @@ namespace ams::kern { virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override; virtual void DoTask() override; - void Unregister(s32 interrupt_id); + void Unregister(s32 interrupt_id, s32 core_id); public: - static Result Register(s32 interrupt_id, bool level, KInterruptEvent *event); + static Result Register(s32 interrupt_id, s32 core_id, bool level, KInterruptEvent *event); }; } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_manager.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_manager.cpp index a554dcf3c..1a1a64a5b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_manager.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_interrupt_manager.cpp @@ -239,14 +239,6 @@ namespace ams::kern::arch::arm64 { } } - Result KInterruptManager::ClearInterrupt(s32 irq) { - R_UNLESS(KInterruptController::IsGlobal(irq), svc::ResultOutOfRange()); - - KScopedInterruptDisable di; - KScopedSpinLock lk(this->GetGlobalInterruptLock()); - return this->ClearGlobal(irq); - } - Result KInterruptManager::ClearInterrupt(s32 irq, s32 core_id) { MESOSPHERE_UNUSED(core_id); diff --git a/libraries/libmesosphere/source/kern_k_interrupt_event.cpp b/libraries/libmesosphere/source/kern_k_interrupt_event.cpp index 08c46dd71..bb88a7d60 100644 --- a/libraries/libmesosphere/source/kern_k_interrupt_event.cpp +++ b/libraries/libmesosphere/source/kern_k_interrupt_event.cpp @@ -27,14 +27,21 @@ namespace ams::kern { Result KInterruptEvent::Initialize(int32_t interrupt_name, ams::svc::InterruptType type) { MESOSPHERE_ASSERT_THIS(); + /* Verify the interrupt is defined and global. */ + R_UNLESS(Kernel::GetInterruptManager().IsInterruptDefined(interrupt_name), svc::ResultOutOfRange()); + R_UNLESS(Kernel::GetInterruptManager().IsGlobal(interrupt_name), svc::ResultOutOfRange()); + /* Set interrupt id. */ m_interrupt_id = interrupt_name; + /* Set core id. */ + m_core_id = GetCurrentCoreId(); + /* Initialize readable event base. */ KReadableEvent::Initialize(nullptr); /* Try to register the task. */ - R_TRY(KInterruptEventTask::Register(m_interrupt_id, type == ams::svc::InterruptType_Level, this)); + R_TRY(KInterruptEventTask::Register(m_interrupt_id, m_core_id, type == ams::svc::InterruptType_Level, this)); /* Mark initialized. */ m_is_initialized = true; @@ -44,7 +51,7 @@ namespace ams::kern { void KInterruptEvent::Finalize() { MESOSPHERE_ASSERT_THIS(); - g_interrupt_event_task_table[m_interrupt_id]->Unregister(m_interrupt_id); + g_interrupt_event_task_table[m_interrupt_id]->Unregister(m_interrupt_id, m_core_id); /* Perform inherited finalization. */ KAutoObjectWithSlabHeapAndContainer::Finalize(); @@ -60,16 +67,12 @@ namespace ams::kern { R_TRY(KReadableEvent::Reset()); /* Clear the interrupt. */ - Kernel::GetInterruptManager().ClearInterrupt(m_interrupt_id); + Kernel::GetInterruptManager().ClearInterrupt(m_interrupt_id, m_core_id); return ResultSuccess(); } - Result KInterruptEventTask::Register(s32 interrupt_id, bool level, KInterruptEvent *event) { - /* Verify the interrupt id is defined and global. */ - R_UNLESS(Kernel::GetInterruptManager().IsInterruptDefined(interrupt_id), svc::ResultOutOfRange()); - R_UNLESS(Kernel::GetInterruptManager().IsGlobal(interrupt_id), svc::ResultOutOfRange()); - + Result KInterruptEventTask::Register(s32 interrupt_id, s32 core_id, bool level, KInterruptEvent *event) { /* Lock the task table. */ KScopedLightLock lk(g_interrupt_event_lock); @@ -96,7 +99,7 @@ namespace ams::kern { KScopedLightLock tlk(task->m_lock); /* Bind the interrupt handler. */ - R_TRY(Kernel::GetInterruptManager().BindHandler(task, interrupt_id, GetCurrentCoreId(), KInterruptController::PriorityLevel_High, true, level)); + R_TRY(Kernel::GetInterruptManager().BindHandler(task, interrupt_id, core_id, KInterruptController::PriorityLevel_High, true, level)); /* Set the event. */ task->m_event = event; @@ -112,7 +115,7 @@ namespace ams::kern { return ResultSuccess(); } - void KInterruptEventTask::Unregister(s32 interrupt_id) { + void KInterruptEventTask::Unregister(s32 interrupt_id, s32 core_id) { MESOSPHERE_ASSERT_THIS(); /* Lock the task table. */ @@ -127,7 +130,7 @@ namespace ams::kern { /* Unbind the interrupt. */ m_event = nullptr; - Kernel::GetInterruptManager().UnbindHandler(interrupt_id, GetCurrentCoreId()); + Kernel::GetInterruptManager().UnbindHandler(interrupt_id, core_id); } KInterruptTask *KInterruptEventTask::OnInterrupt(s32 interrupt_id) {