[ros-diffs] [sir_richard] 45231: [PERF]: Make the trap entry/exit macros inlined, just as they used to be before in their pure-assembly forms. This should boost performance quite a bit by avoiding 2-3 extra calls during traps and system calls. [NTOS]: Cleanup the traphdlr.c vs. trap_x.h mess into something much more structured. trap_x.h is now all inlined C functions which pretty much replace the asmmacros.S file. It is meant to be used outside the kernel as well (such as by the HAL, which requires trap entry/exit too). [PERF]: Give UNREACHABLE another try, this time with GCC 4.5+, 4.4+, 4.4- and MSVC support. [PERF]: Remove ABIOS checks since ReactOS does not support this, and since it doesn't look like the target kernel actually does either, we can remove this vestigal/unsupported code, saving some extra branches and checks.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Sun Jan 24 06:40:05 CET 2010


Author: sir_richard
Date: Sun Jan 24 06:40:04 2010
New Revision: 45231

URL: http://svn.reactos.org/svn/reactos?rev=45231&view=rev
Log:
[PERF]: Make the trap entry/exit macros inlined, just as they used to be before in their pure-assembly forms. This should boost performance quite a bit by avoiding 2-3 extra calls during traps and system calls.
[NTOS]: Cleanup the traphdlr.c vs. trap_x.h mess into something much more structured. trap_x.h is now all inlined C functions which pretty much replace the asmmacros.S file. It is meant to be used outside the kernel as well (such as by the HAL, which requires trap entry/exit too).
[PERF]: Give UNREACHABLE another try, this time with GCC 4.5+, 4.4+, 4.4- and MSVC support.
[PERF]: Remove ABIOS checks since ReactOS does not support this, and since it doesn't look like the target kernel actually does either, we can remove this vestigal/unsupported code, saving some extra branches and checks.

Modified:
    trunk/reactos/ntoskrnl/include/internal/i386/ke.h
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/include/internal/trap_x.h
    trunk/reactos/ntoskrnl/ke/i386/exp.c
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c

Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/ke.h?rev=45231&r1=45230&r2=45231&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Sun Jan 24 06:40:04 2010
@@ -410,6 +410,18 @@
 ULONG_PTR
 FASTCALL
 KiExitV86Mode(
+    IN PKTRAP_FRAME TrapFrame
+);
+
+VOID
+NTAPI
+KiDispatchExceptionFromTrapFrame(
+    IN NTSTATUS Code,
+    IN ULONG_PTR Address,
+    IN ULONG ParameterCount,
+    IN ULONG_PTR Parameter1,
+    IN ULONG_PTR Parameter2,
+    IN ULONG_PTR Parameter3,
     IN PKTRAP_FRAME TrapFrame
 );
 
@@ -443,6 +455,14 @@
 extern VOID __cdecl ReadBatch(VOID);
 extern VOID __cdecl FrRestore(VOID);
 
+//
+// Trap Macros
+//
+#include "../trap_x.h"
+
+//
+// Returns a thread's FPU save area
+//
 PFX_SAVE_AREA
 FORCEINLINE
 KiGetThreadNpxArea(IN PKTHREAD Thread)
@@ -523,20 +543,196 @@
             (DrAddress <= MM_HIGHEST_USER_ADDRESS) ? DrAddress : 0);
 }
 
-FORCEINLINE
-VOID
-KiV86TrapReturn(IN ULONG_PTR Stack)
-{
-    /* Restore volatiles and stack */
+//
+// Exception with no arguments
+//
+VOID
+FORCEINLINE
+//DECLSPEC_NORETURN
+KiDispatchException0Args(IN NTSTATUS Code,
+                         IN ULONG_PTR Address,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    /* Helper for exceptions with no arguments */
+    KiDispatchExceptionFromTrapFrame(Code, Address, 0, 0, 0, 0, TrapFrame);
+}
+
+//
+// Exception with one argument
+//
+VOID
+FORCEINLINE
+//DECLSPEC_NORETURN
+KiDispatchException1Args(IN NTSTATUS Code,
+                         IN ULONG_PTR Address,
+                         IN ULONG P1,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    /* Helper for exceptions with no arguments */
+    KiDispatchExceptionFromTrapFrame(Code, Address, 1, P1, 0, 0, TrapFrame);
+}
+
+//
+// Exception with two arguments
+//
+VOID
+FORCEINLINE
+//DECLSPEC_NORETURN
+KiDispatchException2Args(IN NTSTATUS Code,
+                         IN ULONG_PTR Address,
+                         IN ULONG P1,
+                         IN ULONG P2,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    /* Helper for exceptions with no arguments */
+    KiDispatchExceptionFromTrapFrame(Code, Address, 2, P1, P2, 0, TrapFrame);
+}
+
+//
+// Performs a system call
+//
+NTSTATUS
+FORCEINLINE
+KiSystemCallTrampoline(IN PVOID Handler,
+                       IN PVOID Arguments,
+                       IN ULONG StackBytes)
+{
+    NTSTATUS Result;
+    
+    /*
+     * This sequence does a RtlCopyMemory(Stack - StackBytes, Arguments, StackBytes)
+     * and then calls the function associated with the system call.
+     *
+     * It's done in assembly for two reasons: we need to muck with the stack,
+     * and the call itself restores the stack back for us. The only way to do
+     * this in C is to do manual C handlers for every possible number of args on
+     * the stack, and then have the handler issue a call by pointer. This is
+     * wasteful since it'll basically push the values twice and require another
+     * level of call indirection.
+     *
+     * The ARM kernel currently does this, but it should probably be changed
+     * later to function like this as well.
+     *
+     */
+    __asm__ __volatile__
+    (
+        "subl %1, %%esp\n"
+        "movl %%esp, %%edi\n"
+        "movl %2, %%esi\n"
+        "shrl $2, %1\n"
+        "rep movsd\n"
+        "call *%3\n"
+        "movl %%eax, %0\n"
+        : "=r"(Result)
+        : "c"(StackBytes),
+          "d"(Arguments),
+          "r"(Handler)
+        : "%esp", "%esi", "%edi"
+    );
+    
+    return Result;
+}
+
+//
+// Checks for pending APCs
+//
+VOID
+FORCEINLINE
+KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
+{
+    PKTHREAD Thread;
+    KIRQL OldIrql;
+
+    /* Check for V8086 or user-mode trap */
+    if ((TrapFrame->EFlags & EFLAGS_V86_MASK) || (KiUserTrap(TrapFrame)))
+    {
+        /* Get the thread */
+        Thread = KeGetCurrentThread();
+        while (TRUE)
+        {
+            /* Turn off the alerted state for kernel mode */
+            Thread->Alerted[KernelMode] = FALSE;
+
+            /* Are there pending user APCs? */
+            if (!Thread->ApcState.UserApcPending) break;
+
+            /* Raise to APC level and enable interrupts */
+            OldIrql = KfRaiseIrql(APC_LEVEL);
+            _enable();
+
+            /* Deliver APCs */
+            KiDeliverApc(UserMode, NULL, TrapFrame);
+
+            /* Restore IRQL and disable interrupts once again */
+            KfLowerIrql(OldIrql);
+            _disable();
+        }
+    }
+}
+
+//
+// Converts a base thread to a GUI thread
+//
+NTSTATUS
+FORCEINLINE
+KiConvertToGuiThread(VOID)
+{
+    NTSTATUS Result;  
+    PVOID StackFrame;
+
+    /*
+     * Converting to a GUI thread safely updates ESP in-place as well as the
+     * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called.
+     *
+     * However, PsConvertToGuiThread "helpfully" restores EBP to the original
+     * caller's value, since it is considered a nonvolatile register. As such,
+     * as soon as we're back after the conversion and we try to store the result
+     * which will probably be in some stack variable (EBP-based), we'll crash as
+     * we are touching the de-allocated non-expanded stack.
+     *
+     * Thus we need a way to update our EBP before EBP is touched, and the only
+     * way to guarantee this is to do the call itself in assembly, use the EAX
+     * register to store the result, fixup EBP, and then let the C code continue
+     * on its merry way.
+     *
+     */
+    __asm__ __volatile__
+    (
+        "movl %%ebp, %1\n"
+        "subl %%esp, %1\n"
+        "call _PsConvertToGuiThread at 0\n"
+        "addl %%esp, %1\n"
+        "movl %1, %%ebp\n"
+        "movl %%eax, %0\n"
+        : "=r"(Result), "=r"(StackFrame)
+        :
+        : "%esp", "%ecx", "%edx"
+    );
+        
+    return Result;
+}
+
+//
+// Switches from boot loader to initial kernel stack
+//
+VOID
+FORCEINLINE
+KiSwitchToBootStack(IN ULONG_PTR InitialStack)
+{
+    /* We have to switch to a new stack before continuing kernel initialization */
     __asm__ __volatile__
     (
         "movl %0, %%esp\n"
-        "popa\n"
-        "ret\n"
-        :
-        : "r"(Stack)
+        "subl %1, %%esp\n"
+        "pushl %2\n"
+        "jmp _KiSystemStartupBootStack at 0\n"
+        : 
+        : "c"(InitialStack),
+          "i"(NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH),
+          "i"(CR0_EM | CR0_TS | CR0_MP)
         : "%esp"
     );
 }
+
 #endif
 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H */

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=45231&r1=45230&r2=45231&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Sun Jan 24 06:40:04 2010
@@ -863,19 +863,7 @@
     ULONG_PTR BugCheckParameter4,
     PKTRAP_FRAME Tf
 );
