kern: update KInterruptEvent to store core id

This commit is contained in:
Michael Scire 2021-04-07 01:25:42 -07:00 committed by SciresM
parent e64fef109c
commit f67d1b7026
4 changed files with 18 additions and 23 deletions

View file

@ -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) {

View file

@ -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);
};
}

View file

@ -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);

View file

@ -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<KInterruptEvent, KReadableEvent>::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) {