VOID HalpLowerIrql(KIRQL NewIrql) { if (NewIrql >= PROFILE_LEVEL) { KeGetPcr()->Irql = NewIrql; return; } HalpExecuteIrqs(NewIrql); if (NewIrql >= DISPATCH_LEVEL) { KeGetPcr()->Irql = NewIrql; return; } KeGetPcr()->Irql = DISPATCH_LEVEL; if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST]) { ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE; KiDispatchInterrupt(); } KeGetPcr()->Irql = APC_LEVEL; if (NewIrql == APC_LEVEL) { return; } if (KeGetCurrentThread() != NULL && KeGetCurrentThread()->ApcState.KernelApcPending) { KiDeliverApc(KernelMode, NULL, NULL); } KeGetPcr()->Irql = PASSIVE_LEVEL; }
VOID HalpLowerIrql(KIRQL NewIrql, BOOLEAN FromHalEndSystemInterrupt) { ULONG Flags; UCHAR DpcRequested; if (NewIrql >= DISPATCH_LEVEL) { KeSetCurrentIrql (NewIrql); APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI); return; } Flags = __readeflags(); if (KeGetCurrentIrql() > APC_LEVEL) { KeSetCurrentIrql (DISPATCH_LEVEL); APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI); DpcRequested = __readfsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST])); if (FromHalEndSystemInterrupt || DpcRequested) { __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 0); _enable(); KiDispatchInterrupt(); if (!(Flags & EFLAGS_INTERRUPT_MASK)) { _disable(); } } KeSetCurrentIrql (APC_LEVEL); } if (NewIrql == APC_LEVEL) { return; } if (KeGetCurrentThread () != NULL && KeGetCurrentThread ()->ApcState.KernelApcPending) { _enable(); KiDeliverApc(KernelMode, NULL, NULL); if (!(Flags & EFLAGS_INTERRUPT_MASK)) { _disable(); } } KeSetCurrentIrql (PASSIVE_LEVEL); }
VOID DECLSPEC_NORETURN FASTCALL HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame) { KIRQL OldIrql; ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL); /* Enter trap */ KiEnterInterruptTrap(TrapFrame); #ifdef APIC_LAZY_IRQL if (!HalBeginSystemInterrupt(DISPATCH_LEVEL, DISPATCH_VECTOR, &OldIrql)) { /* "Spurious" interrupt, exit the interrupt */ KiEoiHelper(TrapFrame); } #else /* Get the current IRQL */ OldIrql = ApicGetCurrentIrql(); ASSERT(OldIrql < DISPATCH_LEVEL); #endif /* Raise to DISPATCH_LEVEL */ ApicRaiseIrql(DISPATCH_LEVEL); /* End the interrupt */ ApicSendEOI(); /* Enable interrupts and call the kernel's DPC interrupt handler */ _enable(); KiDispatchInterrupt(); _disable(); /* Restore the old IRQL */ ApicLowerIrql(OldIrql); /* Exit the interrupt */ KiEoiHelper(TrapFrame); }