00055 :
00056
00057 This function initializes
the machine dependent context of a thread object.
00058
00059 Actually, what
it does
is to lay
out the stack
for the thread so that
00060
it contains a stack frame that will be picked up by SwapContext and
00061 returned thru, resulting in a transfer of
control to
KiThreadStartup.
00062 In otherwords, we lay
out a stack with a stack frame that looks as
if
00063 SwapContext had been called just before
the first instruction in
00064
KiThreadStartup.
00065
00066 N.B. This function does not check
the accessibility of
the context record.
00067 It
is assumed
the the caller of
this routine
is either prepared to
00068 handle access violations or has probed and copied
the context record
00069 as appropriate.
00070
00071 N.B. Arguments to
the new thread are passed in
the Swap Frame gprs
00072 16 thru 20 which will be loaded into
the thread's gprs when
00073 execution begins.
00074
00075
WARNING: If
the thread has a user mode context
the Top of stack MUST
00076 be laid
out identically to
the top of stack laid
out when an
00077 interrupt or system call from user mode occurs.
00078
00079 Arguments:
00080
00081 Thread - Supplies a pointer to a dispatcher object of
type thread.
00082
00083 SystemRoutine - Supplies a pointer to
the system function that
is to be
00084 called when
the thread
is first scheduled
for execution.
00085
00086 StartRoutine - Supplies an optional pointer to a function that
is to be
00087 called after
the system has finished initializing
the thread. This
00088 parameter
is specified
if the thread
is a system thread and will
00089 execute totally in kernel mode.
00090
00091 StartContext - Supplies an optional pointer to an arbitrary data structure
00092 which will be passed to
the StartRoutine as a parameter. This
00093 parameter
is specified
if the thread
is a system thread and will
00094 execute totally in kernel mode.
00095
00096 ContextRecord - Supplies an optional pointer a context frame which contains
00097
the initial user mode state of
the thread. This parameter
is specified
00098
if the thread
is a user thread and will execute in user mode. If
this
00099 parameter
is not specified, then
the Teb parameter
is ignored.
00100
00101 Return Value:
00102
00103 None.
00104
00105 --*/
00106
00107 {
00108
00109 PKEXCEPTION_FRAME ExFrame;
00110 ULONG InitialStack;
00111 PKTRAP_FRAME TrFrame;
00112 PKSWAP_FRAME SwFrame;
00113 PSTACK_FRAME_HEADER StkFrame, ResumeFrame;
00114
00115
00116
00117
00118
00119
00120
00121 InitialStack = (LONG)Thread->InitialStack;
00122
00123
00124
00125
00126
00127
00128
if (ARGUMENT_PRESENT(ContextRecord)) {
00129 ExFrame = (PKEXCEPTION_FRAME)(InitialStack - 8 -
00130
sizeof(KEXCEPTION_FRAME));
00131 TrFrame = (PKTRAP_FRAME)((ULONG)ExFrame -
sizeof(KTRAP_FRAME));
00132 StkFrame = (PSTACK_FRAME_HEADER)((ULONG)TrFrame - (8 *
sizeof(ULONG)) -
00133
sizeof(STACK_FRAME_HEADER));
00134
00135
00136
00137
00138
00139
00140 RtlZeroMemory((PVOID)ExFrame,
sizeof(KEXCEPTION_FRAME));
00141 RtlZeroMemory((PVOID)TrFrame,
sizeof(KTRAP_FRAME));
00142
KeContextToKframes(TrFrame, ExFrame,
00143 ContextRecord,
00144 ContextRecord->ContextFlags | CONTEXT_CONTROL,
00145 UserMode);
00146
00147
00148
00149
00150
00151
00152 TrFrame->PreviousMode =
UserMode;
00153 Thread->PreviousMode =
UserMode;
00154
00155 }
else {
00156
00157 StkFrame = (PSTACK_FRAME_HEADER)((InitialStack -
00158
sizeof(STACK_FRAME_HEADER)) & 0xfffffff0);
00159 ExFrame =
NULL;
00160 TrFrame =
NULL;
00161
00162
00163
00164
00165
00166 Thread->PreviousMode =
KernelMode;
00167 }
00168
00169 StkFrame->BackChain = (ULONG)0;
00170
00171
00172
00173
00174
00175
00176 SwFrame = (PKSWAP_FRAME)(((ULONG)StkFrame -
00177
sizeof(KSWAP_FRAME)) & 0xfffffff0);
00178
00179
00180
00181
00182
00183
if (ExFrame ==
NULL) {
00184 SwFrame->ExceptionFrame.Gpr20 = (ULONG)ExFrame;
00185 }
else {
00186 SwFrame->ExceptionFrame.Gpr20 = (ULONG)TrFrame;
00187 }
00188
00189 SwFrame->ExceptionFrame.Gpr16 = (ULONG)ContextRecord;
00190 SwFrame->ExceptionFrame.Gpr17 = (ULONG)StartContext;
00191 SwFrame->ExceptionFrame.Gpr18 = (ULONG)StartRoutine;
00192
00193
00194
00195
00196
00197
00198 SwFrame->ExceptionFrame.Gpr19 = *(ULONG *)SystemRoutine;
00199
00200 SwFrame->SwapReturn = *(ULONG *)
KiThreadStartup;
00201 SwFrame->ConditionRegister = 0;
00202
00203
00204
00205
00206
00207
00208
00209 ResumeFrame = ((PSTACK_FRAME_HEADER)SwFrame) - 1;
00210
00211 ResumeFrame->BackChain = (ULONG)StkFrame;
00212
00213
00214
00215
00216
00217 Thread->KernelStack = (PVOID)ResumeFrame;
00218
ASSERT(!((ULONG)ResumeFrame & 0x7));
00219
return;
00220 }