Author: sir_richard
Date: Sun Jan 10 16:00:44 2010
New Revision: 45028

URL: http://svn.reactos.org/svn/reactos?rev=45028&view=rev
Log:
[NTOS]: Simplify trap exit code.
[NTOS]: Move some stuff in appropriate headers.
[NTOS]: Write V86 fast entry/exit traps, needed for later.

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/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=45028&r1=45027&r2=45028&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 10 
16:00:44 2010
@@ -65,7 +65,26 @@
 //
 #define KeGetTrapFrameInterruptState(TrapFrame) \
         BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
-        
+
+//
+// Flags for exiting a trap
+//
+#define KTE_SKIP_PM_BIT  (((KTRAP_EXIT_SKIP_BITS) { { .SkipPreviousMode = TRUE 
} }).Bits)
+#define KTE_SKIP_SEG_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipSegments  = TRUE } 
}).Bits)
+#define KTE_SKIP_VOL_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipVolatiles = TRUE } 
}).Bits)
+ 
+typedef union _KTRAP_EXIT_SKIP_BITS
+{
+    struct
+    {
+        UCHAR SkipPreviousMode:1;
+        UCHAR SkipSegments:1;
+        UCHAR SkipVolatiles:1;
+        UCHAR Reserved:5;
+    };
+    UCHAR Bits;
+} KTRAP_EXIT_SKIP_BITS, *PKTRAP_EXIT_SKIP_BITS;
+              
 //
 // Registers an interrupt handler with an IDT vector
 //
@@ -287,6 +306,25 @@
 NTAPI
 Ki386EnableXMMIExceptions(
     IN ULONG_PTR Context
+);
+
+BOOLEAN
+NTAPI
+VdmDispatchBop(
+    IN PKTRAP_FRAME TrapFrame
+);
+ 
+BOOLEAN
+FASTCALL
+KiVdmOpcodePrefix(
+    IN PKTRAP_FRAME TrapFrame,
+    IN ULONG Flags
+);
+
+BOOLEAN
+FASTCALL
+Ki386HandleOpcodeV86(
+    IN PKTRAP_FRAME TrapFrame
 );
 
 //
@@ -312,6 +350,10 @@
 extern VOID __cdecl KiTrap8(VOID);
 extern VOID __cdecl KiTrap19(VOID);
 extern VOID __cdecl KiFastCallEntry(VOID);
+extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
+extern VOID __cdecl CopyParams(VOID);
+extern VOID __cdecl ReadBatch(VOID);
+extern VOID __cdecl FrRestore(VOID);
 
 //
 // Sanitizes a selector

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=45028&r1=45027&r2=45028&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 10 
16:00:44 2010
@@ -71,20 +71,6 @@
     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)(

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=45028&r1=45027&r2=45028&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 10 
16:00:44 2010
@@ -66,7 +66,7 @@
 FORCEINLINE
 VOID
 KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
-                      IN KTRAP_STATE_BITS StateBits)
+                      IN KTRAP_STATE_BITS SkipBits)
 {
     /* Make sure interrupts are disabled */
     if (__readeflags() & EFLAGS_INTERRUPT_MASK)
@@ -105,7 +105,7 @@
     }
     
     /* If we're ignoring previous mode, make sure caller doesn't actually want 
it */
-    if (!(StateBits.PreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
+    if ((SkipBits.SkipPreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
     {
         DPRINT1("Exiting a trap witout restoring previous mode, yet previous 
mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
         while (TRUE);

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45028&r1=45027&r2=45028&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 10 16:00:44 
2010
@@ -18,16 +18,19 @@
 VOID
 FASTCALL
 KiExitTrap(IN PKTRAP_FRAME TrapFrame,
-           IN UCHAR State)
-{
-    KTRAP_STATE_BITS StateBits = { .Bits = State };
-    KiExitTrapDebugChecks(TrapFrame, StateBits);
+           IN UCHAR Skip)
+{
+    KTRAP_EXIT_SKIP_BITS SkipBits = { .Bits = Skip };
+    KiExitTrapDebugChecks(TrapFrame, SkipBits);
+
+    /* If you skip volatile reload, you must skip segment reload */
+    ASSERT((SkipBits.SkipVolatiles == FALSE) || (SkipBits.SkipSegments == 
TRUE));
 
     /* Restore the SEH handler chain */
     KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
     
     /* Check if the previous mode must be restored */
-    if (StateBits.PreviousMode)
+    if (!SkipBits.SkipPreviousMode)
     {
         /* Not handled yet */
         UNIMPLEMENTED;
@@ -53,34 +56,31 @@
         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);
-        }
-        
+    /* Check if segments should be restored */
+    if (!SkipBits.SkipSegments)
+    {
+        /* Restore segments */
+        Ke386SetGs(TrapFrame->SegGs);
+        Ke386SetEs(TrapFrame->SegEs);
+        Ke386SetDs(TrapFrame->SegDs);
+        Ke386SetFs(TrapFrame->SegFs);
+    }
+    else if (KiUserTrap(TrapFrame))
+    {
         /* Always restore FS since it goes from KPCR to TEB */
         Ke386SetFs(TrapFrame->SegFs);
     }
+    
+    /* Check if the caller wants to skip volatiles */
+    if (SkipBits.SkipVolatiles)
+    {
+        /* 
+         * When we do the system call handler through this path, we need
+         * to have some sort to restore the kernel EAX instead of pushing
+         * back the user EAX. We'll figure it out...
+         */
+        DPRINT1("Warning: caller doesn't want volatiles restored\n"); 
+    }
 
     /* Check for ABIOS code segment */
     if (TrapFrame->SegCs == 0x80)
@@ -90,8 +90,8 @@
         while (TRUE);
     }
     
-    /* Check for system call */
-    if (StateBits.SystemCall)
+    /* Check for system call -- a system call skips volatiles! */
+    if (SkipBits.SkipVolatiles)
     {
         /* Not handled yet */
         UNIMPLEMENTED;
@@ -106,6 +106,50 @@
 
 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 (!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();
+        
+        /* Return if this isn't V86 mode anymore */
+        if (TrapFrame->EFlags & EFLAGS_V86_MASK) return;
+    }
+     
+    /* If we got here, we're still in a valid V8086 context, so quit it */
+    if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
+    {
+        /* Not handled yet */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+     
+    /* Return from interrupt */
+    KiTrapReturn(TrapFrame);
+}
+
+VOID
+FASTCALL
 KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
 {
     /* Disable interrupts until we return */
@@ -115,10 +159,38 @@
     KiCheckForApcDelivery(TrapFrame);
     
     /* Now exit the trap for real */
-    KiExitTrap(TrapFrame, KTS_SEG_BIT | KTS_VOL_BIT);
+    KiExitTrap(TrapFrame, KTE_SKIP_PM_BIT);
 }
 
 /* TRAP ENTRY CODE 
************************************************************/
+
+VOID
+FASTCALL
+KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Save registers */
+    KiTrapFrameFromPushaStack(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 (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
+    {
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+}
 
 VOID
 FASTCALL
@@ -258,7 +330,6 @@
              IN PFX_SAVE_AREA SaveArea)
 {
     ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
-    extern VOID FrRestore(VOID);
     
     /* Check for VDM trap */
     ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
@@ -718,9 +789,6 @@
     PKTHREAD Thread;
     ULONG_PTR Cr2;
     NTSTATUS Status;
-    extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
-    extern VOID CopyParams(VOID);
-    extern VOID ReadBatch(VOID);
 
     /* Save trap frame */
     KiEnterTrap(TrapFrame);


Reply via email to