-
-VOID
-NTAPI
-KiDispatchExceptionFromTrapFrame(
-    IN NTSTATUS Code,
-    IN ULONG_PTR Address,
-    IN ULONG ParameterCount,
-    IN ULONG_PTR Parameter1,
-    IN ULONG_PTR Parameter2,
-    IN ULONG_PTR Parameter3,
-    IN PKTRAP_FRAME TrapFrame
-);
-                                  
+                              
 BOOLEAN
 NTAPI
 KiHandleNmi(VOID);
@@ -1124,6 +1112,14 @@
     VOID
 );
 
+VOID
+FASTCALL
+//DECLSPEC_NORETURN
+KiSystemFatalException(
+    IN ULONG ExceptionCode,
+    IN PKTRAP_FRAME TrapFrame
+);
+
 #include "ke_x.h"
 
 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */

Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/trap_x.h?rev=45231&r1=45230&r2=45231&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Sun Jan 24 06:40:04 2010
@@ -5,26 +5,21 @@
  * PURPOSE:         Internal Inlined Functions for the Trap Handling Code
  * PROGRAMMERS:     ReactOS Portable Systems Group
  */
-
-#if 0
-
-#ifdef __GNUC__
+#ifndef _TRAP_X_
+#define _TRAP_X_
+
+//
+// Unreachable code hint for GCC 4.5.x, 4.4.x, and MSVC
+//
 #if __GNUC__ * 100 + __GNUC_MINOR__ >= 405
 #define UNREACHABLE __builtin_unreachable()
+#elif __GNUC__ * 100 + __GNUC_MINOR__ >= 404
+#define UNREACHABLE __builtin_trap()
+#elif _MSC_VER
+#define UNREACHABLE __assume(0)
 #else
-DECLSPEC_NORETURN void exit(int s) {exit(s);}
-#define UNREACHABLE exit(0)
+#define UNREACHABLE
 #endif
-#else /* not __GNUC__ */
-DECLSPEC_NORETURN void exit(int s) {exit(s);}
-#define UNREACHABLE exit(0)
-#endif
-
-#else
-
-#define UNREACHABLE
-
-#endif
 
 //
 // Debug Macros
