152 lines
4.4 KiB
ArmAsm
152 lines
4.4 KiB
ArmAsm
|
// TITLE("Thread Startup")
|
|||
|
//++
|
|||
|
//
|
|||
|
// Copyright (c) 1990 Microsoft Corporation
|
|||
|
// Copyright (c) 1992, 1993 Digital Equipment Corporation
|
|||
|
//
|
|||
|
// Module Name:
|
|||
|
//
|
|||
|
// threadbg.s
|
|||
|
//
|
|||
|
// Abstract:
|
|||
|
//
|
|||
|
// This module implements the MIPS machine dependent code necessary to
|
|||
|
// startup a thread in kernel mode.
|
|||
|
//
|
|||
|
// Author:
|
|||
|
//
|
|||
|
// David N. Cutler (davec) 28-Mar-1990
|
|||
|
// Joe Notarangelo 21-Apr-1992
|
|||
|
//
|
|||
|
// Environment:
|
|||
|
//
|
|||
|
// Kernel mode only, IRQL APC_LEVEL.
|
|||
|
//
|
|||
|
// Revision History:
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
#include "ksalpha.h"
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// RoutineDescription:
|
|||
|
//
|
|||
|
// The following code is never executed. Its purpose is to allow the
|
|||
|
// kernel debugger to walk call frames backwards through thread startup
|
|||
|
// and to support get/set user context.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
NESTED_ENTRY(KiThreadDispatch, ExceptionFrameLength, zero)
|
|||
|
|
|||
|
lda sp, -ExceptionFrameLength(sp) // allocate exception frame
|
|||
|
stq ra, ExIntRa(sp) // save return address
|
|||
|
stq s0, ExIntS0(sp) // save integer regs s0-s5
|
|||
|
stq s1, ExIntS1(sp) //
|
|||
|
stq s2, ExIntS2(sp) //
|
|||
|
stq s3, ExIntS3(sp) //
|
|||
|
stq s4, ExIntS4(sp) //
|
|||
|
stq s5, ExIntS5(sp) //
|
|||
|
|
|||
|
stt f2, ExFltF2(sp) // save floating regs f2 - f9
|
|||
|
stt f3, ExFltF3(sp) //
|
|||
|
stt f4, ExFltF4(sp) //
|
|||
|
stt f5, ExFltF5(sp) //
|
|||
|
stt f6, ExFltF6(sp) //
|
|||
|
stt f7, ExFltF7(sp) //
|
|||
|
stt f8, ExFltF8(sp) //
|
|||
|
stt f9, ExFltF9(sp) //
|
|||
|
|
|||
|
PROLOGUE_END
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// 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.
|
|||
|
//
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// sp - Supplies a pointer to the exception frame which contains the
|
|||
|
// startup parameters.
|
|||
|
//
|
|||
|
// Within Exception frame:
|
|||
|
//
|
|||
|
// s0 - Supplies a boolean value that specified whether a user mode
|
|||
|
// thread context was established when the thread was initialized.
|
|||
|
//
|
|||
|
// s1 - Supplies the starting context parameter for the initial thread
|
|||
|
// procedure.
|
|||
|
//
|
|||
|
// s2 - Supplies the starting address of the initial thread routine.
|
|||
|
//
|
|||
|
// s3 - Supplies the starting address of the initial system routine.
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
ALTERNATE_ENTRY(KiThreadStartup)
|
|||
|
|
|||
|
//
|
|||
|
// Capture the arguments for startup from the exception frame.
|
|||
|
// After the arguments are captured, deallocate the exception frame.
|
|||
|
//
|
|||
|
|
|||
|
ldq s0, ExIntS0(sp) // capture user context boolean
|
|||
|
ldq s1, ExIntS1(sp) // set startup context parameter
|
|||
|
ldq s2, ExIntS2(sp) // set address of thread routine
|
|||
|
ldq s3, ExIntS3(sp) // capture startup routine address
|
|||
|
ldq s4, ExIntS4(sp) // restore s4
|
|||
|
ldq s5, ExIntS5(sp) // restore s5
|
|||
|
ldq fp, ExIntFp(sp) // restore trap frame pointer
|
|||
|
lda sp, ExceptionFrameLength(sp) // deallocate exception frame
|
|||
|
|
|||
|
//
|
|||
|
// Lower Irql to APC level.
|
|||
|
//
|
|||
|
|
|||
|
ldil a0, APC_LEVEL // set IRQL to APC level
|
|||
|
|
|||
|
SWAP_IRQL // lower IRQL
|
|||
|
|
|||
|
//
|
|||
|
// Jump to the startup routine with the address of the thread routine and
|
|||
|
// the startup context parameter.
|
|||
|
//
|
|||
|
|
|||
|
bis s2, zero, a0 // set address of thread routine
|
|||
|
bis s1, zero, a1 // set startup context parameter
|
|||
|
jsr ra, (s3) // call system startup routine
|
|||
|
|
|||
|
//
|
|||
|
// If we return and no user context was supplied then we have trouble.
|
|||
|
//
|
|||
|
|
|||
|
beq s0, 20f // if eq, no user context
|
|||
|
|
|||
|
//
|
|||
|
// Finish in common exception exit code which will restore the nonvolatile
|
|||
|
// registers and exit to user mode.
|
|||
|
//
|
|||
|
|
|||
|
br zero, KiExceptionExit // finish in exception exit code
|
|||
|
|
|||
|
//
|
|||
|
// An attempt was made to enter user mode for a thread that has no user mode
|
|||
|
// context. Generate a bug check.
|
|||
|
//
|
|||
|
|
|||
|
20: ldil a0, NO_USER_MODE_CONTEXT // set bug check code
|
|||
|
bsr ra, KeBugCheck // call bug check routine
|
|||
|
|
|||
|
.end KiThreadDispatch
|
|||
|
|