[ros-diffs] [ros-arm-bringup] 45000: Trap Handlers in C Patch 1 of X (Patch by Sir_Richard <ros.arm at reactos.org>): [NTOS]: The kernel normally does not save FPU state during Ring 0 transitions since the FPU should not be used. The one exception is when a kernel debugger is attached. Unfortunately, the latter check in ReactOS results in even "print on the serial line" to count as "debugger attached", and thus FPU state was almost always saved, slowing down traps significantly. [NTOS]: The kernel also does not typically save DRx (debug) registers unless they were in use. During an exception dispatch, they are zeroed out, and later during trap exit, if any debug register is set, DR7 is updated to enable that hardware breakpoint. Unfortunately, the code to clear the debug registers had a bug: DR2 was never cleared. Because DR2 ended up being a random stack value during trap frame generation, this caused a bogus address to be added to DR2, and DR7 would then enable the 2nd hardware breakpoint. This caused the kernel to always save DRx state, which is slow, and worse, could cause random hardware breakpoints to fire. [NTOS]: Start implementing trap handling in C. ASM trap handlers will now only be 5 lines of assembly including a function call to a C handler. All C handling code uses maximum two arguments and is all FASTCALL for efficiency. [NTOS]: Implement C versions of TRAP_PROLOG and TRAP_EPILOG. Implement C version of Ki386EoiHelper. Implement C version of CommonDispatchException (and helper) and KiFatalSystemException. Implement C version of CHECK_FOR_APC_DELIVER. Implement trap debugging checks as a separate entity instead of always doing them. [NTOS]: Add missing intrinsics for DS/ES/GS segment query. The kernel is now ready for some trap handling to be done in C. Due to the FPU/Debug fixes and relaxation of paranoid debug checks, the C code will likely be faster than the original assembly.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Fri Jan 8 16:04:19 CET 2010


Author: ros-arm-bringup
Date: Fri Jan  8 16:04:19 2010
New Revision: 45000

URL: http://svn.reactos.org/svn/reactos?rev=45000&view=rev
Log:
Trap Handlers in C Patch 1 of X (Patch by Sir_Richard <ros.arm at reactos.org>):
    [NTOS]: The kernel normally does not save FPU state during Ring 0 transitions since the FPU should not be used. The one exception is when a kernel debugger is attached. Unfortunately, the latter check in ReactOS results in even "print on the serial line" to count as "debugger attached", and thus FPU state was almost always saved, slowing down traps significantly.
    [NTOS]: The kernel also does not typically save DRx (debug) registers unless they were in use. During an exception dispatch, they are zeroed out, and later during trap exit, if any debug register is set, DR7 is updated to enable that hardware breakpoint. Unfortunately, the code to clear the debug registers had a bug: DR2 was never cleared. Because DR2 ended up being a random stack value during trap frame generation, this caused a bogus address to be added to DR2, and DR7 would then enable the 2nd hardware breakpoint. This caused the kernel to always save DRx state, which is slow, and worse, could cause random hardware breakpoints to fire.
    [NTOS]: Start implementing trap handling in C. ASM trap handlers will now only be 5 lines of assembly including a function call to a C handler. All C handling code uses maximum two arguments and is all FASTCALL for efficiency.
    [NTOS]: Implement C versions of TRAP_PROLOG and TRAP_EPILOG. Implement C version of Ki386EoiHelper. Implement C version of CommonDispatchException (and helper) and KiFatalSystemException. Implement C version of CHECK_FOR_APC_DELIVER. Implement trap debugging checks as a separate entity instead of always doing them.
    [NTOS]: Add missing intrinsics for DS/ES/GS segment query.

The kernel is now ready for some trap handling to be done in C. Due to the FPU/Debug fixes and relaxation of paranoid debug checks, the C code will likely be faster than the original assembly.

Added:
    trunk/reactos/ntoskrnl/include/internal/trap_x.h   (with props)
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c   (with props)
Modified:
    trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
    trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/ke/i386/exp.c
    trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild

Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S?rev=45000&r1=44999&r2=45000&view=diff
==============================================================================
--- 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  8 16:04:19 2010
@@ -221,6 +221,28 @@
 .endm
 
 //
