From 88d1f6f2ae55d96a058eb613c7f389ffde6bb540 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 27 Apr 2026 20:22:28 +0200 Subject: [PATCH] Implement system interrupt prologue and epilogue functions --- xtoskrnl/hl/amd64/irq.cc | 100 ++++++++++++++++++++++++++++++++++- xtoskrnl/hl/i686/irq.cc | 101 +++++++++++++++++++++++++++++++++++- xtoskrnl/includes/hl/irq.hh | 7 +++ 3 files changed, 206 insertions(+), 2 deletions(-) diff --git a/xtoskrnl/hl/amd64/irq.cc b/xtoskrnl/hl/amd64/irq.cc index 963b3ba..4d8f28d 100644 --- a/xtoskrnl/hl/amd64/irq.cc +++ b/xtoskrnl/hl/amd64/irq.cc @@ -10,6 +10,86 @@ #include +/** + * Begins a system interrupt handler by raising the processor's run level and re-enabling + * hardware interrupts to allow preemption by higher-priority events. + * + * @param RunLevel + * Supplies the target run level to raise the processor to. + * + * @param OldRunLevel + * Receives the previous run level before the elevation. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel, + OUT PKRUNLEVEL OldRunLevel) +{ + /* Get the current IRQL */ + *OldRunLevel = KE::RunLevel::GetCurrentRunLevel(); + + /* Raise run level */ + KE::RunLevel::RaiseRunLevel(RunLevel); + + /* Enable interrupts */ + AR::CpuFunc::SetInterruptFlag(); +} + +/** + * Safely concludes an interrupt handler by disabling hardware interrupts. + * + * @param TrapFrame + * Supplies a pointer to the kernel trap frame containing the interrupted execution state. + * + * @param OldRunLevel + * Supplies the previous run level to restore. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL OldRunLevel) +{ + /* Disable interrupts */ + AR::CpuFunc::ClearInterruptFlag(); + + /* End system interrupt */ + EndSystemInterrupt(TrapFrame, OldRunLevel); +} + +/** + * Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware + * controller and restoring the processor's previous run level. + * + * @param TrapFrame + * Supplies a pointer to the kernel trap frame containing the interrupted execution state. + * + * @param OldRunLevel + * Supplies the previous run level to restore. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL OldRunLevel) +{ + /* Send EOI */ + HL::Pic::SendEoi(); + + /* Restore previous run level */ + KE::RunLevel::LowerRunLevel(OldRunLevel); +} + /** * Handles profiling interrupt. * @@ -24,7 +104,7 @@ XTCDECL VOID HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame) { - /* Send EOI*/ + /* Send EOI */ HL::Pic::SendEoi(); } @@ -160,3 +240,21 @@ HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector, /* Update interrupt handler in the processor's interrupt dispatch table */ ProcessorBlock->InterruptDispatchTable[Vector] = Handler; } + +/** + * Requests a software interrupt by sending a Self-IPI mapped to the specified run level. + * + * @param RunLevel + * Supplies the target run level for the software interrupt. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel) +{ + /* Request a software interrupt */ + HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel)); +} diff --git a/xtoskrnl/hl/i686/irq.cc b/xtoskrnl/hl/i686/irq.cc index 03b95df..85288f4 100644 --- a/xtoskrnl/hl/i686/irq.cc +++ b/xtoskrnl/hl/i686/irq.cc @@ -10,6 +10,87 @@ #include + +/** + * Begins a system interrupt handler by raising the processor's run level and re-enabling + * hardware interrupts to allow preemption by higher-priority events. + * + * @param RunLevel + * Supplies the target run level to raise the processor to. + * + * @param OldRunLevel + * Receives the previous run level before the elevation. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel, + OUT PKRUNLEVEL OldRunLevel) +{ + /* Get the current IRQL */ + *OldRunLevel = KE::RunLevel::GetCurrentRunLevel(); + + /* Raise run level */ + KE::RunLevel::RaiseRunLevel(RunLevel); + + /* Enable interrupts */ + AR::CpuFunc::SetInterruptFlag(); +} + +/** + * Safely concludes an interrupt handler by disabling hardware interrupts. + * + * @param TrapFrame + * Supplies a pointer to the kernel trap frame containing the interrupted execution state. + * + * @param OldRunLevel + * Supplies the previous run level to restore. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL OldRunLevel) +{ + /* Disable interrupts */ + AR::CpuFunc::ClearInterruptFlag(); + + /* End system interrupt */ + EndSystemInterrupt(TrapFrame, OldRunLevel); +} + +/** + * Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware + * controller and restoring the processor's previous run level. + * + * @param TrapFrame + * Supplies a pointer to the kernel trap frame containing the interrupted execution state. + * + * @param OldRunLevel + * Supplies the previous run level to restore. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL OldRunLevel) +{ + /* Send EOI */ + HL::Pic::SendEoi(); + + /* Restore previous run level */ + KE::RunLevel::LowerRunLevel(OldRunLevel); +} + /** * Handles profiling interrupt. * @@ -24,7 +105,7 @@ XTCDECL VOID HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame) { - /* Send EOI*/ + /* Send EOI */ HL::Pic::SendEoi(); } @@ -158,3 +239,21 @@ HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector, /* Update interrupt handler in the processor's interrupt dispatch table */ ProcessorBlock->InterruptDispatchTable[Vector] = Handler; } + +/** + * Requests a software interrupt by sending a Self-IPI mapped to the specified run level. + * + * @param RunLevel + * Supplies the target run level for the software interrupt. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel) +{ + /* Request a software interrupt */ + HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel)); +} diff --git a/xtoskrnl/includes/hl/irq.hh b/xtoskrnl/includes/hl/irq.hh index a6ed759..2f49889 100644 --- a/xtoskrnl/includes/hl/irq.hh +++ b/xtoskrnl/includes/hl/irq.hh @@ -18,6 +18,12 @@ namespace HL class Irq { public: + STATIC XTAPI VOID BeginSystemInterrupt(IN KRUNLEVEL RunLevel, + OUT PKRUNLEVEL OldRunLevel); + STATIC XTAPI VOID EndInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL RunLevel); + STATIC XTAPI VOID EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame, + IN KRUNLEVEL RunLevel); STATIC XTCDECL VOID HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame); STATIC XTCDECL VOID HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame); STATIC XTAPI PVOID QueryInterruptHandler(IN ULONG Vector); @@ -26,6 +32,7 @@ namespace HL IN PVOID Handler); STATIC XTAPI VOID RegisterSystemInterruptHandler(IN ULONG Vector, IN PINTERRUPT_HANDLER Handler); + STATIC XTFASTCALL VOID SendSoftwareInterrupt(IN KRUNLEVEL RunLevel); }; }