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

thredini.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_PROCESS(E)
#define ASSERT_THREAD(E)

Functions

VOID KeContextToKframesSpecial (IN PKTHREAD Thread, IN OUT PKTRAP_FRAME TrapFrame, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN PCONTEXT ContextFrame, IN ULONG ContextFlags)
VOID KiInitializeContextThread (IN PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL, IN PCONTEXT ContextRecord OPTIONAL)
BOOLEAN KeSetAutoAlignmentProcess (IN PRKPROCESS Process, IN BOOLEAN Enable)
BOOLEAN KeSetAutoAlignmentThread (IN PKTHREAD Thread, IN BOOLEAN Enable)


Define Documentation

#define ASSERT_PROCESS  ) 
 

Value:

{ \ ASSERT((E)->Header.Type == ProcessObject); \ }

Definition at line 44 of file ia64/thredini.c.

#define ASSERT_THREAD  ) 
 

Value:

{ \ ASSERT((E)->Header.Type == ThreadObject); \ }

Definition at line 48 of file ia64/thredini.c.


Function Documentation

VOID KeContextToKframesSpecial IN PKTHREAD  Thread,
IN OUT PKTRAP_FRAME  TrapFrame,
IN OUT PKEXCEPTION_FRAME  ExceptionFrame,
IN PCONTEXT  ContextFrame,
IN ULONG  ContextFlags
 

Definition at line 766 of file ke/ia64/context.c.

References CONTEXT_CONTROL, CONTEXT_INTEGER, DbgPrint, EXTRACT_NATS, KeGetCurrentThread, KiSetDebugContext(), SHORT, UserMode, and USHORT.

Referenced by KiInitializeContextThread().

