Author: sir_richard
Date: Fri Jan 29 00:18:53 2010
New Revision: 45304
URL: 
http://svn.reactos.org/svn/reactos?rev=45304&view=rev
Log:
[NTOS]: The last big step. Now that the HAL is in C, we can handle interrupts in C. Do so
using the proposed model that was #if'ed out, but with some improvements.
[NTOS]: Implement KiUnexpectedInterruptTail and KiUnexpectedInterrupt in C as well.
This is [PERF] too since the C interrupt handling code is a lot more efficient than the
ASM one. Numbers look good here.
Modified:
    trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/ke/i386/irqobj.c
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] Fri Jan 29
00:18:53 2010
@@ -197,7 +197,7 @@
 .macro GENERATE_INT_HANDLER Number
 .func KiUnexpectedInterrupt&Number
 _KiUnexpectedInterrupt&Number:
-    push PRIMARY_VECTOR_BASE + Number
+    mov eax, PRIMARY_VECTOR_BASE + Number
     jmp _KiEndUnexpectedRange@0
 .endfunc
 .endm
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Fri Jan 29 00:18:53 2010
@@ -954,19 +954,6 @@
     IN PKTRAP_FRAME TrapFrame
 );
-#ifndef HAL_INTERRUPT_SUPPORT_IN_C
-VOID
-NTAPI
-KiInterruptDispatch(
-    VOID
-);
-
-VOID
-NTAPI
-KiChainedDispatch(
-    VOID
-);
-#else
 VOID
 FASTCALL
 KiInterruptDispatch(
@@ -980,7 +967,6 @@
     IN PKTRAP_FRAME TrapFrame,
     IN PKINTERRUPT Interrupt
 );
-#endif
 VOID
 NTAPI
Modified: trunk/reactos/ntoskrnl/ke/i386/irqobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irqobj.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] Fri Jan 29 00:18:53 2010
@@ -97,9 +97,6 @@
 {
     DISPATCH_INFO Dispatch;
     PKINTERRUPT_ROUTINE Handler;
-#ifndef HAL_INTERRUPT_SUPPORT_IN_C
-    PULONG Patch = &Interrupt->DispatchCode[0];
-#endif
     /* Get vector data */
     KiGetVectorDispatch(Interrupt->Vector, &Dispatch);
@@ -122,15 +119,6 @@
         Interrupt->DispatchAddress = Handler;
         /* Read note in trap.s -- patching not needed since JMP is static */
-#ifndef HAL_INTERRUPT_SUPPORT_IN_C
-        /* Jump to the last 4 bytes */
-        Patch = (PULONG)((ULONG_PTR)Patch +
-                         ((ULONG_PTR)&KiInterruptTemplateDispatch -
-                          (ULONG_PTR)KiInterruptTemplate) - 4);
-
-        /* Apply the patch */
-        *Patch = (ULONG)((ULONG_PTR)Handler - ((ULONG_PTR)Patch + 4));
-#endif
         /* Now set the final handler address */
         ASSERT(Dispatch.FlatDispatch == NULL);
@@ -140,6 +128,130 @@
     /* Register the interrupt */
     KeRegisterInterruptHandler(Interrupt->Vector, Handler);
 }
