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

psctxi64.c File Reference

#include "psp.h"
#include <ia64.h>

Go to the source code of this file.

Defines

#define ALIGN_NATS(Result, Source, Start, AddressOffset, Mask)
#define EXTRACT_NATS(Result, Source, Start, AddressOffset, Mask)

Functions

VOID KiGetDebugContext (IN PKTRAP_FRAME TrapFrame, IN OUT PCONTEXT ContextFrame)
VOID KiSetDebugContext (IN OUT PKTRAP_FRAME TrapFrame, IN PCONTEXT ContextFrame, IN KPROCESSOR_MODE ProcessorMode)
VOID KiFlushUserRseState (IN PKTRAP_FRAME TrapFrame)
VOID PspGetContext (IN PKTRAP_FRAME TrapFrame, IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, IN OUT PCONTEXT ContextEM)
VOID PspSetContext (IN OUT PKTRAP_FRAME TrapFrame, IN PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, IN PCONTEXT ContextEM, IN KPROCESSOR_MODE ProcessorMode)
VOID PspGetSetContextSpecialApcMain (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)


Define Documentation

#define ALIGN_NATS Result,
Source,
Start,
AddressOffset,
Mask   ) 
 

Value:

if (AddressOffset == Start) { \ Result = (ULONGLONG)Source; \ } else if (AddressOffset < Start) { \ Result = (ULONGLONG)(Source << (Start - AddressOffset)); \ } else { \ Result = (ULONGLONG)((Source >> (AddressOffset - Start)) | \ (Source << (64 + Start - AddressOffset))); \ } \ Result = Result & (ULONGLONG)Mask

Definition at line 25 of file psctxi64.c.

#define EXTRACT_NATS Result,
Source,
Start,
AddressOffset,
Mask   ) 
 

Value:

Result = (ULONGLONG)(Source & (ULONGLONG)Mask); \ if (AddressOffset < Start) { \ Result = Result >> (Start - AddressOffset); \ } else if (AddressOffset > Start) { \ Result = ((Result << (AddressOffset - Start)) | \ (Result >> (64 + Start - AddressOffset))); \ }

Definition at line 36 of file psctxi64.c.


Function Documentation

VOID KiFlushUserRseState IN PKTRAP_FRAME  TrapFrame  ) 
 

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

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, RtlpFlushRSE(), SHORT, and USHORT.

Referenced by KiSaveProcessorState(), and PspGetSetContextSpecialApcMain().

