ReactOS  0.4.14-dev-815-ge410a12
irqobj.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for irqobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Typedefs

typedef VOID(FASTCALLPKI_INTERRUPT_DISPATCH) (IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
 

Functions

ULONG NTAPI KiChainedDispatch2ndLvl (VOID)
 
VOID NTAPI KiGetVectorDispatch (IN ULONG Vector, IN PDISPATCH_INFO Dispatch)
 
VOID NTAPI KiConnectVectorToInterrupt (IN PKINTERRUPT Interrupt, IN CONNECT_TYPE Type)
 
FORCEINLINE DECLSPEC_NORETURN VOID KiExitInterrupt (IN PKTRAP_FRAME TrapFrame, IN KIRQL OldIrql, IN BOOLEAN Spurious)
 
DECLSPEC_NORETURN VOID __cdecl KiUnexpectedInterrupt (VOID)
 
VOID FASTCALL KiUnexpectedInterruptTailHandler (IN PKTRAP_FRAME TrapFrame)
 
VOID FASTCALL KiInterruptDispatch (IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
 
VOID FASTCALL KiChainedDispatch (IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
 
VOID FASTCALL KiInterruptTemplateHandler (IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
 
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

ULONG KiISRTimeout = 55
 
USHORT KiISROverflow = 30000
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file irqobj.c.

Typedef Documentation

◆ PKI_INTERRUPT_DISPATCH

typedef VOID(FASTCALL * PKI_INTERRUPT_DISPATCH) (IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)

Definition at line 190 of file irqobj.c.

Function Documentation

◆ KeConnectInterrupt()

BOOLEAN NTAPI KeConnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 394 of file irqobj.c.

395 {
396  BOOLEAN Connected, Error, Status;
397  KIRQL Irql, OldIrql;
398  UCHAR Number;
399  ULONG Vector;
401 
402  /* Get data from interrupt */
403  Number = Interrupt->Number;
404  Vector = Interrupt->Vector;
405  Irql = Interrupt->Irql;
406 
407  /* Validate the settings */
408  if ((Irql > HIGH_LEVEL) ||
409  (Number >= KeNumberProcessors) ||
410  (Interrupt->SynchronizeIrql < Irql) ||
411  (Interrupt->FloatingSave))
412  {
413  return FALSE;
414  }
415 
416  /* Set defaults */
417  Connected = FALSE;
418  Error = FALSE;
419 
420  /* Set the system affinity and acquire the dispatcher lock */
423 
424  /* Check if it's already been connected */
425  if (!Interrupt->Connected)
426  {
427  /* Get vector dispatching information */
429 
430  /* Check if the vector is already connected */
431  if (Dispatch.Type == NoConnect)
432  {
433  /* Do the connection */
434  Interrupt->Connected = Connected = TRUE;
435 
436  /* Initialize the list */
437  InitializeListHead(&Interrupt->InterruptListEntry);
438 
439  /* Connect and enable the interrupt */
441  Status = HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode);
442  if (!Status) Error = TRUE;
443  }
444  else if ((Dispatch.Type != UnknownConnect) &&
445  (Interrupt->ShareVector) &&
446  (Dispatch.Interrupt->ShareVector) &&
447  (Dispatch.Interrupt->Mode == Interrupt->Mode))
448  {
449  /* The vector is shared and the interrupts are compatible */
450  Interrupt->Connected = Connected = TRUE;
451 
452  /*
453  * Verify the IRQL for chained connect,
454  */
455 #if defined(CONFIG_SMP)
456  ASSERT(Irql <= SYNCH_LEVEL);
457 #else
458  ASSERT(Irql <= (IPI_LEVEL - 2));
459 #endif
460 
461  /* Check if this is the first chain */
462  if (Dispatch.Type != ChainConnect)
463  {
464  /* This is not supported */
465  ASSERT(Dispatch.Interrupt->Mode != Latched);
466 
467  /* Setup the chainned handler */
469  }
470 
471  /* Insert into the interrupt list */
472  InsertTailList(&Dispatch.Interrupt->InterruptListEntry,
473  &Interrupt->InterruptListEntry);
474  }
475  }
476 
477  /* Unlock the dispatcher and revert affinity */
480 
481  /* Check if we failed while trying to connect */
482  if ((Connected) && (Error))
483  {
484  DPRINT1("HalEnableSystemInterrupt failed\n");
485  KeDisconnectInterrupt(Interrupt);
486  Connected = FALSE;
487  }
488 
489  /* Return to caller */
490  return Connected;
491 }
VOID NTAPI KiGetVectorDispatch(IN ULONG Vector, IN PDISPATCH_INFO Dispatch)
Definition: irqobj.c:28
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
#define TRUE
Definition: types.h:120
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
BOOLEAN NTAPI KeDisconnectInterrupt(IN PKINTERRUPT Interrupt)
Definition: irqobj.c:498
#define InsertTailList(ListHead, Entry)
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
UCHAR KIRQL
Definition: env_spec_w32.h:591
Definition: ke.h:22
unsigned char BOOLEAN
#define IPI_LEVEL
Definition: env_spec_w32.h:701
BOOL Error
Definition: chkdsk.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
Status
Definition: gdiplustypes.h:24
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:182
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:798
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt, IN CONNECT_TYPE Type)
Definition: irqobj.c:95
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

◆ KeDisconnectInterrupt()

BOOLEAN NTAPI KeDisconnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 498 of file irqobj.c.

499 {
500  KIRQL OldIrql, Irql;
501  ULONG Vector;
503  PKINTERRUPT NextInterrupt;
504  BOOLEAN State;
505 
506  /* Set the affinity */
507  KeSetSystemAffinityThread(1 << Interrupt->Number);
508 
509  /* Lock the dispatcher */
511 
512  /* Check if it's actually connected */
513  State = Interrupt->Connected;
514  if (State)
515  {
516  /* Get the vector and IRQL */
517  Irql = Interrupt->Irql;
518  Vector = Interrupt->Vector;
519 
520  /* Get vector dispatch data */
522 
523  /* Check if it was chained */
524  if (Dispatch.Type == ChainConnect)
525  {
526  /* Check if the top-level interrupt is being removed */
527 #if defined(CONFIG_SMP)
528  ASSERT(Irql <= SYNCH_LEVEL);
529 #else
530  ASSERT(Irql <= (IPI_LEVEL - 2));
531 #endif
532  if (Interrupt == Dispatch.Interrupt)
533  {
534  /* Get the next one */
535  Dispatch.Interrupt = CONTAINING_RECORD(Dispatch.Interrupt->
536  InterruptListEntry.Flink,
537  KINTERRUPT,
538  InterruptListEntry);
539 
540  /* Reconnect it */
542  }
543 
544  /* Remove it */
545  RemoveEntryList(&Interrupt->InterruptListEntry);
546 
547  /* Get the next one */
548  NextInterrupt = CONTAINING_RECORD(Dispatch.Interrupt->
549  InterruptListEntry.Flink,
550  KINTERRUPT,
551  InterruptListEntry);
552 
553  /* Check if this is the only one left */
554  if (Dispatch.Interrupt == NextInterrupt)
555  {
556  /* Connect it in non-chained mode */
558  }
559  }
560  else
561  {
562  /* Only one left, disable and remove it */
563  HalDisableSystemInterrupt(Interrupt->Vector, Irql);
565  }
566 
567  /* Disconnect it */
568  Interrupt->Connected = FALSE;
569  }
570 
571  /* Unlock the dispatcher and revert affinity */
574 
575  /* Return to caller */
576  return State;
577 }
VOID NTAPI KiGetVectorDispatch(IN ULONG Vector, IN PDISPATCH_INFO Dispatch)
Definition: irqobj.c:28
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
Definition: ke.h:22
unsigned char BOOLEAN
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define IPI_LEVEL
Definition: env_spec_w32.h:701
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:182
enum State_ State
Definition: pofuncs.h:54
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:798
VOID NTAPI KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt, IN CONNECT_TYPE Type)
Definition: irqobj.c:95
unsigned int ULONG
Definition: retypes.h:1

Referenced by KeConnectInterrupt().

◆ 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 326 of file irqobj.c.

337 {
338  ULONG i;
339  PULONG DispatchCode = &Interrupt->DispatchCode[0], Patch = DispatchCode;
340 
341  /* Set the Interrupt Header */
342  Interrupt->Type = InterruptObject;
343  Interrupt->Size = sizeof(KINTERRUPT);
344 
345  /* Check if we got a spinlock */
346  if (SpinLock)
347  {
348  Interrupt->ActualLock = SpinLock;
349  }
350  else
351  {
352  /* This means we'll be usin the built-in one */
353  KeInitializeSpinLock(&Interrupt->SpinLock);
354  Interrupt->ActualLock = &Interrupt->SpinLock;
355  }
356 
357  /* Set the other settings */
358  Interrupt->ServiceRoutine = ServiceRoutine;
359  Interrupt->ServiceContext = ServiceContext;
360  Interrupt->Vector = Vector;
361  Interrupt->Irql = Irql;
362  Interrupt->SynchronizeIrql = SynchronizeIrql;
363  Interrupt->Mode = InterruptMode;
364  Interrupt->ShareVector = ShareVector;
365  Interrupt->Number = ProcessorNumber;
366  Interrupt->FloatingSave = FloatingSave;
367  Interrupt->TickCount = MAXULONG;
368  Interrupt->DispatchCount = MAXULONG;
369 
370  /* Loop the template in memory */
371  for (i = 0; i < DISPATCH_LENGTH; i++)
372  {
373  /* Copy the dispatch code */
374  *DispatchCode++ = ((PULONG)KiInterruptTemplate)[i];
375  }
376 
377  /* Jump to the last 4 bytes */
378  Patch = (PULONG)((ULONG_PTR)Patch +
381 
382  /* Apply the patch */
383  *Patch = PtrToUlong(Interrupt);
384 
385  /* Disconnect it at first */
386  Interrupt->Connected = FALSE;
387 }
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
_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:798
VOID __cdecl KiInterruptTemplate(VOID)
_Out_ PKIRQL Irql
Definition: csq.h:179
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK SpinLock
Definition: iofuncs.h:798
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: patch.h:62
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL SynchronizeIrql
Definition: iofuncs.h:798
#define PtrToUlong(u)
Definition: config.h:107
PULONG KiInterruptTemplateObject
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
_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:798
#define MAXULONG
Definition: typedefs.h:250
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:798
unsigned int * PULONG
Definition: retypes.h:1
#define DISPATCH_LENGTH
Definition: ketypes.h:207
struct _KINTERRUPT KINTERRUPT
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:798

◆ KeSynchronizeExecution()

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

Definition at line 584 of file irqobj.c.

587 {
589  KIRQL OldIrql;
590 
591  /* Raise IRQL */
592  KeRaiseIrql(Interrupt->SynchronizeIrql,
593  &OldIrql);
594 
595  /* Acquire interrupt spinlock */
596  KeAcquireSpinLockAtDpcLevel(Interrupt->ActualLock);
597 
598  /* Call the routine */
600 
601  /* Release lock */
602  KeReleaseSpinLockFromDpcLevel(Interrupt->ActualLock);
603 
604  /* Lower IRQL */
606 
607  /* Return status */
608  return Success;
609 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
UCHAR KIRQL
Definition: env_spec_w32.h:591
unsigned char BOOLEAN
_In_ PKSYNCHRONIZE_ROUTINE SynchronizeRoutine
Definition: kefuncs.h:549
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:549

◆ KiChainedDispatch()

VOID FASTCALL KiChainedDispatch ( IN PKTRAP_FRAME  TrapFrame,
IN PKINTERRUPT  Interrupt 
)

Definition at line 231 of file irqobj.c.

233 {
234  KIRQL OldIrql, OldInterruptIrql = 0;
236  PLIST_ENTRY NextEntry, ListHead;
237 
238  /* Increase interrupt count */
239  KeGetCurrentPrcb()->InterruptCount++;
240 
241  /* Begin the interrupt, making sure it's not spurious */
242  if (HalBeginSystemInterrupt(Interrupt->Irql,
243  Interrupt->Vector,
244  &OldIrql))
245  {
246  /* Get list pointers */
247  ListHead = &Interrupt->InterruptListEntry;
248  NextEntry = ListHead; /* The head is an entry! */
249  while (TRUE)
250  {
251  /* Check if this interrupt's IRQL is higher than the current one */
252  if (Interrupt->SynchronizeIrql > Interrupt->Irql)
253  {
254  /* Raise to higher IRQL */
255  OldInterruptIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
256  }
257 
258  /* Acquire interrupt lock */
259  KxAcquireSpinLock(Interrupt->ActualLock);
260 
261  /* Call the ISR */
262  Handled = Interrupt->ServiceRoutine(Interrupt,
263  Interrupt->ServiceContext);
264 
265  /* Release interrupt lock */
266  KxReleaseSpinLock(Interrupt->ActualLock);
267 
268  /* Check if this interrupt's IRQL is higher than the current one */
269  if (Interrupt->SynchronizeIrql > Interrupt->Irql)
270  {
271  /* Lower the IRQL back */
272  ASSERT(OldInterruptIrql == Interrupt->Irql);
273  KfLowerIrql(OldInterruptIrql);
274  }
275 
276  /* Check if the interrupt got handled and it's level */
277  if ((Handled) && (Interrupt->Mode == LevelSensitive)) break;
278 
279  /* What's next? */
280  NextEntry = NextEntry->Flink;
281 
282  /* Is this the last one? */
283  if (NextEntry == ListHead)
284  {
285  /* Level should not have gotten here */
286  if (Interrupt->Mode == LevelSensitive) break;
287 
288  /* As for edge, we can only exit once nobody can handle the interrupt */
289  if (!Handled) break;
290  }
291 
292  /* Get the interrupt object for the next pass */
293  Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
294  }
295 
296  /* Now call the epilogue code */
297  KiExitInterrupt(TrapFrame, OldIrql, FALSE);
298  }
299  else
300  {
301  /* Now call the epilogue code */
302  KiExitInterrupt(TrapFrame, OldIrql, TRUE);
303  }
304 }
#define TRUE
Definition: types.h:120
FORCEINLINE VOID KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:35
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
UCHAR KIRQL
Definition: env_spec_w32.h:591
unsigned char BOOLEAN
FORCEINLINE VOID KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:20
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ BOOLEAN Handled
Definition: ketypes.h:337
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE DECLSPEC_NORETURN VOID KiExitInterrupt(IN PKTRAP_FRAME TrapFrame, IN KIRQL OldIrql, IN BOOLEAN Spurious)
Definition: irqobj.c:135
Definition: typedefs.h:117
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232

Referenced by KiGetVectorDispatch().

◆ KiChainedDispatch2ndLvl()

ULONG NTAPI KiChainedDispatch2ndLvl ( VOID  )

◆ KiConnectVectorToInterrupt()

VOID NTAPI KiConnectVectorToInterrupt ( IN PKINTERRUPT  Interrupt,
IN CONNECT_TYPE  Type 
)

Definition at line 95 of file irqobj.c.

97 {
100 
101  /* Get vector data */
102  KiGetVectorDispatch(Interrupt->Vector, &Dispatch);
103 
104  /* Check if we're only disconnecting */
105  if (Type == NoConnect)
106  {
107  /* Set the handler to NoDispatch */
108  Handler = Dispatch.NoDispatch;
109  }
110  else
111  {
112  /* Get the right handler */
113  Handler = (Type == NormalConnect) ?
114  Dispatch.InterruptDispatch:
115  Dispatch.ChainedDispatch;
116  ASSERT(Interrupt->FloatingSave == FALSE);
117 
118  /* Set the handler */
119  Interrupt->DispatchAddress = Handler;
120 
121  /* Read note in trap.s -- patching not needed since JMP is static */
122 
123  /* Now set the final handler address */
124  ASSERT(Dispatch.FlatDispatch == NULL);
125  Handler = (PVOID)&Interrupt->DispatchCode;
126  }
127 
128  /* Register the interrupt */
129  KeRegisterInterruptHandler(Interrupt->Vector, Handler);
130 }
VOID NTAPI KiGetVectorDispatch(IN ULONG Vector, IN PDISPATCH_INFO Dispatch)
Definition: irqobj.c:28
Type
Definition: Type.h:6
Definition: ke.h:22
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
VOID(NTAPI * PKINTERRUPT_ROUTINE)(VOID)
Definition: ketypes.h:490
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:668
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:242
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:182

Referenced by KeConnectInterrupt(), and KeDisconnectInterrupt().

◆ KiExitInterrupt()

FORCEINLINE DECLSPEC_NORETURN VOID KiExitInterrupt ( IN PKTRAP_FRAME  TrapFrame,
IN KIRQL  OldIrql,
IN BOOLEAN  Spurious 
)

Definition at line 135 of file irqobj.c.

138 {
139  /* Check if this was a real interrupt */
140  if (!Spurious)
141  {
142  /* It was, disable interrupts and restore the IRQL */
143  _disable();
144  HalEndSystemInterrupt(OldIrql, TrapFrame);
145  }
146 
147  /* Now exit the trap */
148  KiEoiHelper(TrapFrame);
149 }
VOID NTAPI HalEndSystemInterrupt(IN KIRQL OldIrql, IN PKTRAP_FRAME TrapFrame)
Definition: pic.c:335
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
void __cdecl _disable(void)
Definition: intrin_arm.h:365

Referenced by KiChainedDispatch(), KiInterruptDispatch(), and KiUnexpectedInterruptTailHandler().

◆ KiGetVectorDispatch()

VOID NTAPI KiGetVectorDispatch ( IN ULONG  Vector,
IN PDISPATCH_INFO  Dispatch 
)

Definition at line 28 of file irqobj.c.

30 {
32  PVOID Current;
33  UCHAR Type;
34  UCHAR Entry;
35 
36  /* Check if this is a primary or 2nd-level dispatch */
38  &Dispatch->FlatDispatch,
39  &Dispatch->NoDispatch);
40  ASSERT(Type == 0);
41 
42  /* Get the IDT entry for this vector */
44 
45  /* Setup the unhandled dispatch */
46  Dispatch->NoDispatch = (PVOID)(((ULONG_PTR)&KiStartUnexpectedRange) +
49 
50  /* Setup the handlers */
51  Dispatch->InterruptDispatch = (PVOID)KiInterruptDispatch;
52  Dispatch->FloatingDispatch = NULL; // Floating Interrupts are not supported
53  Dispatch->ChainedDispatch = (PVOID)KiChainedDispatch;
54  Dispatch->FlatDispatch = NULL;
55 
56  /* Get the current handler */
58 
59  /* Set the interrupt */
60  Dispatch->Interrupt = CONTAINING_RECORD(Current,
61  KINTERRUPT,
62  DispatchCode);
63 
64  /* Check what this interrupt is connected to */
65  if ((PKINTERRUPT_ROUTINE)Current == Dispatch->NoDispatch)
66  {
67  /* Not connected */
68  Dispatch->Type = NoConnect;
69  }
70  else
71  {
72  /* Get the handler */
73  Handler = Dispatch->Interrupt->DispatchAddress;
74  if (Handler == Dispatch->ChainedDispatch)
75  {
76  /* It's a chained interrupt */
77  Dispatch->Type = ChainConnect;
78  }
79  else if ((Handler == Dispatch->InterruptDispatch) ||
80  (Handler == Dispatch->FloatingDispatch))
81  {
82  /* It's unchained */
83  Dispatch->Type = NormalConnect;
84  }
85  else
86  {
87  /* Unknown */
88  Dispatch->Type = UnknownConnect;
89  }
90  }
91 }
Type
Definition: Type.h:6
struct _Entry Entry
Definition: kefuncs.h:640
ULONG KiUnexpectedEntrySize
VOID FASTCALL KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
Definition: irqobj.c:197
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
VOID NTAPI KiStartUnexpectedRange(VOID)
FORCEINLINE PVOID KeQueryInterruptHandler(IN ULONG Vector)
Definition: ke.h:268
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: ke.h:22
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID(NTAPI * PKINTERRUPT_ROUTINE)(VOID)
Definition: ketypes.h:490
UCHAR FASTCALL HalSystemVectorDispatchEntry(IN ULONG Vector, OUT PKINTERRUPT_ROUTINE **FlatDispatch, OUT PKINTERRUPT_ROUTINE *NoConnection)
Definition: misc.c:24
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:668
VOID FASTCALL KiChainedDispatch(IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
Definition: irqobj.c:231
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:182
base of all file and directory entries
Definition: entries.h:82
#define HalVectorToIDTEntry
Definition: halfuncs.h:51

Referenced by KeConnectInterrupt(), KeDisconnectInterrupt(), and KiConnectVectorToInterrupt().

◆ KiInterruptDispatch()

VOID FASTCALL KiInterruptDispatch ( IN PKTRAP_FRAME  TrapFrame,
IN PKINTERRUPT  Interrupt 
)

Definition at line 197 of file irqobj.c.

199 {
200  KIRQL OldIrql;
201 
202  /* Increase interrupt count */
203  KeGetCurrentPrcb()->InterruptCount++;
204 
205  /* Begin the interrupt, making sure it's not spurious */
206  if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
207  Interrupt->Vector,
208  &OldIrql))
209  {
210  /* Acquire interrupt lock */
211  KxAcquireSpinLock(Interrupt->ActualLock);
212 
213  /* Call the ISR */
214  Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
215 
216  /* Release interrupt lock */
217  KxReleaseSpinLock(Interrupt->ActualLock);
218 
219  /* Now call the epilogue code */
220  KiExitInterrupt(TrapFrame, OldIrql, FALSE);
221  }
222  else
223  {
224  /* Now call the epilogue code */
225  KiExitInterrupt(TrapFrame, OldIrql, TRUE);
226  }
227 }
#define TRUE
Definition: types.h:120
FORCEINLINE VOID KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:35
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
UCHAR KIRQL
Definition: env_spec_w32.h:591
FORCEINLINE VOID KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:20
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE DECLSPEC_NORETURN VOID KiExitInterrupt(IN PKTRAP_FRAME TrapFrame, IN KIRQL OldIrql, IN BOOLEAN Spurious)
Definition: irqobj.c:135

Referenced by KiGetVectorDispatch().

◆ KiInterruptTemplateHandler()

VOID FASTCALL KiInterruptTemplateHandler ( IN PKTRAP_FRAME  TrapFrame,
IN PKINTERRUPT  Interrupt 
)

Definition at line 308 of file irqobj.c.

310 {
311  /* Enter interrupt frame */
312  KiEnterInterruptTrap(TrapFrame);
313 
314  /* Call the correct dispatcher */
315  ((PKI_INTERRUPT_DISPATCH)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
316 }
VOID(FASTCALL * PKI_INTERRUPT_DISPATCH)(IN PKTRAP_FRAME TrapFrame, IN PKINTERRUPT Interrupt)
Definition: irqobj.c:190
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:369

◆ KiUnexpectedInterrupt()

DECLSPEC_NORETURN VOID __cdecl KiUnexpectedInterrupt ( VOID  )

Definition at line 154 of file irqobj.c.

155 {
156  /* Crash the machine */
157  KeBugCheck(TRAP_CAUSE_UNKNOWN);
158 }
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507

◆ KiUnexpectedInterruptTailHandler()

VOID FASTCALL KiUnexpectedInterruptTailHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 162 of file irqobj.c.

163 {
164  KIRQL OldIrql;
165 
166  /* Enter trap */
167  KiEnterInterruptTrap(TrapFrame);
168 
169  /* Increase interrupt count */
170  KeGetCurrentPrcb()->InterruptCount++;
171 
172  /* Start the interrupt */
173  if (HalBeginSystemInterrupt(HIGH_LEVEL, TrapFrame->ErrCode, &OldIrql))
174  {
175  /* Warn user */
176  DPRINT1("\n\x7\x7!!! Unexpected Interrupt 0x%02lx !!!\n", TrapFrame->ErrCode);
177 
178  /* Now call the epilogue code */
179  KiExitInterrupt(TrapFrame, OldIrql, FALSE);
180  }
181  else
182  {
183  /* Now call the epilogue code */
184  KiExitInterrupt(TrapFrame, OldIrql, TRUE);
185  }
186 }
#define TRUE
Definition: types.h:120
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
BOOLEAN NTAPI HalBeginSystemInterrupt(IN KIRQL Irql, IN ULONG Vector, OUT PKIRQL OldIrql)
Definition: pic.c:321
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE DECLSPEC_NORETURN VOID KiExitInterrupt(IN PKTRAP_FRAME TrapFrame, IN KIRQL OldIrql, IN BOOLEAN Spurious)
Definition: irqobj.c:135
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
FORCEINLINE VOID KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:369
#define DPRINT1
Definition: precomp.h:8

Variable Documentation

◆ KiISROverflow

USHORT KiISROverflow = 30000

Definition at line 21 of file irqobj.c.

◆ KiISRTimeout

ULONG KiISRTimeout = 55

Definition at line 20 of file irqobj.c.