xbox-kernel/private/ntos/ke/i386/thredini.c
2020-09-30 17:17:25 +02:00

150 lines
3.6 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
thredini.c
Abstract:
This module implements the machine dependent function to set the initial
context and data alignment handling mode for a process or thread object.
Author:
David N. Cutler (davec) 31-Mar-1990
Environment:
Kernel mode only.
Revision History:
3 April 90 bryan willman
This version ported to 386.
--*/
#include "ki.h"
VOID
KiInitializeContextThread (
IN PKTHREAD Thread,
IN SIZE_T TlsDataSize,
IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine OPTIONAL,
IN PVOID StartContext OPTIONAL
)
/*++
Routine Description:
This function initializes the machine dependent context of a thread object.
Arguments:
Thread - Supplies a pointer to a dispatcher object of type thread.
TlsDataSize - Supplies the number of bytes reserved from the kernel stack
for thread local storage.
SystemRoutine - Supplies a pointer to the system function that is to be
called when the thread is first scheduled for execution.
StartRoutine - Supplies an optional pointer to a function that is to be
called after the system has finished initializing the thread. This
parameter is specified if the thread is a system thread and will
execute totally in kernel mode.
StartContext - Supplies an optional pointer to an arbitrary data structure
which will be passed to the StartRoutine as a parameter. This
parameter is specified if the thread is a system thread and will
execute totally in kernel mode.
Return Value:
None.
--*/
{
PFX_SAVE_AREA NpxFrame;
PVOID TlsData;
PKSWITCHFRAME SwitchFrame;
PULONG PSystemRoutine;
PULONG PStartRoutine;
PULONG PStartContext;
//
// Load up an initial NPX state.
//
NpxFrame = (PFX_SAVE_AREA)(((ULONG)(Thread->StackBase) -
sizeof(FX_SAVE_AREA)));
RtlZeroMemory((PVOID)NpxFrame, sizeof(FX_SAVE_AREA));
NpxFrame->FloatSave.ControlWord = 0x27f; //like fpinit but 64bit mode
NpxFrame->FloatSave.MXCsr = 0x1f80; // mask all the exceptions
//
// Thread's NPX state is not in the coprocessor.
//
Thread->NpxState = NPX_STATE_NOT_LOADED;
//
// Zero the thread local storage area.
//
TlsDataSize = ALIGN_UP(TlsDataSize, ULONG);
TlsData = ((PUCHAR)(ULONG)NpxFrame) - TlsDataSize;
if (TlsDataSize != 0) {
Thread->TlsData = TlsData;
RtlZeroMemory(TlsData, TlsDataSize);
} else {
Thread->TlsData = NULL;
}
//
// Space for arguments to KiThreadStartup. Order of fields in the
// switchframe is important, since args are passed on stack through
// KiThreadStartup to PStartRoutine with PStartContext as an argument.
//
PStartContext = (PULONG)((ULONG)TlsData) - 1;
PStartRoutine = PStartContext - 1;
PSystemRoutine = PStartRoutine - 1;
SwitchFrame = (PKSWITCHFRAME)((PUCHAR)PSystemRoutine - sizeof(KSWITCHFRAME));
//
// Set up thread start parameters.
//
*PStartContext = (ULONG)StartContext;
*PStartRoutine = (ULONG)StartRoutine;
*PSystemRoutine = (ULONG)SystemRoutine;
//
// Set up switch frame.
//
SwitchFrame->RetAddr = (ULONG)KiThreadStartup;
SwitchFrame->Eflags = EFLAGS_INTERRUPT_MASK;
SwitchFrame->ExceptionList = (ULONG)(EXCEPTION_CHAIN_END);
//
// Set the initial kernel stack pointer.
//
Thread->KernelStack = (PVOID)SwitchFrame;
return;
}