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

getsetrg.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 getsetrg.c 00008 00009 Abstract: 00010 00011 This module implement the code necessary to get and set register values. 00012 These routines are used during the emulation of unaligned data references 00013 and floating point exceptions. 00014 00015 Author: 00016 00017 David N. Cutler (davec) 17-Jun-1991 00018 00019 Environment: 00020 00021 Kernel mode only. 00022 00023 Revision History: 00024 00025 --*/ 00026 00027 #include "ki.h" 00028 #include "ntfpia64.h" 00029 00030 00031 00032 ULONGLONG 00033 KiGetRegisterValue ( 00034 IN ULONG Register, 00035 IN PKEXCEPTION_FRAME ExceptionFrame, 00036 IN PKTRAP_FRAME TrapFrame 00037 ) 00038 00039 /*++ 00040 00041 Routine Description: 00042 00043 This function is called to get the value of a register from the specified 00044 exception or trap frame. 00045 00046 Arguments: 00047 00048 Register - Supplies the number of the register whose value is to be 00049 returned. Integer registers are specified as 0 - 31 and floating 00050 registers are specified as 32 - 63. 00051 00052 ExceptionFrame - Supplies a pointer to an exception frame. 00053 00054 TrapFrame - Supplies a pointer to a trap frame. 00055 00056 Return Value: 00057 00058 The value of the specified register is returned as the function value. 00059 00060 --*/ 00061 00062 { 00063 // 00064 // Dispatch on the register number. 00065 // 00066 00067 if (Register == 0) { 00068 return 0; 00069 } else if (Register <= 3) { 00070 Register -= 1; 00071 return ( *(&TrapFrame->IntGp + Register) ); 00072 } else if (Register <= 7) { 00073 Register -= 4; 00074 return ( *(&ExceptionFrame->IntS0 + Register) ); 00075 } else if (Register <= 31) { 00076 Register -= 8; 00077 return ( *(&TrapFrame->IntV0 + Register) ); 00078 } 00079 00080 // 00081 // Register is the stacked register 00082 // 00083 // (R32 - R127) 00084 // 00085 00086 { 00087 PULONGLONG UserBStore, KernelBStore; 00088 ULONG RegisterOffset; 00089 ULONG i; 00090 ULONG SizeOfCurrentFrame; 00091 ULONG SizeOfDirty; 00092 LONG NumberOfDirty; 00093 00094 SizeOfDirty = (ULONG)(TrapFrame->RsBSP - TrapFrame->RsBSPSTORE); 00095 NumberOfDirty = SizeOfDirty >> 3; 00096 SizeOfCurrentFrame = (ULONG)(TrapFrame->StIFS & 0x7F); 00097 00098 if (TrapFrame->PreviousMode == UserMode) { 00099 00100 // 00101 // PreviousMode is user 00102 // 00103 00104 KernelBStore = (PULONGLONG)(PCR->InitialBStore + (TrapFrame->RsBSPSTORE & 0x1F8) + SizeOfDirty); 00105 00106 UserBStore = (ULONGLONG *) TrapFrame->RsBSP; 00107 00108 RegisterOffset = Register - 32; 00109 00110 do { 00111 00112 KernelBStore = KernelBStore - 1; 00113 UserBStore = UserBStore - 1; 00114 NumberOfDirty = NumberOfDirty -1; 00115 00116 SizeOfCurrentFrame = SizeOfCurrentFrame - 1; 00117 00118 if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) { 00119 00120 // 00121 // Adjust UserBsp, by skipping RNAT 00122 // 00123 00124 KernelBStore = KernelBStore -1; 00125 } 00126 00127 if (((ULONG_PTR) UserBStore & 0x1F8) == 0x1F8) { 00128 00129 // 00130 // Adjust UserBsp, by skipping RNAT 00131 // 00132 00133 UserBStore = UserBStore -1; 00134 } 00135 00136 } while (RegisterOffset < SizeOfCurrentFrame); 00137 00138 if (NumberOfDirty >= 0) { 00139 00140 return (*KernelBStore); 00141 00142 } else { 00143 00144 return (*UserBStore); 00145 } 00146 00147 } else { 00148 00149 // 00150 // PreviousMode is kernel 00151 // 00152 00153 KernelBStore = (ULONGLONG *) TrapFrame->RsBSP; 00154 00155 RegisterOffset = Register - 32; 00156 00157 do { 00158 00159 KernelBStore = KernelBStore - 1; 00160 00161 SizeOfCurrentFrame = SizeOfCurrentFrame - 1; 00162 00163 if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) { 00164 00165 // 00166 // Adjust UserBsp, by skipping RNAT 00167 // 00168 00169 KernelBStore = KernelBStore -1; 00170 } 00171 00172 } while (RegisterOffset < SizeOfCurrentFrame); 00173 00174 return (*KernelBStore); 00175 } 00176 } 00177 } 00178 00179 00180 VOID 00181 KiSetRegisterValue ( 00182 IN ULONG Register, 00183 IN ULONGLONG Value, 00184 OUT PKEXCEPTION_FRAME ExceptionFrame, 00185 OUT PKTRAP_FRAME TrapFrame 00186 ) 00187 00188 /*++ 00189 00190 Routine Description: 00191 00192 This function is called to set the value of a register in the specified 00193 exception or trap frame. 00194 00195 Arguments: 00196 00197 Register - Supplies the number of the register whose value is to be 00198 stored. Integer registers are specified as 0 - 31 and floating 00199 registers are specified as 32 - 63. 00200 00201 Value - Supplies the value to be stored in the specified register. 00202 00203 ExceptionFrame - Supplies a pointer to an exception frame. 00204 00205 TrapFrame - Supplies a pointer to a trap frame. 00206 00207 Return Value: 00208 00209 None. 00210 00211 --*/ 00212 00213 { 00214 00215 // 00216 // Dispatch on the register number. 00217 // 00218 00219 if (Register == 0) { 00220 return; 00221 } else if (Register <= 3) { 00222 Register -= 1; 00223 *(&TrapFrame->IntGp + Register) = Value; 00224 return; 00225 } else if (Register <= 7) { 00226 Register -= 4; 00227 *(&ExceptionFrame->IntS0 + Register) = Value; 00228 return; 00229 } else if (Register <= 31) { 00230 Register -= 8; 00231 *(&TrapFrame->IntV0 + Register) = Value; 00232 return; 00233 } 00234 00235 // 00236 // Register is the stacked register 00237 // 00238 // (R32 - R127) 00239 // 00240 00241 { 00242 PULONGLONG UserBStore, KernelBStore; 00243 ULONG RegisterOffset; 00244 ULONG i; 00245 ULONG SizeOfCurrentFrame; 00246 ULONG SizeOfDirty; 00247 LONG NumberOfDirty; 00248 00249 SizeOfDirty = (ULONG)(TrapFrame->RsBSP - TrapFrame->RsBSPSTORE); 00250 NumberOfDirty = SizeOfDirty >> 3; 00251 SizeOfCurrentFrame = (ULONG)(TrapFrame->StIFS & 0x7F); 00252 00253 if (TrapFrame->PreviousMode == UserMode) { 00254 00255 // 00256 // PreviousMode is user 00257 // 00258 00259 KernelBStore = (PULONGLONG)(PCR->InitialBStore + (TrapFrame->RsBSPSTORE & 0x1F8) + SizeOfDirty); 00260 00261 UserBStore = (ULONGLONG *) TrapFrame->RsBSP; 00262 00263 RegisterOffset = Register - 32; 00264 00265 do { 00266 00267 KernelBStore = KernelBStore - 1; 00268 UserBStore = UserBStore - 1; 00269 NumberOfDirty = NumberOfDirty -1; 00270 00271 SizeOfCurrentFrame = SizeOfCurrentFrame - 1; 00272 00273 if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) { 00274 00275 // 00276 // Adjust UserBsp, by skipping RNAT 00277 // 00278 00279 KernelBStore = KernelBStore -1; 00280 } 00281 00282 if (((ULONG_PTR) UserBStore & 0x1F8) == 0x1F8) { 00283 00284 // 00285 // Adjust UserBsp, by skipping RNAT 00286 // 00287 00288 UserBStore = UserBStore -1; 00289 } 00290 00291 } while (RegisterOffset < SizeOfCurrentFrame); 00292 00293 if (NumberOfDirty >= 0) { 00294 00295 *KernelBStore = Value; 00296 00297 } else { 00298 00299 *UserBStore = Value; 00300 } 00301 00302 } else { 00303 00304 // 00305 // PreviousMode is kernel 00306 // 00307 00308 KernelBStore = (ULONGLONG *) TrapFrame->RsBSP; 00309 00310 RegisterOffset = Register - 32; 00311 00312 do { 00313 00314 KernelBStore = KernelBStore - 1; 00315 00316 SizeOfCurrentFrame = SizeOfCurrentFrame - 1; 00317 00318 if (((ULONG_PTR) KernelBStore & 0x1F8) == 0x1F8) { 00319 00320 // 00321 // Adjust UserBsp, by skipping RNAT 00322 // 00323 00324 KernelBStore = KernelBStore -1; 00325 } 00326 00327 } while (RegisterOffset < SizeOfCurrentFrame); 00328 00329 *KernelBStore = Value; 00330 } 00331 } 00332 } 00333 00334 #define GET_NAT_ADDRESS(addr) (((ULONG_PTR) (addr) >> 3) & 0x3F) 00335 00336 #define GET_NAT(Nats, addr) (UCHAR)((Nats >> GET_NAT_ADDRESS(addr)) & 1) 00337 00338 00339 UCHAR 00340 KiGetRegisterNaT ( 00341 IN ULONG Register, 00342 IN PKEXCEPTION_FRAME ExceptionFrame, 00343 IN PKTRAP_FRAME TrapFrame 00344 ) 00345 { 00346 // 00347 // Dispatch on the register number. 00348 // 00349 00350 switch (Register) { 00351 00352 // 00353 // Integer register V0. 00354 // 00355 00356 case 0: 00357 return 0; 00358 00359 // 00360 // Integer Register R1 (GP) 00361 // 00362 00363 case 1: 00364 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntGp)); 00365 00366 // 00367 // Integer Register R2 (T0) 00368 // 00369 00370 case 2: 00371 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT0)); 00372 00373 // 00374 // Integer Register R3 (T1) 00375 // 00376 00377 case 3: 00378 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT1)); 00379 00380 // 00381 // Integer Register R4 (S0) 00382 // 00383 00384 case 4: 00385 return (GET_NAT(ExceptionFrame->IntNats, &ExceptionFrame->IntS0)); 00386 00387 // 00388 // Integer Register R5 (S1) 00389 // 00390 00391 case 5: 00392 return (GET_NAT(ExceptionFrame->IntNats, &ExceptionFrame->IntS1)); 00393 00394 // 00395 // Integer Register R6 (S2) 00396 // 00397 00398 case 6: 00399 return (GET_NAT(ExceptionFrame->IntNats, &ExceptionFrame->IntS2)); 00400 00401 // 00402 // Integer Register R7 (S3) 00403 // 00404 00405 case 7: 00406 return (GET_NAT(ExceptionFrame->IntNats, &ExceptionFrame->IntS3)); 00407 00408 // 00409 // Integer Register R8 (V0) 00410 // 00411 00412 case 8: 00413 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntV0)); 00414 00415 // 00416 // Integer Register R9 (T2) 00417 // 00418 00419 case 9: 00420 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT2)); 00421 00422 // 00423 // Integer Register R10 (T3) 00424 // 00425 00426 case 10: 00427 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT3)); 00428 00429 // 00430 // Integer Register R11 (T4) 00431 // 00432 00433 case 11: 00434 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT4)); 00435 00436 // 00437 // Integer Register R12 (Sp) 00438 // 00439 00440 case 12: 00441 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntSp)); 00442 00443 // 00444 // Integer Register R13 (Teb) 00445 // 00446 00447 case 13: 00448 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntTeb)); 00449 00450 // 00451 // Integer Register R14 (T5) 00452 // 00453 00454 case 14: 00455 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT5)); 00456 00457 // 00458 // Integer Register R15 (T6) 00459 // 00460 00461 case 15: 00462 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT6)); 00463 00464 // 00465 // Integer Register R16 (T7) 00466 // 00467 00468 case 16: 00469 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT7)); 00470 00471 // 00472 // Integer Register R17 (T8) 00473 // 00474 00475 case 17: 00476 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT8)); 00477 00478 // 00479 // Integer Register R18 (T9) 00480 // 00481 00482 case 18: 00483 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT9)); 00484 00485 // 00486 // Integer Register R19 (T10) 00487 // 00488 00489 case 19: 00490 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT10)); 00491 00492 // 00493 // Integer Register R20 (T11) 00494 // 00495 00496 case 20: 00497 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT11)); 00498 00499 // 00500 // Integer Register R21 (T12) 00501 // 00502 00503 case 21: 00504 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT12)); 00505 00506 // 00507 // Integer Register R22 (T13) 00508 // 00509 00510 case 22: 00511 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT13)); 00512 00513 // 00514 // Integer Register R23 (T14) 00515 // 00516 00517 case 23: 00518 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT14)); 00519 00520 // 00521 // Integer Register R24 (T15) 00522 // 00523 00524 case 24: 00525 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT15)); 00526 00527 // 00528 // Integer Register R25 (T16) 00529 // 00530 00531 case 25: 00532 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT16)); 00533 00534 // 00535 // Integer Register R26 (T17) 00536 // 00537 00538 case 26: 00539 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT17)); 00540 00541 // 00542 // Integer Register R27 (T18) 00543 // 00544 00545 case 27: 00546 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT18)); 00547 00548 // 00549 // Integer Register R28 (T19) 00550 // 00551 00552 case 28: 00553 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT19)); 00554 00555 // 00556 // Integer Register R29 (T20) 00557 // 00558 00559 case 29: 00560 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT20)); 00561 00562 // 00563 // Integer Register R30 (T21) 00564 // 00565 00566 case 30: 00567 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT21)); 00568 00569 // 00570 // Integer Register R31 (T22) 00571 // 00572 00573 case 31: 00574 return (GET_NAT(TrapFrame->IntNats, &TrapFrame->IntT22)); 00575 00576 default: 00577 break; 00578 00579 } 00580 00581 return 0; 00582 } 00583 00584 00585 FLOAT128 00586 KiGetFloatRegisterValue ( 00587 IN ULONG Register, 00588 IN struct _KEXCEPTION_FRAME *ExceptionFrame, 00589 IN struct _KTRAP_FRAME *TrapFrame 00590 ) 00591 00592 { 00593 if (Register == 0) { 00594 FLOAT128 t = {0ULL,0ULL}; 00595 return t; 00596 } else if (Register == 1) { 00597 FLOAT128 t = {0x8000000000000000ULL,0x000000000000FFFFULL}; // low,high 00598 return t; 00599 } else if (Register <= 5) { 00600 Register -= 2; 00601 return ( *(&ExceptionFrame->FltS0 + Register) ); 00602 } else if (Register <= 15) { 00603 Register -= 6; 00604 return ( *(&TrapFrame->FltT0 + Register) ); 00605 } else if (Register <= 31) { 00606 Register -= 16; 00607 return ( *(&ExceptionFrame->FltS4 + Register) ); 00608 } else { 00609 PKHIGHER_FP_VOLATILE HigherVolatile; 00610 00611 HigherVolatile = GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(); 00612 Register -= 32; 00613 return ( *(&HigherVolatile->FltF32 + Register) ); 00614 } 00615 } 00616 00617 00618 VOID 00619 KiSetFloatRegisterValue ( 00620 IN ULONG Register, 00621 IN FLOAT128 Value, 00622 OUT struct _KEXCEPTION_FRAME *ExceptionFrame, 00623 OUT struct _KTRAP_FRAME *TrapFrame 00624 ) 00625 00626 { 00627 if (Register <= 1) { 00628 return; 00629 } else if (Register <= 5) { 00630 Register -= 2; 00631 *(&ExceptionFrame->FltS0 + Register) = Value; 00632 return; 00633 } else if (Register <= 15) { 00634 Register -= 6; 00635 *(&TrapFrame->FltT0 + Register) = Value; 00636 return; 00637 } else if (Register <= 31) { 00638 Register -= 16; 00639 *(&ExceptionFrame->FltS4 + Register) = Value; 00640 return; 00641 } else { 00642 PKHIGHER_FP_VOLATILE HigherVolatile; 00643 00644 HigherVolatile = GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(); 00645 Register -= 32; 00646 *(&HigherVolatile->FltF32 + Register) = Value; 00647 return; 00648 } 00649 } 00650 00651 VOID 00652 __cdecl 00653 KeSaveStateForHibernate( 00654 IN PKPROCESSOR_STATE ProcessorState 00655 ) 00656 /*++ 00657 00658 Routine Description: 00659 00660 Saves all processor-specific state that must be preserved 00661 across an S4 state (hibernation). 00662 00663 Arguments: 00664 00665 ProcessorState - Supplies the KPROCESSOR_STATE where the 00666 current CPU's state is to be saved. 00667 00668 Return Value: 00669 00670 None. 00671 00672 --*/ 00673 00674 { 00675 // 00676 // BUGBUG John Vert (jvert) 4/30/1998 00677 // someone needs to implement this and probably put it in a more 00678 // appropriate file. 00679 00680 } 00681 00682 00683 FLOAT128 00684 get_fp_register ( 00685 IN ULONG Register, 00686 IN PVOID FpState 00687 ) 00688 { 00689 return(KiGetFloatRegisterValue ( 00690 Register, 00691 ((PFLOATING_POINT_STATE)FpState)->ExceptionFrame, 00692 ((PFLOATING_POINT_STATE)FpState)->TrapFrame 00693 )); 00694 } 00695 00696 VOID 00697 set_fp_register ( 00698 IN ULONG Register, 00699 IN FLOAT128 Value, 00700 IN PVOID FpState 00701 ) 00702 { 00703 KiSetFloatRegisterValue ( 00704 Register, 00705 Value, 00706 ((PFLOATING_POINT_STATE)FpState)->ExceptionFrame, 00707 ((PFLOATING_POINT_STATE)FpState)->TrapFrame 00708 ); 00709 }

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