VOID 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, &OldIrql)) { /* 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); } else { /* Now call the epilogue code */ KiExitInterrupt(TrapFrame, OldIrql, TRUE); } }
/* * @implemented */ VOID KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle) { /* Simply lower IRQL back */ KxReleaseSpinLock(LockHandle->LockQueue.Lock); // HACK KeLowerIrql(LockHandle->OldIrql); }
/* * @implemented */ VOID FASTCALL KfReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL OldIrql) { /* Release the lock and lower IRQL back */ KxReleaseSpinLock(SpinLock); KeLowerIrql(OldIrql); }
/* * @implemented */ VOID KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql) { /* Release the lock */ KxReleaseSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK /* Lower IRQL back */ KeLowerIrql(OldIrql); }
FORCEINLINE VOID _ExiReleaseSpinLockAndRestoreInterupts( IN OUT PKSPIN_LOCK Lock, BOOLEAN Enable) { /* Release the spinlock */ KxReleaseSpinLock(Lock); /* Restore interrupts */ KeRestoreInterrupts(Enable); }
VOID NTAPI HalpReleaseCmosSpinLock(VOID) { ULONG_PTR Flags; /* Get the flags */ Flags = HalpSystemHardwareFlags; /* Release the lock */ KxReleaseSpinLock(&HalpSystemHardwareLock); /* Restore the flags */ __writeeflags(Flags); }
VOID FASTCALL KiChainedDispatch(IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt) { KIRQL OldIrql, OldInterruptIrql = 0; BOOLEAN Handled; PLIST_ENTRY NextEntry, ListHead; /* Increase interrupt count */ KeGetCurrentPrcb()->InterruptCount++; /* Begin the interrupt, making sure it's not spurious */ if (HalBeginSystemInterrupt(Interrupt->Irql, Interrupt->Vector, &OldIrql)) { /* Get list pointers */ 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 */ OldInterruptIrql = KfRaiseIrql(Interrupt->SynchronizeIrql); } /* Acquire interrupt lock */ KxAcquireSpinLock(Interrupt->ActualLock); /* Call the ISR */ Handled = Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext); /* 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 */ 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); } /* Now call the epilogue code */ KiExitInterrupt(TrapFrame, OldIrql, FALSE); } else { /* Now call the epilogue code */ KiExitInterrupt(TrapFrame, OldIrql, TRUE); } }