branch update for HEAD-2003021201
[reactos.git] / ntoskrnl / ke / i386 / irq.c
index 286ef5e..fd4dbe6 100644 (file)
@@ -41,6 +41,9 @@
 #include <internal/ps.h>
 #include <internal/i386/segment.h>
 #include <internal/pool.h>
+#ifdef KDBG
+#include <../dbg/kdb.h>
+#endif /* KDBG */
 
 #ifdef MP
 #include <internal/hal/mps.h>
@@ -290,6 +293,41 @@ KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
 
 #ifdef MP
 
+VOID STDCALL
+KiInterruptDispatch2 (ULONG Irq, KIRQL old_level)
+/*
+ * FUNCTION: Calls all the interrupt handlers for a given irq.
+ * ARGUMENTS:
+ *        Irq - The number of the irq to call handlers for.
+ *        old_level - The irql of the processor when the irq took place.
+ * NOTES: Must be called at DIRQL.
+ */
+{
+  PKINTERRUPT isr;
+  PLIST_ENTRY current;
+
+   DPRINT("\nWARNING - KiInterruptDispatch2 copied directly from UP version for build\npurposes only, please review\n\n");
+
+  if (Irq == 0)
+    {
+      KiUpdateSystemTime(old_level, 0);
+    }
+  else
+    {
+      /*
+       * Iterate the list until one of the isr tells us its device interrupted
+       */
+      current = isr_table[Irq].Flink;
+      isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
+      while (current != &isr_table[Irq] && 
+            !isr->ServiceRoutine(isr, isr->ServiceContext))
+       {
+         current = current->Flink;
+         isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
+       }
+   }
+}
+
 VOID
 KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
 /*
@@ -335,6 +373,9 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
        if (KeGetCurrentProcessorNumber() == 0)
          {
        KiUpdateSystemTime(old_level, Trapframe->Eip);
+#ifdef KDBG
+       KdbProfileInterrupt(Trapframe->Eip);
+#endif /* KDBG */
          }
      }
    else
@@ -378,7 +419,8 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
 
        if (KeGetCurrentThread() != NULL)
          {
-            KeGetCurrentThread()->LastEip = Trapframe->Eip;
+        // FIXME TODO - What happend to LastEip definition?
+        //KeGetCurrentThread()->LastEip = Trapframe->Eip;
          }
        KiDispatchInterrupt();
        if (KeGetCurrentThread() != NULL &&
@@ -418,13 +460,19 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level)
        * Iterate the list until one of the isr tells us its device interrupted
        */
       current = isr_table[Irq].Flink;
-      isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
-      while (current != &isr_table[Irq] && 
-            !isr->ServiceRoutine(isr, isr->ServiceContext))
-       {
+      while (current != &isr_table[Irq])
+      { 
+          isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
+#if 0
+         if (isr->ServiceRoutine(isr, isr->ServiceContext))
+         {
+            break;
+         }
+#else
+         isr->ServiceRoutine(isr, isr->ServiceContext);
+#endif
          current = current->Flink;
-         isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
-       }
+      }
    }
 }
 
@@ -465,18 +513,27 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
     */
    KiInterruptDispatch2(irq, old_level);
 
-   /*
-    * End the system interrupt.
-    */
-   HalEndSystemInterrupt (old_level, 0);
+#ifdef KDBG
+   if (irq == 0)
+     {
+       KdbProfileInterrupt(Trapframe->Eip);
+     }
+#endif /* KDBG */
 
    /*
     * Maybe do a reschedule as well.
     */
    if (old_level < DISPATCH_LEVEL && irq == 0)
      {
+       KeLowerIrql(APC_LEVEL);
        PsDispatchThread(THREAD_STATE_READY);
      }
+
+   /*
+    * End the system interrupt.
+    */
+   __asm__("cli\n\t");
+   HalEndSystemInterrupt (old_level, 0);
 }
 
 #endif /* MP */
@@ -543,6 +600,10 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
    KeRaiseIrql(InterruptObject->SynchLevel,&synch_oldlvl);
    KeAcquireSpinLockAtDpcLevel(InterruptObject->IrqLock);
    DPRINT("%x %x\n",isr_table[Vector].Flink,isr_table[Vector].Blink);
+   if (IsListEmpty(&isr_table[Vector]))
+   {
+      HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0);
+   }
    InsertTailList(&isr_table[Vector],&InterruptObject->Entry);
    DPRINT("%x %x\n",InterruptObject->Entry.Flink,
           InterruptObject->Entry.Blink);
@@ -573,6 +634,10 @@ KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
    KeRaiseIrql(InterruptObject->SynchLevel,&oldlvl);
    KeAcquireSpinLockAtDpcLevel(InterruptObject->IrqLock);
    RemoveEntryList(&InterruptObject->Entry);
+   if (IsListEmpty(&isr_table[InterruptObject->Vector]))
+   {
+      HalDisableSystemInterrupt(InterruptObject->Vector + IRQ_BASE, 0);
+   }
    KeReleaseSpinLockFromDpcLevel(InterruptObject->IrqLock);
    KeLowerIrql(oldlvl);
 }