+
+VOID
+FORCEINLINE
+DECLSPEC_NORETURN
+KiExitInterrupt(IN PKTRAP_FRAME TrapFrame,
+                IN KIRQL OldIrql,
+                IN BOOLEAN Spurious)
+{
+    /* Check if this was a real interrupt */
+    if (!Spurious)
+    {
+        /* Set nested trap frame */
+        KeGetPcr()->VdmAlert = (ULONG_PTR)TrapFrame;
+
+        /* It was, disable interrupts and restore the IRQL */
+        _disable();
+        HalEndSystemInterrupt(OldIrql, 0);
+    }
+
+    /* Now exit the trap */
+    KiEoiHelper(TrapFrame);
+}
+
+VOID
+KiUnexpectedInterrupt(VOID)
+{
+    /* Crash the machine */
+    KeBugCheck(TRAP_CAUSE_UNKNOWN);
+}
+
+VOID
+FASTCALL
+KiUnexpectedInterruptTailHandler(IN PKTRAP_FRAME TrapFrame)
+{
+    KIRQL OldIrql;
+
+    /* Enter trap */
+    KiEnterInterruptTrap(TrapFrame);
+
+    /* Increase interrupt count */
+    KeGetCurrentPrcb()->InterruptCount++;
+
+    /* Start the interrupt */
+    if (HalBeginSystemInterrupt(HIGH_LEVEL, TrapFrame->Eax, &OldIrql))
+    {
+        /* Warn user */
+        DPRINT1("\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n");
+
+        /* Now call the epilogue code */
+        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
+    }
+    else
+    {
+        /* Now call the epilogue code */
+        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
+    }
+}
+
+typedef
+FASTCALL
+VOID
+(PKI_INTERRUPT_DISPATCH)(
+    IN PKTRAP_FRAME TrapFrame,
+    IN PKINTERRUPT Interrupt
+);
+
+VOID
+FASTCALL
+KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame,
+                    IN PKINTERRUPT Interrupt)
+{
+    KIRQL OldIrql;
+
+    /* Increase interrupt count */
+    KeGetCurrentPrcb()->InterruptCount++;
+
+    /* Begin the interrupt, making sure it's not spurious */
+    if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
+                                Interrupt->Vector,
+                                &OldIrql))
+    {
+        /* Acquire interrupt lock */
+        KxAcquireSpinLock(Interrupt->ActualLock);
+
+        /* Call the ISR */
+        Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
+
+        /* Release interrupt lock */
+        KxReleaseSpinLock(Interrupt->ActualLock);
+
+        /* Now call the epilogue code */
+        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
+    }
+    else
+    {
+        /* Now call the epilogue code */
+        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
+    }
+}
+
+VOID
+FASTCALL
+KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
+                  IN PKINTERRUPT Interrupt)
+{
+    /* Increase interrupt count */
+    KeGetCurrentPrcb()->InterruptCount++;
+    UNIMPLEMENTED;
+    while (TRUE);
+}
+
+VOID
+FASTCALL
+KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
+                   IN PKINTERRUPT Interrupt)
+{
+    /* Enter interrupt frame */
+    KiEnterInterruptTrap(TrapFrame);
+
+    /* Call the correct dispatcher */
+    ((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
+}
+
+KiTrap(KiUnexpectedInterruptTail,   KI_PUSH_FAKE_ERROR_CODE);
 /* PUBLIC FUNCTIONS **********************************************************/
@@ -199,12 +311,6 @@
         *DispatchCode++ = KiInterruptTemplate[i];
     }
-    /* Sanity check */
-#ifndef HAL_INTERRUPT_SUPPORT_IN_C
-    ASSERT((ULONG_PTR)&KiChainedDispatch2ndLvl -
-           (ULONG_PTR)KiInterruptTemplate <= (KINTERRUPT_DISPATCH_CODES * 4));
-#endif
-
     /* Jump to the last 4 bytes */
     Patch = (PULONG)((ULONG_PTR)Patch +
                      ((ULONG_PTR)&KiInterruptTemplateObject -
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Fri Jan 29 00:18:53 2010
@@ -152,58 +152,8 @@
 _KiEndUnexpectedRange@0:
     jmp _KiUnexpectedInterruptTail
-.func KiUnexpectedInterruptTail
-TRAP_FIXUPS kui_a, kui_t, DoFixupV86, DoFixupAbios
-_KiUnexpectedInterruptTail:
-
-    /* Enter interrupt trap */
-    INT_PROLOG kui_a, kui_t, DoNotPushFakeErrorCode
-
-    /* Increase interrupt count */
-    inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
-
-    /* Put vector in EBX and make space for KIRQL */
-    mov ebx, [esp]
-    sub esp, 4
-
-    /* Begin interrupt */
-    push esp
-    push ebx
-    push HIGH_LEVEL
-    call _HalBeginSystemInterrupt@12
-
-    /* Check if it was spurious or not */
-    or al, al
-    jnz Handled
-
-    /* Spurious, ignore it */
-    add esp, 8
-    jmp _Kei386EoiHelper@0
-
-Handled:
-    /* Unexpected interrupt, print a message on debug builds */
-#if DBG
-    push [esp+4]
-    push offset _UnexpectedMsg
-    call _DbgPrint
-    add esp, 8
-#endif
-
-    /* Exit the interrupt */
-    mov esi, $
-    cli
-    call _HalEndSystemInterrupt@8
-    jmp _Kei386EoiHelper@0
-.endfunc
-
-.globl _KiUnexpectedInterrupt
-_KiUnexpectedInterrupt:
-
-    /* Bugcheck with invalid interrupt code */
-    push TRAP_CAUSE_UNKNOWN
-    call _KeBugCheck@4
-
-/* INTERRUPT HANDLERS ********************************************************/
+
+/* DPC INTERRUPT HANDLER ******************************************************/
 .func KiDispatchInterrupt@0
 _KiDispatchInterrupt@0:
@@ -321,10 +271,8 @@
 .endfunc
 /*
- * This is how the new-style interrupt template will look like.
- *
  * We setup the stack for a trap frame in the KINTERRUPT DispatchCode itself and
- * then mov the stack address in ECX, since the handlers are FASTCALL. We also
+ * then move the stack address in ECX, since the handlers are FASTCALL. We also
  * need to know the address of the KINTERRUPT. To do this, we maintain the old
  * dynamic patching technique (EDX instead of EDI, however) and let the C API
  * up in KeInitializeInterrupt replace the 0 with the address. Since this is in
@@ -343,13 +291,9 @@
  * use EDI to store the absolute offset, and jump to that instead.
  *
  */
-#ifdef HAL_INTERRUPT_SUPPORT_IN_C
 .func KiInterruptTemplate
 _KiInterruptTemplate:
-    push 0
-    pushad
-    sub esp, KTRAP_FRAME_LENGTH - KTRAP_FRAME_PREVIOUS_MODE
-    mov ecx, esp
+    TRAP_HANDLER_PROLOG 1, 0
 _KiInterruptTemplate2ndDispatch:
     /* Dummy code, will be replaced by the address of the KINTERRUPT */
@@ -363,221 +307,3 @@
 _KiInterruptTemplateDispatch:
     /* Marks the end of the template so that the jump above can be edited */
 .endfunc
-
-#else
-
-.func KiInterruptTemplate
-_KiInterruptTemplate:
-
-    /* Enter interrupt trap */
-    INT_PROLOG kit_a, kit_t, DoPushFakeErrorCode
-
-_KiInterruptTemplate2ndDispatch:
-    /* Dummy code, will be replaced by the address of the KINTERRUPT */
-    mov edi, 0
-
-_KiInterruptTemplateObject:
-    /* Dummy jump, will be replaced by the actual jump */
-    jmp _KeSynchronizeExecution@12
-
-_KiInterruptTemplateDispatch:
-    /* Marks the end of the template so that the jump above can be edited */
-
-TRAP_FIXUPS kit_a, kit_t, DoFixupV86, DoFixupAbios
-.endfunc
-
-.func KiChainedDispatch2ndLvl@0
-_KiChainedDispatch2ndLvl@0:
-
-NextSharedInt:
-    /* Raise IRQL if necessary */
-    mov cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
-    cmp cl, [edi+KINTERRUPT_IRQL]
-    je 1f
-    call @KfRaiseIrql@4
-
-1:
-    /* Acquire the lock */
-    mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
-GetIntLock2:
-    ACQUIRE_SPINLOCK(esi, IntSpin2)
-
-    /* Make sure that this interrupt isn't storming */
-    VERIFY_INT kid2
-
-    /* Save the tick count */
-    mov esi, _KeTickCount
-
-    /* Call the ISR */
-    mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
-    push eax
-    push edi
-    call [edi+KINTERRUPT_SERVICE_ROUTINE]
-
-    /* Save the ISR result */
-    mov bl, al
-
-    /* Check if the ISR timed out */
-    add esi, _KiISRTimeout
-    cmp _KeTickCount, esi
-    jnc ChainedIsrTimeout
-
-ReleaseLock2:
-    /* Release the lock */
-    mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
-    RELEASE_SPINLOCK(esi)
-
-    /* Lower IRQL if necessary */
-    mov cl, [edi+KINTERRUPT_IRQL]
-    cmp cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
-    je 1f
-    call @KfLowerIrql@4
-
-1:
-    /* Check if the interrupt is handled */
-    or bl, bl
-    jnz 1f
-
-    /* Try the next shared interrupt handler */
-    mov eax, [edi+KINTERRUPT_INTERRUPT_LIST_HEAD]
-    lea edi, [eax-KINTERRUPT_INTERRUPT_LIST_HEAD]
-    jmp NextSharedInt
-
-1:
-    ret
-
-#ifdef CONFIG_SMP
-IntSpin2:
-    SPIN_ON_LOCK(esi, GetIntLock2)
-#endif
-
-ChainedIsrTimeout:
-    /* Print warning message */
-    push [edi+KINTERRUPT_SERVICE_ROUTINE]
-    push offset _IsrTimeoutMsg
-    call _DbgPrint
-    add esp,8
-
-    /* Break into debugger, then continue */
-    int 3
-    jmp ReleaseLock2
-
-    /* Cleanup verification */
-    VERIFY_INT_END kid2, 0
-.endfunc
-
-.func KiChainedDispatch@0
-_KiChainedDispatch@0:
-
-    /* Increase interrupt count */
-    inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
-
-    /* Save trap frame */
-    mov ebp, esp
-
-    /* Save vector and IRQL */
-    mov eax, [edi+KINTERRUPT_VECTOR]
-    mov ecx, [edi+KINTERRUPT_IRQL]
-
-    /* Save old irql */
-    push eax
-    sub esp, 4
-
-    /* Begin interrupt */
-    push esp
-    push eax
-    push ecx
-    call _HalBeginSystemInterrupt@12
-
-    /* Check if it was handled */
-    or al, al
-    jz SpuriousInt
-
-    /* Call the 2nd-level handler */
-    call _KiChainedDispatch2ndLvl@0
-
-    /* Exit the interrupt */
-    INT_EPILOG 0
-.endfunc
-
-.func KiInterruptDispatch@0
-_KiInterruptDispatch@0:
-
-    /* Increase interrupt count */
-    inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
-
-    /* Save trap frame */
-    mov ebp, esp
-
-    /* Save vector and IRQL */
-    mov eax, [edi+KINTERRUPT_VECTOR]
-    mov ecx, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
-
-    /* Save old irql */
-    push eax
-    sub esp, 4
-
-    /* Begin interrupt */
-    push esp
-    push eax
-    push ecx
-    call _HalBeginSystemInterrupt@12
-
-    /* Check if it was handled */
-    or al, al
-    jz SpuriousInt
-
-    /* Acquire the lock */
-    mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
-GetIntLock:
-    ACQUIRE_SPINLOCK(esi, IntSpin)
-
-    /* Make sure that this interrupt isn't storming */
-    VERIFY_INT kid
-
-    /* Save the tick count */
-    mov ebx, _KeTickCount
-
-    /* Call the ISR */
-    mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
-    push eax
-    push edi
-    call [edi+KINTERRUPT_SERVICE_ROUTINE]
-
-    /* Check if the ISR timed out */
-    add ebx, _KiISRTimeout
-    cmp _KeTickCount, ebx
-    jnc IsrTimeout
-
-ReleaseLock:
-    /* Release the lock */
-    RELEASE_SPINLOCK(esi)
-
-    /* Exit the interrupt */
-    INT_EPILOG 0
-
-SpuriousInt:
-    /* Exit the interrupt */
-    add esp, 8
-    INT_EPILOG 1
-
-#ifdef CONFIG_SMP
-IntSpin:
-    SPIN_ON_LOCK(esi, GetIntLock)
-#endif
-
-IsrTimeout:
-    /* Print warning message */
-    push [edi+KINTERRUPT_SERVICE_ROUTINE]
-    push offset _IsrTimeoutMsg
-    call _DbgPrint
-    add esp,8
-
-    /* Break into debugger, then continue */
-    int 3
-    jmp ReleaseLock
-
-    /* Cleanup verification */
-    VERIFY_INT_END kid, 0
-.endfunc
-#endif
Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Fri Jan 29 00:18:53 2010
@@ -1601,104 +1601,4 @@
 KiTrap(KiSystemService,  KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
 KiTrap(KiFastCallEntry,  KI_FAST_SYSTEM_CALL);
-/* HARDWARE INTERRUPTS ********************************************************/
-
-/*
- * This code can only be used once the HAL handles system interrupt code in C.
- *
- * This is because the HAL, when ending a system interrupt, might see pending
- * DPC or APC interrupts, and attempt to piggyback on the interrupt context in
- * order to deliver them. Once they have been devlivered, it will then "end"
the
- * interrupt context by doing a call to the ASM EOI Handler which naturally will
- * throw up on our C-style KTRAP_FRAME.
- *
- * Once it works, expect a noticeable speed boost during hardware interrupts.
- */
-#ifdef HAL_INTERRUPT_SUPPORT_IN_C
-
-typedef
-FASTCALL
-VOID
-(PKI_INTERRUPT_DISPATCH)(
-    IN PKTRAP_FRAME TrapFrame,
-    IN PKINTERRUPT Interrupt
-);
-
-VOID
-FORCEINLINE
-KiExitInterrupt(IN PKTRAP_FRAME TrapFrame,
-                IN KIRQL OldIrql,
-                IN BOOLEAN Spurious)
-{
-    if (Spurious) KiEoiHelper(TrapFrame);
-
-    _disable();
-
-    DPRINT1("Calling HAL to restore IRQL to: %d\n", OldIrql);
-    HalEndSystemInterrupt(OldIrql, 0);
-
-    DPRINT1("Exiting trap\n");
-    KiEoiHelper(TrapFrame);
-}
-
-VOID
-FASTCALL
-KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame,
-                    IN PKINTERRUPT Interrupt)
-{
-    KIRQL OldIrql;
-
-    KeGetCurrentPrcb()->InterruptCount++;
-
-    DPRINT1("Calling HAL with %lx %lx\n", Interrupt->SynchronizeIrql,
Interrupt->Vector);
-    if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
-                                Interrupt->Vector,
-                                &OldIrql))
-    {
-        /* Acquire interrupt lock */
-        KxAcquireSpinLock(Interrupt->ActualLock);
-
-        /* Call the ISR */
-        DPRINT1("Calling ISR: %p with context: %p\n",
Interrupt->ServiceRoutine, Interrupt->ServiceContext);
-        Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
-
-        /* Release interrupt lock */
-        KxReleaseSpinLock(Interrupt->ActualLock);
-
-        /* Now call the epilogue code */
-        DPRINT1("Exiting interrupt\n");
-        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
-    }
-    else
-    {
-        /* Now call the epilogue code */
-        DPRINT1("Exiting Spurious interrupt\n");
-        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
-    }
-}
-
-VOID
-FASTCALL
-KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
-                  IN PKINTERRUPT Interrupt)
-{
-    KeGetCurrentPrcb()->InterruptCount++;
-
-    UNIMPLEMENTED;
-    while (TRUE);
-}
-
-VOID
-FASTCALL
-KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
-                   IN PKINTERRUPT Interrupt)
-{
-    /* Enter interrupt frame */
-    KiEnterInterruptTrap(TrapFrame);
-
-    /* Call the correct dispatcher */
-    ((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
-}
-#endif
-
 /* EOF */