/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ke/i386/thread.c
+ * FILE: ntoskrnl/ke/amd64/thrdini.c
* PURPOSE: amd64 Thread Context Creation
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
* Alex Ionescu (alex@relsoft.net)
#define NDEBUG
#include <debug.h>
+extern void KiInvalidSystemThreadStartupExit(void);
+extern void KiUserThreadStartupExit(void);
+extern void KiServiceExit3(void);
+
typedef struct _KUINIT_FRAME
{
KSWITCH_FRAME CtxSwitchFrame;
/* Zero out the trap frame */
RtlZeroMemory(TrapFrame, sizeof(KTRAP_FRAME));
+ RtlZeroMemory(&InitFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME));
/* Set up a trap frame from the context. */
KeContextToTrapFrame(Context,
- NULL,
+ &InitFrame->ExceptionFrame,
TrapFrame,
CONTEXT_AMD64 | ContextFlags,
UserMode);
/* Terminate the Exception Handler List */
TrapFrame->ExceptionFrame = 0;
- /* We return to ... */
- StartFrame->Return = (ULONG64)KiServiceExit2;
+ /* KiThreadStartup returns to KiUserThreadStartupExit */
+ StartFrame->Return = (ULONG64)KiUserThreadStartupExit;
+
+ /* KiUserThreadStartupExit returns to KiServiceExit3 */
+ InitFrame->ExceptionFrame.Return = (ULONG64)KiServiceExit3;
}
else
{
/* No NPX State */
Thread->NpxState = 0xA;
- /* We have no return address! */
- StartFrame->Return = 0;
+ /* This must never return! */
+ StartFrame->Return = (ULONG64)KiInvalidSystemThreadStartupExit;
}
/* Set up the Context Switch Frame */
CtxSwitchFrame->Return = (ULONG64)KiThreadStartup;
- CtxSwitchFrame->ApcBypass = FALSE;
+ CtxSwitchFrame->ApcBypass = TRUE;
StartFrame->P1Home = (ULONG64)StartRoutine;
StartFrame->P2Home = (ULONG64)StartContext;
StartFrame->P3Home = 0;
StartFrame->P4Home = (ULONG64)SystemRoutine;
- StartFrame->P5Home = 0;
-
+ StartFrame->Reserved = 0;
}
BOOLEAN
KiSwapContextResume(
- IN PKTHREAD NewThread,
- IN PKTHREAD OldThread,
- IN BOOLEAN ApcBypass)
+ _In_ BOOLEAN ApcBypass,
+ _In_ PKTHREAD OldThread,
+ _In_ PKTHREAD NewThread)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
PKPROCESS OldProcess, NewProcess;
0);
}
+ /* Old thread os no longer busy */
+ OldThread->SwapBusy = FALSE;
+
/* Kernel APCs may be pending */
if (NewThread->ApcState.KernelApcPending)
{
/* Are APCs enabled? */
- if (!NewThread->SpecialApcDisable)
+ if ((NewThread->SpecialApcDisable == 0) &&
+ (ApcBypass == 0))
{
- /* Request APC delivery */
- if (!ApcBypass)
- HalRequestSoftwareInterrupt(APC_LEVEL);
- else
- return TRUE;
+ /* Return TRUE to indicate that we want APCs to be delivered */
+ return TRUE;
}
+
+ /* Request an APC interrupt to be delivered later */
+ HalRequestSoftwareInterrupt(APC_LEVEL);
}
/* Return stating that no kernel APCs are pending*/