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 */ KIRQL FASTCALL KfAcquireSpinLock(PKSPIN_LOCK SpinLock) { KIRQL OldIrql; /* Raise to dispatch and acquire the lock */ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); KxAcquireSpinLock(SpinLock); return OldIrql; }
/* * @implemented */ KIRQL KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber) { KIRQL OldIrql; /* Raise to synch */ KeRaiseIrql(SYNCH_LEVEL, &OldIrql); /* Acquire the lock */ KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK return OldIrql; }
/* * @implemented */ KIRQL KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock) { KIRQL OldIrql; /* Raise to sync */ KeRaiseIrql(SYNCH_LEVEL, &OldIrql); /* Acquire the lock and return */ KxAcquireSpinLock(SpinLock); return OldIrql; }
/* * @implemented */ KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber) { KIRQL OldIrql; /* Raise to dispatch */ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* Acquire the lock */ KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK return OldIrql; }
/* * @implemented */ KIRQL NTAPI KeAcquireSpinLockRaiseToDpc(PKSPIN_LOCK SpinLock) { KIRQL OldIrql; /* Raise to dispatch */ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* Acquire the lock and return */ KxAcquireSpinLock(SpinLock); return OldIrql; }
/* * @implemented */ VOID KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle) { /* Set up the lock */ LockHandle->LockQueue.Next = NULL; LockHandle->LockQueue.Lock = SpinLock; /* Raise to synch */ KeRaiseIrql(SYNCH_LEVEL, &LockHandle->OldIrql); /* Acquire the lock */ KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK }
FORCEINLINE BOOLEAN _ExiDisableInteruptsAndAcquireSpinlock( IN OUT PKSPIN_LOCK Lock) { BOOLEAN Enabled; /* Disable interrupts */ Enabled = KeDisableInterrupts(); /* Acquire the spinlock (inline) */ KxAcquireSpinLock(Lock); return Enabled; }
/* * @implemented */ VOID FASTCALL KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle) { /* Set up the lock */ LockHandle->LockQueue.Next = NULL; LockHandle->LockQueue.Lock = SpinLock; /* Raise to dispatch */ KeRaiseIrql(DISPATCH_LEVEL, &LockHandle->OldIrql); /* Acquire the lock */ KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK }
VOID NTAPI HalpAcquireCmosSpinLock(VOID) { ULONG_PTR Flags; /* Get flags and disable interrupts */ Flags = __readeflags(); _disable(); /* Acquire the lock */ KxAcquireSpinLock(&HalpSystemHardwareLock); /* We have the lock, save the flags now */ HalpSystemHardwareFlags = 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); } }