00776 : 00777 00778 This routine moves the selected contents of the specified context frame into 00779 the specified trap and exception frames according to the specified context 00780 flags. 00781 00782 Arguments: 00783 00784 TrapFrame - Supplies a pointer to a trap frame that receives the volatile 00785 context from the context record. 00786 00787 ExceptionFrame - Supplies a pointer to an exception frame that receives 00788 the nonvolatile context from the context record. 00789 00790 ContextFrame - Supplies a pointer to a context frame that contains the 00791 context that is to be copied into the trap and exception frames. 00792 00793 ContextFlags - Supplies the set of flags that specify which parts of the 00794 context frame are to be copied into the trap and exception frames. 00795 00796 PreviousMode - Supplies the processor mode for which the trap and exception 00797 frames are being built. 00798 00799 Return Value: 00800 00801 None. 00802 00803 --*/ 00804 00805 { 00806 USHORT R1Offset, R4Offset; 00807 USHORT RNatSaveIndex; 00808 SHORT BsFrameSize; 00809 SHORT TempFrameSize; 00810 00811 // 00812 // Set control information if specified. 00813 // 00814 00815 if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00816 00817 TrapFrame->IntGp = ContextFrame->IntGp; 00818 TrapFrame->IntSp = ContextFrame->IntSp; 00819 TrapFrame->ApUNAT = ContextFrame->ApUNAT; 00820 TrapFrame->BrRp = ContextFrame->BrRp; 00821 TrapFrame->ApCCV = ContextFrame->ApCCV; 00822 TrapFrame->ApDCR = SANITIZE_DCR(ContextFrame->ApDCR, UserMode); 00823 00824 // 00825 // Set preserved applicaton registers in exception frame. 00826 // 00827 00828 ExceptionFrame->ApLC = ContextFrame->ApLC; 00829 ExceptionFrame->ApEC &= ~(PFS_EC_MASK << PFS_EC_MASK); 00830 ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT); 00831 00832 // 00833 // Set RSE control states in the trap frame. 00834 // 00835 00836 TrapFrame->RsPFS = ContextFrame->RsPFS; 00837 00838 BsFrameSize = (SHORT)(ContextFrame->StIFS & PFS_SIZE_MASK); 00839 RNatSaveIndex = (USHORT)((ContextFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG); 00840 00841 TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG; 00842 while (TempFrameSize >= 0) { 00843 BsFrameSize++; 00844 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 00845 } 00846 00847 TrapFrame->RsBSPSTORE = ContextFrame->RsBSPSTORE + BsFrameSize * 8; 00848 TrapFrame->RsBSP = TrapFrame->RsBSPSTORE; 00849 TrapFrame->RsRSC = ContextFrame->RsRSC; 00850 TrapFrame->RsRNAT = ContextFrame->RsRNAT; 00851 00852 #if DEBUG 00853 DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT); 00854 #endif // DEBUG 00855 00856 // 00857 // Set FPSR, IPSR, IIP, and IFS in the trap frame. 00858 // 00859 00860 TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode); 00861 TrapFrame->StIPSR = SANITIZE_PSR(ContextFrame->StIPSR, UserMode); 00862 if (((TrapFrame->StIPSR >> PSR_RI) & 3) == 3) { 00863 TrapFrame->StIPSR &= ~(3i64 << PSR_RI); 00864 } 00865 TrapFrame->StIFS = SANITIZE_IFS(ContextFrame->StIFS, UserMode); 00866 TrapFrame->StIIP = ContextFrame->StIIP; 00867 00868 // 00869 // DebugActive controls h/w debug registers. Set if new psr.db = 1 00870 // 00871 00872 KeGetCurrentThread()->DebugActive = ((TrapFrame->StIPSR & (1I64 << PSR_DB)) != 0); 00873 00874 // 00875 // Set application registers directly 00876 // 00877 00878 if (Thread == KeGetCurrentThread()) { 00879 __setReg(CV_IA64_AR21, ContextFrame->StFCR); 00880 __setReg(CV_IA64_AR24, ContextFrame->Eflag); 00881 __setReg(CV_IA64_AR25, ContextFrame->SegCSD); 00882 __setReg(CV_IA64_AR26, ContextFrame->SegSSD); 00883 __setReg(CV_IA64_AR27, ContextFrame->Cflag); 00884 __setReg(CV_IA64_AR28, ContextFrame->StFSR); 00885 __setReg(CV_IA64_AR29, ContextFrame->StFIR); 00886 __setReg(CV_IA64_AR30, ContextFrame->StFDR); 00887 } else { 00888 PKAPPLICATION_REGISTERS AppRegs; 00889 00890 AppRegs = GET_APPLICATION_REGISTER_SAVEAREA(Thread->StackBase); 00891 AppRegs->Ar21 = ContextFrame->StFCR; 00892 AppRegs->Ar24 = ContextFrame->Eflag; 00893 AppRegs->Ar25 = ContextFrame->SegCSD; 00894 AppRegs->Ar26 = ContextFrame->SegSSD; 00895 AppRegs->Ar27 = ContextFrame->Cflag; 00896 AppRegs->Ar28 = ContextFrame->StFSR; 00897 AppRegs->Ar29 = ContextFrame->StFIR; 00898 AppRegs->Ar30 = ContextFrame->StFDR; 00899 } 00900 } 00901 00902 // 00903 // Set integer registers contents if specified. 00904 // 00905 00906 if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00907 00908 TrapFrame->IntT0 = ContextFrame->IntT0; 00909 TrapFrame->IntT1 = ContextFrame->IntT1; 00910 TrapFrame->IntT2 = ContextFrame->IntT2; 00911 TrapFrame->IntT3 = ContextFrame->IntT3; 00912 TrapFrame->IntT4 = ContextFrame->IntT4; 00913 TrapFrame->IntV0 = ContextFrame->IntV0; 00914 TrapFrame->IntTeb = ContextFrame->IntTeb; 00915 TrapFrame->Preds = ContextFrame->Preds; 00916 00917 // 00918 // t5 - t22 00919 // 00920 00921 memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG)); 00922 00923 // 00924 // Set integer registers s0 - s3 in exception frame. 00925 // 00926 00927 ExceptionFrame->IntS0 = ContextFrame->IntS0; 00928 ExceptionFrame->IntS1 = ContextFrame->IntS1; 00929 ExceptionFrame->IntS2 = ContextFrame->IntS2; 00930 ExceptionFrame->IntS3 = ContextFrame->IntS3; 00931 00932 // 00933 // Set the integer nats field in the trap & exception frames 00934 // 00935 00936 R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f; 00937 R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f; 00938 00939 EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats, 00940 1, R1Offset, 0xFFFFFF0E); 00941 EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats, 00942 4, R4Offset, 0xF0); 00943 00944 #if DEBUG 00945 DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n", 00946 TrapFrame->IntNats, ContextFrame->IntNats, R1Offset); 00947 DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n", 00948 ExceptionFrame->IntNats, R4Offset); 00949 #endif // DEBUG 00950 00951 // 00952 // Set other branch registers in trap and exception frames 00953 // 00954 00955 TrapFrame->BrT0 = ContextFrame->BrT0; 00956 TrapFrame->BrT1 = ContextFrame->BrT1; 00957 00958 memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG)); 00959 00960 } 00961 00962 // 00963 // Set lower floating register contents if specified. 00964 // 00965 00966 if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) { 00967 00968 TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode); 00969 00970 // 00971 // Set floating registers fs0 - fs19 in exception frame. 00972 // 00973 00974 RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0, 00975 &ContextFrame->FltS0, 00976 sizeof(FLOAT128) * (4)); 00977 00978 RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4, 00979 &ContextFrame->FltS4, 00980 16*sizeof(FLOAT128)); 00981 00982 // 00983 // Set floating registers ft0 - ft9 in trap frame. 00984 // 00985 00986 RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0, 00987 &ContextFrame->FltT0, 00988 sizeof(FLOAT128) * (10)); 00989 00990 } 00991 00992 // 00993 // Set higher floating register contents if specified. 00994 // 00995 00996 if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) { 00997 00998 TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode); 00999 01000 // 01001 // Update the higher floating point save area (f32-f127) and 01002 // set the corresponding modified bit in the PSR to 1. 01003 // 01004 01005 RtlCopyIa64FloatRegisterContext( 01006 (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(), 01007 &ContextFrame->FltF32, 01008 96*sizeof(FLOAT128) 01009 ); 01010 01011 TrapFrame->StIPSR |= (1i64 << PSR_DFH); 01012 01013 } 01014 01015 // 01016 // Set debug registers. 01017 // 01018 01019 if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) { 01020 KiSetDebugContext (TrapFrame, ContextFrame, UserMode); 01021 } 01022 01023 return; 01024 } }

BOOLEAN KeSetAutoAlignmentProcess IN PRKPROCESS  Process,
IN BOOLEAN  Enable
 

Definition at line 224 of file ia64/thredini.c.

References ASSERT_PROCESS, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

00231 : 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 }

BOOLEAN KeSetAutoAlignmentThread IN PKTHREAD  Thread,
IN BOOLEAN  Enable
 

Definition at line 285 of file ia64/thredini.c.

References ASSERT_THREAD, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

00292 : 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 } }

VOID KiInitializeContextThread IN PKTHREAD  Thread,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE StartRoutine  OPTIONAL,
IN PVOID StartContext  OPTIONAL,
IN PCONTEXT ContextRecord  OPTIONAL
 

Definition at line 55 of file ia64/thredini.c.

References CONTEXT_CONTROL, KeContextToKframesSpecial(), KernelMode, KiThreadStartup(), and UserMode.

00065 : 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 }


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