00652 : 00653 00654 This routine flushes the user rse state from the kernel backing store to the 00655 user backing store. The user context frame is update to reflect the new 00656 context state. 00657 00658 Arguments: 00659 00660 TrapFrame - Supplies a pointer to a trap frame. 00661 00662 Return Value: 00663 00664 None. 00665 00666 --*/ 00667 00668 { 00669 SHORT BsFrameSize; 00670 SHORT RNatSaveIndex; 00671 SHORT Temp; 00672 USHORT TearPointOffset; 00673 ULONGLONG TopBound, BottomBound; 00674 ULONGLONG UserRnats1, UserRnats2; 00675 ULONGLONG Mask; 00676 00677 // 00678 // Copy user stacked registers' contents to user backing store. 00679 // N.B. Stack overflow could happen. 00680 // 00681 00682 try { 00683 00684 BsFrameSize = (SHORT)(TrapFrame->RsBSP - TrapFrame->RsBSPSTORE); 00685 00686 if (BsFrameSize) { 00687 00688 ULONGLONG Bsp, Rnat, KernelInitBsp; 00689 00690 // 00691 // Copy the dirty stacked registers back into the 00692 // user backing store 00693 // 00694 00695 RtlpFlushRSE(&Bsp, &Rnat); 00696 TearPointOffset = (USHORT) TrapFrame->RsBSPSTORE & 0x1F8; 00697 00698 KernelInitBsp= (PCR->InitialBStore | TearPointOffset) + BsFrameSize; 00699 if ((KernelInitBsp | RNAT_ALIGNMENT) != (Bsp | RNAT_ALIGNMENT)) { 00700 Rnat = *(PULONGLONG)(KernelInitBsp | RNAT_ALIGNMENT); 00701 } 00702 00703 RtlCopyMemory((PVOID)(TrapFrame->RsBSPSTORE), 00704 (PVOID)(PCR->InitialBStore + TearPointOffset), 00705 BsFrameSize); 00706 00707 TopBound = TrapFrame->RsBSP | RNAT_ALIGNMENT; 00708 BottomBound = TrapFrame->RsBSPSTORE | RNAT_ALIGNMENT; 00709 00710 RNatSaveIndex = TearPointOffset >> 3; 00711 Mask = (((1ULL << (NAT_BITS_PER_RNAT_REG - RNatSaveIndex)) - 1) << RNatSaveIndex); 00712 UserRnats1 = TrapFrame->RsRNAT & ((1ULL << RNatSaveIndex) - 1); 00713 00714 if (TopBound > BottomBound) { 00715 00716 // 00717 // user dirty stacked GR span across at least one RNAT 00718 // boundary; need to deposit the valid RNAT bits from 00719 // the trap frame into the kernel backing store. Also, 00720 // the RNAT field in the trap frame has to be updated. 00721 // 00722 00723 UserRnats2 = *(PULONGLONG)BottomBound & Mask; 00724 *(PULONGLONG)BottomBound = UserRnats1 | UserRnats2; 00725 TrapFrame->RsRNAT = Rnat; 00726 00727 #if DEBUG 00728 DbgPrint("KiFlushUserRseState 1: UserRnats1 = 0x%I64x, UserRnats2 = 0x%I64x, TF->RsRNAT = 0x%I64x\n", 00729 UserRnats1, UserRnats2, TrapFrame->RsRNAT); 00730 #endif // DEBUG 00731 00732 } else { 00733 00734 // 00735 // user stacked register region does not span across an 00736 // RNAT boundary; combine the RNAT fields from both the 00737 // trap frame and the context frame. 00738 // 00739 00740 UserRnats2 = Rnat & Mask; 00741 TrapFrame->RsRNAT = UserRnats1 | UserRnats2; 00742 00743 #if DEBUG 00744 DbgPrint("KiFlushUserRseState 2: UserRnats1 = 0x%I64x, UserRnats2 = 0x%I64x, TF->RsRNAT = 0x%I64x\n", 00745 UserRnats1, UserRnats2, TrapFrame->RsRNAT); 00746 #endif // DEBUG 00747 00748 } 00749 } 00750 00751 // 00752 // Successfully copied to user backing store; set the user's 00753 // bspstore to the value of its own bsp. 00754 // 00755 00756 TrapFrame->RsBSPSTORE = TrapFrame->RsBSP; 00757 00758 } except (EXCEPTION_EXECUTE_HANDLER) { 00759 DbgPrint("WARNING: Exception raised in krnl-to-user bstore copy\n"); 00760 } 00761 00762 return; 00763 }

VOID KiGetDebugContext IN PKTRAP_FRAME  TrapFrame,
IN OUT PCONTEXT  ContextFrame
 

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

References UserMode.

Referenced by KeContextFromKframes(), and PspGetContext().

00061 : 00062 00063 This routine moves the user mode h/w debug registers from the debug register 00064 save area in the kernel stack to the context record. 00065 00066 Arguments: 00067 00068 TrapFrame - Supplies a pointer to a trap frame from which volatile context 00069 should be copied into the context record. 00070 00071 ContextFrame - Supplies a pointer to the context frame that receives the 00072 context. 00073 00074 Return Value: 00075 00076 None. 00077 00078 Note: 00079 00080 PSR.db must be set to activate the debug registers. 00081 00082 This is used for getting user mode debug registers. 00083 00084 --*/ 00085 00086 { 00087 PKDEBUG_REGISTERS DebugRegistersSaveArea; 00088 00089 if (TrapFrame->PreviousMode == UserMode) { 00090 DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA(); 00091 00092 RtlCopyMemory(&ContextFrame->DbI0, 00093 (PVOID)DebugRegistersSaveArea, 00094 sizeof(KDEBUG_REGISTERS)); 00095 } 00096 }

VOID KiSetDebugContext IN OUT PKTRAP_FRAME  TrapFrame,
IN PCONTEXT  ContextFrame,
IN KPROCESSOR_MODE  ProcessorMode
 

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

References UserMode.

Referenced by KeContextToKframes(), KeContextToKframesSpecial(), and PspSetContext().

00106 : 00107 00108 This routine moves the debug context from the specified context frame into 00109 the debug registers save area in the kernel stack. 00110 00111 Arguments: 00112 00113 TrapFrame - Supplies a pointer to a trap frame. 00114 00115 ContextFrame - Supplies a pointer to a context frame that contains the 00116 context that is to be copied. 00117 00118 PreviousMode - Supplies the processor mode for the target context. 00119 00120 Return Value: 00121 00122 None. 00123 00124 Notes: 00125 00126 PSR.db must be set to activate the debug registers. 00127 00128 This is used for setting up debug registers for user mode. 00129 00130 --*/ 00131 00132 { 00133 PKDEBUG_REGISTERS DebugRegistersSaveArea; // User mode h/w debug registers 00134 00135 if (PreviousMode == UserMode) { 00136 00137 DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA(); 00138 00139 // 00140 // Sanitize the debug control regs. Leave the addresses unchanged. 00141 // 00142 00143 DebugRegistersSaveArea->DbI0 = ContextFrame->DbI0; 00144 DebugRegistersSaveArea->DbI1 = SANITIZE_DR(ContextFrame->DbI1,UserMode); 00145 DebugRegistersSaveArea->DbI2 = ContextFrame->DbI2; 00146 DebugRegistersSaveArea->DbI3 = SANITIZE_DR(ContextFrame->DbI3,UserMode); 00147 DebugRegistersSaveArea->DbI4 = ContextFrame->DbI4; 00148 DebugRegistersSaveArea->DbI5 = SANITIZE_DR(ContextFrame->DbI5,UserMode); 00149 DebugRegistersSaveArea->DbI6 = ContextFrame->DbI6; 00150 DebugRegistersSaveArea->DbI7 = SANITIZE_DR(ContextFrame->DbI7,UserMode); 00151 00152 DebugRegistersSaveArea->DbD0 = ContextFrame->DbD0; 00153 DebugRegistersSaveArea->DbD1 = SANITIZE_DR(ContextFrame->DbD1,UserMode); 00154 DebugRegistersSaveArea->DbD2 = ContextFrame->DbD2; 00155 DebugRegistersSaveArea->DbD3 = SANITIZE_DR(ContextFrame->DbD3,UserMode); 00156 DebugRegistersSaveArea->DbD4 = ContextFrame->DbD4; 00157 DebugRegistersSaveArea->DbD5 = SANITIZE_DR(ContextFrame->DbD5,UserMode); 00158 DebugRegistersSaveArea->DbD6 = ContextFrame->DbD6; 00159 DebugRegistersSaveArea->DbD7 = SANITIZE_DR(ContextFrame->DbD7,UserMode); 00160 00161 } 00162 }

VOID PspGetContext IN PKTRAP_FRAME  TrapFrame,
IN PKNONVOLATILE_CONTEXT_POINTERS  ContextPointers,
IN OUT PCONTEXT  ContextEM
 

Definition at line 65 of file psctxi64.c.

References ALIGN_NATS, CONTEXT_CONTROL, CONTEXT_INTEGER, DbgPrint, KiGetDebugContext(), SHORT, UserMode, and USHORT.

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

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

Definition at line 616 of file psctxi64.c.

References _GETSETCONTEXT::Context, FALSE, KeSetEvent(), KiFlushUserRseState(), _GETSETCONTEXT::Mode, NULL, _GETSETCONTEXT::OperationComplete, PsGetCurrentThread, PspGetContext(), PspSetContext(), RtlLookupFunctionEntry(), RtlVirtualUnwind(), and SHORT.

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

VOID PspSetContext IN OUT PKTRAP_FRAME  TrapFrame,
IN PKNONVOLATILE_CONTEXT_POINTERS  ContextPointers,
IN PCONTEXT  ContextEM,
IN KPROCESSOR_MODE  ProcessorMode
 

Definition at line 304 of file psctxi64.c.

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

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


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