ReactOS 0.4.15-dev-6679-g945ee4b
interrupt.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for interrupt.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

void KiInterruptDispatch (void)
 
VOID NTAPI KeInitializeInterrupt (IN PKINTERRUPT Interrupt, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN CHAR ProcessorNumber, IN BOOLEAN FloatingSave)
 
BOOLEAN NTAPI KeConnectInterrupt (IN PKINTERRUPT Interrupt)
 
BOOLEAN NTAPI KeDisconnectInterrupt (IN PKINTERRUPT Interrupt)
 
BOOLEAN NTAPI KeSynchronizeExecution (IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
 

Variables

UCHAR KiInterruptDispatchTemplate [16]
 
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange [256]
 
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file interrupt.c.

Function Documentation

◆ KeConnectInterrupt()

BOOLEAN NTAPI KeConnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 81 of file interrupt.c.

82{
83 PVOID CurrentHandler;
84 PKINTERRUPT ConnectedInterrupt;
86
90 ASSERT(Interrupt->Irql <= HIGH_LEVEL);
91 ASSERT(Interrupt->SynchronizeIrql >= Interrupt->Irql);
92 ASSERT(Interrupt->Irql == (Interrupt->Vector >> 4));
93
94 /* Check if its already connected */
95 if (Interrupt->Connected) return TRUE;
96
97 /* Set the system affinity and acquire the dispatcher lock */
98 KeSetSystemAffinityThread(1ULL << Interrupt->Number);
100
101 /* Query the current handler */
102 CurrentHandler = KeQueryInterruptHandler(Interrupt->Vector);
103
104 /* Check if the vector is unused */
105 if ((CurrentHandler >= (PVOID)KiUnexpectedRange) &&
106 (CurrentHandler <= (PVOID)KiUnexpectedRangeEnd))
107 {
108 /* Initialize the list for chained interrupts */
109 InitializeListHead(&Interrupt->InterruptListEntry);
110
111 /* Set normal dispatch address */
112 Interrupt->DispatchAddress = KiInterruptDispatch;
113
114 /* Set the new handler */
116 Interrupt->DispatchCode);
117
118 /* Enable the interrupt */
120 Interrupt->Irql,
121 Interrupt->Mode))
122 {
123 /* Didn't work, restore old handler */
124 DPRINT1("HalEnableSystemInterrupt failed\n");
125 KeRegisterInterruptHandler(Interrupt->Vector, CurrentHandler);
126 goto Cleanup;
127 }
128 }
129 else
130 {
131 /* Get the connected interrupt */
132 ConnectedInterrupt = CONTAINING_RECORD(CurrentHandler, KINTERRUPT, DispatchCode);
133
134 /* Check if sharing is ok */
135 if ((Interrupt->ShareVector == 0) ||
136 (ConnectedInterrupt->ShareVector == 0) ||
137 (Interrupt->Mode != ConnectedInterrupt->Mode))
138 {
139 goto Cleanup;
140 }
141
142 /* Insert the new interrupt into the connected interrupt's list */
143 InsertTailList(&ConnectedInterrupt->InterruptListEntry,
144 &Interrupt->InterruptListEntry);
145 }
146
147 /* Mark as connected */
148 Interrupt->Connected = TRUE;
149
150Cleanup:
151 /* Release the dispatcher lock and restore the thread affinity */
154 return Interrupt->Connected;
155}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
static const WCHAR Cleanup[]
Definition: register.c:80
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ASSERT(a)
Definition: mode.c:44
#define MAXIMUM_IDTVECTOR
Definition: asm.h:280
FORCEINLINE PVOID KeQueryInterruptHandler(IN ULONG Vector)
Definition: ke.h:327
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:301
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
void KiInterruptDispatch(void)
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd[]
KINTERRUPT_MODE Mode
Definition: ketypes.h:895
BOOLEAN ShareVector
Definition: ketypes.h:894
LIST_ENTRY InterruptListEntry
Definition: ketypes.h:877
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792

Referenced by IoConnectInterrupt().

◆ KeDisconnectInterrupt()

BOOLEAN NTAPI KeDisconnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 159 of file interrupt.c.

160{
162 PVOID VectorHandler, UnexpectedHandler;
163 PKINTERRUPT VectorFirstInterrupt, NextInterrupt;
164 PLIST_ENTRY HandlerHead;
165
166 /* Set the system affinity and acquire the dispatcher lock */
167 KeSetSystemAffinityThread(1ULL << Interrupt->Number);
169
170 /* Check if the interrupt was connected - otherwise there's nothing to do */
171 if (Interrupt->Connected)
172 {
173 /* Get the handler for this interrupt vector */
174 VectorHandler = KeQueryInterruptHandler(Interrupt->Vector);
175
176 /* Get the first interrupt for this handler */
177 VectorFirstInterrupt = CONTAINING_RECORD(VectorHandler, KINTERRUPT, DispatchCode);
178
179 /* The first interrupt list entry is the interrupt list head */
180 HandlerHead = &VectorFirstInterrupt->InterruptListEntry;
181
182 /* If the list is empty, this is the only interrupt for this vector */
183 if (IsListEmpty(HandlerHead))
184 {
185 /* If the list is empty, and the head is not from this interrupt,
186 * this interrupt is somehow incorrectly connected */
187 ASSERT(VectorFirstInterrupt == Interrupt);
188
189 UnexpectedHandler = &KiUnexpectedRange[Interrupt->Vector]._Op_push;
190
191 /* This is the only interrupt, the handler can be disconnected */
193 KeRegisterInterruptHandler(Interrupt->Vector, UnexpectedHandler);
194 }
195 /* If the interrupt to be disconnected is the list head, but some others follow */
196 else if (VectorFirstInterrupt == Interrupt)
197 {
198 /* Relocate the head to the next element */
199 HandlerHead = HandlerHead->Flink;
200 RemoveTailList(HandlerHead);
201
202 /* Get the next interrupt from the list head */
203 NextInterrupt = CONTAINING_RECORD(HandlerHead,
205 InterruptListEntry);
206
207 /* Set the next interrupt as the handler for this vector */
209 NextInterrupt->DispatchCode);
210 }
211 /* If the interrupt to be disconnected is not the list head */
212 else
213 {
214 /* Remove the to be disconnected interrupt from the interrupt list */
215 RemoveEntryList(&Interrupt->InterruptListEntry);
216 }
217
218 /* Mark as not connected */
219 Interrupt->Connected = FALSE;
220 }
221
222 /* Release the dispatcher lock and restore the thread affinity */
225
226 return TRUE;
227}
#define FALSE
Definition: types.h:117
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
ULONG DispatchCode[DISPATCH_LENGTH]
Definition: ketypes.h:908
UCHAR _Op_push
Definition: ke.h:105
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by IoDisconnectInterrupt().