@@ -34,46 +29,46 @@
 KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame)
 {
     /* Dump the whole thing */
-    DPRINT1("DbgEbp: %x\n", TrapFrame->DbgEbp);
-    DPRINT1("DbgEip: %x\n", TrapFrame->DbgEip);
-    DPRINT1("DbgArgMark: %x\n", TrapFrame->DbgArgMark);
-    DPRINT1("DbgArgPointer: %x\n", TrapFrame->DbgArgPointer);
-    DPRINT1("TempSegCs: %x\n", TrapFrame->TempSegCs);
-    DPRINT1("TempEsp: %x\n", TrapFrame->TempEsp);
-    DPRINT1("Dr0: %x\n", TrapFrame->Dr0);
-    DPRINT1("Dr1: %x\n", TrapFrame->Dr1);
-    DPRINT1("Dr2: %x\n", TrapFrame->Dr2);
-    DPRINT1("Dr3: %x\n", TrapFrame->Dr3);
-    DPRINT1("Dr6: %x\n", TrapFrame->Dr6);
-    DPRINT1("Dr7: %x\n", TrapFrame->Dr7);
-    DPRINT1("SegGs: %x\n", TrapFrame->SegGs);
-    DPRINT1("SegEs: %x\n", TrapFrame->SegEs);
-    DPRINT1("SegDs: %x\n", TrapFrame->SegDs);
-    DPRINT1("Edx: %x\n", TrapFrame->Edx);
-    DPRINT1("Ecx: %x\n", TrapFrame->Ecx);
-    DPRINT1("Eax: %x\n", TrapFrame->Eax);
-    DPRINT1("PreviousPreviousMode: %x\n", TrapFrame->PreviousPreviousMode);
-    DPRINT1("ExceptionList: %x\n", TrapFrame->ExceptionList);
-    DPRINT1("SegFs: %x\n", TrapFrame->SegFs);
-    DPRINT1("Edi: %x\n", TrapFrame->Edi);
-    DPRINT1("Esi: %x\n", TrapFrame->Esi);
-    DPRINT1("Ebx: %x\n", TrapFrame->Ebx);
-    DPRINT1("Ebp: %x\n", TrapFrame->Ebp);
-    DPRINT1("ErrCode: %x\n", TrapFrame->ErrCode);
-    DPRINT1("Eip: %x\n", TrapFrame->Eip);
-    DPRINT1("SegCs: %x\n", TrapFrame->SegCs);
-    DPRINT1("EFlags: %x\n", TrapFrame->EFlags);
-    DPRINT1("HardwareEsp: %x\n", TrapFrame->HardwareEsp);
-    DPRINT1("HardwareSegSs: %x\n", TrapFrame->HardwareSegSs);
-    DPRINT1("V86Es: %x\n", TrapFrame->V86Es);
-    DPRINT1("V86Ds: %x\n", TrapFrame->V86Ds);
-    DPRINT1("V86Fs: %x\n", TrapFrame->V86Fs);
-    DPRINT1("V86Gs: %x\n", TrapFrame->V86Gs);
-}
-
-#if YDEBUG
-FORCEINLINE
-VOID
+    DbgPrint("DbgEbp: %x\n", TrapFrame->DbgEbp);
+    DbgPrint("DbgEip: %x\n", TrapFrame->DbgEip);
+    DbgPrint("DbgArgMark: %x\n", TrapFrame->DbgArgMark);
+    DbgPrint("DbgArgPointer: %x\n", TrapFrame->DbgArgPointer);
+    DbgPrint("TempSegCs: %x\n", TrapFrame->TempSegCs);
+    DbgPrint("TempEsp: %x\n", TrapFrame->TempEsp);
+    DbgPrint("Dr0: %x\n", TrapFrame->Dr0);
+    DbgPrint("Dr1: %x\n", TrapFrame->Dr1);
+    DbgPrint("Dr2: %x\n", TrapFrame->Dr2);
+    DbgPrint("Dr3: %x\n", TrapFrame->Dr3);
+    DbgPrint("Dr6: %x\n", TrapFrame->Dr6);
+    DbgPrint("Dr7: %x\n", TrapFrame->Dr7);
+    DbgPrint("SegGs: %x\n", TrapFrame->SegGs);
+    DbgPrint("SegEs: %x\n", TrapFrame->SegEs);
+    DbgPrint("SegDs: %x\n", TrapFrame->SegDs);
+    DbgPrint("Edx: %x\n", TrapFrame->Edx);
+    DbgPrint("Ecx: %x\n", TrapFrame->Ecx);
+    DbgPrint("Eax: %x\n", TrapFrame->Eax);
+    DbgPrint("PreviousPreviousMode: %x\n", TrapFrame->PreviousPreviousMode);
+    DbgPrint("ExceptionList: %x\n", TrapFrame->ExceptionList);
+    DbgPrint("SegFs: %x\n", TrapFrame->SegFs);
+    DbgPrint("Edi: %x\n", TrapFrame->Edi);
+    DbgPrint("Esi: %x\n", TrapFrame->Esi);
+    DbgPrint("Ebx: %x\n", TrapFrame->Ebx);
+    DbgPrint("Ebp: %x\n", TrapFrame->Ebp);
+    DbgPrint("ErrCode: %x\n", TrapFrame->ErrCode);
+    DbgPrint("Eip: %x\n", TrapFrame->Eip);
+    DbgPrint("SegCs: %x\n", TrapFrame->SegCs);
+    DbgPrint("EFlags: %x\n", TrapFrame->EFlags);
+    DbgPrint("HardwareEsp: %x\n", TrapFrame->HardwareEsp);
+    DbgPrint("HardwareSegSs: %x\n", TrapFrame->HardwareSegSs);
+    DbgPrint("V86Es: %x\n", TrapFrame->V86Es);
+    DbgPrint("V86Ds: %x\n", TrapFrame->V86Ds);
+    DbgPrint("V86Fs: %x\n", TrapFrame->V86Fs);
+    DbgPrint("V86Gs: %x\n", TrapFrame->V86Gs);
+}
+
+#ifdef TRAP_DEBUG
+VOID
+FORCEINLINE
 KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
 {
     /* Set the debug information */
@@ -83,22 +78,22 @@
     TrapFrame->DbgEbp = TrapFrame->Ebp;   
 }
 
