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

psctxi64.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1998 Intel Corporation 00004 Copyright (c) 1990 Microsoft Corporation 00005 00006 Module Name: 00007 00008 psctxi64.c 00009 00010 Abstract: 00011 00012 This module implements function to get and set the context of a thread. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 1-Oct-1990 00017 00018 Revision History: 00019 00020 --*/ 00021 #include "psp.h" 00022 #include <ia64.h> 00023 00024 00025 #define ALIGN_NATS(Result, Source, Start, AddressOffset, Mask) \ 00026 if (AddressOffset == Start) { \ 00027 Result = (ULONGLONG)Source; \ 00028 } else if (AddressOffset < Start) { \ 00029 Result = (ULONGLONG)(Source << (Start - AddressOffset)); \ 00030 } else { \ 00031 Result = (ULONGLONG)((Source >> (AddressOffset - Start)) | \ 00032 (Source << (64 + Start - AddressOffset))); \ 00033 } \ 00034 Result = Result & (ULONGLONG)Mask 00035 00036 #define EXTRACT_NATS(Result, Source, Start, AddressOffset, Mask) \ 00037 Result = (ULONGLONG)(Source & (ULONGLONG)Mask); \ 00038 if (AddressOffset < Start) { \ 00039 Result = Result >> (Start - AddressOffset); \ 00040 } else if (AddressOffset > Start) { \ 00041 Result = ((Result << (AddressOffset - Start)) | \ 00042 (Result >> (64 + Start - AddressOffset))); \ 00043 } 00044 00045 00046 VOID 00047 KiGetDebugContext ( 00048 IN PKTRAP_FRAME TrapFrame, 00049 IN OUT PCONTEXT ContextFrame 00050 ); 00051 00052 VOID 00053 KiSetDebugContext ( 00054 IN OUT PKTRAP_FRAME TrapFrame, 00055 IN PCONTEXT ContextFrame, 00056 IN KPROCESSOR_MODE ProcessorMode 00057 ); 00058 00059 VOID 00060 KiFlushUserRseState ( 00061 IN PKTRAP_FRAME TrapFrame 00062 ); 00063 00064 VOID 00065 PspGetContext ( 00066 IN PKTRAP_FRAME TrapFrame, 00067 IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, 00068 IN OUT PCONTEXT ContextEM 00069 ) 00070 00071 /*++ 00072 00073 Routine Description: 00074 00075 This function selectively moves the contents of the specified trap frame 00076 and nonvolatile context to the specified context record. 00077 00078 Arguments: 00079 00080 TrapFrame - Supplies a pointer to a trap frame. 00081 00082 ContextPointers - Supplies the address of context pointers record. 00083 00084 ContextEM - Supplies the address of a context record. 00085 00086 Return Value: 00087 00088 None. 00089 00090 N.B. The side effect of this routine is that the dirty user stacked 00091 registers that were flushed into the kernel backing store are 00092 copied backed into the user backing store and the trap frame 00093 will be modified as a result of that. 00094 00095 --*/ 00096 00097 { 00098 00099 ULONGLONG IntNats1, IntNats2 = 0; 00100 USHORT R1Offset, R4Offset; 00101 SHORT Temp, BsFrameSize; 00102 00103 if ((ContextEM->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00104 00105 ContextEM->IntGp = TrapFrame->IntGp; 00106 ContextEM->IntSp = TrapFrame->IntSp; 00107 ContextEM->ApUNAT = TrapFrame->ApUNAT; 00108 ContextEM->BrRp = TrapFrame->BrRp; 00109 ContextEM->ApCCV = TrapFrame->ApCCV; 00110 ContextEM->ApDCR = TrapFrame->ApDCR; 00111 00112 ContextEM->StFPSR = TrapFrame->StFPSR; 00113 ContextEM->StIPSR = TrapFrame->StIPSR; 00114 ContextEM->StIIP = TrapFrame->StIIP; 00115 ContextEM->StIFS = TrapFrame->StIFS; 00116 00117 // 00118 // Get RSE control states from the trap frame. 00119 // 00120 00121 ContextEM->RsPFS = TrapFrame->RsPFS; 00122 ContextEM->RsRSC = TrapFrame->RsRSC; 00123 ContextEM->RsRNAT = TrapFrame->RsRNAT; 00124 00125 if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) { 00126 BsFrameSize = (SHORT) (TrapFrame->StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK; 00127 } else { 00128 BsFrameSize = (SHORT) TrapFrame->StIFS & PFS_SIZE_MASK; 00129 } 00130 Temp = BsFrameSize - (SHORT)((TrapFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG); 00131 while (Temp > 0) { 00132 BsFrameSize++; 00133 Temp -= NAT_BITS_PER_RNAT_REG; 00134 } 00135 00136 ContextEM->RsBSP = TrapFrame->RsBSP - (BsFrameSize * 8); 00137 ContextEM->RsBSPSTORE = ContextEM->RsBSP; 00138 00139 // 00140 // Get preserved applicaton registers 00141 // 00142 00143 ContextEM->ApLC = *ContextPointers->ApLC; 00144 ContextEM->ApEC = (*ContextPointers->ApEC >> PFS_EC_SHIFT) & PFS_EC_MASK; 00145 00146 // 00147 // Get iA status 00148 // 00149 00150 ContextEM->StFSR = *ContextPointers->StFSR; 00151 ContextEM->StFIR = *ContextPointers->StFIR; 00152 ContextEM->StFDR = *ContextPointers->StFDR; 00153 ContextEM->Cflag = *ContextPointers->Cflag; 00154 00155 } 00156 00157 if ((ContextEM->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00158 00159 ContextEM->IntT0 = TrapFrame->IntT0; 00160 ContextEM->IntT1 = TrapFrame->IntT1; 00161 ContextEM->IntT2 = TrapFrame->IntT2; 00162 ContextEM->IntT3 = TrapFrame->IntT3; 00163 ContextEM->IntT4 = TrapFrame->IntT4; 00164 ContextEM->IntV0 = TrapFrame->IntV0; 00165 ContextEM->IntTeb = TrapFrame->IntTeb; 00166 ContextEM->Preds = TrapFrame->Preds; 00167 00168 // 00169 // t5 - t22 00170 // 00171 00172 memcpy(&ContextEM->IntT5, &TrapFrame->IntT5, 18*sizeof(ULONGLONG)); 00173 00174 00175 // 00176 // Get branch registers 00177 // 00178 00179 ContextEM->BrT0 = TrapFrame->BrT0; 00180 ContextEM->BrT1 = TrapFrame->BrT1; 00181 00182 ContextEM->BrS0 = *ContextPointers->BrS0; 00183 ContextEM->BrS1 = *ContextPointers->BrS1; 00184 ContextEM->BrS2 = *ContextPointers->BrS2; 00185 ContextEM->BrS3 = *ContextPointers->BrS3; 00186 ContextEM->BrS4 = *ContextPointers->BrS4; 00187 00188 // 00189 // Get integer registers s0 - s3 from exception frame. 00190 // 00191 00192 ContextEM->IntS0 = *ContextPointers->IntS0; 00193 ContextEM->IntS1 = *ContextPointers->IntS1; 00194 ContextEM->IntS2 = *ContextPointers->IntS2; 00195 ContextEM->IntS3 = *ContextPointers->IntS3; 00196 IntNats2 |= (((*ContextPointers->IntS0Nat >> (((ULONG_PTR)ContextPointers->IntS0 & 0x1F8) >> 3)) & 0x1) << 4); 00197 IntNats2 |= (((*ContextPointers->IntS1Nat >> (((ULONG_PTR)ContextPointers->IntS1 & 0x1F8) >> 3)) & 0x1) << 5); 00198 IntNats2 |= (((*ContextPointers->IntS2Nat >> (((ULONG_PTR)ContextPointers->IntS2 & 0x1F8) >> 3)) & 0x1) << 6); 00199 IntNats2 |= (((*ContextPointers->IntS3Nat >> (((ULONG_PTR)ContextPointers->IntS3 & 0x1F8) >> 3)) & 0x1) << 7); 00200 00201 // 00202 // Get the integer nats field in the context 00203 // *ContextPointers->IntNats has Nats for preserved regs 00204 // 00205 00206 R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f; 00207 R4Offset = (USHORT)((ULONG_PTR)(ContextPointers->IntS0) >> 3) & 0x3f; 00208 ALIGN_NATS(IntNats1, TrapFrame->IntNats, 1, R1Offset, 0xFFFFFF0E); 00209 00210 ContextEM->IntNats = IntNats1 | IntNats2; 00211 00212 #ifdef DEBUG 00213 DbgPrint("PspGetContext INTEGER: R1Offset = 0x%x, TF->IntNats = 0x%I64x, IntNats1 = 0x%I64x\n", 00214 R1Offset, TrapFrame->IntNats, IntNats1); 00215 #endif 00216 00217 } 00218 00219 if ((ContextEM->ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) { 00220 00221 // 00222 // Get EM + ia32 FP status 00223 // 00224 00225 ContextEM->StFPSR = TrapFrame->StFPSR; 00226 ContextEM->StFSR = *ContextPointers->StFSR; 00227 ContextEM->StFIR = *ContextPointers->StFIR; 00228 ContextEM->StFDR = *ContextPointers->StFDR; 00229 00230 // 00231 // Get floating registers fs0 - fs19 00232 // 00233 00234 ContextEM->FltS0 = *ContextPointers->FltS0; 00235 ContextEM->FltS1 = *ContextPointers->FltS1; 00236 ContextEM->FltS2 = *ContextPointers->FltS2; 00237 ContextEM->FltS3 = *ContextPointers->FltS3; 00238 00239 ContextEM->FltS4 = *ContextPointers->FltS4; 00240 ContextEM->FltS5 = *ContextPointers->FltS5; 00241 ContextEM->FltS6 = *ContextPointers->FltS6; 00242 ContextEM->FltS7 = *ContextPointers->FltS7; 00243 00244 ContextEM->FltS8 = *ContextPointers->FltS8; 00245 ContextEM->FltS9 = *ContextPointers->FltS9; 00246 ContextEM->FltS10 = *ContextPointers->FltS10; 00247 ContextEM->FltS11 = *ContextPointers->FltS11; 00248 00249 ContextEM->FltS12 = *ContextPointers->FltS12; 00250 ContextEM->FltS13 = *ContextPointers->FltS13; 00251 ContextEM->FltS14 = *ContextPointers->FltS14; 00252 ContextEM->FltS15 = *ContextPointers->FltS15; 00253 00254 ContextEM->FltS16 = *ContextPointers->FltS16; 00255 ContextEM->FltS17 = *ContextPointers->FltS17; 00256 ContextEM->FltS18 = *ContextPointers->FltS18; 00257 ContextEM->FltS19 = *ContextPointers->FltS19; 00258 00259 // 00260 // Get floating registers ft0 - ft9 from trap frame. 00261 // 00262 00263 RtlCopyIa64FloatRegisterContext(&ContextEM->FltT0, 00264 &TrapFrame->FltT0, 00265 sizeof(FLOAT128) * (10)); 00266 } 00267 00268 if ((ContextEM->ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) { 00269 00270 // 00271 // Get EM + ia32 FP status 00272 // 00273 00274 ContextEM->StFPSR = TrapFrame->StFPSR; 00275 ContextEM->StFSR = *ContextPointers->StFSR; 00276 ContextEM->StFIR = *ContextPointers->StFIR; 00277 ContextEM->StFDR = *ContextPointers->StFDR; 00278 00279 // 00280 // Get floating regs f32 - f127 from higher floating point save area 00281 // 00282 00283 if (TrapFrame->PreviousMode == UserMode) { 00284 RtlCopyIa64FloatRegisterContext( 00285 &ContextEM->FltF32, 00286 (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(), 00287 96*sizeof(FLOAT128) 00288 ); 00289 } 00290 } 00291 00292 // 00293 // Get h/w debug register context 00294 // 00295 00296 if ((ContextEM->ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) { 00297 KiGetDebugContext(TrapFrame, ContextEM); 00298 } 00299 00300 return; 00301 } 00302 00303 VOID 00304 PspSetContext ( 00305 IN OUT PKTRAP_FRAME TrapFrame, 00306 IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, 00307 IN PCONTEXT ContextEM, 00308 IN KPROCESSOR_MODE ProcessorMode 00309 ) 00310 00311 /*++ 00312 00313 Routine Description: 00314 00315 This function selectively moves the contents of the specified context 00316 record to the specified trap frame and nonvolatile context. 00317 00318 We're expecting a plabel to have been passed in the IIP (we won't have a valid 00319 Global pointer) and if we have a plabel we fill in the correct Global pointer and 00320 IIP. Technically, the GP is part of the CONTEXT_CONTROL with the EM architecture 00321 so we only need to check to see if CONTEXT_CONTROL has been specified. 00322 00323 Arguments: 00324 00325 TrapFrame - Supplies the address of the trap frame. 00326 00327 ContextPointers - Supplies the address of context pointers record. 00328 00329 ContextEM - Supplies the address of a context record. 00330 00331 ProcessorMode - Supplies the processor mode to use when sanitizing 00332 the PSR and FSR. 00333 00334 Return Value: 00335 00336 None. 00337 00338 --*/ 00339 00340 { 00341 SHORT BsFrameSize; 00342 SHORT TempFrameSize; 00343 USHORT R1Offset, R4Offset; 00344 USHORT RNatSaveIndex; 00345 00346 if ((ContextEM->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { 00347 00348 if (ContextEM->IntGp == 0) { 00349 try { 00350 00351 // 00352 // Make sure we have read access to the plabel 00353 // 00354 00355 ProbeForRead(ContextEM->StIIP, 00356 sizeof(PLABEL_DESCRIPTOR), 00357 sizeof(ULONGLONG)); 00358 ContextEM->IntGp = ((PPLABEL_DESCRIPTOR)(ContextEM->StIIP))->GlobalPointer; 00359 ContextEM->StIIP = ((PPLABEL_DESCRIPTOR)(ContextEM->StIIP))->EntryPoint; 00360 00361 } except(EXCEPTION_EXECUTE_HANDLER) { 00362 00363 // 00364 // Remote thread does not have access to the plabel. Just 00365 // let the thread take the exception. 00366 // 00367 00368 ; 00369 } 00370 } 00371 00372 TrapFrame->IntGp = ContextEM->IntGp; 00373 TrapFrame->IntSp = ContextEM->IntSp; 00374 TrapFrame->ApUNAT = ContextEM->ApUNAT; 00375 TrapFrame->BrRp = ContextEM->BrRp; 00376 TrapFrame->ApCCV = ContextEM->ApCCV; 00377 TrapFrame->ApDCR = SANITIZE_DCR(ContextEM->ApDCR, ProcessorMode); 00378 00379 // 00380 // Set preserved applicaton registers. 00381 // 00382 00383 *ContextPointers->ApLC = ContextEM->ApLC; 00384 *ContextPointers->ApEC &= ~(PFS_EC_MASK << PFS_EC_SHIFT); 00385 *ContextPointers->ApEC |= ((ContextEM->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT); 00386 00387 TrapFrame->StFPSR = SANITIZE_FSR(ContextEM->StFPSR, ProcessorMode); 00388 TrapFrame->StIIP = ContextEM->StIIP; 00389 TrapFrame->StIFS = SANITIZE_IFS(ContextEM->StIFS, ProcessorMode); 00390 TrapFrame->StIPSR = SANITIZE_PSR(ContextEM->StIPSR, ProcessorMode); 00391 00392 if (((TrapFrame->StIPSR >> PSR_RI) & 3) == 3) { 00393 00394 // 00395 // 3 is an invalid slot number; sanitize it to zero 00396 // 00397 00398 TrapFrame->StIPSR &= ~(3i64 << PSR_RI); 00399 } 00400 00401 TrapFrame->RsPFS = ContextEM->RsPFS; 00402 00403 if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) { 00404 if (TrapFrame->StIPSR & (1i64 << PSR_SS)) { 00405 00406 // 00407 // if the psr.ss bit is set when the target thread is in a 00408 // system call, the psr.lp bit has to be set in order for 00409 // the target thread to pick up its setting when it returns 00410 // from the system call. i.e. psr.ss is not saved and 00411 // and restored by the EPC system call handler. 00412 // 00413 00414 TrapFrame->StIPSR |= (1i64 << PSR_LP); 00415 } 00416 00417 // 00418 // in the case of EPC system call, the frame size that needs to be 00419 // adjusted is the local frame size, not the total framze size. 00420 // 00421 00422 BsFrameSize = (SHORT) (ContextEM->StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK; 00423 } else { 00424 BsFrameSize = (SHORT) ContextEM->StIFS & PFS_SIZE_MASK; 00425 } 00426 RNatSaveIndex = (USHORT)((ContextEM->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG); 00427 00428 TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG; 00429 while (TempFrameSize >= 0) { 00430 BsFrameSize++; 00431 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 00432 } 00433 00434 TrapFrame->RsBSPSTORE = ContextEM->RsBSPSTORE + BsFrameSize * 8; 00435 TrapFrame->RsBSP = TrapFrame->RsBSPSTORE; 00436 TrapFrame->RsRSC = ContextEM->RsRSC; 00437 TrapFrame->RsRNAT = ContextEM->RsRNAT; 00438 00439 #ifdef DEBUG 00440 DbgPrint ("PspSetContext CONTROL: TrapFrame->RsRNAT = 0x%I64x\n", 00441 TrapFrame->RsRNAT); 00442 #endif 00443 00444 // 00445 // DebugActive controls h/w debug registers. Set if new psr.db = 1 00446 // 00447 00448 KeGetCurrentThread()->DebugActive = ((TrapFrame->StIPSR & (1I64 << PSR_DB)) != 0); 00449 00450 // 00451 // Set iA status 00452 // *** TBD SANATIZE?? 00453 // 00454 00455 *ContextPointers->StFSR = ContextEM->StFSR; 00456 *ContextPointers->StFIR = ContextEM->StFIR; 00457 *ContextPointers->StFDR = ContextEM->StFDR; 00458 *ContextPointers->Cflag = ContextEM->Cflag; 00459 00460 } 00461 00462 if ((ContextEM->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { 00463 00464 TrapFrame->IntT0 = ContextEM->IntT0; 00465 TrapFrame->IntT1 = ContextEM->IntT1; 00466 TrapFrame->IntT2 = ContextEM->IntT2; 00467 TrapFrame->IntT3 = ContextEM->IntT3; 00468 TrapFrame->IntT4 = ContextEM->IntT4; 00469 TrapFrame->IntV0 = ContextEM->IntV0; 00470 TrapFrame->IntTeb = ContextEM->IntTeb; 00471 TrapFrame->Preds = ContextEM->Preds; 00472 00473 // 00474 // t5 - t2 00475 // 00476 00477 RtlCopyMemory(&TrapFrame->IntT5, &ContextEM->IntT5, 18*sizeof(ULONGLONG)); 00478 00479 // 00480 // Set the integer nats fields 00481 // 00482 00483 R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f; 00484 00485 EXTRACT_NATS(TrapFrame->IntNats, ContextEM->IntNats, 00486 1, R1Offset, 0xFFFFFF0E); 00487 00488 // 00489 // Set the preserved integer NAT fields 00490 // 00491 00492 R4Offset = (USHORT)((ULONG_PTR)(ContextPointers->IntS0) >> 3) & 0x3f; 00493 00494 // 00495 // BUGBUG: TBD 00496 // 00497 // EXTRACT_NATS(*ContextPointers->IntNats, ContextEM->IntNats, 00498 // 4, R4Offset, 0xF0); 00499 00500 *ContextPointers->IntS0 = ContextEM->IntS0; 00501 *ContextPointers->IntS1 = ContextEM->IntS1; 00502 *ContextPointers->IntS2 = ContextEM->IntS2; 00503 *ContextPointers->IntS3 = ContextEM->IntS3; 00504 00505 *ContextPointers->IntS0Nat &= ~(0x1 << (((ULONG_PTR)ContextPointers->IntS0 & 0x1F8) >> 3)); 00506 *ContextPointers->IntS1Nat &= ~(0x1 << (((ULONG_PTR)ContextPointers->IntS1 & 0x1F8) >> 3)); 00507 *ContextPointers->IntS2Nat &= ~(0x1 << (((ULONG_PTR)ContextPointers->IntS2 & 0x1F8) >> 3)); 00508 *ContextPointers->IntS3Nat &= ~(0x1 << (((ULONG_PTR)ContextPointers->IntS3 & 0x1F8) >> 3)); 00509 00510 *ContextPointers->IntS0Nat |= (((ContextEM->IntNats >> 4) & 0x1) << (((ULONG_PTR)ContextPointers->IntS0 & 0x1F8) >> 3)); 00511 *ContextPointers->IntS1Nat |= (((ContextEM->IntNats >> 4) & 0x1) << (((ULONG_PTR)ContextPointers->IntS1 & 0x1F8) >> 3)); 00512 *ContextPointers->IntS2Nat |= (((ContextEM->IntNats >> 4) & 0x1) << (((ULONG_PTR)ContextPointers->IntS2 & 0x1F8) >> 3)); 00513 *ContextPointers->IntS3Nat |= (((ContextEM->IntNats >> 4) & 0x1) << (((ULONG_PTR)ContextPointers->IntS3 & 0x1F8) >> 3)); 00514 00515 #ifdef DEBUG 00516 DbgPrint("PspSetContext INTEGER: R1Offset = 0x%x, TF->IntNats = 0x%I64x, Context->IntNats = 0x%I64x\n", 00517 R1Offset, TrapFrame->IntNats, ContextEM->IntNats); 00518 #endif 00519 00520 *ContextPointers->BrS0 = ContextEM->BrS0; 00521 *ContextPointers->BrS1 = ContextEM->BrS1; 00522 *ContextPointers->BrS2 = ContextEM->BrS2; 00523 *ContextPointers->BrS3 = ContextEM->BrS3; 00524 *ContextPointers->BrS4 = ContextEM->BrS4; 00525 TrapFrame->BrT0 = ContextEM->BrT0; 00526 TrapFrame->BrT1 = ContextEM->BrT1; 00527 } 00528 00529 if ((ContextEM->ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) { 00530 00531 TrapFrame->StFPSR = SANITIZE_FSR(ContextEM->StFPSR, ProcessorMode); 00532 *ContextPointers->StFSR = ContextEM->StFSR; 00533 *ContextPointers->StFIR = ContextEM->StFIR; 00534 *ContextPointers->StFDR = ContextEM->StFDR; 00535 00536 // 00537 // Set floating registers fs0 - fs19. 00538 // 00539 00540 *ContextPointers->FltS0 = ContextEM->FltS0; 00541 *ContextPointers->FltS1 = ContextEM->FltS1; 00542 *ContextPointers->FltS2 = ContextEM->FltS2; 00543 *ContextPointers->FltS3 = ContextEM->FltS3; 00544 00545 *ContextPointers->FltS4 = ContextEM->FltS4; 00546 *ContextPointers->FltS5 = ContextEM->FltS5; 00547 *ContextPointers->FltS6 = ContextEM->FltS6; 00548 *ContextPointers->FltS7 = ContextEM->FltS7; 00549 00550 *ContextPointers->FltS8 = ContextEM->FltS8; 00551 *ContextPointers->FltS9 = ContextEM->FltS9; 00552 *ContextPointers->FltS10 = ContextEM->FltS10; 00553 *ContextPointers->FltS11 = ContextEM->FltS11; 00554 00555 *ContextPointers->FltS12 = ContextEM->FltS12; 00556 *ContextPointers->FltS13 = ContextEM->FltS13; 00557 *ContextPointers->FltS14 = ContextEM->FltS14; 00558 *ContextPointers->FltS15 = ContextEM->FltS15; 00559 00560 *ContextPointers->FltS16 = ContextEM->FltS16; 00561 *ContextPointers->FltS17 = ContextEM->FltS17; 00562 *ContextPointers->FltS18 = ContextEM->FltS18; 00563 *ContextPointers->FltS19 = ContextEM->FltS19; 00564 00565 // 00566 // Set floating registers ft0 - ft9. 00567 // 00568 00569 RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0, 00570 &ContextEM->FltT0, 00571 sizeof(FLOAT128) * (10)); 00572 } 00573 00574 if ((ContextEM->ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) { 00575 00576 00577 TrapFrame->StFPSR = SANITIZE_FSR(ContextEM->StFPSR, ProcessorMode); 00578 *ContextPointers->StFSR = ContextEM->StFSR; 00579 *ContextPointers->StFIR = ContextEM->StFIR; 00580 *ContextPointers->StFDR = ContextEM->StFDR; 00581 00582 if (ProcessorMode == UserMode) { 00583 00584 // 00585 // Update the higher floating point save area (f32-f127) and 00586 // set the corresponding modified bit in the PSR to 1. 00587 // 00588 00589 RtlCopyIa64FloatRegisterContext( 00590 (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(), 00591 &ContextEM->FltF32, 00592 96*sizeof(FLOAT128)); 00593 00594 // 00595 // set the dfh bit to force a reload of the high fp register 00596 // set on the next user access 00597 // 00598 00599 TrapFrame->StIPSR |= (1i64 << PSR_DFH); 00600 } 00601 00602 } 00603 00604 // 00605 // Set debug register contents if specified. 00606 // 00607 00608 if ((ContextEM->ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) { 00609 KiSetDebugContext (TrapFrame, ContextEM, ProcessorMode); 00610 } 00611 00612 return; 00613 } 00614 00615 VOID 00616 PspGetSetContextSpecialApcMain ( 00617 IN PKAPC Apc, 00618 IN PKNORMAL_ROUTINE *NormalRoutine, 00619 IN PVOID *NormalContext, 00620 IN PVOID *SystemArgument1, 00621 IN PVOID *SystemArgument2 00622 ) 00623 00624 /*++ 00625 00626 Routine Description: 00627 00628 This function either captures the user mode state of the current 00629 thread, or sets the user mode state of the current thread. The 00630 operation type is determined by the value of SystemArgument1. A 00631 zero value is used for get context, and a nonzero value is used 00632 for set context. 00633 00634 Arguments: 00635 00636 Apc - Supplies a pointer to the APC control object that caused entry 00637 into this routine. 00638 00639 NormalRoutine - Supplies a pointer to the normal routine function that 00640 was specified when the APC was initialized. This parameter is not 00641 used. 00642 00643 NormalContext - Supplies a pointer to an arbitrary data structure that 00644 was specified when the APC was initialized. This parameter is not 00645 used. 00646 00647 SystemArgument1, SystemArgument2 - Supplies a set of two pointers to two 00648 arguments that contain untyped data. 00649 The first arguement is used to distinguish between get and set requests. 00650 A value of zero signifies that GetThreadContext was requested. 00651 A non-zero value signifies that SetThreadContext was requested. 00652 The Second arguement has the thread handle. The second arguement is 00653 not used. 00654 00655 Return Value: 00656 00657 None. 00658 00659 --*/ 00660 00661 { 00662 PGETSETCONTEXT ContextInfo; 00663 KNONVOLATILE_CONTEXT_POINTERS ContextPointers; // Not currently used, needed later. 00664 CONTEXT ContextRecord; 00665 ULONGLONG ControlPc; 00666 FRAME_POINTERS EstablisherFrame; 00667 PRUNTIME_FUNCTION FunctionEntry; 00668 BOOLEAN InFunction; 00669 PETHREAD Thread; 00670 PKTRAP_FRAME TrFrame1; 00671 ULONGLONG ImageBase; 00672 ULONGLONG TargetGp; 00673 00674 // 00675 // Get the address of the context frame and compute the address of the 00676 // system entry trap frame. 00677 // 00678 00679 ContextInfo = CONTAINING_RECORD(Apc, GETSETCONTEXT, Apc); 00680 00681 TrFrame1 = (PKTRAP_FRAME)(((ULONG_PTR)PsGetCurrentThread()->Tcb.InitialStack 00682 - KTHREAD_STATE_SAVEAREA_LENGTH - KTRAP_FRAME_LENGTH)); 00683 00684 // 00685 // Capture the current thread context and set the initial control PC 00686 // value. 00687 // 00688 00689 RtlCaptureContext(&ContextRecord); 00690 ControlPc = ContextRecord.BrRp; 00691 00692 // 00693 // Initialize context pointers for the nonvolatile integer and floating 00694 // registers. 00695 // 00696 00697 ContextPointers.FltS0 = &ContextRecord.FltS0; 00698 ContextPointers.FltS1 = &ContextRecord.FltS1; 00699 ContextPointers.FltS2 = &ContextRecord.FltS2; 00700 ContextPointers.FltS3 = &ContextRecord.FltS3; 00701 ContextPointers.FltS4 = &ContextRecord.FltS4; 00702 ContextPointers.FltS5 = &ContextRecord.FltS5; 00703 ContextPointers.FltS6 = &ContextRecord.FltS6; 00704 ContextPointers.FltS7 = &ContextRecord.FltS7; 00705 ContextPointers.FltS8 = &ContextRecord.FltS8; 00706 ContextPointers.FltS9 = &ContextRecord.FltS9; 00707 ContextPointers.FltS10 = &ContextRecord.FltS10; 00708 ContextPointers.FltS11 = &ContextRecord.FltS11; 00709 ContextPointers.FltS12 = &ContextRecord.FltS12; 00710 ContextPointers.FltS13 = &ContextRecord.FltS13; 00711 ContextPointers.FltS14 = &ContextRecord.FltS14; 00712 ContextPointers.FltS15 = &ContextRecord.FltS15; 00713 ContextPointers.FltS16 = &ContextRecord.FltS16; 00714 ContextPointers.FltS17 = &ContextRecord.FltS17; 00715 ContextPointers.FltS18 = &ContextRecord.FltS18; 00716 ContextPointers.FltS19 = &ContextRecord.FltS19; 00717 00718 ContextPointers.IntS0 = &ContextRecord.IntS0; 00719 ContextPointers.IntS1 = &ContextRecord.IntS1; 00720 ContextPointers.IntS2 = &ContextRecord.IntS2; 00721 ContextPointers.IntS3 = &ContextRecord.IntS3; 00722 ContextPointers.IntSp = &ContextRecord.IntSp; 00723 00724 ContextPointers.BrS0 = &ContextRecord.BrS0; 00725 ContextPointers.BrS1 = &ContextRecord.BrS1; 00726 ContextPointers.BrS2 = &ContextRecord.BrS2; 00727 ContextPointers.BrS3 = &ContextRecord.BrS3; 00728 ContextPointers.BrS4 = &ContextRecord.BrS4; 00729 00730 ContextPointers.ApLC = &ContextRecord.ApLC; 00731 ContextPointers.ApEC = &ContextRecord.ApEC; 00732 00733 ContextPointers.StFSR = &ContextRecord.StFSR; 00734 ContextPointers.StFIR = &ContextRecord.StFIR; 00735 ContextPointers.StFDR = &ContextRecord.StFDR; 00736 ContextPointers.Cflag = &ContextRecord.Cflag; 00737 00738 // 00739 // Start with the frame specified by the context record and virtually 00740 // unwind call frames until the system entry trap frame is encountered. 00741 // 00742 00743 do { 00744 00745 // 00746 // Lookup the function table entry using the point at which control 00747 // left the procedure. 00748 // 00749 00750 FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, &TargetGp); 00751 00752 // 00753 // If there is a function table entry for the routine, then virtually 00754 // unwind to the caller of the current routine to obtain the address 00755 // where control left the caller. 00756 // 00757 00758 if (FunctionEntry != NULL) { 00759 ControlPc = RtlVirtualUnwind(ImageBase, 00760 ControlPc, 00761 FunctionEntry, 00762 &ContextRecord, 00763 &InFunction, 00764 &EstablisherFrame, 00765 &ContextPointers); 00766 00767 } else { 00768 SHORT BsFrameSize, TempFrameSize; 00769 00770 ControlPc = ContextRecord.BrRp; 00771 ContextRecord.StIFS = ContextRecord.RsPFS; 00772 BsFrameSize = (SHORT)(ContextRecord.StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK; 00773 TempFrameSize = BsFrameSize - (SHORT)((ContextRecord.RsBSP >> 3) & NAT_BITS_PER_RNAT_REG); 00774 while (TempFrameSize > 0) { 00775 BsFrameSize++; 00776 TempFrameSize -= NAT_BITS_PER_RNAT_REG; 00777 } 00778 ContextRecord.RsBSP -= BsFrameSize * sizeof(ULONGLONG); 00779 } 00780 00781 } while ((PVOID)ContextRecord.IntSp != TrFrame1); 00782 00783 // 00784 // Process GetThreadContext or SetThreadContext as specified. 00785 // 00786 00787 if (*SystemArgument1 != 0) { 00788 00789 // 00790 // Set Context from proper Context mode 00791 // 00792 00793 PspSetContext(TrFrame1, &ContextPointers, &ContextInfo->Context, 00794 ContextInfo->Mode); 00795 00796 } else { 00797 00798 // 00799 // Get Context from proper Context mode 00800 // 00801 00802 KiFlushUserRseState(TrFrame1); 00803 PspGetContext(TrFrame1, &ContextPointers, &ContextInfo->Context); 00804 00805 } 00806 00807 KeSetEvent(&ContextInfo->OperationComplete, 0, FALSE); 00808 return; 00809 }

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