test: getsetrg.c Source File

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 }