-FORCEINLINE
-VOID
+VOID
+FORCEINLINE
 KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
                       IN KTRAP_STATE_BITS SkipBits)
 {
     /* Make sure interrupts are disabled */
     if (__readeflags() & EFLAGS_INTERRUPT_MASK)
     {
-        DPRINT1("Exiting with interrupts enabled: %lx\n", __readeflags());
+        DbgPrint("Exiting with interrupts enabled: %lx\n", __readeflags());
         while (TRUE);
     }
     
     /* Make sure this is a real trap frame */
     if (TrapFrame->DbgArgMark != 0xBADB0D00)
     {
-        DPRINT1("Exiting with an invalid trap frame? (No MAGIC in trap frame)\n");
+        DbgPrint("Exiting with an invalid trap frame? (No MAGIC in trap frame)\n");
         KiDumpTrapFrame(TrapFrame);
         while (TRUE);
     }
@@ -106,34 +101,34 @@
     /* Make sure we're not in user-mode or something */
     if (Ke386GetFs() != KGDT_R0_PCR)
     {
-        DPRINT1("Exiting with an invalid FS: %lx\n", Ke386GetFs());
+        DbgPrint("Exiting with an invalid FS: %lx\n", Ke386GetFs());
         while (TRUE);   
     }
     
     /* Make sure we have a valid SEH chain */
     if (KeGetPcr()->Tib.ExceptionList == 0)
     {
-        DPRINT1("Exiting with NULL exception chain: %p\n", KeGetPcr()->Tib.ExceptionList);
+        DbgPrint("Exiting with NULL exception chain: %p\n", KeGetPcr()->Tib.ExceptionList);
         while (TRUE);
     }
     
     /* Make sure we're restoring a valid SEH chain */
     if (TrapFrame->ExceptionList == 0)
     {
-        DPRINT1("Entered a trap with a NULL exception chain: %p\n", TrapFrame->ExceptionList);
+        DbgPrint("Entered a trap with a NULL exception chain: %p\n", TrapFrame->ExceptionList);
         while (TRUE);
     }
     
     /* If we're ignoring previous mode, make sure caller doesn't actually want it */
     if ((SkipBits.SkipPreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
     {
-        DPRINT1("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
-        while (TRUE);
-    }
-}
-
-FORCEINLINE
-VOID
+        DbgPrint("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
+        while (TRUE);
+    }
+}
+
+VOID
+FORCEINLINE
 KiExitSystemCallDebugChecks(IN ULONG SystemCall,
                             IN PKTRAP_FRAME TrapFrame)
 {
@@ -188,88 +183,11 @@
     return (TrapFrame->SegCs & MODE_MASK);
 }
 
-BOOLEAN
-FORCEINLINE
-KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
-{
-    /* Either the V8086 flag is on, or this is user-mode with a VDM */
-    return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
-            ((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
-}
-
-VOID
-FORCEINLINE
-KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
-{
-    PKTHREAD Thread;
-    KIRQL OldIrql;
-
-    /* Check for V8086 or user-mode trap */
-    if ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
-        (KiUserTrap(TrapFrame)))
-    {
-        /* Get the thread */
-        Thread = KeGetCurrentThread();
-        while (TRUE)
-        {
-            /* Turn off the alerted state for kernel mode */
-            Thread->Alerted[KernelMode] = FALSE;
-
-            /* Are there pending user APCs? */
-            if (!Thread->ApcState.UserApcPending) break;
-
-            /* Raise to APC level and enable interrupts */
-            OldIrql = KfRaiseIrql(APC_LEVEL);
-            _enable();
-
-            /* Deliver APCs */
-            KiDeliverApc(UserMode, NULL, TrapFrame);
-
-            /* Restore IRQL and disable interrupts once again */
-            KfLowerIrql(OldIrql);
-            _disable();
-        }
-    }
-}
-
-VOID
-FORCEINLINE
-//DECLSPEC_NORETURN
-KiDispatchException0Args(IN NTSTATUS Code,
-                         IN ULONG_PTR Address,
-                         IN PKTRAP_FRAME TrapFrame)
-{
-    /* Helper for exceptions with no arguments */
-    KiDispatchExceptionFromTrapFrame(Code, Address, 0, 0, 0, 0, TrapFrame);
-}
-
-VOID
-FORCEINLINE
-//DECLSPEC_NORETURN
-KiDispatchException1Args(IN NTSTATUS Code,
-                         IN ULONG_PTR Address,
-                         IN ULONG P1,
-                         IN PKTRAP_FRAME TrapFrame)
-{
-    /* Helper for exceptions with no arguments */
-    KiDispatchExceptionFromTrapFrame(Code, Address, 1, P1, 0, 0, TrapFrame);
-}
-
-VOID
-FORCEINLINE
-//DECLSPEC_NORETURN
-KiDispatchException2Args(IN NTSTATUS Code,
-                         IN ULONG_PTR Address,
-                         IN ULONG P1,
-                         IN ULONG P2,
-                         IN PKTRAP_FRAME TrapFrame)
-{
-    /* Helper for exceptions with no arguments */
-    KiDispatchExceptionFromTrapFrame(Code, Address, 2, P1, P2, 0, TrapFrame);
-}
-
-FORCEINLINE
-VOID
+//
+// Assembly exit stubs
+//
+VOID
+FORCEINLINE
 //DECLSPEC_NORETURN
 KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame)
 {
@@ -299,8 +217,8 @@
     UNREACHABLE;
 }
 
-FORCEINLINE
-VOID
+VOID
+FORCEINLINE
 //DECLSPEC_NORETURN
 KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame)
 {
@@ -328,8 +246,8 @@
     UNREACHABLE;
 }
 
-FORCEINLINE
-VOID
+VOID
+FORCEINLINE
 //DECLSPEC_NORETURN
 KiSystemCallSysExitReturn(IN PKTRAP_FRAME TrapFrame)
 {
@@ -361,8 +279,8 @@
     UNREACHABLE;
 }
 
-FORCEINLINE
-VOID
+VOID
+FORCEINLINE
 //DECLSPEC_NORETURN
 KiTrapReturn(IN PKTRAP_FRAME TrapFrame)
 {
@@ -394,8 +312,8 @@
     UNREACHABLE;
 }
 
-FORCEINLINE
-VOID
+VOID
+FORCEINLINE
 //DECLSPEC_NORETURN
 KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame)
 {
@@ -428,102 +346,326 @@
     UNREACHABLE;
 }
 
