mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NTOSKRNL]
Implement Ke386SetGdtEntryBase and KiSetTebBase and use it in the appropriate places. svn path=/trunk/; revision=58460
This commit is contained in:
parent
e850321ffc
commit
8cb3ec617f
3 changed files with 103 additions and 105 deletions
|
@ -279,6 +279,23 @@ KiRundownThread(IN PKTHREAD Thread)
|
|||
#endif
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
Ke386SetGdtEntryBase(PKGDTENTRY GdtEntry, PVOID BaseAddress)
|
||||
{
|
||||
GdtEntry->BaseLow = (USHORT)((ULONG_PTR)BaseAddress & 0xFFFF);
|
||||
GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)BaseAddress >> 16);
|
||||
GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)BaseAddress >> 24);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiSetTebBase(PKPCR Pcr, PVOID TebAddress)
|
||||
{
|
||||
Pcr->NtTib.Self = TebAddress;
|
||||
Ke386SetGdtEntryBase(&Pcr->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)], TebAddress);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
Ki386InitializeTss(
|
||||
|
|
|
@ -332,7 +332,6 @@ KiSwapContextExit(IN PKTHREAD OldThread,
|
|||
{
|
||||
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||
PKPROCESS OldProcess, NewProcess;
|
||||
PKGDTENTRY GdtEntry;
|
||||
PKTHREAD NewThread;
|
||||
|
||||
/* We are on the new thread stack now */
|
||||
|
@ -347,7 +346,7 @@ KiSwapContextExit(IN PKTHREAD OldThread,
|
|||
if (*(PULONGLONG)&OldProcess->LdtDescriptor != *(PULONGLONG)&NewProcess->LdtDescriptor)
|
||||
{
|
||||
DPRINT1("LDT switch not implemented\n");
|
||||
ASSERT(FALSE);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
/* Switch address space and flush TLB */
|
||||
|
@ -358,11 +357,7 @@ KiSwapContextExit(IN PKTHREAD OldThread,
|
|||
Ke386SetGs(0);
|
||||
|
||||
/* Set the TEB */
|
||||
Pcr->NtTib.Self = (PVOID)NewThread->Teb;
|
||||
GdtEntry = &Pcr->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)];
|
||||
GdtEntry->BaseLow = (USHORT)((ULONG_PTR)NewThread->Teb & 0xFFFF);
|
||||
GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)NewThread->Teb >> 16);
|
||||
GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)NewThread->Teb >> 24);
|
||||
KiSetTebBase((PKPCR)Pcr, NewThread->Teb);
|
||||
|
||||
/* Set new TSS fields */
|
||||
Pcr->TSS->Esp0 = (ULONG_PTR)NewThread->InitialStack;
|
||||
|
@ -491,7 +486,7 @@ KiDispatchInterrupt(VOID)
|
|||
KiQuantumEnd();
|
||||
}
|
||||
else if (Prcb->NextThread)
|
||||
{
|
||||
{
|
||||
/* Capture current thread data */
|
||||
OldThread = Prcb->CurrentThread;
|
||||
NewThread = Prcb->NextThread;
|
||||
|
|
|
@ -45,14 +45,14 @@ KiVdmUnhandledOpcode(INTO);
|
|||
KiVdmUnhandledOpcode(INV);
|
||||
|
||||
/* OPCODE HANDLERS ************************************************************/
|
||||
|
||||
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
KiVdmOpcodePUSHF(IN PKTRAP_FRAME TrapFrame,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
ULONG Esp, V86EFlags, TrapEFlags;
|
||||
|
||||
|
||||
/* Check for VME support */
|
||||
ASSERT(KeI386VirtualIntExtensions == FALSE);
|
||||
|
||||
|
@ -67,10 +67,10 @@ KiVdmOpcodePUSHF(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Add in those flags if they exist, and add in the IOPL flag */
|
||||
V86EFlags |= TrapEFlags;
|
||||
V86EFlags |= EFLAGS_IOPL;
|
||||
|
||||
|
||||
/* Build flat ESP */
|
||||
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
|
||||
|
||||
|
||||
/* Check for OPER32 */
|
||||
if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
|
||||
{
|
||||
|
@ -84,11 +84,11 @@ KiVdmOpcodePUSHF(IN PKTRAP_FRAME TrapFrame,
|
|||
Esp -= 2;
|
||||
*(PUSHORT)Esp = (USHORT)V86EFlags;
|
||||
}
|
||||
|
||||
|
||||
/* Set new ESP and EIP */
|
||||
TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
|
||||
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
|
||||
|
||||
|
||||
/* We're done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -99,10 +99,10 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
|
|||
IN ULONG Flags)
|
||||
{
|
||||
ULONG Esp, V86EFlags, EFlags, TrapEFlags;
|
||||
|
||||
|
||||
/* Build flat ESP */
|
||||
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
|
||||
|
||||
|
||||
/* Check for OPER32 */
|
||||
if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
|
||||
{
|
||||
|
@ -116,22 +116,22 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
|
|||
EFlags = *(PUSHORT)Esp;
|
||||
Esp += 2;
|
||||
}
|
||||
|
||||
|
||||
/* Set new ESP */
|
||||
TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
|
||||
|
||||
|
||||
/* Mask out IOPL from the flags */
|
||||
EFlags &= ~EFLAGS_IOPL;
|
||||
|
||||
|
||||
/* Save the V86 flags, but mask out the nested task flag */
|
||||
V86EFlags = EFlags & ~EFLAGS_NESTED_TASK;
|
||||
|
||||
|
||||
/* Now leave only alignment, nested task and interrupt flag */
|
||||
EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* Get trap EFlags */
|
||||
TrapEFlags = TrapFrame->EFlags;
|
||||
|
||||
|
||||
/* Check for VME support */
|
||||
ASSERT(KeI386VirtualIntExtensions == FALSE);
|
||||
|
||||
|
@ -143,16 +143,16 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
|
|||
|
||||
/* Check if ESP0 needs to be fixed up */
|
||||
if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame);
|
||||
|
||||
|
||||
/* Update the V8086 EFlags state */
|
||||
KiVdmClearVdmEFlags(EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
|
||||
KiVdmSetVdmEFlags(EFlags);
|
||||
|
||||
|
||||
/* FIXME: Check for VDM interrupts */
|
||||
|
||||
|
||||
/* Update EIP */
|
||||
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
|
||||
|
||||
|
||||
/* We're done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -163,63 +163,63 @@ KiVdmOpcodeINTnn(IN PKTRAP_FRAME TrapFrame,
|
|||
IN ULONG Flags)
|
||||
{
|
||||
ULONG Esp, V86EFlags, TrapEFlags, Eip, Interrupt;
|
||||
|
||||
|
||||
/* Read trap frame EFlags */
|
||||
TrapEFlags = TrapFrame->EFlags;
|
||||
|
||||
|
||||
/* Remove interrupt flag from V8086 EFlags */
|
||||
V86EFlags = *KiNtVdmState;
|
||||
KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* Keep only alignment and interrupt flag from the V8086 state */
|
||||
V86EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* Check for VME support */
|
||||
ASSERT(KeI386VirtualIntExtensions == FALSE);
|
||||
|
||||
|
||||
/* Mask in the relevant V86 EFlags into the trap flags */
|
||||
V86EFlags |= (TrapEFlags & ~EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* And mask out the VIF, nested task and TF flag from the trap flags */
|
||||
TrapFrame->EFlags = TrapEFlags &~ (EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF);
|
||||
|
||||
|
||||
/* Add the IOPL flag to the local trap flags */
|
||||
V86EFlags |= EFLAGS_IOPL;
|
||||
|
||||
|
||||
/* Build flat ESP */
|
||||
Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
|
||||
|
||||
|
||||
/* Push EFlags */
|
||||
Esp -= 2;
|
||||
*(PUSHORT)(Esp) = (USHORT)V86EFlags;
|
||||
|
||||
|
||||
/* Push CS */
|
||||
Esp -= 2;
|
||||
*(PUSHORT)(Esp) = (USHORT)TrapFrame->SegCs;
|
||||
|
||||
|
||||
/* Push IP */
|
||||
Esp -= 2;
|
||||
*(PUSHORT)(Esp) = (USHORT)TrapFrame->Eip + KiVdmGetInstructionSize(Flags) + 1;
|
||||
|
||||
|
||||
/* Update ESP */
|
||||
TrapFrame->HardwareEsp = (USHORT)Esp;
|
||||
|
||||
|
||||
/* Get flat EIP */
|
||||
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
|
||||
|
||||
|
||||
/* Now get the *next* EIP address (current is original + the count - 1) */
|
||||
Eip += KiVdmGetInstructionSize(Flags);
|
||||
|
||||
|
||||
/* Now read the interrupt number */
|
||||
Interrupt = *(PUCHAR)Eip;
|
||||
|
||||
|
||||
/* Read the EIP from its IVT entry */
|
||||
Interrupt = *(PULONG)(Interrupt * 4);
|
||||
TrapFrame->Eip = (USHORT)Interrupt;
|
||||
|
||||
|
||||
/* Now get the CS segment */
|
||||
Interrupt = (USHORT)(Interrupt >> 16);
|
||||
|
||||
|
||||
/* Check if the trap was not V8086 trap */
|
||||
if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
|
||||
{
|
||||
|
@ -241,7 +241,7 @@ KiVdmOpcodeINTnn(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Set IVT CS */
|
||||
TrapFrame->SegCs = Interrupt;
|
||||
}
|
||||
|
||||
|
||||
/* We're done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -255,17 +255,17 @@ KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame,
|
|||
|
||||
/* Build flat ESP */
|
||||
Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
|
||||
|
||||
|
||||
/* Check for OPER32 */
|
||||
if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
|
||||
{
|
||||
/* Build segmented EIP */
|
||||
TrapFrame->Eip = *(PULONG)Esp;
|
||||
TrapFrame->SegCs = *(PUSHORT)(Esp + 4);
|
||||
|
||||
|
||||
/* Set new ESP */
|
||||
TrapFrame->HardwareEsp += 12;
|
||||
|
||||
|
||||
/* Get EFLAGS */
|
||||
EFlags = *(PULONG)(Esp + 8);
|
||||
}
|
||||
|
@ -281,28 +281,28 @@ KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Get EFLAGS */
|
||||
EFlags = *(PUSHORT)(Esp + 4);
|
||||
}
|
||||
|
||||
|
||||
/* Mask out EFlags */
|
||||
EFlags &= ~(EFLAGS_IOPL + EFLAGS_VIF + EFLAGS_NESTED_TASK + EFLAGS_VIP);
|
||||
V86EFlags = EFlags;
|
||||
|
||||
|
||||
/* Check for VME support */
|
||||
ASSERT(KeI386VirtualIntExtensions == FALSE);
|
||||
|
||||
|
||||
/* Add V86 and Interrupt flag */
|
||||
EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK;
|
||||
|
||||
|
||||
/* Update EFlags in trap frame */
|
||||
TrapEFlags = TrapFrame->EFlags;
|
||||
TrapFrame->EFlags = (TrapFrame->EFlags & EFLAGS_VIP) | EFlags;
|
||||
|
||||
|
||||
/* Check if ESP0 needs to be fixed up */
|
||||
if (!(TrapEFlags & EFLAGS_V86_MASK)) Ki386AdjustEsp0(TrapFrame);
|
||||
|
||||
|
||||
/* Update the V8086 EFlags state */
|
||||
KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK);
|
||||
KiVdmSetVdmEFlags(V86EFlags);
|
||||
|
||||
|
||||
/* Build flat EIP and check if this is the BOP instruction */
|
||||
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
|
||||
if (*(PUSHORT)Eip == 0xC4C4)
|
||||
|
@ -315,7 +315,7 @@ KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame,
|
|||
/* FIXME: Check for VDM interrupts */
|
||||
DPRINT("FIXME: Check for VDM interrupts\n");
|
||||
}
|
||||
|
||||
|
||||
/* We're done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -324,16 +324,16 @@ BOOLEAN
|
|||
FASTCALL
|
||||
KiVdmOpcodeCLI(IN PKTRAP_FRAME TrapFrame,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
{
|
||||
/* Check for VME support */
|
||||
ASSERT(KeI386VirtualIntExtensions == FALSE);
|
||||
|
||||
/* Disable interrupts */
|
||||
KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* Skip instruction */
|
||||
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
|
||||
|
||||
|
||||
/* Done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -348,10 +348,10 @@ KiVdmOpcodeSTI(IN PKTRAP_FRAME TrapFrame,
|
|||
|
||||
/* Enable interrupts */
|
||||
KiVdmSetVdmEFlags(EFLAGS_INTERRUPT_MASK);
|
||||
|
||||
|
||||
/* Skip instruction */
|
||||
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
|
||||
|
||||
|
||||
/* Done */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -364,11 +364,11 @@ KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame,
|
|||
IN ULONG Flags)
|
||||
{
|
||||
ULONG Eip;
|
||||
|
||||
|
||||
/* Get flat EIP of the *current* instruction (not the original EIP) */
|
||||
Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
|
||||
Eip += KiVdmGetInstructionSize(Flags) - 1;
|
||||
|
||||
|
||||
/* Read the opcode entry */
|
||||
switch (*(PUCHAR)Eip)
|
||||
{
|
||||
|
@ -401,11 +401,11 @@ KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame,
|
|||
case 0x9D: return KiCallVdmHandler(POPF);
|
||||
case 0xCD: return KiCallVdmHandler(INTnn);
|
||||
case 0xCE: return KiCallVdmHandler(INTO);
|
||||
case 0xCF: return KiCallVdmHandler(IRET);
|
||||
case 0xE4: return KiCallVdmHandler(INBimm);
|
||||
case 0xCF: return KiCallVdmHandler(IRET);
|
||||
case 0xE4: return KiCallVdmHandler(INBimm);
|
||||
case 0xE5: return KiCallVdmHandler(INWimm);
|
||||
case 0xE6: return KiCallVdmHandler(OUTBimm);
|
||||
case 0xE7: return KiCallVdmHandler(OUTWimm);
|
||||
case 0xE7: return KiCallVdmHandler(OUTWimm);
|
||||
case 0xEC: return KiCallVdmHandler(INB);
|
||||
case 0xED: return KiCallVdmHandler(INW);
|
||||
case 0xEE: return KiCallVdmHandler(OUTB);
|
||||
|
@ -414,7 +414,7 @@ KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame,
|
|||
case 0xFA: return KiCallVdmHandler(CLI);
|
||||
case 0xFB: return KiCallVdmHandler(STI);
|
||||
default: return KiCallVdmHandler(INV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PREFIX HANDLER *************************************************************/
|
||||
|
@ -426,7 +426,7 @@ KiVdmOpcodePrefix(IN PKTRAP_FRAME TrapFrame,
|
|||
{
|
||||
/* Increase instruction size */
|
||||
Flags++;
|
||||
|
||||
|
||||
/* Handle the next opcode */
|
||||
return KiVdmHandleOpcode(TrapFrame, Flags);
|
||||
}
|
||||
|
@ -450,37 +450,30 @@ FASTCALL
|
|||
KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PKV8086_STACK_FRAME StackFrame;
|
||||
PKGDTENTRY GdtEntry;
|
||||
PKTHREAD Thread;
|
||||
PKTRAP_FRAME PmTrapFrame;
|
||||
PKV86_FRAME V86Frame;
|
||||
PFX_SAVE_AREA NpxFrame;
|
||||
|
||||
|
||||
/* Get the stack frame back */
|
||||
StackFrame = CONTAINING_RECORD(TrapFrame->Esi, KV8086_STACK_FRAME, V86Frame);
|
||||
PmTrapFrame = &StackFrame->TrapFrame;
|
||||
V86Frame = &StackFrame->V86Frame;
|
||||
NpxFrame = &StackFrame->NpxArea;
|
||||
|
||||
|
||||
/* Copy the FPU frame back */
|
||||
Thread = KeGetCurrentThread();
|
||||
RtlCopyMemory(KiGetThreadNpxArea(Thread), NpxFrame, sizeof(FX_SAVE_AREA));
|
||||
|
||||
/* Set initial stack back */
|
||||
Thread->InitialStack = (PVOID)((ULONG_PTR)V86Frame->ThreadStack + sizeof(FX_SAVE_AREA));
|
||||
|
||||
|
||||
/* Set ESP0 back in the KTSS */
|
||||
KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&PmTrapFrame->V86Es;
|
||||
|
||||
/* Restore TEB addresses */
|
||||
Thread->Teb = V86Frame->ThreadTeb;
|
||||
KeGetPcr()->NtTib.Self = V86Frame->PcrTeb;
|
||||
|
||||
/* Setup real TEB descriptor */
|
||||
GdtEntry = &((PKIPCR)KeGetPcr())->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)];
|
||||
GdtEntry->BaseLow = (USHORT)((ULONG_PTR)Thread->Teb & 0xFFFF);
|
||||
GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Thread->Teb >> 16);
|
||||
GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Thread->Teb >> 24);
|
||||
KiSetTebBase(KeGetPcr(), V86Frame->ThreadTeb);
|
||||
|
||||
/* Enable interrupts and return a pointer to the trap frame */
|
||||
_enable();
|
||||
|
@ -492,7 +485,6 @@ FASTCALL
|
|||
KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
|
||||
{
|
||||
PKTHREAD Thread;
|
||||
PKGDTENTRY GdtEntry;
|
||||
PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame;
|
||||
PKV86_FRAME V86Frame = &StackFrame->V86Frame;
|
||||
PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea;
|
||||
|
@ -501,26 +493,26 @@ KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
|
|||
TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK;
|
||||
TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0;
|
||||
TrapFrame->ErrCode = 0;
|
||||
|
||||
|
||||
/* Get the current thread's initial stack */
|
||||
Thread = KeGetCurrentThread();
|
||||
V86Frame->ThreadStack = KiGetThreadNpxArea(Thread);
|
||||
|
||||
|
||||
/* Save TEB addresses */
|
||||
V86Frame->ThreadTeb = Thread->Teb;
|
||||
V86Frame->PcrTeb = KeGetPcr()->NtTib.Self;
|
||||
|
||||
|
||||
/* Save return EIP */
|
||||
TrapFrame->Eip = (ULONG_PTR)Ki386BiosCallReturnAddress;
|
||||
|
||||
|
||||
/* Save our stack (after the frames) */
|
||||
TrapFrame->Esi = (ULONG_PTR)V86Frame;
|
||||
TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4;
|
||||
|
||||
|
||||
/* Sanitize EFlags and enable interrupts */
|
||||
TrapFrame->EFlags = __readeflags() & 0x60DD7;
|
||||
TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
|
||||
|
||||
|
||||
/* Fill out the rest of the frame */
|
||||
TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
|
||||
TrapFrame->HardwareEsp = 0x11FFE;
|
||||
|
@ -529,38 +521,32 @@ KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
|
|||
|
||||
/* Set some debug fields if trap debugging is enabled */
|
||||
KiFillTrapFrameDebug(TrapFrame);
|
||||
|
||||
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
|
||||
|
||||
/* Copy the thread's NPX frame */
|
||||
RtlCopyMemory(NpxFrame, V86Frame->ThreadStack, sizeof(FX_SAVE_AREA));
|
||||
|
||||
|
||||
/* Clear exception list */
|
||||
KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
|
||||
|
||||
/* Set new ESP0 */
|
||||
KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&TrapFrame->V86Es;
|
||||
|
||||
|
||||
/* Set new initial stack */
|
||||
Thread->InitialStack = V86Frame;
|
||||
|
||||
|
||||
/* Set VDM TEB */
|
||||
Thread->Teb = (PTEB)TRAMPOLINE_TEB;
|
||||
KeGetPcr()->NtTib.Self = (PVOID)TRAMPOLINE_TEB;
|
||||
|
||||
/* Setup VDM TEB descriptor */
|
||||
GdtEntry = &((PKIPCR)KeGetPcr())->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)];
|
||||
GdtEntry->BaseLow = (USHORT)((ULONG_PTR)TRAMPOLINE_TEB & 0xFFFF);
|
||||
GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)TRAMPOLINE_TEB >> 16);
|
||||
GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)TRAMPOLINE_TEB >> 24);
|
||||
|
||||
KiSetTebBase(KeGetPcr(), (PVOID)TRAMPOLINE_TEB);
|
||||
|
||||
/* Enable interrupts */
|
||||
_enable();
|
||||
|
||||
|
||||
/* Start VDM execution */
|
||||
NtVdmControl(VdmStartExecution, NULL);
|
||||
|
||||
|
||||
/* Exit to V86 mode */
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
|
@ -585,14 +571,14 @@ Ke386SetIOPL(VOID)
|
|||
/* Convert to a context */
|
||||
Context.ContextFlags = CONTEXT_CONTROL;
|
||||
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
||||
|
||||
|
||||
/* Set the IOPL flag */
|
||||
Context.EFlags |= EFLAGS_IOPL;
|
||||
|
||||
|
||||
/* Convert back to a trap frame */
|
||||
KeContextToTrapFrame(&Context, NULL, TrapFrame, CONTEXT_CONTROL, UserMode);
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue