mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[NTOS]: Implement KiSwapProcess in C.
[NTOS]: Implement KiIsNpxPresent and KiIsNpxErrataPresent in C. It's much clearer what these are doing now. [NTOS]: Implement KiFlushNPXState and fix some bugs that were present in the ASM version, such as a wrong NPX state check. [NTOS]: Implement working intrinsics for fxrstor, fxsave, fnsave and enable them for flushing. We'll update the FPU trap code to use these later. svn path=/trunk/; revision=45156
This commit is contained in:
parent
04a018d92b
commit
01d2a95033
5 changed files with 223 additions and 287 deletions
|
@ -14,6 +14,28 @@
|
||||||
: /* no input */ \
|
: /* no input */ \
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
Ke386FxStore(IN PFX_SAVE_AREA SaveArea)
|
||||||
|
{
|
||||||
|
asm volatile ("fxrstor (%0)" : : "r"(SaveArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
Ke386FxSave(IN PFX_SAVE_AREA SaveArea)
|
||||||
|
{
|
||||||
|
asm volatile ("fxsave (%0)" : : "r"(SaveArea));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea)
|
||||||
|
{
|
||||||
|
asm volatile ("fnsave (%0); wait" : : "r"(SaveArea));
|
||||||
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
|
Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
|
||||||
|
|
51
reactos/ntoskrnl/ke/i386/context.c
Normal file
51
reactos/ntoskrnl/ke/i386/context.c
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||||
|
* FILE: ntoskrnl/ke/i386/context.c
|
||||||
|
* PURPOSE: Context Switching Related Code
|
||||||
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiSwapProcess(IN PKPROCESS NewProcess,
|
||||||
|
IN PKPROCESS OldProcess)
|
||||||
|
{
|
||||||
|
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
ULONG SetMember;
|
||||||
|
|
||||||
|
/* Update active processor mask */
|
||||||
|
SetMember = Pcr->SetMember;
|
||||||
|
InterlockedXor(NewProcess->ActiveProcessors, SetMember);
|
||||||
|
InterlockedXor(OldProcess->ActiveProcessors, SetMember);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check for new LDT */
|
||||||
|
if (NewProcess->LdtDescriptor.LimitLow != OldProcess->LdtDescriptor.LimitLow)
|
||||||
|
{
|
||||||
|
/* Not handled yet */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
while (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update CR3 */
|
||||||
|
__writecr3(NewProcess->DirectoryTableBase[0]);
|
||||||
|
|
||||||
|
/* Clear GS */
|
||||||
|
Ke386SetGs(0);
|
||||||
|
|
||||||
|
/* Update IOPM offset */
|
||||||
|
Pcr->TSS->IoMapBase = NewProcess->IopmOffset;
|
||||||
|
}
|
||||||
|
|
|
@ -944,6 +944,155 @@ KiSaveProcessorState(IN PKTRAP_FRAME TrapFrame,
|
||||||
KiSaveProcessorControlState(&Prcb->ProcessorState);
|
KiSaveProcessorControlState(&Prcb->ProcessorState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KiIsNpxPresent(VOID)
|
||||||
|
{
|
||||||
|
ULONG Cr0;
|
||||||
|
USHORT Magic;
|
||||||
|
|
||||||
|
/* Set magic */
|
||||||
|
Magic = 0xFFFF;
|
||||||
|
|
||||||
|
/* Read CR0 and mask out FPU flags */
|
||||||
|
Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
|
||||||
|
|
||||||
|
/* Store on FPU stack */
|
||||||
|
asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
|
||||||
|
|
||||||
|
/* Magic should now be cleared */
|
||||||
|
if (Magic & 0xFF)
|
||||||
|
{
|
||||||
|
/* You don't have an FPU -- enable emulation for now */
|
||||||
|
__writecr0(Cr0 | CR0_EM | CR0_TS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You have an FPU, enable it */
|
||||||
|
Cr0 |= CR0_ET;
|
||||||
|
|
||||||
|
/* Enable INT 16 on 486 and higher */
|
||||||
|
if (KeGetCurrentPrcb()->CpuType >= 3) Cr0 |= CR0_NE;
|
||||||
|
|
||||||
|
/* Set FPU state */
|
||||||
|
__writecr0(Cr0 | CR0_EM | CR0_TS);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KiIsNpxErrataPresent(VOID)
|
||||||
|
{
|
||||||
|
BOOLEAN ErrataPresent;
|
||||||
|
ULONG Cr0;
|
||||||
|
volatile double Value1, Value2;
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Read CR0 and remove FPU flags */
|
||||||
|
Cr0 = __readcr0();
|
||||||
|
__writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
|
||||||
|
|
||||||
|
/* Initialize FPU state */
|
||||||
|
asm volatile ("fninit");
|
||||||
|
|
||||||
|
/* Multiply the magic values and divide, we should get the result back */
|
||||||
|
Value1 = 4195835.0;
|
||||||
|
Value2 = 3145727.0;
|
||||||
|
ErrataPresent = (Value1 * Value2 / 3145727.0) != 4195835.0;
|
||||||
|
|
||||||
|
/* Restore CR0 */
|
||||||
|
__writecr0(Cr0);
|
||||||
|
|
||||||
|
/* Enable interrupts */
|
||||||
|
_enable();
|
||||||
|
|
||||||
|
/* Return if there's an errata */
|
||||||
|
return ErrataPresent;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTAPI
|
||||||
|
VOID
|
||||||
|
KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
|
||||||
|
{
|
||||||
|
ULONG EFlags, Cr0;
|
||||||
|
PKTHREAD Thread, NpxThread;
|
||||||
|
PFX_SAVE_AREA FxSaveArea;
|
||||||
|
|
||||||
|
/* Save volatiles and disable interrupts */
|
||||||
|
EFlags = __readeflags();
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Save the PCR and get the current thread */
|
||||||
|
Thread = KeGetCurrentThread();
|
||||||
|
|
||||||
|
/* Check if we're already loaded */
|
||||||
|
if (Thread->NpxState != NPX_STATE_LOADED)
|
||||||
|
{
|
||||||
|
/* If there's nothing to load, quit */
|
||||||
|
if (!SaveArea) return;
|
||||||
|
|
||||||
|
/* Need FXSR support for this */
|
||||||
|
ASSERT(KeI386FxsrPresent == TRUE);
|
||||||
|
|
||||||
|
/* Check for sane CR0 */
|
||||||
|
Cr0 = __readcr0();
|
||||||
|
if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
|
||||||
|
{
|
||||||
|
/* Mask out FPU flags */
|
||||||
|
__writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the NPX thread and check its FPU state */
|
||||||
|
NpxThread = KeGetCurrentPrcb()->NpxThread;
|
||||||
|
if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
|
||||||
|
{
|
||||||
|
/* Get the FX frame and store the state there */
|
||||||
|
FxSaveArea = KiGetThreadNpxArea(NpxThread);
|
||||||
|
Ke386FxSave(FxSaveArea);
|
||||||
|
|
||||||
|
/* NPX thread has lost its state */
|
||||||
|
NpxThread->NpxState = NPX_STATE_NOT_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now load NPX state from the NPX area */
|
||||||
|
FxSaveArea = KiGetThreadNpxArea(Thread);
|
||||||
|
Ke386FxStore(FxSaveArea);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check for sane CR0 */
|
||||||
|
Cr0 = __readcr0();
|
||||||
|
if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
|
||||||
|
{
|
||||||
|
/* Mask out FPU flags */
|
||||||
|
__writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get FX frame */
|
||||||
|
FxSaveArea = KiGetThreadNpxArea(Thread);
|
||||||
|
Thread->NpxState = NPX_STATE_NOT_LOADED;
|
||||||
|
|
||||||
|
/* Save state if supported by CPU */
|
||||||
|
if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now save the FN state wherever it was requested */
|
||||||
|
if (SaveArea) Ke386FnSave(SaveArea);
|
||||||
|
|
||||||
|
/* Clear NPX thread */
|
||||||
|
KeGetCurrentPrcb()->NpxThread = NULL;
|
||||||
|
|
||||||
|
/* Add the CR0 from the NPX frame */
|
||||||
|
Cr0 |= NPX_STATE_NOT_LOADED;
|
||||||
|
Cr0 |= FxSaveArea->Cr0NpxState;
|
||||||
|
__writecr0(Cr0);
|
||||||
|
|
||||||
|
/* Restore interrupt state */
|
||||||
|
__writeeflags(EFlags);
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -17,237 +17,8 @@
|
||||||
#define Running 2
|
#define Running 2
|
||||||
#define WrDispatchInt 0x1F
|
#define WrDispatchInt 0x1F
|
||||||
|
|
||||||
Dividend: .float 4195835.0
|
|
||||||
Divisor: .float 3145727.0
|
|
||||||
Result1: .float 0
|
|
||||||
Result2: .float 0
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
.globl _KiIsNpxErrataPresent@0
|
|
||||||
.func KiIsNpxErrataPresent@0
|
|
||||||
_KiIsNpxErrataPresent@0:
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Get CR0 and mask out FPU flags */
|
|
||||||
mov eax, cr0
|
|
||||||
mov ecx, eax
|
|
||||||
and eax, ~(CR0_MP + CR0_TS + CR0_EM)
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
/* Initialize the FPU */
|
|
||||||
fninit
|
|
||||||
|
|
||||||
/* Do the divison and inverse multiplication */
|
|
||||||
fld qword ptr Dividend
|
|
||||||
fstp qword ptr Result1
|
|
||||||
fld qword ptr Divisor
|
|
||||||
fstp qword ptr Result2
|
|
||||||
fld qword ptr Result1
|
|
||||||
fdiv qword ptr Result2
|
|
||||||
fmul qword ptr Result2
|
|
||||||
|
|
||||||
/* Do the compare and check flags */
|
|
||||||
fcomp qword ptr Result1
|
|
||||||
fstsw ax
|
|
||||||
sahf
|
|
||||||
|
|
||||||
/* Restore CR0 and interrupts */
|
|
||||||
mov cr0, ecx
|
|
||||||
sti
|
|
||||||
|
|
||||||
/* Return errata status */
|
|
||||||
xor eax, eax
|
|
||||||
jz NoErrata
|
|
||||||
inc eax
|
|
||||||
|
|
||||||
NoErrata:
|
|
||||||
ret
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.globl _KiIsNpxPresent@0
|
|
||||||
.func KiIsNpxPresent@0
|
|
||||||
_KiIsNpxPresent@0:
|
|
||||||
|
|
||||||
/* Save stack */
|
|
||||||
push ebp
|
|
||||||
|
|
||||||
/* Get CR0 and mask out FPU flags */
|
|
||||||
mov eax, cr0
|
|
||||||
and eax, ~(CR0_MP + CR0_TS + CR0_EM + CR0_ET)
|
|
||||||
|
|
||||||
/* Initialize the FPU and assume FALSE for return */
|
|
||||||
xor edx, edx
|
|
||||||
fninit
|
|
||||||
|
|
||||||
/* Save magic value on stack */
|
|
||||||
mov ecx, 0x42424242
|
|
||||||
push ecx
|
|
||||||
|
|
||||||
/* Setup stack for FPU store */
|
|
||||||
mov ebp ,esp
|
|
||||||
fnstsw [ebp]
|
|
||||||
|
|
||||||
/* Now check if our magic got cleared */
|
|
||||||
cmp byte ptr [ebp], 0
|
|
||||||
jnz NoFpu
|
|
||||||
|
|
||||||
/* Enable FPU, set return to TRUE */
|
|
||||||
or eax, CR0_ET
|
|
||||||
mov edx, 1
|
|
||||||
|
|
||||||
/* If this is a 486 or higher, enable INT 16 as well */
|
|
||||||
cmp dword ptr fs:KPCR_PRCB_CPU_TYPE, 3
|
|
||||||
jbe NoFpu
|
|
||||||
or eax, CR0_NE
|
|
||||||
|
|
||||||
NoFpu:
|
|
||||||
/* Set emulation enabled during the first boot phase and set the CR0 */
|
|
||||||
or eax, (CR0_EM + CR0_TS)
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
/* Restore stack */
|
|
||||||
pop eax
|
|
||||||
pop ebp
|
|
||||||
|
|
||||||
/* Return true or false */
|
|
||||||
mov eax, edx
|
|
||||||
ret
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.globl _KiFlushNPXState@4
|
|
||||||
.func KiFlushNPXState@4
|
|
||||||
_KiFlushNPXState@4:
|
|
||||||
|
|
||||||
/* Save volatiles and disable interrupts */
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Save the PCR and get the current thread */
|
|
||||||
mov edi, fs:[KPCR_SELF]
|
|
||||||
mov esi, [edi+KPCR_CURRENT_THREAD]
|
|
||||||
|
|
||||||
/* Check if we're already loaded */
|
|
||||||
cmp byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_LOADED
|
|
||||||
je IsValid
|
|
||||||
|
|
||||||
/* Check if we're supposed to get it */
|
|
||||||
cmp dword ptr [esp+20], 0
|
|
||||||
je Return
|
|
||||||
|
|
||||||
#if DBG
|
|
||||||
/* Assert Fxsr support */
|
|
||||||
test byte ptr _KeI386FxsrPresent, 1
|
|
||||||
jnz AssertOk
|
|
||||||
int 3
|
|
||||||
AssertOk:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get CR0 and test if it's valid */
|
|
||||||
mov ebx, cr0
|
|
||||||
test bl, CR0_MP + CR0_TS + CR0_EM
|
|
||||||
jz Cr0OK
|
|
||||||
|
|
||||||
/* Enable fnsave to work */
|
|
||||||
and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
|
|
||||||
mov cr0, ebx
|
|
||||||
|
|
||||||
Cr0OK:
|
|
||||||
/* Check if we are the NPX Thread */
|
|
||||||
mov eax, [edi+KPCR_NPX_THREAD]
|
|
||||||
or eax, eax
|
|
||||||
jz DontSave
|
|
||||||
|
|
||||||
/* Check if it's not loaded */
|
|
||||||
cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
|
|
||||||
jnz DontSave
|
|
||||||
|
|
||||||
#if DBG
|
|
||||||
/* We are the NPX Thread with an unloaded NPX State... this isn't normal! */
|
|
||||||
int 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save the NPX State */
|
|
||||||
mov ecx, [eax+KTHREAD_INITIAL_STACK]
|
|
||||||
sub ecx, NPX_FRAME_LENGTH
|
|
||||||
fxsave [ecx]
|
|
||||||
mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
|
|
||||||
|
|
||||||
DontSave:
|
|
||||||
/* Load the NPX State */
|
|
||||||
mov ecx, [esi+KTHREAD_INITIAL_STACK]
|
|
||||||
sub ecx, NPX_FRAME_LENGTH
|
|
||||||
fxrstor [ecx]
|
|
||||||
|
|
||||||
/* Get the CR0 state and destination */
|
|
||||||
mov edx, [ecx+FN_CR0_NPX_STATE]
|
|
||||||
mov ecx, [esp+20]
|
|
||||||
jmp DoneLoad
|
|
||||||
|
|
||||||
IsValid:
|
|
||||||
/* We already have a valid state, flush it */
|
|
||||||
mov ebx, cr0
|
|
||||||
test bl, CR0_MP + CR0_TS + CR0_EM
|
|
||||||
jz Cr0OK2
|
|
||||||
|
|
||||||
/* Enable fnsave to work */
|
|
||||||
and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
|
|
||||||
mov cr0, ebx
|
|
||||||
|
|
||||||
Cr0OK2:
|
|
||||||
/* Get the kernel stack */
|
|
||||||
mov ecx, [esi+KTHREAD_INITIAL_STACK]
|
|
||||||
test byte ptr _KeI386FxsrPresent, 1
|
|
||||||
lea ecx, [ecx-NPX_FRAME_LENGTH]
|
|
||||||
|
|
||||||
/* Set the NPX State */
|
|
||||||
mov byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
|
|
||||||
|
|
||||||
/* Get Cr0 */
|
|
||||||
mov edx, [ecx+FN_CR0_NPX_STATE]
|
|
||||||
jz DoneLoad
|
|
||||||
|
|
||||||
/* Save the FX State */
|
|
||||||
fxsave [ecx]
|
|
||||||
|
|
||||||
/* Check if we also have to save it in the parameter */
|
|
||||||
mov ecx, [esp+20]
|
|
||||||
jecxz NoSave
|
|
||||||
|
|
||||||
DoneLoad:
|
|
||||||
/* Save the Fn state in the parameter we got */
|
|
||||||
fnsave [ecx]
|
|
||||||
fwait
|
|
||||||
|
|
||||||
NoSave:
|
|
||||||
/* Clear eax */
|
|
||||||
xor eax, eax
|
|
||||||
|
|
||||||
/* Add NPX State */
|
|
||||||
or ebx, NPX_STATE_NOT_LOADED
|
|
||||||
|
|
||||||
/* Clear the NPX thread */
|
|
||||||
mov [edi+KPCR_NPX_THREAD], eax
|
|
||||||
|
|
||||||
/* Add saved CR0 into NPX State, and set it */
|
|
||||||
or ebx, edx
|
|
||||||
mov cr0, ebx
|
|
||||||
|
|
||||||
/* Re-enable interrupts and return */
|
|
||||||
Return:
|
|
||||||
popf
|
|
||||||
pop ebx
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* KiSwapContextInternal
|
* KiSwapContextInternal
|
||||||
*
|
*
|
||||||
|
@ -736,64 +507,6 @@ NoNextThread:
|
||||||
#endif
|
#endif
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
.globl _KiSwapProcess@8
|
|
||||||
.func KiSwapProcess@8
|
|
||||||
_KiSwapProcess@8:
|
|
||||||
|
|
||||||
/* Get process pointers */
|
|
||||||
mov edx, [esp+4]
|
|
||||||
mov eax, [esp+8]
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Update active processors */
|
|
||||||
mov ecx, fs:[KPCR_SET_MEMBER]
|
|
||||||
lock xor [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
|
|
||||||
lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
#if DBG
|
|
||||||
test [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
|
|
||||||
jz WrongCpu1
|
|
||||||
test [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
|
|
||||||
jnz WrongCpu2
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if their LDTs changed */
|
|
||||||
mov ecx, [edx+KPROCESS_LDT_DESCRIPTOR0]
|
|
||||||
or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0]
|
|
||||||
jnz NewLdt
|
|
||||||
|
|
||||||
/* Update CR3 */
|
|
||||||
mov eax, [edx+KPROCESS_DIRECTORY_TABLE_BASE]
|
|
||||||
mov cr3, eax
|
|
||||||
|
|
||||||
/* Get the KTSS */
|
|
||||||
mov ecx, fs:[KPCR_TSS]
|
|
||||||
|
|
||||||
/* Clear GS on process swap */
|
|
||||||
xor eax, eax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
/* Update IOPM offset */
|
|
||||||
mov ax, [edx+KPROCESS_IOPM_OFFSET]
|
|
||||||
mov [ecx+KTSS_IOMAPBASE], ax
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
NewLdt:
|
|
||||||
/* FIXME: TODO */
|
|
||||||
int 3
|
|
||||||
|
|
||||||
#if DBG
|
|
||||||
WrongCpu1:
|
|
||||||
int 3
|
|
||||||
WrongCpu2:
|
|
||||||
int 3
|
|
||||||
#endif
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.globl _Ki386SetupAndExitToV86Mode@4
|
.globl _Ki386SetupAndExitToV86Mode@4
|
||||||
.func Ki386SetupAndExitToV86Mode@4
|
.func Ki386SetupAndExitToV86Mode@4
|
||||||
_Ki386SetupAndExitToV86Mode@4:
|
_Ki386SetupAndExitToV86Mode@4:
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
<directory name="i386">
|
<directory name="i386">
|
||||||
<file>abios.c</file>
|
<file>abios.c</file>
|
||||||
<file>cpu.c</file>
|
<file>cpu.c</file>
|
||||||
|
<file>context.c</file>
|
||||||
<file>ctxswitch.S</file>
|
<file>ctxswitch.S</file>
|
||||||
<file>exp.c</file>
|
<file>exp.c</file>
|
||||||
<file>irqobj.c</file>
|
<file>irqobj.c</file>
|
||||||
|
|
Loading…
Reference in a new issue