-NTSTATUS
-FORCEINLINE
-KiSystemCallTrampoline(IN PVOID Handler,
-                       IN PVOID Arguments,
-                       IN ULONG StackBytes)
-{
-    NTSTATUS Result;
+//
+// Generic Exit Routine
+//
+VOID
+FORCEINLINE
+//DECLSPEC_NORETURN
+KiExitTrap(IN PKTRAP_FRAME TrapFrame,
+           IN UCHAR Skip)
+{
+    KTRAP_EXIT_SKIP_BITS SkipBits = { .Bits = Skip };
+    PULONG ReturnStack;
+    
+    /* Debugging checks */
+    KiExitTrapDebugChecks(TrapFrame, SkipBits);
+
+    /* Restore the SEH handler chain */
+    KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
+    
+    /* Check if the previous mode must be restored */
+    if (__builtin_expect(!SkipBits.SkipPreviousMode, 0)) /* More INTS than SYSCALLs */
+    {
+        /* Restore it */
+        KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
+    }
+
+    /* Check if there are active debug registers */
+    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
+    {
+        /* Not handled yet */
+        DbgPrint("Need Hardware Breakpoint Support!\n");
+        DbgBreakPoint();
+        while (TRUE);
+    }
+    
+    /* Check if this was a V8086 trap */
+    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0)) KiTrapReturn(TrapFrame);
+
+    /* Check if the trap frame was edited */
+    if (__builtin_expect(!(TrapFrame->SegCs & FRAME_EDITED), 0))
+    {   
+        /*
+         * An edited trap frame happens when we need to modify CS and/or ESP but
+         * don't actually have a ring transition. This happens when a kernelmode
+         * caller wants to perform an NtContinue to another kernel address, such
+         * as in the case of SEH (basically, a longjmp), or to a user address.
+         *
+         * Therefore, the CPU never saved CS/ESP on the stack because we did not
+         * get a trap frame due to a ring transition (there was no interrupt).
+         * Even if we didn't want to restore CS to a new value, a problem occurs
+         * due to the fact a normal RET would not work if we restored ESP since
+         * RET would then try to read the result off the stack.
+         *
+         * The NT kernel solves this by adding 12 bytes of stack to the exiting
+         * trap frame, in which EFLAGS, CS, and EIP are stored, and then saving
+         * the ESP that's being requested into the ErrorCode field. It will then
+         * exit with an IRET. This fixes both issues, because it gives the stack
+         * some space where to hold the return address and then end up with the
+         * wanted stack, and it uses IRET which allows a new CS to be inputted.
+         *
+         */
+         
+        /* Set CS that is requested */
+        TrapFrame->SegCs = TrapFrame->TempSegCs;
+         
+        /* First make space on requested stack */
+        ReturnStack = (PULONG)(TrapFrame->TempEsp - 12);
+        TrapFrame->ErrCode = (ULONG_PTR)ReturnStack;
+         
+        /* Now copy IRET frame */
+        ReturnStack[0] = TrapFrame->Eip;
+        ReturnStack[1] = TrapFrame->SegCs;
+        ReturnStack[2] = TrapFrame->EFlags;
+        
+        /* Do special edited return */
+        KiEditedTrapReturn(TrapFrame);
+    }
+    
+    /* Check if this is a user trap */
+    if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* Ring 3 is where we spend time */
+    {
+        /* Check if segments should be restored */
+        if (!SkipBits.SkipSegments)
+        {
+            /* Restore segments */
+            Ke386SetGs(TrapFrame->SegGs);
+            Ke386SetEs(TrapFrame->SegEs);
+            Ke386SetDs(TrapFrame->SegDs);
+            Ke386SetFs(TrapFrame->SegFs);
+        }
+        
+        /* Always restore FS since it goes from KPCR to TEB */
+        Ke386SetFs(TrapFrame->SegFs);
+    }
+    
+    /* Check for system call -- a system call skips volatiles! */
+    if (__builtin_expect(SkipBits.SkipVolatiles, 0)) /* More INTs than SYSCALLs */
+    {
+        /* Kernel call or user call? */
+        if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* More Ring 3 than 0 */
+        {
+            /* Is SYSENTER supported and/or enabled, or are we stepping code? */
+            if (__builtin_expect((KiFastSystemCallDisable) ||
+                                 (TrapFrame->EFlags & EFLAGS_TF), 0))
+            {
+                /* Exit normally */
+                KiSystemCallTrapReturn(TrapFrame);
+            }
+            else
+            {
+                /* Restore user FS */
+                Ke386SetFs(KGDT_R3_TEB | RPL_MASK);
+                
+                /* Remove interrupt flag */
+                TrapFrame->EFlags &= ~EFLAGS_INTERRUPT_MASK;
+                __writeeflags(TrapFrame->EFlags);
+                
+                /* Exit through SYSEXIT */
+                KiSystemCallSysExitReturn(TrapFrame);
+            }
+        }
+        else
+        {
+            /* Restore EFLags */
+            __writeeflags(TrapFrame->EFlags);
+            
+            /* Call is kernel, so do a jump back since this wasn't a real INT */
+            KiSystemCallReturn(TrapFrame);
+        }  
+    }
+    else
+    {
+        /* Return from interrupt */
+        KiTrapReturn(TrapFrame);
+    }
+}
+
+//
+// Virtual 8086 Mode Optimized Trap Exit
+//
+VOID
+FORCEINLINE
+KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
+{
+    PKTHREAD Thread;
+    KIRQL OldIrql;
+    
+    /* Get the thread */
+    Thread = KeGetCurrentThread();
+    while (TRUE)
+    {
+        /* Turn off the alerted state for kernel mode */
+        Thread->Alerted[KernelMode] = FALSE;
+
+        /* Are there pending user APCs? */
+        if (__builtin_expect(!Thread->ApcState.UserApcPending, 1)) break;
+
+        /* Raise to APC level and enable interrupts */
+        OldIrql = KfRaiseIrql(APC_LEVEL);
+        _enable();
+
+        /* Deliver APCs */
+        KiDeliverApc(UserMode, NULL, TrapFrame);
+
+        /* Restore IRQL and disable interrupts once again */
+        KfLowerIrql(OldIrql);
+        _disable();
+        
+        /* Return if this isn't V86 mode anymore */
+        if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0)) return;
+    }
+     
+    /* If we got here, we're still in a valid V8086 context, so quit it */
+    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
+    {
+        /* Not handled yet */
+        DbgPrint("Need Hardware Breakpoint Support!\n");
+        while (TRUE);
+    }
+     
+    /* Return from interrupt */
+    KiTrapReturn(TrapFrame);
+}
+
+//
+// Virtual 8086 Mode Optimized Trap Entry
+//
+VOID
+FORCEINLINE
+KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Load correct registers */
+    Ke386SetFs(KGDT_R0_PCR);
+    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+
+    /* Save exception list and bogus previous mode */
+    TrapFrame->PreviousPreviousMode = -1;
+    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
+
+    /* Clear direction flag */
+    Ke386ClearDirectionFlag();
+    
+    /* Save DR7 and check for debugging */
+    TrapFrame->Dr7 = __readdr(7);
+    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
+    {
+        DbgPrint("Need Hardware Breakpoint Support!\n");
+        while (TRUE);
+    }
+}
+
+//
+// Interrupt Trap Entry
+//
+VOID
+FORCEINLINE
+KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Set bogus previous mode */
+    TrapFrame->PreviousPreviousMode = -1;
+    
+    /* Check for V86 mode */
+    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
+    {
+        DbgPrint("Need V8086 Interrupt Support!\n");
+        while (TRUE);
+    }
+    
+    /* Check if this wasn't kernel code */
+    if (__builtin_expect(TrapFrame->SegCs != KGDT_R0_CODE, 1)) /* Ring 3 is more common */
+    {
+        /* Save segments and then switch to correct ones */
+        TrapFrame->SegFs = Ke386GetFs();
+        TrapFrame->SegGs = Ke386GetGs();
+        TrapFrame->SegDs = Ke386GetDs();
+        TrapFrame->SegEs = Ke386GetEs();
+        Ke386SetFs(KGDT_R0_PCR);
+        Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+        Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+    }
+    
+    /* Save exception list and terminate it */
+    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
+    KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
+    
+    /* No error code */
+    TrapFrame->ErrCode = 0;
+    
+    /* Clear direction flag */
+    Ke386ClearDirectionFlag();
+    
+    /* Flush DR7 and check for debugging */
+    TrapFrame->Dr7 = 0;
+    if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
+    {
+        DbgPrint("Need Hardware Breakpoint Support!\n");
+        while (TRUE);
+    }
+    
+    /* Set debug header */
+    KiFillTrapFrameDebug(TrapFrame);
+}
+
+//
+// Generic Trap Entry
+//
+VOID
+FORCEINLINE
+KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
+{
+    ULONG Ds, Es;
     
     /*
-     * This sequence does a RtlCopyMemory(Stack - StackBytes, Arguments, StackBytes)
-     * and then calls the function associated with the system call.
+     * We really have to get a good DS/ES first before touching any data.
      *
-     * It's done in assembly for two reasons: we need to muck with the stack,
-     * and the call itself restores the stack back for us. The only way to do
-     * this in C is to do manual C handlers for every possible number of args on
-     * the stack, and then have the handler issue a call by pointer. This is
-     * wasteful since it'll basically push the values twice and require another
-     * level of call indirection.
+     * These two reads will either go in a register (with optimizations ON) or
+     * a stack variable (which is on SS:ESP, guaranteed to be good/valid).
      *
-     * The ARM kernel currently does this, but it should probably be changed
-     * later to function like this as well.
+     * Because the assembly is marked volatile, the order of instructions is
+     * as-is, otherwise the optimizer could simply get rid of our DS/ES.
      *
      */
-    __asm__ __volatile__
-    (
-        "subl %1, %%esp\n"
-        "movl %%esp, %%edi\n"
-        "movl %2, %%esi\n"
-        "shrl $2, %1\n"
-        "rep movsd\n"
-        "call *%3\n"
-        "movl %%eax, %0\n"
-        : "=r"(Result)
-        : "c"(StackBytes),
-          "d"(Arguments),
-          "r"(Handler)
-        : "%esp", "%esi", "%edi"
-    );
-    
-    return Result;
-}
-
-NTSTATUS
-FORCEINLINE
-KiConvertToGuiThread(VOID)
-{
-    NTSTATUS Result;  
-    PVOID StackFrame;
-
-    /*
-     * Converting to a GUI thread safely updates ESP in-place as well as the
-     * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called.
-     *
-     * However, PsConvertToGuiThread "helpfully" restores EBP to the original
-     * caller's value, since it is considered a nonvolatile register. As such,
-     * as soon as we're back after the conversion and we try to store the result
-     * which will probably be in some stack variable (EBP-based), we'll crash as
-     * we are touching the de-allocated non-expanded stack.
-     *
-     * Thus we need a way to update our EBP before EBP is touched, and the only
-     * way to guarantee this is to do the call itself in assembly, use the EAX
-     * register to store the result, fixup EBP, and then let the C code continue
-     * on its merry way.
-     *
-     */
-    __asm__ __volatile__
-    (
-        "movl %%ebp, %1\n"
-        "subl %%esp, %1\n"
-        "call _PsConvertToGuiThread at 0\n"
-        "addl %%esp, %1\n"
-        "movl %1, %%ebp\n"
-        "movl %%eax, %0\n"
-        : "=r"(Result), "=r"(StackFrame)
-        :
-        : "%esp", "%ecx", "%edx"
-    );
+    Ds = Ke386GetDs();
+    Es = Ke386GetEs();
+    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+    TrapFrame->SegDs = Ds;
+    TrapFrame->SegEs = Es;
         
-    return Result;
-}
-
-VOID
-FORCEINLINE
-KiSwitchToBootStack(IN ULONG_PTR InitialStack)
-{
-    /* We have to switch to a new stack before continuing kernel initialization */
-    __asm__ __volatile__
-    (
-        "movl %0, %%esp\n"
-        "subl %1, %%esp\n"
-        "pushl %2\n"
-        "jmp _KiSystemStartupBootStack at 0\n"
-        : 
-        : "c"(InitialStack),
-          "i"(NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH),
-          "i"(CR0_EM | CR0_TS | CR0_MP)
-        : "%esp"
-    );
-}
+    /* Now we can save the other segments and then switch to the correct FS */
+    TrapFrame->SegFs = Ke386GetFs();
+    TrapFrame->SegGs = Ke386GetGs();
+    Ke386SetFs(KGDT_R0_PCR);
+
+    /* Save exception list and bogus previous mode */
+    TrapFrame->PreviousPreviousMode = -1;
+    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
+    
+    /* Check for V86 mode */
+    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
+    {
+        /* Restore V8086 segments into Protected Mode segments */
+        TrapFrame->SegFs = TrapFrame->V86Fs;
+        TrapFrame->SegGs = TrapFrame->V86Gs;
+        TrapFrame->SegDs = TrapFrame->V86Ds;
+        TrapFrame->SegEs = TrapFrame->V86Es;
+    }
+
+    /* Clear direction flag */
+    Ke386ClearDirectionFlag();
+    
+    /* Flush DR7 and check for debugging */
+    TrapFrame->Dr7 = 0;
+    if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
+    {
+        DbgPrint("Need Hardware Breakpoint Support!\n");
+        while (TRUE);
+    }
+    
+    /* Set debug header */
+    KiFillTrapFrameDebug(TrapFrame);
+}
+#endif

Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev=45231&r1=45230&r2=45231&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] Sun Jan 24 06:40:04 2010
@@ -1105,6 +1105,62 @@
     return;
 }
 
