- NDK 0.98, now with versionned headers. Too many changes to list, see the TinyKRNL...
[reactos.git] / reactos / ntoskrnl / ke / i386 / irq.c
index 5b72804..0a567f8 100644 (file)
@@ -6,7 +6,6 @@
  * PURPOSE:         IRQ handling
  *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Hartmut Birr
  */
 
 /*
 
 #include <ntoskrnl.h>
 #include <../hal/halx86/include/halirq.h>
+#include <../hal/halx86/include/mps.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
 /* GLOBALS *****************************************************************/
 
-#ifdef CONFIG_SMP
+/* Interrupt handler list */
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
+#ifdef CONFIG_SMP
 
-#define INT_NAME(intnum) _KiUnexpectedInterrupt##intnum
 #define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum
 
-#define BUILD_COMMON_INTERRUPT_HANDLER() \
-__asm__( \
-  "_KiCommonInterrupt:\n\t" \
-  "cld\n\t" \
-  "pushl %ds\n\t" \
-  "pushl %es\n\t" \
-  "pushl %fs\n\t" \
-  "pushl %gs\n\t" \
-  "movl        $0xceafbeef,%eax\n\t" \
-  "pushl %eax\n\t" \
-  "movl        $" STR(KERNEL_DS) ",%eax\n\t" \
-  "movl        %eax,%ds\n\t" \
-  "movl        %eax,%es\n\t" \
-  "movl %eax,%gs\n\t" \
-  "movl        $" STR(PCR_SELECTOR) ",%eax\n\t" \
-  "movl        %eax,%fs\n\t" \
-  "pushl %esp\n\t" \
-  "pushl %ebx\n\t" \
-  "call        _KiInterruptDispatch\n\t" \
-  "addl        $0xC, %esp\n\t" \
-  "popl        %gs\n\t" \
-  "popl        %fs\n\t" \
-  "popl        %es\n\t" \
-  "popl        %ds\n\t" \
-  "popa\n\t" \
-  "iret\n\t");
-
 #define BUILD_INTERRUPT_HANDLER(intnum) \
-VOID INT_NAME2(intnum)(VOID); \
-__asm__( \
-  STR(INT_NAME(intnum)) ":\n\t" \
-  "pusha\n\t" \
-  "movl $0x" STR(intnum) ",%ebx\n\t" \
-  "jmp _KiCommonInterrupt");
-
-
-/* Interrupt handlers and declarations */
+VOID INT_NAME2(intnum)(VOID);
 
