test: psctxalp.c File Reference

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

# psctxalp.c File Reference

`#include "psp.h"`

Go to the source code of this file.

## Functions

VOID | PspGetContext (IN PKTRAP_FRAME TrapFrame, IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, IN OUT PCONTEXT ContextRecord)
VOID | PspSetContext (IN OUT PKTRAP_FRAME TrapFrame, IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE ProcessorMode)
VOID | PspGetSetContextSpecialApcMain (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)

## Function Documentation

VOID PspGetContext | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKNONVOLATILE_CONTEXT_POINTERS | ContextPointers,
|  | IN OUT PCONTEXT | ContextRecord
| ) |

Definition at line 29 of file psctxalp.c.

    00037                    :
    00038
    00039     This function selectively moves the contents of the specified trap frame
    00040     and nonvolatile context to the specified context record.
    00041
    00042 Arguments:
    00043
    00044     TrapFrame - Supplies a pointer to a trap frame.
    00045
    00046     ContextPointers - Supplies the address of context pointers record.
    00047
    00048     ContextRecord - Supplies the address of a context record.
    00049
    00050 Return Value:
    00051
    00052     None.
    00053
    00054 --*/
    00055
    00056 {
    00057
    00058     //
    00059     // Get control information if specified.
    00060     //
    00061
    00062     if ((ContextRecord->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00063
    00064         //
    00065         // Get integer registers gp, ra, sp, FIR, and PSR from trap frame.
    00066         //
    00067
    00068         ContextRecord->IntGp = TrapFrame->IntGp;
    00069         ContextRecord->IntSp = TrapFrame->IntSp;
    00070         ContextRecord->IntRa = TrapFrame->IntRa;
    00071         ContextRecord->Fir = TrapFrame->Fir;
    00072         ContextRecord->Psr = TrapFrame->Psr;
    00073     }
    00074
    00075     //
    00076     // Get integer register contents if specified.
    00077     //
    00078
    00079     if ((ContextRecord->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00080
    00081         //
    00082         // Get volatile integer registers v0 and t0 - t7 from trap frame.
    00083         //
    00084
    00085         ContextRecord->IntV0 = TrapFrame->IntV0;
    00086         ContextRecord->IntT0 = TrapFrame->IntT0;
    00087         ContextRecord->IntT1 = TrapFrame->IntT1;
    00088         ContextRecord->IntT2 = TrapFrame->IntT2;
    00089         ContextRecord->IntT3 = TrapFrame->IntT3;
    00090         ContextRecord->IntT4 = TrapFrame->IntT4;
    00091         ContextRecord->IntT5 = TrapFrame->IntT5;
    00092         ContextRecord->IntT6 = TrapFrame->IntT6;
    00093         ContextRecord->IntT7 = TrapFrame->IntT7;
    00094
    00095         //
    00096         // Get nonvolatile integer registers s0 - s5 through context pointers.
    00097         //
    00098
    00099         ContextRecord->IntS0 = *ContextPointers->IntS0;
    00100         ContextRecord->IntS1 = *ContextPointers->IntS1;
    00101         ContextRecord->IntS2 = *ContextPointers->IntS2;
    00102         ContextRecord->IntS3 = *ContextPointers->IntS3;
    00103         ContextRecord->IntS4 = *ContextPointers->IntS4;
    00104         ContextRecord->IntS5 = *ContextPointers->IntS5;
    00105
    00106         //
    00107         // Get volatile integer registers fp/s6, a0 - a5, and t8 - t12 from
    00108         // trap frame.
    00109         //
    00110
    00111         ContextRecord->IntFp = TrapFrame->IntFp;
    00112
    00113         ContextRecord->IntA0 = TrapFrame->IntA0;
    00114         ContextRecord->IntA1 = TrapFrame->IntA1;
    00115         ContextRecord->IntA2 = TrapFrame->IntA2;
    00116         ContextRecord->IntA3 = TrapFrame->IntA3;
    00117         ContextRecord->IntA4 = TrapFrame->IntA4;
    00118         ContextRecord->IntA5 = TrapFrame->IntA5;
    00119
    00120         ContextRecord->IntT8 = TrapFrame->IntT8;
    00121         ContextRecord->IntT9 = TrapFrame->IntT9;
    00122         ContextRecord->IntT10 = TrapFrame->IntT10;
    00123         ContextRecord->IntT11 = TrapFrame->IntT11;
    00124         ContextRecord->IntT12 = TrapFrame->IntT12;
    00125
    00126         //
    00127         // Get volatile integer register AT from trap frame.
    00128         // Get integer register zero.
    00129         //
    00130
    00131         ContextRecord->IntAt = TrapFrame->IntAt;
    00132         ContextRecord->IntZero = 0;
    00133     }
    00134
    00135     //
    00136     // Get floating register contents if specified.
    00137     //
    00138
    00139     if ((ContextRecord->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00140
    00141         //
    00142         // Get volatile floating registers f0 - f1 from trap frame.
    00143         //
    00144
    00145         ContextRecord->FltF0 = TrapFrame->FltF0;
    00146         ContextRecord->FltF1 = TrapFrame->FltF1;
    00147
    00148         //
    00149         // Get volatile floating registers f10 - f30 from trap frame.
    00150         // This assumes that f10 - f30 are contiguous in the trap frame.
    00151         //
    00152
    00153         ASSERT((&ContextRecord->FltF30 - &ContextRecord->FltF10) == 20);
    00154         RtlMoveMemory(&ContextRecord->FltF10, &TrapFrame->FltF10,
    00155                       sizeof(ULONGLONG) * 21);
    00156
    00157         ContextRecord->FltF31 = 0;
    00158
    00159         //
    00160         // Get nonvolatile floating registers f2 - f9 through context pointers.
    00161         //
    00162
    00163         ContextRecord->FltF2 = *ContextPointers->FltF2;
    00164         ContextRecord->FltF3 = *ContextPointers->FltF3;
    00165         ContextRecord->FltF4 = *ContextPointers->FltF4;
    00166         ContextRecord->FltF5 = *ContextPointers->FltF5;
    00167         ContextRecord->FltF6 = *ContextPointers->FltF6;
    00168         ContextRecord->FltF7 = *ContextPointers->FltF7;
    00169         ContextRecord->FltF8 = *ContextPointers->FltF8;
    00170         ContextRecord->FltF9 = *ContextPointers->FltF9;
    00171
    00172         //
    00173         // Get floating point control register from trap frame.
    00174         // Get the current software FPCR value from the TEB.
    00175         //
    00176
    00177         ContextRecord->Fpcr = TrapFrame->Fpcr;
    00178         try {
    00179             ContextRecord->SoftFpcr =
    00180                 (ULONGLONG)(NtCurrentTeb()->FpSoftwareStatusRegister);
    00181
    00182         } except (EXCEPTION_EXECUTE_HANDLER) {
    00183             ContextRecord->SoftFpcr = 0;
    00184         }
    00185     }
    00186
    00187     return;
    00188 }

VOID PspGetSetContextSpecialApcMain | ( | IN PKAPC | Apc,
|  | IN PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN PVOID * | NormalContext,
|  | IN PVOID * | SystemArgument1,
|  | IN PVOID * | SystemArgument2
| ) |

Definition at line 349 of file psctxalp.c.

References _GETSETCONTEXT::Context, FALSE, _KTHREAD::InitialStack, KeSetEvent(), _GETSETCONTEXT::Mode, NULL, _GETSETCONTEXT::OperationComplete, PsGetCurrentThread, PspGetContext(), PspSetContext(), RtlLookupFunctionEntry(), RtlVirtualUnwind(), and _ETHREAD::Tcb.

    00359                    :
    00360
    00361     This function either captures the user mode state of the current
    00362     thread, or sets the user mode state of the current thread. The
    00363     operation type is determined by the value of SystemArgument1. A
    00364     zero value is used for get context, and a nonzero value is used
    00365     for set context.
    00366
    00367 Arguments:
    00368
    00369     Apc - Supplies a pointer to the APC control object that caused entry
    00370           into this routine.
    00371
    00372     NormalRoutine - Supplies a pointer to the normal routine function that
    00373         was specified when the APC was initialized. This parameter is not
    00374         used.
    00375
    00376     NormalContext - Supplies a pointer to an arbitrary data structure that
    00377         was specified when the APC was initialized. This parameter is not
    00378         used.
    00379
    00380     SystemArgument1, SystemArgument2 - Supplies a set of two pointer to two
    00381         arguments that contain untyped data. These parameters are not used.
    00382
    00383 Return Value:
    00384
    00385     None.
    00386
    00387 --*/
    00388
    00389 {
    00390
    00391     PGETSETCONTEXT ContextBlock;
    00392     KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
    00393     CONTEXT ContextRecord;
    00394     ULONG_PTR ControlPc;
    00395     FRAME_POINTERS EstablisherFrame;
    00396     PRUNTIME_FUNCTION FunctionEntry;
    00397     BOOLEAN InFunction;
    00398     PETHREAD Thread;
    00399     ULONGLONG TrapFrame1;
    00400     ULONGLONG TrapFrame2;
    00401
    00402     //
    00403     // Get the address of the context block and compute the address of the
    00404     // system entry trap frame.
    00405     //
    00406
    00407     ContextBlock = CONTAINING_RECORD(Apc, GETSETCONTEXT, Apc);
    00408     Thread = PsGetCurrentThread();
    00409     TrapFrame1 = (ULONGLONG)(LONG_PTR)Thread->Tcb.InitialStack - KTRAP_FRAME_LENGTH;
    00410
    00411     //
    00412     // The lower bounds for locating the first system service trap frame on
    00413     // the kernel stack is one trap frame below TrapFrame1.
    00414     //
    00415
    00416     TrapFrame2 = TrapFrame1 - KTRAP_FRAME_LENGTH;
    00417
    00418     //
    00419     // Capture the current thread context and set the initial control PC
    00420     // value.
    00421     //
    00422
    00423     RtlCaptureContext(&ContextRecord);
    00424     ControlPc = (ULONG_PTR)ContextRecord.IntRa;
    00425
    00426     //
    00427     // Initialize context pointers for the nonvolatile integer and floating
    00428     // registers.
    00429     //
    00430
    00431     ContextPointers.IntS0 = &ContextRecord.IntS0;
    00432     ContextPointers.IntS1 = &ContextRecord.IntS1;
    00433     ContextPointers.IntS2 = &ContextRecord.IntS2;
    00434     ContextPointers.IntS3 = &ContextRecord.IntS3;
    00435     ContextPointers.IntS4 = &ContextRecord.IntS4;
    00436     ContextPointers.IntS5 = &ContextRecord.IntS5;
    00437
    00438     ContextPointers.FltF2 = &ContextRecord.FltF2;
    00439     ContextPointers.FltF3 = &ContextRecord.FltF3;
    00440     ContextPointers.FltF4 = &ContextRecord.FltF4;
    00441     ContextPointers.FltF5 = &ContextRecord.FltF5;
    00442     ContextPointers.FltF6 = &ContextRecord.FltF6;
    00443     ContextPointers.FltF7 = &ContextRecord.FltF7;
    00444     ContextPointers.FltF8 = &ContextRecord.FltF8;
    00445     ContextPointers.FltF9 = &ContextRecord.FltF9;
    00446
    00447     //
    00448     // Start with the frame specified by the context record and virtually
    00449     // unwind call frames until the system entry trap frame is encountered.
    00450     //
    00451
    00452     do {
    00453
    00454         //
    00455         // Lookup the function table entry using the point at which control
    00456         // left the procedure.
    00457         //
    00458
    00459         FunctionEntry = RtlLookupFunctionEntry(ControlPc);
    00460
    00461         //
    00462         // If there is a function table entry for the routine, then virtually
    00463         // unwind to the caller of the current routine to obtain the address
    00464         // where control left the caller. Otherwise, the function is a leaf
    00465         // function and the return address register contains the address of
    00466         // where control left the caller.
    00467         //
    00468
    00469         if (FunctionEntry != NULL) {
    00470             ControlPc = RtlVirtualUnwind(ControlPc,
    00471                                          FunctionEntry,
    00472                                          &ContextRecord,
    00473                                          &InFunction,
    00474                                          &EstablisherFrame,
    00475                                          &ContextPointers);
    00476
    00477         } else {
    00478             ControlPc = (ULONG_PTR)ContextRecord.IntRa;
    00479         }
    00480
    00481         //
    00482         // N.B. The virtual frame pointer of the kernel frame just below the
    00483         // trap frame may not be exactly equal to TrapFrame1 since the trap
    00484         // code can allocate additional stack space (for local variables or
    00485         // system service arguments). Therefore we must check for a range of
    00486         // values at or below TrapFrame1, but also above TrapFrame2 (so in
    00487         // case there is more than one trap frame on the stack, we get the
    00488         // one at the top.
    00489         //
    00490
    00491     } while ((ContextRecord.IntSp != TrapFrame1) &&
    00492              ((ContextRecord.IntSp < TrapFrame2) ||
    00493               (ControlPc < PCR->SystemServiceDispatchStart) ||
    00494               (ControlPc >= PCR->SystemServiceDispatchEnd)));
    00495
    00496     //
    00497     // If system argument one is nonzero, then set the context of the current
    00498     // thread. Otherwise, get the context of the current thread.
    00499     //
    00500
    00501     if (Apc->SystemArgument1 != 0) {
    00502
    00503         //
    00504         // Set context of current thread.
    00505         //
    00506
    00507         PspSetContext((PKTRAP_FRAME)TrapFrame1,
    00508                       &ContextPointers,
    00509                       &ContextBlock->Context,
    00510                       ContextBlock->Mode);
    00511
    00512     } else {
    00513
    00514         //
    00515         // Get context of current thread.
    00516         //
    00517
    00518         PspGetContext((PKTRAP_FRAME)TrapFrame1,
    00519                       &ContextPointers,
    00520                       &ContextBlock->Context);
    00521     }
    00522
    00523     KeSetEvent(&ContextBlock->OperationComplete, 0, FALSE);
    00524     return;
    00525 }
    }

VOID PspSetContext | ( | IN OUT PKTRAP_FRAME | TrapFrame,
|  | IN PKNONVOLATILE_CONTEXT_POINTERS | ContextPointers,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | ProcessorMode
| ) |

Definition at line 191 of file psctxalp.c.

References ASSERT, CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, and EXCEPTION_EXECUTE_HANDLER.

    00200                    :
    00201
    00202     This function selectively moves the contents of the specified context
    00203     record to the specified trap frame and nonvolatile context.
    00204
    00205 Arguments:
    00206
    00207     TrapFrame - Supplies the address of a trap frame.
    00208
    00209     ContextPointers - Supplies the address of a context pointers record.
    00210
    00211     ContextRecord - Supplies the address of a context record.
    00212
    00213     ProcessorMode - Supplies the processor mode to use when sanitizing
    00214         the PSR and FSR.
    00215
    00216 Return Value:
    00217
    00218     None.
    00219
    00220 --*/
    00221
    00222 {
    00223
    00224     //
    00225     // Set control information if specified.
    00226     //
    00227
    00228     if ((ContextRecord->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00229
    00230         //
    00231         // Set integer registers gp, sp, ra, FIR, and PSR in trap frame.
    00232         //
    00233
    00234         TrapFrame->IntGp = ContextRecord->IntGp;
    00235         TrapFrame->IntSp = ContextRecord->IntSp;
    00236         TrapFrame->IntRa = ContextRecord->IntRa;
    00237         TrapFrame->Fir = ContextRecord->Fir;
    00238         TrapFrame->Psr = SANITIZE_PSR(ContextRecord->Psr, ProcessorMode);
    00239     }
    00240
    00241     //
    00242     // Set integer register contents if specified.
    00243     //
    00244
    00245     if ((ContextRecord->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00246
    00247         //
    00248         // Set volatile integer registers v0 and t0 - t7 in trap frame.
    00249         //
    00250
    00251         TrapFrame->IntV0 = ContextRecord->IntV0;
    00252         TrapFrame->IntT0 = ContextRecord->IntT0;
    00253         TrapFrame->IntT1 = ContextRecord->IntT1;
    00254         TrapFrame->IntT2 = ContextRecord->IntT2;
    00255         TrapFrame->IntT3 = ContextRecord->IntT3;
    00256         TrapFrame->IntT4 = ContextRecord->IntT4;
    00257         TrapFrame->IntT5 = ContextRecord->IntT5;
    00258         TrapFrame->IntT6 = ContextRecord->IntT6;
    00259         TrapFrame->IntT7 = ContextRecord->IntT7;
    00260
    00261         //
    00262         // Set nonvolatile integer registers s0 - s5 through context pointers.
    00263         //
    00264
    00265         *ContextPointers->IntS0 = ContextRecord->IntS0;
    00266         *ContextPointers->IntS1 = ContextRecord->IntS1;
    00267         *ContextPointers->IntS2 = ContextRecord->IntS2;
    00268         *ContextPointers->IntS3 = ContextRecord->IntS3;
    00269         *ContextPointers->IntS4 = ContextRecord->IntS4;
    00270         *ContextPointers->IntS5 = ContextRecord->IntS5;
    00271
    00272         //
    00273         // Set volatile integer registers fp/s6, a0 - a5, t8 - t12, and AT
    00274         // in trap frame.
    00275         //
    00276
    00277         TrapFrame->IntFp = ContextRecord->IntFp;
    00278
    00279         TrapFrame->IntA0 = ContextRecord->IntA0;
    00280         TrapFrame->IntA1 = ContextRecord->IntA1;
    00281         TrapFrame->IntA2 = ContextRecord->IntA2;
    00282         TrapFrame->IntA3 = ContextRecord->IntA3;
    00283         TrapFrame->IntA4 = ContextRecord->IntA4;
    00284         TrapFrame->IntA5 = ContextRecord->IntA5;
    00285
    00286         TrapFrame->IntT8 = ContextRecord->IntT8;
    00287         TrapFrame->IntT9 = ContextRecord->IntT9;
    00288         TrapFrame->IntT10 = ContextRecord->IntT10;
    00289         TrapFrame->IntT11 = ContextRecord->IntT11;
    00290         TrapFrame->IntT12 = ContextRecord->IntT12;
    00291
    00292         TrapFrame->IntAt = ContextRecord->IntAt;
    00293     }
    00294
    00295     //
    00296     // Set floating register contents if specified.
    00297     //
    00298
    00299     if ((ContextRecord->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00300
    00301         //
    00302         // Set volatile floating registers f0 - f1 in trap frame.
    00303         //
    00304
    00305         TrapFrame->FltF0 = ContextRecord->FltF0;
    00306         TrapFrame->FltF1 = ContextRecord->FltF1;
    00307
    00308         //
    00309         // Set volatile floating registers f10 - f30 in trap frame.
    00310         // This assumes that f10 - f30 are contiguous in the trap frame.
    00311         //
    00312
    00313         ASSERT((&ContextRecord->FltF30 - &ContextRecord->FltF10) == 20);
    00314         RtlMoveMemory(&TrapFrame->FltF10, &ContextRecord->FltF10,
    00315                       sizeof(ULONGLONG) * 21);
    00316
    00317         //
    00318         // Set nonvolatile floating registers f2 - f9 through context pointers.
    00319         //
    00320
    00321         *ContextPointers->FltF2 = ContextRecord->FltF2;
    00322         *ContextPointers->FltF3 = ContextRecord->FltF3;
    00323         *ContextPointers->FltF4 = ContextRecord->FltF4;
    00324         *ContextPointers->FltF5 = ContextRecord->FltF5;
    00325         *ContextPointers->FltF6 = ContextRecord->FltF6;
    00326         *ContextPointers->FltF7 = ContextRecord->FltF7;
    00327         *ContextPointers->FltF8 = ContextRecord->FltF8;
    00328         *ContextPointers->FltF9 = ContextRecord->FltF9;
    00329
    00330         //
    00331         // Set floating point control register in trap frame.
    00332         // Set the current software FPCR value in the TEB.
    00333         //
    00334
    00335         TrapFrame->Fpcr = ContextRecord->Fpcr;
    00336         try {
    00337             NtCurrentTeb()->FpSoftwareStatusRegister =
    00338                 (ULONG)ContextRecord->SoftFpcr;
    00339
    00340         } except (EXCEPTION_EXECUTE_HANDLER) {
    00341             NOTHING;
    00342         }
    00343     }
    00344
    00345     return;
    00346 }