Fix AMD64 thread context setup
Some checks failed
Builds / ExectOS (i686, release) (push) Successful in 34s
Builds / ExectOS (i686, debug) (push) Successful in 36s
Builds / ExectOS (amd64, release) (push) Failing after 41s
Builds / ExectOS (amd64, debug) (push) Failing after 44s

This commit is contained in:
2026-06-14 00:44:02 +02:00
parent f79c9023d8
commit 15523e7d71

View File

@@ -40,6 +40,7 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
IN PCONTEXT ContextRecord) IN PCONTEXT ContextRecord)
{ {
PKTHREAD_INIT_FRAME ThreadFrame; PKTHREAD_INIT_FRAME ThreadFrame;
CONTEXT ContextFrame;
/* Set initial thread frame */ /* Set initial thread frame */
ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1; ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1;
@@ -50,45 +51,60 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
/* Check if context provided for this thread */ /* Check if context provided for this thread */
if(ContextRecord) if(ContextRecord)
{ {
/* User mode thread needs further initialization, this is not completed */ /* Make a local copy of the context to avoid mutating caller's memory */
UNIMPLEMENTED; RTL::Memory::CopyMemory(&ContextFrame, ContextRecord, sizeof(CONTEXT));
/* Disable debug registers and enable context registers */
ContextFrame.ContextFlags |= CONTEXT_CONTROL;
ContextFrame.ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
/* Align the stack and reserve space for 4 parameters and return value */
ContextFrame.Rsp = (ContextFrame.Rsp & ~15) - 40;
/* Set CS and SS segments for user mode */
ContextFrame.SegCs = KGDT_R3_CODE | RPL_MASK;
ContextFrame.SegSs = KGDT_R3_DATA | RPL_MASK;
/* Fill exception and trap frames with zeroes */ /* Fill exception and trap frames with zeroes */
RTL::Memory::ZeroMemory(&ThreadFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME)); RTL::Memory::ZeroMemory(&ThreadFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME));
RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME));
/* Disable debug registers and enable context registers */ /* Translate Context frame to Trap frame */
ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL; KE::Processor::RestoreProcessorContext(&ThreadFrame->TrapFrame, &ThreadFrame->ExceptionFrame,
&ContextFrame, ContextFrame.ContextFlags);
/* Align the stack and reserve space for 4 parameters and return value */
ContextRecord->Rsp = (ContextRecord->Rsp & ~15) - 40;
/* Set CS and SS segments for user mode */
ContextRecord->SegCs = KGDT_R3_CODE | RPL_MASK;
ContextRecord->SegSs = KGDT_R3_DATA | RPL_MASK;
/* This is user mode thread */ /* This is user mode thread */
Thread->PreviousMode = UserMode; Thread->PreviousMode = UserMode;
ThreadFrame->TrapFrame.PreviousMode = UserMode;
/* Enable floating point state */ /* Enable floating point state */
Thread->NpxState = NPX_STATE_SCRUB; Thread->NpxState = NPX_STATE_SCRUB;
/* Set initial floating point state */ /* Set initial floating point state */
ThreadFrame->NpxFrame.ControlWord = 0x27F; ThreadFrame->NpxFrame.ControlWord = 0x27F;
ThreadFrame->NpxFrame.DataOffset = 0;
ThreadFrame->NpxFrame.DataSelector = 0;
ThreadFrame->NpxFrame.ErrorOffset = 0;
ThreadFrame->NpxFrame.ErrorOpcode = 0;
ThreadFrame->NpxFrame.ErrorSelector = 0;
ThreadFrame->NpxFrame.StatusWord = 0;
ThreadFrame->NpxFrame.TagWord = 0xFFFF; ThreadFrame->NpxFrame.TagWord = 0xFFFF;
/* Set initial MXCSR register value */
ThreadFrame->TrapFrame.MxCsr = INITIAL_MXCSR;
/* Clear DR6 and DR7 registers */ /* Clear DR6 and DR7 registers */
ThreadFrame->TrapFrame.Dr6 = 0; ThreadFrame->TrapFrame.Dr6 = 0;
ThreadFrame->TrapFrame.Dr7 = 0; ThreadFrame->TrapFrame.Dr7 = 0;
/* Set initial MXCSR register value */ /* Terminate the Exception Handler List */
ThreadFrame->TrapFrame.MxCsr = INITIAL_MXCSR; ThreadFrame->TrapFrame.ExceptionFrame = (ULONGLONG)NULLPTR;
/* Initialize exception frame */ /* Initialize exception frame */
ThreadFrame->ExceptionFrame.P1Home = (ULONG64)StartContext; ThreadFrame->ExceptionFrame.P1Home = (ULONGLONG)StartContext;
ThreadFrame->ExceptionFrame.P2Home = (ULONG64)StartRoutine; ThreadFrame->ExceptionFrame.P2Home = (ULONGLONG)StartRoutine;
ThreadFrame->ExceptionFrame.P3Home = (ULONG64)SystemRoutine; ThreadFrame->ExceptionFrame.P3Home = (ULONGLONG)SystemRoutine;
ThreadFrame->ExceptionFrame.P4Home = (ULONG64)SystemRoutine; ThreadFrame->ExceptionFrame.P4Home = (ULONGLONG)SystemRoutine;
} }
else else
{ {
@@ -97,22 +113,21 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
/* Disable floating point state */ /* Disable floating point state */
Thread->NpxState = NPX_STATE_UNUSED; Thread->NpxState = NPX_STATE_UNUSED;
/* Set thread start address */
ThreadFrame->StartFrame.Return = (ULONG64)NULLPTR;
} }
/* Initialize thread startup information */ /* Initialize thread startup information */
ThreadFrame->StartFrame.P1Home = (ULONG64)StartContext; ThreadFrame->StartFrame.P1Home = (ULONGLONG)StartContext;
ThreadFrame->StartFrame.P2Home = (ULONG64)StartRoutine; ThreadFrame->StartFrame.P2Home = (ULONGLONG)StartRoutine;
ThreadFrame->StartFrame.P3Home = (ULONG64)SystemRoutine; ThreadFrame->StartFrame.P3Home = (ULONGLONG)SystemRoutine;
ThreadFrame->StartFrame.P4Home = (ULONG64)SystemRoutine; ThreadFrame->StartFrame.P4Home = (ULONGLONG)SystemRoutine;
/* Initialize switch frame */ /* Initialize switch frame */
ThreadFrame->SwitchFrame.ApcBypass = APC_LEVEL; ThreadFrame->SwitchFrame.ApcBypass = APC_LEVEL;
ThreadFrame->SwitchFrame.MxCsr = INITIAL_MXCSR; ThreadFrame->SwitchFrame.MxCsr = INITIAL_MXCSR;
ThreadFrame->SwitchFrame.Rbp = (ULONG64)&ThreadFrame->TrapFrame; ThreadFrame->SwitchFrame.Rbp = (ULONGLONG)&ThreadFrame->TrapFrame;
ThreadFrame->SwitchFrame.Return = (ULONGLONG)RunThread;
/* Set thread stack */ /* Set thread stack boundaries */
Thread->InitialStack = (PVOID)&ThreadFrame->NpxFrame;
Thread->KernelStack = &ThreadFrame->SwitchFrame; Thread->KernelStack = &ThreadFrame->SwitchFrame;
} }