+// @name GENERATE_TRAP_HANDLER
+//
+// This macro creates a kernel trap handler.
+//
+// @param None.
+//
+// @remark None.
+//
+.macro GENERATE_TRAP_HANDLER Name, ErrorCode
+.func Name
+_&Name:
+    .if \ErrorCode
+        push 0
+    .endif
+    pushad
+    sub esp, KTRAP_FRAME_LENGTH - KTRAP_FRAME_PREVIOUS_MODE
+    mov ecx, esp
+    call @&Name&Handler at 4
+.endfunc
+.endm
+
+//
 // @name GENERATE_HAL_INT_HANDLER
 //
 // This macro creates a HAL hardware interrupt handler.

Modified: trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h?rev=45000&r1=44999&r2=45000&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -52,6 +52,7 @@
 #define _Ke386SetSeg(N,X)         __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
 
 #define Ke386FnInit()               __asm__("fninit\n\t");
+#define Ke386ClearDirectionFlag()   __asm__ __volatile__ ("cld")
 
 
 //
@@ -64,6 +65,9 @@
 //
 #define Ke386GetSs()                _Ke386GetSeg(ss)
 #define Ke386GetFs()                _Ke386GetSeg(fs)
+#define Ke386GetDs()                _Ke386GetSeg(ds)
+#define Ke386GetEs()                _Ke386GetSeg(es)
+#define Ke386GetGs()                _Ke386GetSeg(gs)
 #define Ke386SetFs(X)               _Ke386SetSeg(fs, X)
 #define Ke386SetDs(X)               _Ke386SetSeg(ds, X)
 #define Ke386SetEs(X)               _Ke386SetSeg(es, X)

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=45000&r1=44999&r2=45000&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -71,6 +71,20 @@
     PVOID Context;
     PVOID Handle;
 } KNMI_HANDLER_CALLBACK, *PKNMI_HANDLER_CALLBACK;
+
+typedef union _KTRAP_STATE_BITS
+{
+    struct
+    {
+        UCHAR SystemCall:1;
+        UCHAR PreviousMode:1;
+        UCHAR Segments:1;
+        UCHAR Volatiles:1;
+        UCHAR Full:1;
+        UCHAR Reserved:3;
+    };
+    UCHAR Bits;
+} KTRAP_STATE_BITS, *PKTRAP_STATE_BITS;
 
 typedef PCHAR
 (NTAPI *PKE_BUGCHECK_UNICODE_TO_ANSI)(
@@ -225,6 +239,12 @@
 
 #endif
 
+#define KTS_SYSCALL_BIT (((KTRAP_STATE_BITS) { { .SystemCall   = TRUE } }).Bits)
+#define KTS_PM_BIT      (((KTRAP_STATE_BITS) { { .PreviousMode   = TRUE } }).Bits)
+#define KTS_SEG_BIT     (((KTRAP_STATE_BITS) { { .Segments  = TRUE } }).Bits)
+#define KTS_VOL_BIT     (((KTRAP_STATE_BITS) { { .Volatiles = TRUE } }).Bits)
+#define KTS_FULL_BIT    (((KTRAP_STATE_BITS) { { .Full = TRUE } }).Bits)
+
 /* INTERNAL KERNEL FUNCTIONS ************************************************/
 
 VOID
@@ -863,6 +883,18 @@
     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);

