VOID
FASTCALL
+Ki386BiosCallReturnAddress(
+ IN PKTRAP_FRAME TrapFrame
+);
+
+ULONG_PTR
+FASTCALL
KiExitV86Mode(
IN PKTRAP_FRAME TrapFrame
);
extern VOID __cdecl CopyParams(VOID);
extern VOID __cdecl ReadBatch(VOID);
extern VOID __cdecl FrRestore(VOID);
-extern VOID Ki386BiosCallReturnAddress(VOID);
PFX_SAVE_AREA
FORCEINLINE
/* Enter V8086 mode */
pushad
- call @KiEnterV86Mode@0
+ sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
+ mov ecx, esp
+ call @KiEnterV86Mode@4
+ jmp $
.endfunc
+.globl @Ki386BiosCallReturnAddress@4
+@Ki386BiosCallReturnAddress@4:
+
+ /* Exit V8086 mode */
+ call @KiExitV86Mode@4
+ mov esp, eax
+ add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
+ popad
+ ret
+
* Why? Because part of the trap frame actually corresponds to the IRET
* stack during the trap exit!
*/
- if ((TrapFrame->HardwareEsp == (ULONG)KiExitV86Mode) &&
+ if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
(TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
{
/* Exit the V86 trap! */
- KiExitV86Mode(TrapFrame);
+ Ki386BiosCallReturnAddress(TrapFrame);
}
else
{
return KiVdmHandleOpcode(TrapFrame, 1);
}
-VOID
+ULONG_PTR
FASTCALL
KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
{
/* Enable interrupts and get back to protected mode */
_enable();
- KiV86TrapReturn(TrapFrame->Edi);
+ return TrapFrame->Edi;
}
VOID
FASTCALL
-KiEnterV86Mode(VOID)
+KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
{
PKTHREAD Thread;
PKGDTENTRY GdtEntry;
- KV8086_STACK_FRAME StackFrameBuffer;
- PKV8086_STACK_FRAME StackFrame = &StackFrameBuffer;
PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame;
PKV86_FRAME V86Frame = &StackFrame->V86Frame;
PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea;
V86Frame->PcrTeb = KeGetPcr()->Tib.Self;
/* Save return EIP */
- TrapFrame->Eip = (ULONG_PTR)KiExitV86Mode;
+ TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress;
/* Save our stack (after the frames) */
TrapFrame->Esi = (ULONG_PTR)V86Frame;