-#define B(x,y) \
+#define D(x,y) \
   BUILD_INTERRUPT_HANDLER(x##y)
 
-#define B16(x) \
-  B(x,0) B(x,1) B(x,2) B(x,3) \
-  B(x,4) B(x,5) B(x,6) B(x,7) \
-  B(x,8) B(x,9) B(x,A) B(x,B) \
-  B(x,C) B(x,D) B(x,E) B(x,F)
+#define D16(x) \
+  D(x,0) D(x,1) D(x,2) D(x,3) \
+  D(x,4) D(x,5) D(x,6) D(x,7) \
+  D(x,8) D(x,9) D(x,A) D(x,B) \
+  D(x,C) D(x,D) D(x,E) D(x,F)
 
-
-BUILD_COMMON_INTERRUPT_HANDLER()
-B16(3) B16(4) B16(5) B16(6)
-B16(7) B16(8) B16(9) B16(A)
-B16(B) B16(C) B16(D) B16(E)
-B16(F)
-
-#undef B
-#undef B16
-
-
-/* Interrupt handler list */
+D16(3) D16(4) D16(5) D16(6)
+D16(7) D16(8) D16(9) D16(A)
+D16(B) D16(C) D16(D) D16(E)
+D16(F)
 
 #define L(x,y) \
   (ULONG)& INT_NAME2(x##y)
 
 #define L16(x) \
-       L(x,0), L(x,1), L(x,2), L(x,3), \
-       L(x,4), L(x,5), L(x,6), L(x,7), \
-       L(x,8), L(x,9), L(x,A), L(x,B), \
-       L(x,C), L(x,D), L(x,E), L(x,F)
+        L(x,0), L(x,1), L(x,2), L(x,3), \
+        L(x,4), L(x,5), L(x,6), L(x,7), \
+        L(x,8), L(x,9), L(x,A), L(x,B), \
+        L(x,C), L(x,D), L(x,E), L(x,F)
 
 static ULONG irq_handler[ROUND_UP(NR_IRQS, 16)] = {
   L16(3), L16(4), L16(5), L16(6),
@@ -111,45 +66,47 @@ static ULONG irq_handler[ROUND_UP(NR_IRQS, 16)] = {
 
 #undef L
 #undef L16
+#undef D
+#undef D16
 
 #else /* CONFIG_SMP */
 
- void irq_handler_0(void);
- void irq_handler_1(void);
- void irq_handler_2(void);
- void irq_handler_3(void);
- void irq_handler_4(void);
- void irq_handler_5(void);
- void irq_handler_6(void);
- void irq_handler_7(void);
- void irq_handler_8(void);
- void irq_handler_9(void);
- void irq_handler_10(void);
- void irq_handler_11(void);
- void irq_handler_12(void);
- void irq_handler_13(void);
- void irq_handler_14(void);
- void irq_handler_15(void);
+void irq_handler_0(void);
+void irq_handler_1(void);
+void irq_handler_2(void);
+void irq_handler_3(void);
+void irq_handler_4(void);
+void irq_handler_5(void);
+void irq_handler_6(void);
+void irq_handler_7(void);
+void irq_handler_8(void);
+void irq_handler_9(void);
+void irq_handler_10(void);
+void irq_handler_11(void);
+void irq_handler_12(void);
+void irq_handler_13(void);
+void irq_handler_14(void);
+void irq_handler_15(void);
 
 static unsigned int irq_handler[NR_IRQS]=
-        {
-                (int)&irq_handler_0,
-                (int)&irq_handler_1,
-                (int)&irq_handler_2,
-                (int)&irq_handler_3,
-                (int)&irq_handler_4,
-                (int)&irq_handler_5,
-                (int)&irq_handler_6,
-                (int)&irq_handler_7,
-                (int)&irq_handler_8,
-                (int)&irq_handler_9,
-                (int)&irq_handler_10,
-                (int)&irq_handler_11,
-                (int)&irq_handler_12,
-                (int)&irq_handler_13,
-                (int)&irq_handler_14,
-                (int)&irq_handler_15,
-        };
+{
+   (int)&irq_handler_0,
+   (int)&irq_handler_1,
+   (int)&irq_handler_2,
+   (int)&irq_handler_3,
+   (int)&irq_handler_4,
+   (int)&irq_handler_5,
+   (int)&irq_handler_6,
+   (int)&irq_handler_7,
+   (int)&irq_handler_8,
+   (int)&irq_handler_9,
+   (int)&irq_handler_10,
+   (int)&irq_handler_11,
+   (int)&irq_handler_12,
+   (int)&irq_handler_13,
+   (int)&irq_handler_14,
+   (int)&irq_handler_15,
+};
 
 #endif /* CONFIG_SMP */
 
@@ -174,13 +131,16 @@ static ISR_TABLE IsrTable[NR_IRQS][1];
 #endif
 
 #define TAG_ISR_LOCK     TAG('I', 'S', 'R', 'L')
+extern IDT_DESCRIPTOR KiIdt[256];
 
 /* FUNCTIONS ****************************************************************/
 
 #define PRESENT (0x8000)
 #define I486_INTERRUPT_GATE (0xe00)
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 KeInitInterrupts (VOID)
 {
    int i, j;
@@ -191,62 +151,62 @@ KeInitInterrupts (VOID)
     */
    for (i=0;i<NR_IRQS;i++)
      {
-       KiIdt[IRQ_BASE+i].a=(irq_handler[i]&0xffff)+(KERNEL_CS<<16);
-       KiIdt[IRQ_BASE+i].b=(irq_handler[i]&0xffff0000)+PRESENT+
-                           I486_INTERRUPT_GATE;
+        KiIdt[IRQ_BASE+i].a=(irq_handler[i]&0xffff)+(KGDT_R0_CODE<<16);
+        KiIdt[IRQ_BASE+i].b=(irq_handler[i]&0xffff0000)+PRESENT+
+                            I486_INTERRUPT_GATE;
 #ifdef CONFIG_SMP
-       for (j = 0; j < MAXIMUM_PROCESSORS; j++)
+        for (j = 0; j < MAXIMUM_PROCESSORS; j++)
 #else
-       j = 0;
+        j = 0;
 #endif
-         {
-           InitializeListHead(&IsrTable[i][j].ListHead);
+          {
+            InitializeListHead(&IsrTable[i][j].ListHead);
             KeInitializeSpinLock(&IsrTable[i][j].Lock);
-           IsrTable[i][j].Count = 0;
-         }
+            IsrTable[i][j].Count = 0;
+          }
      }
 }
 
 STATIC VOID
 KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
-                         PKTRAP_FRAME TrapFrame)
+                          PKTRAP_FRAME TrapFrame)
 {
-   TrapFrame->Gs     = (USHORT)IrqTrapFrame->Gs;
-   TrapFrame->Fs     = (USHORT)IrqTrapFrame->Fs;
-   TrapFrame->Es     = (USHORT)IrqTrapFrame->Es;
-   TrapFrame->Ds     = (USHORT)IrqTrapFrame->Ds;
+   TrapFrame->SegGs     = (USHORT)IrqTrapFrame->Gs;
+   TrapFrame->SegFs     = (USHORT)IrqTrapFrame->Fs;
+   TrapFrame->SegEs     = (USHORT)IrqTrapFrame->Es;
+   TrapFrame->SegDs     = (USHORT)IrqTrapFrame->Ds;
    TrapFrame->Eax    = IrqTrapFrame->Eax;
    TrapFrame->Ecx    = IrqTrapFrame->Ecx;
    TrapFrame->Edx    = IrqTrapFrame->Edx;
    TrapFrame->Ebx    = IrqTrapFrame->Ebx;
-   TrapFrame->Esp    = IrqTrapFrame->Esp;
+   TrapFrame->HardwareEsp    = IrqTrapFrame->Esp;
    TrapFrame->Ebp    = IrqTrapFrame->Ebp;
    TrapFrame->Esi    = IrqTrapFrame->Esi;
    TrapFrame->Edi    = IrqTrapFrame->Edi;
    TrapFrame->Eip    = IrqTrapFrame->Eip;
-   TrapFrame->Cs     = IrqTrapFrame->Cs;
-   TrapFrame->Eflags = IrqTrapFrame->Eflags;
+   TrapFrame->SegCs     = IrqTrapFrame->Cs;
+   TrapFrame->EFlags = IrqTrapFrame->Eflags;
 }
 
 STATIC VOID
 KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame,
-                         PKIRQ_TRAPFRAME IrqTrapFrame)
+                          PKIRQ_TRAPFRAME IrqTrapFrame)
 {
-   IrqTrapFrame->Gs     = TrapFrame->Gs;
-   IrqTrapFrame->Fs     = TrapFrame->Fs;
-   IrqTrapFrame->Es     = TrapFrame->Es;
-   IrqTrapFrame->Ds     = TrapFrame->Ds;
+   IrqTrapFrame->Gs     = TrapFrame->SegGs;
+   IrqTrapFrame->Fs     = TrapFrame->SegFs;
+   IrqTrapFrame->Es     = TrapFrame->SegEs;
+   IrqTrapFrame->Ds     = TrapFrame->SegDs;
    IrqTrapFrame->Eax    = TrapFrame->Eax;
    IrqTrapFrame->Ecx    = TrapFrame->Ecx;
    IrqTrapFrame->Edx    = TrapFrame->Edx;
    IrqTrapFrame->Ebx    = TrapFrame->Ebx;
-   IrqTrapFrame->Esp    = TrapFrame->Esp;
+   IrqTrapFrame->Esp    = TrapFrame->HardwareEsp;
    IrqTrapFrame->Ebp    = TrapFrame->Ebp;
    IrqTrapFrame->Esi    = TrapFrame->Esi;
    IrqTrapFrame->Edi    = TrapFrame->Edi;
    IrqTrapFrame->Eip    = TrapFrame->Eip;
-   IrqTrapFrame->Cs     = TrapFrame->Cs;
-   IrqTrapFrame->Eflags = TrapFrame->Eflags;
+   IrqTrapFrame->Cs     = TrapFrame->SegCs;
+   IrqTrapFrame->Eflags = TrapFrame->EFlags;
 }
 
 VOID STDCALL
