209 lines
5.2 KiB
ArmAsm
209 lines
5.2 KiB
ArmAsm
|
// TITLE("Win32 Thunks")
|
|||
|
//++
|
|||
|
//
|
|||
|
// Copyright (c) 1990 Microsoft Corporation
|
|||
|
//
|
|||
|
// Module Name:
|
|||
|
//
|
|||
|
// thunk.s
|
|||
|
//
|
|||
|
// Abstract:
|
|||
|
//
|
|||
|
// This module implements Win32 functions that must be written in assembler.
|
|||
|
//
|
|||
|
// Author:
|
|||
|
//
|
|||
|
// Mark Lucovsky (markl) 5-Oct-1990
|
|||
|
//
|
|||
|
// Revision History:
|
|||
|
//
|
|||
|
// Thomas Van Baak (tvb) 21-Jul-1992
|
|||
|
//
|
|||
|
// Adapted for Alpha AXP.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
#include "ksalpha.h"
|
|||
|
|
|||
|
SBTTL("Switch Stack Then Terminate")
|
|||
|
//++
|
|||
|
//
|
|||
|
// VOID
|
|||
|
// BaseSwitchStackThenTerminate (
|
|||
|
// IN PVOID StackLimit,
|
|||
|
// IN PVOID NewStack,
|
|||
|
// IN DWORD ExitCode
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// This API is called during thread termination to delete a thread's
|
|||
|
// stack, switch to a stack in the thread's TEB, and then terminate.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// StackLimit (a0) - Supplies the address of the stack to be freed.
|
|||
|
//
|
|||
|
// NewStack (a1) - Supplies an address within the terminating thread's TE
|
|||
|
// that is to be used as its temporary stack while exiting.
|
|||
|
//
|
|||
|
// ExitCode (a2) - Supplies the termination status that the thread
|
|||
|
// is to exit with.
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
LEAF_ENTRY(BaseSwitchStackThenTerminate)
|
|||
|
|
|||
|
//
|
|||
|
// Switch stacks and then jump to BaseFreeStackAndTerminate.
|
|||
|
//
|
|||
|
|
|||
|
mov a1, sp // set new stack pointer
|
|||
|
mov a2, a1 // set exit code argument
|
|||
|
br zero, BaseFreeStackAndTerminate // jump
|
|||
|
|
|||
|
.end BaseSwitchStackThenTerminate
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// VOID
|
|||
|
// WINAPI
|
|||
|
// SwitchToFiber (
|
|||
|
// LPVOID lpFiber
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// This function saves the state of the current fiber and switches
|
|||
|
// to the new fiber.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// CurrentFiber - Supplies the address of the current fiber.
|
|||
|
//
|
|||
|
// NewFiber - Supplies the address of the new fiber.
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
LEAF_ENTRY(SwitchToFiber)
|
|||
|
|
|||
|
GET_THREAD_ENVIRONMENT_BLOCK // get current TEB address
|
|||
|
|
|||
|
//
|
|||
|
// Get current fiber address.
|
|||
|
//
|
|||
|
|
|||
|
LDP a1, TeFiberData(v0) //
|
|||
|
|
|||
|
//
|
|||
|
// Set new deallocation stack and fiber data in TEB.
|
|||
|
//
|
|||
|
|
|||
|
LDP t0, FbDeallocationStack(a0) // set deallocation stack address
|
|||
|
STP t0, TeDeallocationStack(v0) //
|
|||
|
STP a0, TeFiberData(v0) // set new fiber address
|
|||
|
|
|||
|
//
|
|||
|
// Save stack limit.
|
|||
|
//
|
|||
|
|
|||
|
LDP t1, TeStackLimit(v0) // save current stack limit
|
|||
|
STP t1, FbStackLimit(a1) //
|
|||
|
|
|||
|
//
|
|||
|
// Save nonvolatile integer state.
|
|||
|
//
|
|||
|
|
|||
|
stq s0, CxIntS0 + FbFiberContext(a1) //
|
|||
|
stq s1, CxIntS1 + FbFiberContext(a1) //
|
|||
|
stq s2, CxIntS2 + FbFiberContext(a1) //
|
|||
|
stq s3, CxIntS3 + FbFiberContext(a1) //
|
|||
|
stq s4, CxIntS4 + FbFiberContext(a1) //
|
|||
|
stq s5, CxIntS5 + FbFiberContext(a1) //
|
|||
|
stq fp, CxIntFp + FbFiberContext(a1) //
|
|||
|
|
|||
|
//
|
|||
|
// Save nonvolatile float state.
|
|||
|
//
|
|||
|
|
|||
|
stt f2, CxFltF2 + FbFiberContext(a1) //
|
|||
|
stt f3, CxFltF3 + FbFiberContext(a1) //
|
|||
|
stt f4, CxFltF4 + FbFiberContext(a1) //
|
|||
|
stt f5, CxFltF5 + FbFiberContext(a1) //
|
|||
|
stt f6, CxFltF6 + FbFiberContext(a1) //
|
|||
|
stt f7, CxFltF7 + FbFiberContext(a1) //
|
|||
|
stt f8, CxFltF8 + FbFiberContext(a1) //
|
|||
|
stt f9, CxFltF9 + FbFiberContext(a1) //
|
|||
|
|
|||
|
//
|
|||
|
// Save RA and SP.
|
|||
|
//
|
|||
|
|
|||
|
stq ra, CxFir + FbFiberContext(a1) //
|
|||
|
stq sp, CxIntSp + FbFiberContext(a1) //
|
|||
|
|
|||
|
//
|
|||
|
// Restore new fiber's stack base and stack limit.
|
|||
|
//
|
|||
|
|
|||
|
LDP t0, FbStackBase(a0) // restore StackBase
|
|||
|
STP t0, TeStackBase(v0) //
|
|||
|
LDP t1, FbStackLimit(a0) // restore StackLimit
|
|||
|
STP t1, TeStackLimit(v0) //
|
|||
|
|
|||
|
//
|
|||
|
// Restore nonvolatile integer state.
|
|||
|
//
|
|||
|
|
|||
|
ldq s0, CxIntS0 + FbFiberContext(a0) //
|
|||
|
ldq s1, CxIntS1 + FbFiberContext(a0) //
|
|||
|
ldq s2, CxIntS2 + FbFiberContext(a0) //
|
|||
|
ldq s3, CxIntS3 + FbFiberContext(a0) //
|
|||
|
ldq s4, CxIntS4 + FbFiberContext(a0) //
|
|||
|
ldq s5, CxIntS5 + FbFiberContext(a0) //
|
|||
|
ldq fp, CxIntFp + FbFiberContext(a0) //
|
|||
|
|
|||
|
//
|
|||
|
// Restore nonvolatile float state
|
|||
|
//
|
|||
|
ldt f2, CxFltF2 + FbFiberContext(a0) //
|
|||
|
ldt f3, CxFltF3 + FbFiberContext(a0) //
|
|||
|
ldt f4, CxFltF4 + FbFiberContext(a0) //
|
|||
|
ldt f5, CxFltF5 + FbFiberContext(a0) //
|
|||
|
ldt f6, CxFltF6 + FbFiberContext(a0) //
|
|||
|
ldt f7, CxFltF7 + FbFiberContext(a0) //
|
|||
|
ldt f8, CxFltF8 + FbFiberContext(a0) //
|
|||
|
ldt f9, CxFltF9 + FbFiberContext(a0) //
|
|||
|
|
|||
|
//
|
|||
|
// Swap x86 exception list pointer, wx86tib.
|
|||
|
//
|
|||
|
|
|||
|
ldl t1, 0(v0) // save current exception list
|
|||
|
stl t1, FbExceptionList(a1) //
|
|||
|
LDP t0, TeVdm(v0) // save current emulator TIB address
|
|||
|
STP t0, FbWx86Tib(a1) //
|
|||
|
ldl t0, FbExceptionList(a0) // set next exception list
|
|||
|
stl t0, 0(v0) //
|
|||
|
LDP t0, FbWx86Tib(a0) // set next emulator TIB address
|
|||
|
STP t0, TeVdm(v0) //
|
|||
|
|
|||
|
//
|
|||
|
// Restore RA and SP.
|
|||
|
//
|
|||
|
|
|||
|
ldq ra, CxFir + FbFiberContext(a0) //
|
|||
|
ldq sp, CxIntSp + FbFiberContext(a0) //
|
|||
|
ret zero, (ra)
|
|||
|
|
|||
|
.end BasepSwitchToFiber
|
|||
|
|