windows-nt/Source/XPSP1/NT/base/win32/client/ia64/context.c
2020-09-26 16:20:57 +08:00

171 lines
3.4 KiB
C

/*++
Module Name:
context.c
Abstract:
This module contains the context management routines for
Win32
Author:
Revision History:
--*/
#include "basedll.h"
#include "kxia64.h"
VOID
BaseInitializeContext(
OUT PCONTEXT Context,
IN PVOID Parameter OPTIONAL,
IN PVOID InitialPc OPTIONAL,
IN PVOID InitialSp OPTIONAL,
IN BASE_CONTEXT_TYPE ContextType
)
/*++
Routine Description:
This function initializes a context structure so that it can
be used in a subsequent call to NtCreateThread.
Arguments:
Context - Supplies a context buffer to be initialized by this routine.
Parameter - Supplies the thread's parameter.
InitialPc - Supplies an initial program counter value.
InitialSp - Supplies an initial stack pointer value.
NewThread - Supplies a flag that specifies that this is a new
thread, or a new process.
Return Value:
Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly
aligned.
Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly
aligned.
--*/
{
ULONG ArgumentsCount;
//
// Initialize the Context
//
RtlZeroMemory((PVOID)Context, sizeof(CONTEXT));
Context->StFPSR = USER_FPSR_INITIAL;
Context->StIPSR = USER_PSR_INITIAL;
Context->RsBSP = Context->IntSp = (ULONG_PTR)InitialSp;
Context->IntSp -= STACK_SCRATCH_AREA; // scratch area as per convention
Context->IntS1 = (ULONG_PTR)InitialPc;
Context->IntS2 = (ULONG_PTR)Parameter;
//
// Enable RSE engine
//
Context->RsRSC = (RSC_MODE_EA<<RSC_MODE)
| (RSC_BE_LITTLE<<RSC_BE)
| (0x3<<RSC_PL);
if ( ContextType == BaseContextTypeThread ) {
Context->IntS0 = Context->StIIP = (ULONG_PTR)BaseThreadStartThunk;
}
else if ( ContextType == BaseContextTypeFiber ) {
Context->IntS0 = Context->StIIP = (ULONG_PTR)BaseFiberStart;
//
// set up the return pointer here..
// when SwitchToFiber restores context and calls return,
// the contorl goes to this routine
//
Context->BrRp = *((ULONGLONG *)((PUCHAR)BaseFiberStart));
//
// set up sof = 96 in pfs. This will be used to set up CFM for above
// routine
//
Context->RsPFS = 0x60;
}
else {
Context->IntS0 = Context->StIIP = (ULONG_PTR)(LONG_PTR)BaseProcessStartThunk;
}
Context->RsPFS |= MASK_IA64(PFS_PPL, 3i64);
Context->ContextFlags = CONTEXT_CONTROL| CONTEXT_INTEGER;
Context->Eflag = 0x3000i64;
}
VOID
BaseFiberStart(
VOID
)
/*++
Routine Description:
This function is called to start a Win32 fiber. Its purpose
is to call BaseThreadStart, getting the necessary arguments
from the fiber context record.
Arguments:
None.
Return Value:
None.
--*/
{
PFIBER Fiber;
Fiber = GetCurrentFiber();
BaseThreadStart( (LPTHREAD_START_ROUTINE)Fiber->FiberContext.IntS1,
(LPVOID)Fiber->FiberContext.IntS2 );
}
VOID
BaseProcessStartupIA64(
IN PTHREAD_START_ROUTINE StartRoutine,
IN PVOID ThreadParameter
)
/*++
Routine Description:
This function calls to the portable thread starter after moving
its arguments from registers to the argument registers.
Arguments:
StartRoutine - User Target start program counter
ThreadParameter
Return Value:
Never Returns
--*/
{
(StartRoutine)(ThreadParameter);
}