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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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.…
==============================================================================
--- 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);