Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

thredini.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 thredini.c 00008 00009 Abstract: 00010 00011 This module implements the machine dependent functions to set the initial 00012 context and data alignment handling mode for a process or thread object. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 1-Apr-1990 00017 00018 Environment: 00019 00020 Kernel mode only. 00021 00022 Revision History: 00023 00024 3-19-96 Bernard Lint (blint) Conversion to IA64 (from PPC and MIPS versions) 00025 00026 --*/ 00027 00028 #include "ki.h" 00029 00030 VOID 00031 KeContextToKframesSpecial ( 00032 IN PKTHREAD Thread, 00033 IN OUT PKTRAP_FRAME TrapFrame, 00034 IN OUT PKEXCEPTION_FRAME ExceptionFrame, 00035 IN PCONTEXT ContextFrame, 00036 IN ULONG ContextFlags 00037 ); 00038 00039 // 00040 // The following assert macros are used to check that an input object is 00041 // really the proper type. 00042 // 00043 00044 #define ASSERT_PROCESS(E) { \ 00045 ASSERT((E)->Header.Type == ProcessObject); \ 00046 } 00047 00048 #define ASSERT_THREAD(E) { \ 00049 ASSERT((E)->Header.Type == ThreadObject); \ 00050 } 00051 00052 00053 00054 VOID 00055 KiInitializeContextThread ( 00056 IN PKTHREAD Thread, 00057 IN PKSYSTEM_ROUTINE SystemRoutine, 00058 IN PKSTART_ROUTINE StartRoutine OPTIONAL, 00059 IN PVOID StartContext OPTIONAL, 00060 IN PCONTEXT ContextRecord OPTIONAL 00061 ) 00062 00063 /*++ 00064 00065 Routine Description: 00066 00067 This function initializes the machine dependent context of a thread object. 00068 00069 Actually, what it does is to lay out the stack for the thread so that 00070 it contains a stack frame that will be picked up by SwapContext and 00071 returned thru, resulting in a transfer of control to KiThreadStartup. 00072 In otherwords, we lay out a stack with a stack frame that looks as if 00073 SwapContext had been called just before the first instruction in 00074 KiThreadStartup. 00075 00076 N.B. This function does not check the accessibility of the context record. 00077 It is assumed the the caller of this routine is either prepared to 00078 handle access violations or has probed and copied the context record 00079 as appropriate. 00080 00081 N.B. Arguments to the new thread are passed in the Swap Frame preserved registers 00082 s0 - s3 which are restored by Swap Context when thread execution begins. 00083 00084 Arguments: 00085 00086 Thread - Supplies a pointer to a dispatcher object of type thread. 00087 00088 SystemRoutine - Supplies a pointer to the system function that is to be 00089 called when the thread is first scheduled for execution. 00090 00091 N.B. This is the routine entry point, not a function pointer (plabel pointer). 00092 00093 StartRoutine - Supplies an optional pointer to a function that is to be 00094 called after the system has finished initializing the thread. This 00095 parameter is specified if the thread is a system thread and will 00096 execute totally in kernel mode. 00097 00098 N.B. This is the routine function pointer (plabel pointer). 00099 00100 StartContext - Supplies an optional pointer to an arbitrary data structure 00101 which will be passed to the StartRoutine as a parameter. This 00102 parameter is specified if the thread is a system thread and will 00103 execute totally in kernel mode. 00104 00105 ContextRecord - Supplies an optional pointer a context frame which contains 00106 the initial user mode state of the thread. This parameter is specified 00107 if the thread is a user thread and will execute in user mode. If this 00108 parameter is not specified, then the Teb parameter is ignored. 00109 00110 Return Value: 00111 00112 None. 00113 00114 --*/ 00115 00116 { 00117 00118 PKSWITCH_FRAME SwFrame; 00119 PKEXCEPTION_FRAME ExFrame; 00120 ULONG_PTR InitialStack; 00121 PKTRAP_FRAME TrFrame; 00122 00123 // 00124 // Set up the thread backing store pointers from the initial stack pointers. 00125 // 00126 00127 InitialStack = (ULONG_PTR)Thread->InitialStack; 00128 Thread->InitialBStore = (PVOID)InitialStack; 00129 Thread->BStoreLimit = (PVOID)(InitialStack + KERNEL_BSTORE_SIZE); 00130 00131 // 00132 // If a context frame is specified, then initialize a trap frame and 00133 // and an exception frame with the specified user mode context. Also 00134 // allocate the switch frame. 00135 // 00136 00137 if (ARGUMENT_PRESENT(ContextRecord)) { 00138 00139 TrFrame = (PKTRAP_FRAME)((InitialStack) 00140 - KTHREAD_STATE_SAVEAREA_LENGTH 00141 - KTRAP_FRAME_LENGTH); 00142 00143 ExFrame = (PKEXCEPTION_FRAME)(((ULONG_PTR)TrFrame + 00144 STACK_SCRATCH_AREA - 00145 sizeof(KEXCEPTION_FRAME)) & ~((ULONG_PTR)15)); 00146 00147 SwFrame = (PKSWITCH_FRAME)(((ULONG_PTR)ExFrame - 00148 sizeof(KSWITCH_FRAME)) & ~((ULONG_PTR)15)); 00149 00150 KeContextToKframesSpecial(Thread, TrFrame, ExFrame, 00151 ContextRecord, 00152 ContextRecord->ContextFlags | CONTEXT_CONTROL); 00153 00154 // 00155 // Set the saved previous processor mode in the trap frame and the 00156 // previous processor mode in the thread object to user mode. 00157 // 00158 00159 TrFrame->PreviousMode = UserMode; 00160 Thread->PreviousMode = UserMode; 00161 00162 // 00163 // Initialize the FPSR for user mode 00164 // 00165 00166 TrFrame->StFPSR = USER_FPSR_INITIAL; 00167 00168 // 00169 // Initialize the user TEB pointer in the trap frame 00170 // 00171 00172 TrFrame->IntTeb = (ULONGLONG)Thread->Teb; 00173 00174 } else { 00175 00176 SwFrame = (PKSWITCH_FRAME)((InitialStack) - sizeof(KSWITCH_FRAME)); 00177 00178 // 00179 // Set the previous mode in thread object to kernel. 00180 // 00181 00182 Thread->PreviousMode = KernelMode; 00183 } 00184 00185 // 00186 // Initialize context switch frame and set thread start up parameters. 00187 // The Swap return pointer and SystemRoutine are entry points, not function pointers. 00188 // 00189 00190 RtlZeroMemory((PVOID)SwFrame, sizeof(KSWITCH_FRAME)); // init all to 0 00191 00192 SwFrame->SwitchRp = ((PPLABEL_DESCRIPTOR)KiThreadStartup)->EntryPoint; 00193 SwFrame->SwitchExceptionFrame.IntS0 = (ULONGLONG)ContextRecord; 00194 SwFrame->SwitchExceptionFrame.IntS1 = (ULONGLONG)StartContext; 00195 SwFrame->SwitchExceptionFrame.IntS2 = (ULONGLONG)StartRoutine; 00196 SwFrame->SwitchExceptionFrame.IntS3 = 00197 ((PPLABEL_DESCRIPTOR)SystemRoutine)->EntryPoint; 00198 SwFrame->SwitchFPSR = FPSR_FOR_KERNEL; 00199 SwFrame->SwitchBsp = (ULONGLONG)Thread->InitialBStore; 00200 00201 Thread->KernelBStore = Thread->InitialBStore; 00202 Thread->KernelStack = (PVOID)((ULONG_PTR)SwFrame-STACK_SCRATCH_AREA); 00203 00204 if (Thread->Teb) { 00205 PKAPPLICATION_REGISTERS AppRegs; 00206 00207 AppRegs = GET_APPLICATION_REGISTER_SAVEAREA(Thread->StackBase); 00208 00209 AppRegs->Ar21 = 0; // ContextRecord->StFCR; 00210 AppRegs->Ar24 = SANITIZE_FLAGS((ULONG) ContextRecord->Eflag, UserMode); 00211 AppRegs->Ar25 = USER_CODE_DESCRIPTOR; 00212 AppRegs->Ar26 = USER_DATA_DESCRIPTOR; 00213 AppRegs->Ar27 = (ULONGLONG)((CR4_VME << 32) | CR0_PE | CFLG_II); 00214 AppRegs->Ar28 = ContextRecord->StFSR; 00215 AppRegs->Ar29 = ContextRecord->StFIR; 00216 AppRegs->Ar30 = ContextRecord->StFDR; 00217 00218 } 00219 00220 return; 00221 } 00222 00223 BOOLEAN 00224 KeSetAutoAlignmentProcess ( 00225 IN PRKPROCESS Process, 00226 IN BOOLEAN Enable 00227 ) 00228 00229 /*++ 00230 00231 Routine Description: 00232 00233 This function sets the data alignment handling mode for the specified 00234 process and returns the previous data alignment handling mode. 00235 00236 Arguments: 00237 00238 Process - Supplies a pointer to a dispatcher object of type process. 00239 00240 Enable - Supplies a boolean value that determines the handling of data 00241 alignment exceptions for the process. A value of TRUE causes all 00242 data alignment exceptions to be automatically handled by the kernel. 00243 A value of FALSE causes all data alignment exceptions to be actually 00244 raised as exceptions. 00245 00246 Return Value: 00247 00248 A value of TRUE is returned if data alignment exceptions were 00249 previously automatically handled by the kernel. Otherwise, a value 00250 of FALSE is returned. 00251 00252 --*/ 00253 00254 { 00255 00256 KIRQL OldIrql; 00257 BOOLEAN Previous; 00258 00259 ASSERT_PROCESS(Process); 00260 00261 // 00262 // Raise IRQL to dispatcher level and lock dispatcher database. 00263 // 00264 00265 KiLockDispatcherDatabase(&OldIrql); 00266 00267 // 00268 // Capture the previous data alignment handling mode and set the 00269 // specified data alignment mode. 00270 // 00271 00272 Previous = Process->AutoAlignment; 00273 Process->AutoAlignment = Enable; 00274 00275 // 00276 // Unlock dispatcher database, lower IRQL to its previous value, and 00277 // return the previous data alignment mode. 00278 // 00279 00280 KiUnlockDispatcherDatabase(OldIrql); 00281 return Previous; 00282 } 00283 00284 BOOLEAN 00285 KeSetAutoAlignmentThread ( 00286 IN PKTHREAD Thread, 00287 IN BOOLEAN Enable 00288 ) 00289 00290 /*++ 00291 00292 Routine Description: 00293 00294 This function sets the data alignment handling mode for the specified 00295 thread and returns the previous data alignment handling mode. 00296 00297 Arguments: 00298 00299 Thread - Supplies a pointer to a dispatcher object of type thread. 00300 00301 Enable - Supplies a boolean value that determines the handling of data 00302 alignment exceptions for the thread. A value of TRUE causes all 00303 data alignment exceptions to be automatically handled by the kernel. 00304 A value of FALSE causes all data alignment exceptions to be actually 00305 raised as exceptions. 00306 00307 Return Value: 00308 00309 A value of TRUE is returned if data alignment exceptions were 00310 previously automatically handled by the kernel. Otherwise, a value 00311 of FALSE is returned. 00312 00313 --*/ 00314 00315 { 00316 00317 KIRQL OldIrql; 00318 BOOLEAN Previous; 00319 00320 ASSERT_THREAD(Thread); 00321 00322 // 00323 // Raise IRQL to dispatcher level and lock dispatcher database. 00324 // 00325 00326 KiLockDispatcherDatabase(&OldIrql); 00327 00328 // 00329 // Capture the previous data alignment handling mode and set the 00330 // specified data alignment mode. 00331 // 00332 00333 Previous = Thread->AutoAlignment; 00334 Thread->AutoAlignment = Enable; 00335 00336 // 00337 // Unlock dispatcher database, lower IRQL to its previous value, and 00338 // return the previous data alignment mode. 00339 // 00340 00341 KiUnlockDispatcherDatabase(OldIrql); 00342 return Previous; 00343 }

Generated on Sat May 15 19:41:58 2004 for test by doxygen 1.3.7