Added: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/trap_x.h?rev=45000&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h (added)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -1,0 +1,243 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/include/trap_x.h
+ * PURPOSE:         Internal Inlined Functions for the Trap Handling Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+//
+// Debug Macros
+//
+#if YDEBUG
+VOID
+NTAPI
+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);
+}
+
+FORCEINLINE
+VOID
+KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Set the debug information */
+    TrapFrame->DbgArgPointer = TrapFrame->Edx;
+    TrapFrame->DbgArgMark = 0xBADB0D00;
+    TrapFrame->DbgEip = TrapFrame->Eip;
+    TrapFrame->DbgEbp = TrapFrame->Ebp;   
+}
+
+FORCEINLINE
+VOID
+KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
+                      IN KTRAP_STATE_BITS StateBits)
+{
+    /* Make sure interrupts are disabled */
+    if (__readeflags() & EFLAGS_INTERRUPT_MASK)
+    {
+        DPRINT1("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");
+        KiDumpTrapFrame(TrapFrame);
+        while (TRUE);
+    }
+    
+    /* Make sure we're not in user-mode or something */
+    if (Ke386GetFs() != KGDT_R0_PCR)
+    {
+        DPRINT1("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);
+        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);
+        while (TRUE);
+    }
+    
+    /* If we're ignoring previous mode, make sure caller doesn't actually want it */
+    if (!(StateBits.PreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
+    {
+        DPRINT1("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
+        while (TRUE);
+    }
+}
+#else
+#define KiExitTrapDebugChecks(x, y)
+#define KiFillTrapFrameDebug(x)
+#endif
+
+//
+// Helper Code
+//
+
+BOOLEAN
+FORCEINLINE
+KiUserTrap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Anything else but Ring 0 is Ring 3 */
+    return (TrapFrame->SegCs != KGDT_R0_CODE);
+}
+
+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
+KiTrapFrameFromPushaStack(IN PKTRAP_FRAME TrapFrame)
+{
+    /*
+     * This sequence is Bavarian Alchemist Black Magic
+     *
+     * *** DO NOT MODIFY ***
+     */
+    TrapFrame->Edx = TrapFrame->Esi;
+    TrapFrame->Esi = TrapFrame->PreviousPreviousMode;
+    TrapFrame->Ecx = TrapFrame->Ebx;
+    TrapFrame->Ebx = TrapFrame->Edi;
+    TrapFrame->Edi = TrapFrame->Eax;
+    TrapFrame->Eax = TrapFrame->Ebp;
+    TrapFrame->Ebp = (ULONG)TrapFrame->ExceptionList;
+    TrapFrame->TempEsp = TrapFrame->SegFs;
+}
+
+VOID
+FORCEINLINE
+KiPushaStackFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
+{
+    /*
+     * This sequence is Bavarian Alchemist Black Magic
+     *
+     * *** DO NOT MODIFY ***
+     */
+    TrapFrame->SegFs = TrapFrame->TempEsp;
+    TrapFrame->ExceptionList = (PVOID)TrapFrame->Ebp;
+    TrapFrame->Ebp = TrapFrame->Eax;
+    TrapFrame->Eax = TrapFrame->Edi;
+    TrapFrame->Edi = TrapFrame->Ebx;
+    TrapFrame->Ebx = TrapFrame->Ecx;
+    TrapFrame->PreviousPreviousMode = TrapFrame->Esi;
+    TrapFrame->Esi = TrapFrame->Edx;
+}    
+
+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)
+            {
+                /* 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
+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);
+}
+
+FORCEINLINE
+VOID
+KiTrapReturn(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Restore registers */
+    KiPushaStackFromTrapFrame(TrapFrame);
+
+    /* Regular interrupt exit */
+    __asm__ __volatile__
+    (
+        "movl %0, %%esp\n"
+        "addl %1, %%esp\n"
+        "popa\n"
+        "addl $4, %%esp\n"
+        "iret\n"
+        :
+        : "r"(TrapFrame), "i"(KTRAP_FRAME_LENGTH - KTRAP_FRAME_PREVIOUS_MODE)
+        : "%esp"
+    );
+}

Propchange: trunk/reactos/ntoskrnl/include/internal/trap_x.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev=45000&r1=44999&r2=45000&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -772,6 +772,7 @@
             /* Otherwise clear DR registers */
             Context->Dr0 =
             Context->Dr1 =
+            Context->Dr2 =
             Context->Dr3 =
             Context->Dr6 =
             Context->Dr7 = 0;
@@ -838,8 +839,8 @@
     /* Set the context flags */
     Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
 
-    /* Check if User Mode or if the debugger is enabled */
-    if ((PreviousMode == UserMode) || (KdDebuggerEnabled))
+    /* Check if User Mode or if the kernel debugger is enabled */
+    if ((PreviousMode == UserMode) || (KeGetPcr()->KdVersionBlock))
     {
         /* Add the FPU Flag */
         Context.ContextFlags |= CONTEXT_FLOATING_POINT;

Added: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45000&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c (added)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -1,0 +1,231 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/ke/i386/traphdlr.c
+ * PURPOSE:         Kernel Trap Handlers
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+#include "internal/trap_x.h"
+
+/* TRAP EXIT CODE *************************************************************/
+
+VOID
+FASTCALL
+KiExitTrap(IN PKTRAP_FRAME TrapFrame,
+           IN UCHAR State)
+{
+    KTRAP_STATE_BITS StateBits = { .Bits = State };
+    KiExitTrapDebugChecks(TrapFrame, StateBits);
+
+    /* Restore the SEH handler chain */
+    KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
+    
+    /* Check if the previous mode must be restored */
+    if (StateBits.PreviousMode)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+
+    /* Check if there are active debug registers */
+    if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Check if this was a V8086 trap */
+    if (TrapFrame->EFlags & EFLAGS_V86_MASK)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Check if the trap frame was edited */
+    if (!(TrapFrame->SegCs & FRAME_EDITED))
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Check if all registers must be restored */
+    if (StateBits.Full)
+    {
+        /* Only do the restore if we made a transition from user-mode */
+        if (KiUserTrap(TrapFrame))
+        {
+            /* Restore segments */
+            Ke386SetGs(TrapFrame->SegGs);
+            Ke386SetEs(TrapFrame->SegEs);
+            Ke386SetDs(TrapFrame->SegDs);
+        }
+    }
+    
+    /* Check if we came from user-mode */
+    if (KiUserTrap(TrapFrame))
+    {
+        /* Check if the caller wants segments restored */
+        if (StateBits.Segments)
+        {
+            /* Restore them */
+            Ke386SetGs(TrapFrame->SegGs);
+            Ke386SetEs(TrapFrame->SegEs);
+            Ke386SetDs(TrapFrame->SegDs);
+        }
+        
+        /* Always restore FS since it goes from KPCR to TEB */
+        Ke386SetFs(TrapFrame->SegFs);
+    }
+
+    /* Check for ABIOS code segment */
+    if (TrapFrame->SegCs == 0x80)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Check for system call */
+    if (StateBits.SystemCall)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    else
+    {
+        /* Return from interrupt */
+        KiTrapReturn(TrapFrame); 
+    }
+}
+
+VOID
+FASTCALL
+KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Disable interrupts until we return */
+    _disable();
+    
+    /* Check for APC delivery */
+    KiCheckForApcDelivery(TrapFrame);
+    
+    /* Now exit the trap for real */
+    KiExitTrap(TrapFrame, KTS_SEG_BIT | KTS_VOL_BIT);
+}
+
+/* TRAP ENTRY CODE ************************************************************/
+
+VOID
+FASTCALL
+KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Save registers */
+    KiTrapFrameFromPushaStack(TrapFrame);
+    
+    /* 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 bogus previous mode */
+    TrapFrame->PreviousPreviousMode = -1;
+    TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
+    
+    /* Check for 16-bit stack */
+    if ((ULONG_PTR)TrapFrame < 0x10000)
+    {
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Check for V86 mode */
+    if (TrapFrame->EFlags & EFLAGS_V86_MASK)
+    {
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+
+    /* Clear direction flag */
+    Ke386ClearDirectionFlag();
+    
+    /* Flush DR7 and check for debugging */
+    TrapFrame->Dr7 = 0;
+    if (KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF)
+    {
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* Set debug header */
+    KiFillTrapFrameDebug(TrapFrame);
+}
+
+/* EXCEPTION CODE *************************************************************/
+
+VOID
+FASTCALL
+KiSystemFatalException(IN ULONG ExceptionCode,
+                       IN PKTRAP_FRAME TrapFrame)
+{
+    /* Bugcheck the system */
+    KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
+                     ExceptionCode,
+                     0,
+                     0,
+                     0,
+                     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)
+{
+    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 : TrapFrame->SegCs & MODE_MASK,
+                        TRUE);
+
+    /* Return from this trap */
+    KiEoiHelper(TrapFrame);
+}
+
+/* EOF */

Propchange: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild?rev=45000&r1=44999&r2=45000&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Fri Jan  8 16:04:19 2010
@@ -51,6 +51,7 @@
 				<file>systimer.S</file>
 				<file>thrdini.c</file>
 				<file>trap.s</file>
+				<file>traphdlr.c</file>
 				<file>usercall_asm.S</file>
 				<file>usercall.c</file>
 				<file>v86vdm.c</file>




More information about the Ros-diffs mailing list