+VOID
+NTAPI
+//DECLSPEC_NORETURN
+KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
+                                 IN ULONG_PTR Address,
+                                 IN ULONG ParameterCount,
+                                 IN ULONG_PTR Parameter1,
+                                 IN ULONG_PTR Parameter2,
+                                 IN ULONG_PTR Parameter3,
+                                 IN PKTRAP_FRAME TrapFrame)
+{
+    EXCEPTION_RECORD ExceptionRecord;
+
+    /* Build the exception record */
+    ExceptionRecord.ExceptionCode = Code;
+    ExceptionRecord.ExceptionFlags = 0;
+    ExceptionRecord.ExceptionRecord = NULL;
+    ExceptionRecord.ExceptionAddress = (PVOID)Address;
+    ExceptionRecord.NumberParameters = ParameterCount;
+    if (ParameterCount)
+    {
+        /* Copy extra parameters */
+        ExceptionRecord.ExceptionInformation[0] = Parameter1;
+        ExceptionRecord.ExceptionInformation[1] = Parameter2;
+        ExceptionRecord.ExceptionInformation[2] = Parameter3;
+    }
+    
+    /* Now go dispatch the exception */
+    KiDispatchException(&ExceptionRecord,
+                        NULL,
+                        TrapFrame,
+                        TrapFrame->EFlags & EFLAGS_V86_MASK ?
+                        -1 : KiUserTrap(TrapFrame),
+                        TRUE);
+
+    /* Return from this trap */
+    KiEoiHelper(TrapFrame);
+}
+
+VOID
+FASTCALL
+//DECLSPEC_NORETURN
+KiSystemFatalException(IN ULONG ExceptionCode,
+                       IN PKTRAP_FRAME TrapFrame)
+{
+    /* Bugcheck the system */
+    KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
+                     ExceptionCode,
+                     0,
+                     0,
+                     0,
+                     TrapFrame);
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
 /*
  * @implemented
  */

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45231&r1=45230&r2=45231&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Sun Jan 24 06:40:04 2010
@@ -11,7 +11,6 @@
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
-#include "internal/trap_x.h"
 
 /* GLOBALS ********************************************************************/
 
