2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/amd64/ctxswitch.S
5 * PURPOSE: Thread Context Switching
7 * PROGRAMMER: Timo kreuzer (timo.kreuzer@reactos.org)
10 /* INCLUDES ******************************************************************/
12 #include <reactos/asm.h>
13 #include <ndk/amd64/asm.h>
15 /* FUNCTIONS ****************************************************************/
22 * The KiThreadStartup routine is the beginning of any thread.
25 * SystemRoutine - Pointer to the System Startup Routine. Either
26 * PspUserThreadStartup or PspSystemThreadStartup
28 * StartRoutine - For Kernel Threads only, specifies the starting execution
29 * point of the new thread.
31 * StartContext - For Kernel Threads only, specifies a pointer to variable
32 * context data to be sent to the StartRoutine above.
34 * UserThread - Indicates whether or not this is a user thread. This tells
35 * us if the thread has a context or not.
37 * TrapFrame - Pointer to the KTHREAD to which the caller wishes to
41 * Should never return for a system thread. Returns through the System Call
42 * Exit Dispatcher for a user thread.
45 * If a return from a system thread is detected, a bug check will occur.
48 PUBLIC KiThreadStartup
52 * Clear all the non-volatile registers, so the thread won't be tempted to
53 * expect any static data (like some badly coded usermode/win9x apps do)
66 /* It's now safe to go to APC */
71 * Call the System Routine which is right on our stack now.
72 * After we pop the pointer, the Start Routine/Context is on the
73 * stack, we pop it as parameters to the System Routine into rcx
79 /* The thread returned... was it a user-thread? */
84 /* Yes it was, set our trapframe for the System Call Exit Dispatcher */
87 /* Exit back to user-mode */
88 // jmp _KiServiceExit2
89 UNIMPLEMENTED KiThreadStartup_KiServiceExit2
93 /* A system thread returned...this is very bad! */
98 * KiSwapContextInternal
100 * The KiSwapContextInternal routine switches context to another thread.
103 * ESI - Pointer to the KTHREAD to which the caller wishes to
105 * EDI - Pointer to the KTHREAD to which the caller wishes to
112 * Absolutely all registers except ESP can be trampled here for maximum code flexibility.
115 PUBLIC KiSwapContextInternal
116 KiSwapContextInternal:
117 UNIMPLEMENTED KiSwapContextInternal
125 * The KiSwapContext routine switches context to another thread.
128 * KiSwapContext(PKTHREAD CurrentThread, PKTHREAD TargetThread);
130 * \param CurrentThread
131 * Pointer to the KTHREAD of the current thread.
133 * \param TargetThread
134 * Pointer to the KTHREAD to which the caller wishes to switch to.
137 * The WaitStatus of the Target Thread.
140 * This is a wrapper around KiSwapContextInternal which will save all the
141 * non-volatile registers so that the Internal function can use all of
142 * them. It will also save the old current thread and set the new one.
144 * The calling thread does not return after KiSwapContextInternal until
145 * another thread switches to IT.
151 /* Save 10 registers */
154 /* Save all the non-volatile ones */
168 mov rbx, gs:[KPCR_SELF]
170 /* Get the current thread */
173 /* Get the New Thread */
176 /* Get the wait IRQL */
177 movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL]
179 /* Do the swap with the registers correctly setup */
180 call KiSwapContextInternal
182 /* Restore the registers */