Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1993 Microsoft Corporation Copyright (c) 1998 Intel Corporation
Module Name:
intsupc.c
Abstract:
This module implements ruotines for interrupt support.
Author:
Bernard Lint 5-May-1998
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
__inline VOID KiLowerIrqlSpecial(KIRQL NewIrql) { __setReg( CV_IA64_SaTPR, (NewIrql << TPR_IRQL_SHIFT)); KeGetPcr()->CurrentIrql = NewIrql; }
VOID KiDispatchSoftwareInterrupt ( KIRQL Irql )
/*++
Routine Description:
Dispatch pending software interrupt
Arguments:
Irql (a0) - Software interrupt to dispatch
Return Value:
None.
Notes:
Interrupts disabled on entry/return. The function is only called by KiCheckForSoftwareInterrupt that passes an Irql value of APC_LEVEL or DISPATCH_LEVEL.
--*/
{ KiLowerIrqlSpecial(Irql); // set IRQL
if (Irql == APC_LEVEL) {
PCR->ApcInterrupt = 0;
_enable();
//
// Dispatch APC Interrupt via direct call to KiDeliverApc
//
KiDeliverApc(KernelMode,NULL,NULL);
_disable();
} else {
PCR->DispatchInterrupt = 0;
_enable();
//
// Dispatch DPC Interrupt
//
KiDispatchInterrupt();
_disable();
} }
VOID KiCheckForSoftwareInterrupt ( KIRQL RequestIrql )
/*++
Routine Description:
Check for and dispatch pending software interrupts
Arguments:
Irql (a0) - New, lower IRQL
Return Value:
None.
Notes:
Caller must check IRQL has dropped below s/w IRQL level
--*/
{ BOOLEAN InterruptState;
InterruptState = KeDisableInterrupts();
if (RequestIrql == APC_LEVEL) {
//
// Dispatch only DPC requests
//
while (PCR->DispatchInterrupt) { KiDispatchSoftwareInterrupt(DISPATCH_LEVEL); }
} else {
//
// Dispatch either APC or DPC
//
while (PCR->SoftwareInterruptPending) { KIRQL Irql;
if (PCR->DispatchInterrupt) { Irql = DISPATCH_LEVEL; } else { Irql = APC_LEVEL; } KiDispatchSoftwareInterrupt(Irql); } }
//
// Lower IRQL to the requested level, restore interrupts and
// return.
//
KiLowerIrqlSpecial(RequestIrql); KeEnableInterrupts(InterruptState); }
VOID KiRequestSoftwareInterrupt ( KIRQL RequestIrql )
/*++
Routine Description:
This function requests a software interrupt at the specified IRQL level.
Arguments:
RequestIrql (a0) - Supplies the request IRQL value.
Return Value:
None.
--*/
{ KIRQL Irql;
#if DEBUG
if ((RequestIrql < APC_LEVEL) || (RequestIrql > DISPATCH_LEVEL)) KeBugCheckEx(INVALID_SOFTWARE_INTERRUPT, RequestIrql, 0, 0, 0); #endif
((PUCHAR)&PCR->SoftwareInterruptPending)[RequestIrql-APC_LEVEL] = 1;
Irql = KeGetCurrentIrql(); if (Irql < RequestIrql) { KeLowerIrql (Irql); } }
#undef KeRaiseIrql
VOID KeRaiseIrql ( IN KIRQL NewIrql, OUT PKIRQL OldIrql ) /*++
Routine Description:
This function raises the current IRQL to the specified value and returns the previous IRQL.
Arguments:
NewIrql - Supplies the new IRQL value.
OldIrql - Supplies a pointer to the location where the old IRQL is stored. Return Value:
None.
--*/ { *OldIrql = KfRaiseIrql(NewIrql); }
|