Author: jgardou
Date: Thu Apr 25 21:29:59 2013
New Revision: 58852
URL:
http://svn.reactos.org/svn/reactos?rev=58852&view=rev
Log:
[NTOSKRNL]
- Handle VME for the PUSHF and POPF instruction in virtual mode
- There is no reason to set interrupt flag when handling POPF
- Fix a typo in POPF case : mask out the right variable
See
http://www.rcollins.org/articles/vme1/ for reference
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] Thu Apr 25 21:29:59 2013
@@ -53,16 +53,22 @@
{
ULONG Esp, V86EFlags, TrapEFlags;
- /* Check for VME support */
- ASSERT(KeI386VirtualIntExtensions == FALSE);
-
/* Get current V8086 flags and mask out interrupt flag */
V86EFlags = *KiNtVdmState;
V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
- /* Get trap frame EFLags and leave only align, nested task and interrupt */
+ /* Get trap frame EFLags */
TrapEFlags = TrapFrame->EFlags;
- V86EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
+ /* Check for VME support */
+ if(KeI386VirtualIntExtensions)
+ {
+ /* Copy the virtual interrupt flag to the interrupt flag */
+ TrapEFlags &= ~EFLAGS_INTERRUPT_MASK;
+ if(TrapEFlags & EFLAGS_VIF)
+ TrapEFlags |= EFLAGS_INTERRUPT_MASK;
+ }
+ /* Leave only align, nested task and interrupt */
+ TrapEFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
/* Add in those flags if they exist, and add in the IOPL flag */
V86EFlags |= TrapEFlags;
@@ -133,10 +139,20 @@
TrapEFlags = TrapFrame->EFlags;
/* Check for VME support */
- ASSERT(KeI386VirtualIntExtensions == FALSE);
-
- /* Add V86 and Interrupt flag */
- V86EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK;
+ if(KeI386VirtualIntExtensions)
+ {
+ /* Copy the IF flag into the VIF one */
+ V86EFlags &= ~EFLAGS_VIF;
+ if(V86EFlags & EFLAGS_INTERRUPT_MASK)
+ {
+ V86EFlags |= EFLAGS_VIF;
+ /* Don't set the interrupt flag */
+ V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
+ }
+ }
+
+ /* Add V86 flag */
+ V86EFlags |= EFLAGS_V86_MASK;
/* Update EFlags in trap frame */
TrapFrame->EFlags = V86EFlags;