2020-09-30 17:12:29 +02:00

159 lines
3.4 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
context.c
Abstract:
This module contains the context management routines for
Win32
Author:
Mark Lucovsky (markl) 28-Sep-1990
Revision History:
--*/
#include "basedll.h"
#pragma hdrstop
#define _KXPPC_C_HEADER_
#include "kxppc.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:
None.
--*/
{
//
// Initialize the control registers.
// So that the thread begins at BaseThreadStart
//
RtlZeroMemory((PVOID)Context, sizeof(CONTEXT));
//
// Initialize the control registers.
//
Context->Gpr1 = (ULONG)InitialSp - STK_MIN_FRAME;
//
// While we may not NEED to set the ILE bit in the context's
// MSR, it is always safest to do so ...
//
Context->Msr =
MASK_SPR(MSR_ILE,1) |
MASK_SPR(MSR_FP,1) |
MASK_SPR(MSR_FE0,1) |
MASK_SPR(MSR_FE1,1) |
MASK_SPR(MSR_ME,1) |
MASK_SPR(MSR_IR,1) |
MASK_SPR(MSR_DR,1) |
MASK_SPR(MSR_PR,1) |
MASK_SPR(MSR_LE,1);
//
// Set the initial context of the thread in a machine specific way.
//
// For threads, we put in Iar the function descriptor address for
// BaseProcessStart or BaseThreadStart, not the function entry point
// address. This works because LdrInitializeThunk translates the
// descriptor into an entry point address and a TOC pointer before
// allowing the thread to run.
//
// For fibers, we put in Iar the actual entry point address for
// BaseFiberStart. This is because the fiber will first run via
// SwitchToFiber, which needs an entry point, because subsequent
// switches to the fiber only have a return address.
//
// (Note that we don't need to worry about the TOC pointer for
// BaseFiberStart because it's entered from SwitchToFiber, and
// SwitchToFiber and BaseThreadStart use the same TOC.)
//
Context->ContextFlags = CONTEXT_FULL;
Context->Gpr3 = (ULONG)InitialPc;
if ( ContextType == BaseContextTypeProcess ) {
Context->Iar = (ULONG)BaseProcessStart;
} else {
if ( ContextType == BaseContextTypeThread ) {
Context->Iar = (ULONG)BaseThreadStart;
} else {
Context->Iar = *(ULONG *)BaseFiberStart;
}
Context->Gpr4 = (ULONG)Parameter;
}
}
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.Gpr3,
(LPVOID)Fiber->FiberContext.Gpr4 );
}