◆ KeInitializeInterrupt()

VOID NTAPI KeInitializeInterrupt ( IN PKINTERRUPT  Interrupt,
IN PKSERVICE_ROUTINE  ServiceRoutine,
IN PVOID  ServiceContext,
IN PKSPIN_LOCK  SpinLock,
IN ULONG  Vector,
IN KIRQL  Irql,
IN KIRQL  SynchronizeIrql,
IN KINTERRUPT_MODE  InterruptMode,
IN BOOLEAN  ShareVector,
IN CHAR  ProcessorNumber,
IN BOOLEAN  FloatingSave 
)

Definition at line 29 of file interrupt.c.

41{
42
43 /* Initialize the header */
45 Interrupt->Size = sizeof(KINTERRUPT);
46
47 /* If no Spinlock is given, use the internal */
48 if (!SpinLock) SpinLock = &Interrupt->SpinLock;
50
51 /* Set the given parameters */
52 Interrupt->ServiceRoutine = ServiceRoutine;
53 Interrupt->ServiceContext = ServiceContext;
54 Interrupt->ActualLock = SpinLock;
55 Interrupt->Vector = Vector;
56 Interrupt->Irql = Irql;
57 Interrupt->SynchronizeIrql = SynchronizeIrql;
59 Interrupt->ShareVector = ShareVector;
60 Interrupt->Number = ProcessorNumber;
61 Interrupt->FloatingSave = FloatingSave;
62
63 /* Set initial values */
64 Interrupt->TickCount = 0;
65 Interrupt->Connected = FALSE;
66 Interrupt->ServiceCount = 0;
67 Interrupt->DispatchCount = 0;
68 Interrupt->TrapFrame = NULL;
69 Interrupt->Reserved = 0;
70
71 /* Copy the dispatch code (its location independent, no need to patch it) */
72 RtlCopyMemory(Interrupt->DispatchCode,
74 sizeof(Interrupt->DispatchCode));
75
76 Interrupt->DispatchAddress = 0;
77}
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
struct _KINTERRUPT KINTERRUPT
@ InterruptObject
Definition: ketypes.h:461
UCHAR KiInterruptDispatchTemplate[16]
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:228
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:800
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL SynchronizeIrql
Definition: iofuncs.h:805
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN _In_ KAFFINITY _In_ BOOLEAN FloatingSave
Definition: iofuncs.h:809
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN ShareVector
Definition: iofuncs.h:807
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801

Referenced by IoConnectInterrupt().

◆ KeSynchronizeExecution()

BOOLEAN NTAPI KeSynchronizeExecution ( IN OUT PKINTERRUPT  Interrupt,
IN PKSYNCHRONIZE_ROUTINE  SynchronizeRoutine,
IN PVOID SynchronizeContext  OPTIONAL 
)

Definition at line 231 of file interrupt.c.

234{
237
238 /* Raise IRQL */
239 OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
240
241 /* Acquire interrupt spinlock */
243
244 /* Call the routine */
246
247 /* Release lock */
249
250 /* Lower IRQL */
252
253 /* Return status */
254 return Success;
255}
static KSYNCHRONIZE_ROUTINE SynchronizeRoutine
Definition: IoInterrupt.c:30
unsigned char BOOLEAN
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
@ Success
Definition: eventcreate.c:712
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:539

Referenced by _SynchronizeExecution(), FdoCallHWInitialize(), InPortRemoveDevice(), InPortStartDevice(), KspSynchronizedEventRoutine(), NdisMSynchronizeWithInterrupt(), ScsiPortAllocateAdapterChannel(), ScsiPortDpcForIsr(), ScsiPortIoTimer(), ScsiPortStartIo(), SerialDeviceControl(), SpiAdapterControl(), StreamClassStartDevice(), TestSynchronizeExecution(), and VideoPortSynchronizeExecution().

◆ KiInterruptDispatch()

void KiInterruptDispatch ( void  )

Variable Documentation

◆ KiInterruptDispatchTemplate

UCHAR KiInterruptDispatchTemplate[16]
extern

Referenced by KeInitializeInterrupt().

◆ KiUnexpectedRange

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
extern

◆ KiUnexpectedRangeEnd

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd[]
extern

Referenced by KeConnectInterrupt().