KeRegisterInterruptHandler(Interrupt->Vector, Handler);
}
-VOID
FORCEINLINE
DECLSPEC_NORETURN
+VOID
KiExitInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KIRQL OldIrql,
IN BOOLEAN Spurious)
_disable();
HalEndSystemInterrupt(OldIrql, TrapFrame);
}
-
+
/* Now exit the trap */
KiEoiHelper(TrapFrame);
}
/* Crash the machine */
KeBugCheck(TRAP_CAUSE_UNKNOWN);
}
-
+
VOID
FASTCALL
KiUnexpectedInterruptTailHandler(IN PKTRAP_FRAME TrapFrame)
{
KIRQL OldIrql;
-
+
/* Enter trap */
KiEnterInterruptTrap(TrapFrame);
-
+
/* Increase interrupt count */
KeGetCurrentPrcb()->InterruptCount++;
-
+
/* Start the interrupt */
if (HalBeginSystemInterrupt(HIGH_LEVEL, TrapFrame->ErrCode, &OldIrql))
{
/* Warn user */
- DPRINT1("\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n");
-
+ DPRINT1("\n\x7\x7!!! Unexpected Interrupt 0x%02lx !!!\n", TrapFrame->ErrCode);
+
/* Now call the epilogue code */
KiExitInterrupt(TrapFrame, OldIrql, FALSE);
}
FASTCALL
KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame,
IN PKINTERRUPT Interrupt)
-{
+{
KIRQL OldIrql;
/* Increase interrupt count */
KeGetCurrentPrcb()->InterruptCount++;
-
+
/* Begin the interrupt, making sure it's not spurious */
if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
Interrupt->Vector,
{
/* Acquire interrupt lock */
KxAcquireSpinLock(Interrupt->ActualLock);
-
+
/* Call the ISR */
Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
-
+
/* Release interrupt lock */
KxReleaseSpinLock(Interrupt->ActualLock);
-
+
/* Now call the epilogue code */
KiExitInterrupt(TrapFrame, OldIrql, FALSE);
}
FASTCALL
KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
IN PKINTERRUPT Interrupt)
-{
- KIRQL OldIrql;
+{
+ KIRQL OldIrql, OldInterruptIrql = 0;
BOOLEAN Handled;
PLIST_ENTRY NextEntry, ListHead;
ListHead = &Interrupt->InterruptListEntry;
NextEntry = ListHead; /* The head is an entry! */
while (TRUE)
- {
+ {
/* Check if this interrupt's IRQL is higher than the current one */
if (Interrupt->SynchronizeIrql > Interrupt->Irql)
{
/* Raise to higher IRQL */
- OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
+ OldInterruptIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
}
-
+
/* Acquire interrupt lock */
KxAcquireSpinLock(Interrupt->ActualLock);
/* Release interrupt lock */
KxReleaseSpinLock(Interrupt->ActualLock);
-
+
/* Check if this interrupt's IRQL is higher than the current one */
if (Interrupt->SynchronizeIrql > Interrupt->Irql)
{
/* Lower the IRQL back */
- KfLowerIrql(OldIrql);
+ ASSERT(OldInterruptIrql == Interrupt->Irql);
+ KfLowerIrql(OldInterruptIrql);
}
-
+
/* Check if the interrupt got handled and it's level */
if ((Handled) && (Interrupt->Mode == LevelSensitive)) break;
-
+
/* What's next? */
NextEntry = NextEntry->Flink;
-
+
/* Is this the last one? */
if (NextEntry == ListHead)
{
/* Level should not have gotten here */
if (Interrupt->Mode == LevelSensitive) break;
-
+
/* As for edge, we can only exit once nobody can handle the interrupt */
if (!Handled) break;
}
-
+
/* Get the interrupt object for the next pass */
Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
}
FASTCALL
KiInterruptTemplateHandler(IN PKTRAP_FRAME TrapFrame,
IN PKINTERRUPT Interrupt)
-{
+{
/* Enter interrupt frame */
KiEnterInterruptTrap(TrapFrame);
IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
IN PVOID SynchronizeContext OPTIONAL)
{
- NTSTATUS Status;
+ BOOLEAN Success;
KIRQL OldIrql;
-
+
/* Raise IRQL */
OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
-
+
/* Acquire interrupt spinlock */
KeAcquireSpinLockAtDpcLevel(Interrupt->ActualLock);
-
+
/* Call the routine */
- Status = SynchronizeRoutine(SynchronizeContext);
-
+ Success = SynchronizeRoutine(SynchronizeContext);
+
/* Release lock */
KeReleaseSpinLockFromDpcLevel(Interrupt->ActualLock);
-
+
/* Lower IRQL */
KfLowerIrql(OldIrql);
-
+
/* Return status */
- return Status;
+ return Success;
}
/* EOF */