@@ -283,8 +243,8 @@ KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
       if (isr->ServiceRoutine(isr, isr->ServiceContext))
         {
           KeReleaseInterruptSpinLock(isr, oldlvl);
-         break;
-       }
+          break;
+        }
       KeReleaseInterruptSpinLock(isr, oldlvl);
       current = current->Flink;
     }
@@ -316,8 +276,8 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
     * default HAL this will send an EOI to the PIC and alter the IRQL.
     */
    if (!HalBeginSystemInterrupt (vector,
-                                VECTOR2IRQL(vector),
-                                &old_level))
+                                 VECTOR2IRQL(vector),
+                                 &old_level))
      {
        return;
      }
@@ -349,37 +309,43 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
     */
    Ke386DisableInterrupts();
 
-   HalEndSystemInterrupt (old_level, 0);
-
-   if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KERNEL_CS)
+   if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KGDT_R0_CODE)
      {
+       HalEndSystemInterrupt (APC_LEVEL, 0);
+
        CurrentThread = KeGetCurrentThread();
-       if (CurrentThread!=NULL && CurrentThread->Alerted[1])
+       if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending)
          {
            DPRINT("PID: %d, TID: %d CS %04x/%04x\n",
-                 ((PETHREAD)CurrentThread)->ThreadsProcess->UniqueProcessId,
-                 ((PETHREAD)CurrentThread)->Cid.UniqueThread,
-                 Trapframe->Cs,
-                 CurrentThread->TrapFrame ? CurrentThread->TrapFrame->Cs : 0);
-          if (CurrentThread->TrapFrame == NULL)
-            {
-              OldTrapFrame = CurrentThread->TrapFrame;
-              KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
-              CurrentThread->TrapFrame = &KernelTrapFrame;
-            }
-
-          Ke386EnableInterrupts();
-           KiDeliverApc(KernelMode, NULL, NULL);
+                  ((PETHREAD)CurrentThread)->ThreadsProcess->UniqueProcessId,
+                  ((PETHREAD)CurrentThread)->Cid.UniqueThread,
+                  Trapframe->Cs,
+                  CurrentThread->TrapFrame ? CurrentThread->TrapFrame->Cs : 0);
+           if (CurrentThread->TrapFrame == NULL)
+             {
+               OldTrapFrame = CurrentThread->TrapFrame;
+               KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+               CurrentThread->TrapFrame = &KernelTrapFrame;
+             }
+
+           Ke386EnableInterrupts();
+           KiDeliverApc(UserMode, NULL, NULL);
            Ke386DisableInterrupts();
 