@@ -45,198 +44,21 @@
     0x6E,                      /* OUTS                                 */
     0x6F,                      /* OUTS                                 */    
 };
+
+BOOLEAN
+FORCEINLINE
+KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Either the V8086 flag is on, or this is user-mode with a VDM */
+    return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
+            ((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
+}
  
 /* TRAP EXIT CODE *************************************************************/
 
 VOID
 FASTCALL
 //DECLSPEC_NORETURN
-KiExitTrap(IN PKTRAP_FRAME TrapFrame,
-           IN UCHAR Skip)
-{
-    KTRAP_EXIT_SKIP_BITS SkipBits = { .Bits = Skip };
-    PULONG ReturnStack;
-    
-    /* Debugging checks */
-    KiExitTrapDebugChecks(TrapFrame, SkipBits);
-
-    /* Restore the SEH handler chain */
-    KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
-    
-    /* Check if the previous mode must be restored */
-    if (__builtin_expect(!SkipBits.SkipPreviousMode, 0)) /* More INTS than SYSCALLs */
-    {
-        /* Restore it */
-        KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
-    }
-
-    /* Check if there are active debug registers */
-    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
-    {
-        /* Not handled yet */
-        UNIMPLEMENTED;
-        DbgBreakPoint();
-        KiDumpTrapFrame(TrapFrame);
-        while (TRUE);
-    }
-    
-    /* Check if this was a V8086 trap */
-    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0)) KiTrapReturn(TrapFrame);
-
-    /* Check if the trap frame was edited */
-    if (__builtin_expect(!(TrapFrame->SegCs & FRAME_EDITED), 0))
-    {   
-        /*
-         * An edited trap frame happens when we need to modify CS and/or ESP but
-         * don't actually have a ring transition. This happens when a kernelmode
-         * caller wants to perform an NtContinue to another kernel address, such
-         * as in the case of SEH (basically, a longjmp), or to a user address.
-         *
-         * Therefore, the CPU never saved CS/ESP on the stack because we did not
-         * get a trap frame due to a ring transition (there was no interrupt).
-         * Even if we didn't want to restore CS to a new value, a problem occurs
-         * due to the fact a normal RET would not work if we restored ESP since
-         * RET would then try to read the result off the stack.
-         *
-         * The NT kernel solves this by adding 12 bytes of stack to the exiting
-         * trap frame, in which EFLAGS, CS, and EIP are stored, and then saving
-         * the ESP that's being requested into the ErrorCode field. It will then
-         * exit with an IRET. This fixes both issues, because it gives the stack
-         * some space where to hold the return address and then end up with the
-         * wanted stack, and it uses IRET which allows a new CS to be inputted.
-         *
-         */
-         
-        /* Set CS that is requested */
-        TrapFrame->SegCs = TrapFrame->TempSegCs;
-         
-        /* First make space on requested stack */
-        ReturnStack = (PULONG)(TrapFrame->TempEsp - 12);
-        TrapFrame->ErrCode = (ULONG_PTR)ReturnStack;
-         
-        /* Now copy IRET frame */
-        ReturnStack[0] = TrapFrame->Eip;
-        ReturnStack[1] = TrapFrame->SegCs;
-        ReturnStack[2] = TrapFrame->EFlags;
-        
-        /* Do special edited return */
-        KiEditedTrapReturn(TrapFrame);
-    }
-    
-    /* Check if this is a user trap */
-    if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* Ring 3 is where we spend time */
-    {
-        /* Check if segments should be restored */
-        if (!SkipBits.SkipSegments)
-        {
-            /* Restore segments */
-            Ke386SetGs(TrapFrame->SegGs);
-            Ke386SetEs(TrapFrame->SegEs);
-            Ke386SetDs(TrapFrame->SegDs);
-            Ke386SetFs(TrapFrame->SegFs);
-        }
-        
-        /* Always restore FS since it goes from KPCR to TEB */
-        Ke386SetFs(TrapFrame->SegFs);
-    }
-
-    /* Check for ABIOS code segment */
-    if (__builtin_expect(TrapFrame->SegCs == 0x80, 0))
-    {
-        /* Not handled yet */
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
-    /* Check for system call -- a system call skips volatiles! */
-    if (__builtin_expect(SkipBits.SkipVolatiles, 0)) /* More INTs than SYSCALLs */
-    {
-        /* Kernel call or user call? */
-        if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* More Ring 3 than 0 */
-        {
-            /* Is SYSENTER supported and/or enabled, or are we stepping code? */
-            if (__builtin_expect((KiFastSystemCallDisable) ||
-                                 (TrapFrame->EFlags & EFLAGS_TF), 0))
-            {
-                /* Exit normally */
-                KiSystemCallTrapReturn(TrapFrame);
-            }
-            else
-            {
-                /* Restore user FS */
-                Ke386SetFs(KGDT_R3_TEB | RPL_MASK);
-                
-                /* Remove interrupt flag */
-                TrapFrame->EFlags &= ~EFLAGS_INTERRUPT_MASK;
-                __writeeflags(TrapFrame->EFlags);
-                
-                /* Exit through SYSEXIT */
-                KiSystemCallSysExitReturn(TrapFrame);
-            }
-        }
-        else
-        {
-            /* Restore EFLags */
-            __writeeflags(TrapFrame->EFlags);
-            
-            /* Call is kernel, so do a jump back since this wasn't a real INT */
-            KiSystemCallReturn(TrapFrame);
-        }  
-    }
-    else
-    {
-        /* Return from interrupt */
-        KiTrapReturn(TrapFrame);
-    }
-}
-
-VOID
-FASTCALL
-KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
-{
-    PKTHREAD Thread;
-    KIRQL OldIrql;
-    
-    /* Get the thread */
-    Thread = KeGetCurrentThread();
-    while (TRUE)
-    {
-        /* Turn off the alerted state for kernel mode */
-        Thread->Alerted[KernelMode] = FALSE;
-
-        /* Are there pending user APCs? */
-        if (__builtin_expect(!Thread->ApcState.UserApcPending, 1)) break;
-
-        /* Raise to APC level and enable interrupts */
-        OldIrql = KfRaiseIrql(APC_LEVEL);
-        _enable();
-
-        /* Deliver APCs */
-        KiDeliverApc(UserMode, NULL, TrapFrame);
-
-        /* Restore IRQL and disable interrupts once again */
-        KfLowerIrql(OldIrql);
-        _disable();
-        
-        /* Return if this isn't V86 mode anymore */
-        if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0)) return;
-    }
-     
-    /* If we got here, we're still in a valid V8086 context, so quit it */
-    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
-    {
-        /* Not handled yet */
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-     
-    /* Return from interrupt */
-    KiTrapReturn(TrapFrame);
-}
-
-VOID
-FASTCALL
-//DECLSPEC_NORETURN
 KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
 {
     /* Disable interrupts until we return */
@@ -281,202 +103,6 @@
     
     /* Now exit the trap for real */
     KiExitTrap(TrapFrame, 0);
-}
-
-/* TRAP ENTRY CODE ************************************************************/
-
-VOID
-FASTCALL
-KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
-{
-    /* Load correct registers */
-    Ke386SetFs(KGDT_R0_PCR);
-    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
-    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
-
-    /* Save exception list and bogus previous mode */
-    TrapFrame->PreviousPreviousMode = -1;
-    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
-
-    /* Clear direction flag */
-    Ke386ClearDirectionFlag();
-    
-    /* Save DR7 and check for debugging */
-    TrapFrame->Dr7 = __readdr(7);
-    if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
-    {
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-}
-
-VOID
-FASTCALL
-KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
-{
-    /* Set bogus previous mode */
-    TrapFrame->PreviousPreviousMode = -1;
-    
-    /* Check for V86 mode */
-    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
-    {
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
-    /* Check if this wasn't kernel code */
-    if (__builtin_expect(TrapFrame->SegCs != KGDT_R0_CODE, 1)) /* Ring 3 is more common */
-    {
-        /* Save segments and then switch to correct ones */
-        TrapFrame->SegFs = Ke386GetFs();
-        TrapFrame->SegGs = Ke386GetGs();
-        TrapFrame->SegDs = Ke386GetDs();
-        TrapFrame->SegEs = Ke386GetEs();
-        Ke386SetFs(KGDT_R0_PCR);
-        Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
-        Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
-    }
-    
-    /* Save exception list and terminate it */
-    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
-    KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
-    
-    /* FIXME: This doesn't support 16-bit ABIOS interrupts */
-    TrapFrame->ErrCode = 0;
-    
-    /* Clear direction flag */
-    Ke386ClearDirectionFlag();
-    
-    /* Flush DR7 and check for debugging */
-    TrapFrame->Dr7 = 0;
-    if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
-    {
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
-    /* Set debug header */
-    KiFillTrapFrameDebug(TrapFrame);
-}
-
-VOID
-FASTCALL
-KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
-{
-    ULONG Ds, Es;
-    
-    /*
-     * We really have to get a good DS/ES first before touching any data.
-     *
-     * These two reads will either go in a register (with optimizations ON) or
-     * a stack variable (which is on SS:ESP, guaranteed to be good/valid).
-     *
-     * Because the assembly is marked volatile, the order of instructions is
-     * as-is, otherwise the optimizer could simply get rid of our DS/ES.
-     *
-     */
-    Ds = Ke386GetDs();
-    Es = Ke386GetEs();
-    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
-    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
-    TrapFrame->SegDs = Ds;
-    TrapFrame->SegEs = Es;
-        
-    /* Now we can save the other segments and then switch to the correct FS */
-    TrapFrame->SegFs = Ke386GetFs();
-    TrapFrame->SegGs = Ke386GetGs();
-    Ke386SetFs(KGDT_R0_PCR);
-
-    /* Save exception list and bogus previous mode */
-    TrapFrame->PreviousPreviousMode = -1;
-    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
-    
-    /* Check for 16-bit stack */
-    if (__builtin_expect((ULONG_PTR)TrapFrame < 0x10000, 0))
-    {
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
-    /* Check for V86 mode */
-    if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
-    {
-        /* Restore V8086 segments into Protected Mode segments */
-        TrapFrame->SegFs = TrapFrame->V86Fs;
-        TrapFrame->SegGs = TrapFrame->V86Gs;
-        TrapFrame->SegDs = TrapFrame->V86Ds;
-        TrapFrame->SegEs = TrapFrame->V86Es;
-    }
-
-    /* Clear direction flag */
-    Ke386ClearDirectionFlag();
-    
-    /* Flush DR7 and check for debugging */
-    TrapFrame->Dr7 = 0;
-    if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
-    {
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
-    /* Set debug header */
-    KiFillTrapFrameDebug(TrapFrame);
-}
-
-/* EXCEPTION CODE *************************************************************/
-
-VOID
-FASTCALL
-//DECLSPEC_NORETURN
-KiSystemFatalException(IN ULONG ExceptionCode,
-                       IN PKTRAP_FRAME TrapFrame)
-{
-    /* Bugcheck the system */
-    KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
-                     ExceptionCode,
-                     0,
-                     0,
-                     0,
-                     TrapFrame);
-}
-
-VOID
-NTAPI
-//DECLSPEC_NORETURN
-KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
-                                 IN ULONG_PTR Address,
-                                 IN ULONG ParameterCount,
-                                 IN ULONG_PTR Parameter1,
-                                 IN ULONG_PTR Parameter2,
-                                 IN ULONG_PTR Parameter3,
-                                 IN PKTRAP_FRAME TrapFrame)
-{
-    EXCEPTION_RECORD ExceptionRecord;
-
-    /* Build the exception record */
-    ExceptionRecord.ExceptionCode = Code;
-    ExceptionRecord.ExceptionFlags = 0;
-    ExceptionRecord.ExceptionRecord = NULL;
-    ExceptionRecord.ExceptionAddress = (PVOID)Address;
-    ExceptionRecord.NumberParameters = ParameterCount;
-    if (ParameterCount)
-    {
-        /* Copy extra parameters */
-        ExceptionRecord.ExceptionInformation[0] = Parameter1;
-        ExceptionRecord.ExceptionInformation[1] = Parameter2;
-        ExceptionRecord.ExceptionInformation[2] = Parameter3;
-    }
-    
-    /* Now go dispatch the exception */
-    KiDispatchException(&ExceptionRecord,
-                        NULL,
-                        TrapFrame,
-                        TrapFrame->EFlags & EFLAGS_V86_MASK ?
-                        -1 : KiUserTrap(TrapFrame),
-                        TRUE);
-
-    /* Return from this trap */
-    KiEoiHelper(TrapFrame);
 }
 
 /* TRAP HANDLERS **************************************************************/




More information about the Ros-diffs mailing list