title "Thread Startup" ;++ ; ; Copyright (c) 2000 Microsoft Corporation ; ; Module Name: ; ; threadbg.asm ; ; Abstract: ; ; This module implements the code necessary to startup a thread in kernel ; mode. ; ; Author: ; ; David N. Cutler (davec) 10-Jun-2000 ; ; Environment: ; ; Kernel mode only, IRQL APC_LEVEL. ; ;-- include ksamd64.inc altentry KiThreadStartup extern KeBugCheck:proc extern KiExceptionExit:proc subttl "Thread Startup" ;++ ; ; Routine Description: ; ; This routine is called at thread startup. Its function is to call the ; initial thread procedure. If control returns from the initial thread ; procedure and a user mode context was established when the thread ; was initialized, then the user mode context is restored and control ; is transfered to user mode. Otherwise a bug check will occur. ; ; N.B. At thread startup the stack contains at least a legacy floating ; point save area and an exception frame. If the thread is a user ; mode thread, then it also contains a trap frame. The exception ; frame contains the system start call address and parameters. As ; soon as these values are captured the exception frame is deallocated. ; ; Arguments: ; ; r12 - Supplies a logical value that specifies whether a user mode thread ; context was established when the thread was initialized. ; ; r13 - Supplies the starting context parameter for the initial thread ; routine. ; ; r14 - Supplies the starting address of the initial thread routine. ; ; r15 - Supplies the starting address of the initial system routine. ; ; rbp - Supplies the address of a trap frame if a user thread is being ; started. Otherwise, it contains the value 128 and is not meaningful. ; ; Return Value: ; ; None. ; ;-- NESTED_ENTRY KxThreadStartup, _TEXT$00 alloc_stack LEGACY_SAVE_AREA_LENGTH - 8 ; allocate legacy save area set_frame rbx, 0 ; set frame register END_PROLOGUE sub rsp, KEXCEPTION_FRAME_LENGTH ; allocate exception frame ALTERNATE_ENTRY KiThreadStartup mov rbx, ExRbx[rsp] ; set frame register mov r12, ExR12[rsp] ; get user context address mov r13, ExR13[rsp] ; get startup context parameter mov r14, ExR14[rsp] ; get initial thread routine address mov r15, ExR15[rsp] ; get initial system routine address test r12, r12 ; test if user context specified jnz short KiTs10 ; if nz, user context specified add rsp, KEXCEPTION_FRAME_LENGTH - (2 * 8) ; deallocate exception frame KiTs10: mov ecx, APC_LEVEL ; set IRQL to APC level SetIrql ; mov rcx, r14 ; set address of thread routine mov rdx, r13 ; set startup context parameter call r15 ; call system routine test r12, r12 ; test if user context specified jz short KiTs20 ; if z, no user context specified jmp KiExceptionExit ; finish in exception exit code KiTs20: mov rcx, NO_USER_MODE_CONTEXT ; set bug check parameter call KeBugCheck ; call bug check - no return NESTED_END KxThreadStartup, _TEXT$00 end