-          ASSERT(KeGetCurrentThread() == CurrentThread);
+           ASSERT(KeGetCurrentThread() == CurrentThread);
            if (CurrentThread->TrapFrame == &KernelTrapFrame)
-            {
+             {
                KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe);
-              CurrentThread->TrapFrame = OldTrapFrame;
-            }
-        }
+               CurrentThread->TrapFrame = OldTrapFrame;
+             }
+         }
+       KeLowerIrql(PASSIVE_LEVEL);
      }
+   else
+     {
+       HalEndSystemInterrupt (old_level, 0);
+     }
+
 }
 
 static VOID
@@ -387,34 +353,34 @@ KeDumpIrqList(VOID)
 {
    PKINTERRUPT current;
    PLIST_ENTRY current_entry;
-   ULONG i, j;
+   LONG i, j;
    KIRQL oldlvl;
    BOOLEAN printed;
 
    for (i=0;i<NR_IRQS;i++)
      {
-       printed = FALSE;
+        printed = FALSE;
         KeRaiseIrql(VECTOR2IRQL(i + IRQ_BASE),&oldlvl);
 
-       for (j=0; j < KeNumberProcessors; j++)
-         {
-           KiAcquireSpinLock(&IsrTable[i][j].Lock);
-
-           current_entry = IsrTable[i][j].ListHead.Flink;
-           current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
-           while (current_entry!=&(IsrTable[i][j].ListHead))
-             {
-               if (printed == FALSE)
-                 {
-                   printed = TRUE;
-                   DPRINT("For irq %x:\n",i);
-                 }
-               DPRINT("   Isr %x\n",current);
-               current_entry = current_entry->Flink;
-               current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
-             }
-           KiReleaseSpinLock(&IsrTable[i][j].Lock);
-         }
+        for (j=0; j < KeNumberProcessors; j++)
+          {
+            KiAcquireSpinLock(&IsrTable[i][j].Lock);
+
+            current_entry = IsrTable[i][j].ListHead.Flink;
+            current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
+            while (current_entry!=&(IsrTable[i][j].ListHead))
+              {
+                if (printed == FALSE)
+                  {
+                    printed = TRUE;
+                    DPRINT("For irq %x:\n",i);
+                  }
+                DPRINT("   Isr %x\n",current);
+                current_entry = current_entry->Flink;
+                current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
+              }
+            KiReleaseSpinLock(&IsrTable[i][j].Lock);
+          }
         KeLowerIrql(oldlvl);
      }
 }
@@ -473,7 +439,7 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
    if (Result)
    {
       InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
-      DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->Entry.Blink);
+      DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->InterruptListEntry.Blink);
    }
 
    InterruptObject->Connected = TRUE;
@@ -602,7 +568,7 @@ KeInitializeInterrupt(PKINTERRUPT Interrupt,
 
 VOID KePrintInterruptStatistic(VOID)
 {
-   ULONG i, j;
+   LONG i, j;
 
    for (j = 0; j < KeNumberProcessors; j++)
    {
@@ -610,12 +576,11 @@ VOID KePrintInterruptStatistic(VOID)
       for (i = 0; i < NR_IRQS; i++)
       {
          if (IsrTable[i][j].Count)
-        {
-            DPRINT1("  Irq %x(%d): %d\n", i, VECTOR2IRQ(i + IRQ_BASE), IsrTable[i][j].Count);
-        }
+         {
+             DPRINT1("  Irq %x(%d): %d\n", i, VECTOR2IRQ(i + IRQ_BASE), IsrTable[i][j].Count);
+         }
       }
    }
 }
 
-
 /* EOF */