Author: sir_richard
Date: Wed Jan 13 04:43:03 2010
New Revision: 45057
URL:
http://svn.reactos.org/svn/reactos?rev=45057&view=rev
Log:
[NTOS]: Fix some bugs and cleanup V8086 code in regards to flags usage.
[NTOS]: Add VDM debug spew to see why there's now an invalid opcode on Windows builds
of VMWare and certain QEmu combinations. (Note: the double fault issue is fixed, this is a
new issue).
Modified:
trunk/reactos/ntoskrnl/ke/i386/v86vdm.c
Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/v86vdm.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] Wed Jan 13 04:43:03 2010
@@ -12,6 +12,9 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
+
+#define KiVdmGetInstructionSize(x) ((x) & 0xFF)
+#define KiVdmGetPrefixFlags(x) ((x) & 0xFFFFFF00)
/* GLOBALS ********************************************************************/
@@ -51,6 +54,7 @@
ULONG Esp, V86EFlags, TrapEFlags;
/* Get current V8086 flags and mask out interrupt flag */
+ DbgPrint("VDM: Handling PUSHF (PREFIX [0x%lx])\n",
KiVdmGetPrefixFlags(Flags));
V86EFlags = *KiNtVdmState;
V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
@@ -67,7 +71,7 @@
Esp -= 2;
/* Check for OPER32 */
- if (Flags & PFX_FLAG_OPER32)
+ if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
/* Save EFlags */
Esp -= 2;
@@ -81,7 +85,7 @@
/* Set new ESP and EIP */
TrapFrame->HardwareEsp = (USHORT)Esp;
- TrapFrame->Eip += (Flags & 0xFF);
+ TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* We're done */
return TRUE;
@@ -95,6 +99,7 @@
ULONG Esp, V86EFlags, EFlags, TrapEFlags;
/* Build flat ESP */
+ DbgPrint("VDM: Handling POPF (PREFIX [0x%lx])\n",
KiVdmGetPrefixFlags(Flags));
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
/* Read EFlags */
@@ -102,7 +107,7 @@
Esp += 4;
/* Check for OPER32 */
- if (!(Flags & PFX_FLAG_OPER32))
+ if (!(KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32))
{
/* Read correct flags and use correct stack address */
Esp -= 2;
@@ -140,7 +145,7 @@
/* FIXME: Check for VDM interrupts */
/* Update EIP */
- TrapFrame->Eip += (Flags & 0xFF);
+ TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* We're done */
return TRUE;
@@ -187,7 +192,7 @@
/* Push IP */
Esp -= 2;
- *(PUSHORT)(Esp) = (USHORT)TrapFrame->Eip + (Flags & 0xFF) + 1;
+ *(PUSHORT)(Esp) = (USHORT)TrapFrame->Eip + KiVdmGetInstructionSize(Flags) + 1;
/* Update ESP */
TrapFrame->HardwareEsp = (USHORT)Esp;
@@ -196,11 +201,12 @@
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
/* Now get the *next* EIP address (current is original + the count - 1) */
- Eip += (Flags & 0xFF);
+ Eip += KiVdmGetInstructionSize(Flags);
/* Now read the interrupt number */
Interrupt = *(PUCHAR)Eip;
-
+ DbgPrint("VDM: Handling INT [0x%lx]\n", Interrupt);
+
/* Read the EIP from its IVT entry */
Interrupt = *(PULONG)(Interrupt * 4);
TrapFrame->Eip = (USHORT)Interrupt;
@@ -240,12 +246,13 @@
IN ULONG Flags)
{
ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip;
-
+
/* Build flat ESP */
+ DbgPrint("VDM: Handling IRET (PREFIX [0x%lx])\n",
KiVdmGetPrefixFlags(Flags));
Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
/* Check for OPER32 */
- if (Flags & PFX_FLAG_OPER32)
+ if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
/* Build segmented EIP */
TrapFrame->Eip = *(PULONG)Esp;
@@ -292,6 +299,7 @@
/* Build flat EIP and check if this is the BOP instruction */
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
+ DbgPrint("VDM: Handling IRET EIP @ 0x%p [OPCODE: %lx]\n", Eip,
*(PUSHORT)Eip);
if (*(PUSHORT)Eip == 0xC4C4)
{
/* Dispatch the BOP */
@@ -313,11 +321,12 @@
{
/* FIXME: Support VME */
- /* disable interrupts */
+ /* Disable interrupts */
+ DbgPrint("VDM: Handling CLI\n");
KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK);
/* Skip instruction */
- TrapFrame->Eip += (Flags & 0xFF);
+ TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* Done */
return TRUE;
@@ -331,10 +340,11 @@
/* FIXME: Support VME */
/* Enable interrupts */
+ DbgPrint("VDM: Handling STI\n");
KiVdmSetVdmEFlags(EFLAGS_INTERRUPT_MASK);
/* Skip instruction */
- TrapFrame->Eip += (Flags & 0xFF);
+ TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* Done */
return TRUE;
@@ -351,7 +361,8 @@
/* Get flat EIP of the *current* instruction (not the original EIP) */
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
- Eip += (Flags & 0xFF) - 1;
+ DbgPrint("VDM: Handling Opcode @ 0x%p\n", Eip);
+ Eip += KiVdmGetInstructionSize(Flags) - 1;
/* Read the opcode entry */
switch (*(PUCHAR)Eip)
@@ -409,6 +420,7 @@
IN ULONG Flags)
{
/* Increase instruction size */
+ DbgPrint("VDM: Handling PREFIX [%lx] Opcode @ 0x%p\n",
KiVdmGetPrefixFlags(Flags), TrapFrame->Eip);
Flags++;
/* Handle the next opcode */
@@ -623,7 +635,9 @@
Tss->IoMapBase = (USHORT)IOPM_OFFSET;
/* Switch stacks and work the magic */
+ DbgPrint("VDM: Entering V8086 Mode\n");
Ki386SetupAndExitToV86Mode(VdmTeb);
+ DbgPrint("VDM: Exiting V8086 Mode\n");
/* Restore IOPM */
RtlCopyMemory(&Tss->IoMaps[0].IoMap, Ki386IopmSaveArea, PAGE_SIZE * 2);