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

apcuser.c File Reference

#include "ki.h"
#include "kxia64.h"

Go to the source code of this file.

Functions

VOID KiInitializeUserApc (IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)


Function Documentation

VOID KiInitializeUserApc IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN PKNORMAL_ROUTINE  NormalRoutine,
IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 30 of file ia64/apcuser.c.

References CONTEXT_FULL, KeContextFromKframes(), KeUserApcDispatcher, KiCopyInformation(), KiDispatchException(), ProbeForWrite(), SHORT, TRUE, UserMode, and USHORT.

00041 : 00042 00043 This function is called to initialize the context for a user mode APC. 00044 00045 Arguments: 00046 00047 ExceptionFrame - Supplies a pointer to an exception frame. 00048 00049 TrapFrame - Supplies a pointer to a trap frame. 00050 00051 NormalRoutine - Supplies a pointer to the user mode APC routine. 00052 00053 NormalContext - Supplies a pointer to the user context for the APC 00054 routine. 00055 00056 SystemArgument1 - Supplies the first system supplied value. 00057 00058 SystemArgument2 - Supplies the second system supplied value. 00059 00060 Return Value: 00061 00062 None. 00063 00064 --*/ 00065 00066 { 00067 00068 CONTEXT ContextRecord; 00069 EXCEPTION_RECORD ExceptionRecord; 00070 LONG Length; 00071 ULONGLONG UserStack; 00072 ULONGLONG OriginalBSP; 00073 PULONGLONG Arguments; 00074 00075 // 00076 // Move the user mode state from the trap and exception frames to the 00077 // context frame. 00078 // 00079 00080 ContextRecord.ContextFlags = CONTEXT_FULL; 00081 OriginalBSP = TrapFrame->RsBSP; 00082 00083 if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) { 00084 00085 // 00086 // Make the necessary adjustment to the BSP value in the trap frame 00087 // if the user APC is dispatched in the context of a system call 00088 // 00089 00090 SHORT RNatSaveIndex, Temp; 00091 SHORT OutputFrameSize; 00092 00093 OutputFrameSize = (SHORT)((TrapFrame->StIFS & PFS_SIZE_MASK) - ((TrapFrame->StIFS >> PFS_SIZE_SHIFT) & PFS_SIZE_MASK)); 00094 RNatSaveIndex = (SHORT)((TrapFrame->RsBSP>>3) & NAT_BITS_PER_RNAT_REG); 00095 00096 Temp = RNatSaveIndex + OutputFrameSize - NAT_BITS_PER_RNAT_REG; 00097 while (Temp >= 0) { 00098 OutputFrameSize++; 00099 Temp -= NAT_BITS_PER_RNAT_REG; 00100 } 00101 TrapFrame->RsBSP += OutputFrameSize * sizeof(ULONGLONG); 00102 00103 } 00104 00105 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord); 00106 TrapFrame->RsBSP = OriginalBSP; 00107 00108 // 00109 // Transfer the context information to the user stack, initialize the 00110 // APC routine parameters, and modify the trap frame so execution will 00111 // continue in user mode at the user mode APC dispatch routine. 00112 // 00113 // We build the following structure on the user stack: 00114 // 00115 // | | 00116 // |-------------------------------| 00117 // | | 00118 // | Interrupted user's | 00119 // | stack frame | 00120 // | | 00121 // | | 00122 // |-------------------------------| 00123 // | Slack Space due to the | 00124 // | 16-byte stack alignment | 00125 // | - - - - - - - - - - - - - - - | 00126 // | NormalRoutine | 00127 // | SystemArgument2 | 00128 // | SystemArgument1 | 00129 // | NormalContext | 00130 // | - - - - - - - - - - - - - - - | 00131 // | Context Frame | 00132 // | Filled in with state | 00133 // | of interrupted user | 00134 // | program | 00135 // | - - - - - - - - - - - - - - - | 00136 // | Stack Scratch Area | 00137 // |-------------------------------| 00138 // | | 00139 00140 try { 00141 00142 USHORT LocalFrameSize; 00143 PPLABEL_DESCRIPTOR Plabel = (PPLABEL_DESCRIPTOR) KeUserApcDispatcher; 00144 00145 // 00146 // Compute total length of 4 arguments, context record, and 00147 // stack scratch area. 00148 // 00149 // Compute the new 16-byte aligned user stack pointer. 00150 // 00151 00152 Length = (4 * sizeof(ULONGLONG) + CONTEXT_LENGTH + 00153 STACK_SCRATCH_AREA + 15) & (~15); 00154 UserStack = (ContextRecord.IntSp & (~15)) - Length; 00155 Arguments = (PULONGLONG)(UserStack + STACK_SCRATCH_AREA + CONTEXT_LENGTH); 00156 00157 // 00158 // Probe user stack area for writeability and then transfer the 00159 // context record to the user stack. 00160 // 00161 00162 ProbeForWrite((PCHAR)UserStack, Length, sizeof(QUAD)); 00163 RtlCopyMemory((PVOID)(UserStack+STACK_SCRATCH_AREA), 00164 &ContextRecord, sizeof(CONTEXT)); 00165 00166 // 00167 // Set the address of the user APC routine, the APC parameters, the 00168 // interrupt frame set, the new global pointer, and the new stack 00169 // pointer in the current trap frame. The four APC parameters are 00170 // passed via the scratch registers t0 thru t3. 00171 // Set the continuation address so control will be transfered to 00172 // the user APC dispatcher. 00173 // 00174 00175 *Arguments++ = (ULONGLONG)NormalContext; // 1st argument 00176 *Arguments++ = (ULONGLONG)SystemArgument1; // 2nd argument 00177 *Arguments++ = (ULONGLONG)SystemArgument2; // 3rd argument 00178 *Arguments++ = (ULONGLONG)NormalRoutine; // 4th argument 00179 *(PULONGLONG)UserStack = Plabel->GlobalPointer; // user apc dispatcher gp 00180 00181 TrapFrame->IntNats = 0; // sanitize integer Nats 00182 TrapFrame->IntSp = UserStack; // stack pointer 00183 00184 TrapFrame->StIIP = Plabel->EntryPoint; // entry point from plabel 00185 TrapFrame->StIPSR &= ~(0x3ULL << PSR_RI); // start at bundle boundary 00186 TrapFrame->StIFS &= 0xffffffc000000000; // set the initial frame 00187 // size of KeUserApcDispatcher 00188 // to be zero. 00189 00190 // 00191 // If an exception occurs, then copy the exception information to an 00192 // exception record and handle the exception. 00193 // 00194 00195 } except (KiCopyInformation(&ExceptionRecord, 00196 (GetExceptionInformation())->ExceptionRecord)) { 00197 00198 // 00199 // Set the address of the exception to the current program address 00200 // and raise the exception by calling the exception dispatcher. 00201 // 00202 00203 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->StIIP); 00204 KiDispatchException(&ExceptionRecord, 00205 ExceptionFrame, 00206 TrapFrame, 00207 UserMode, 00208 TRUE); 00209 } 00210 00211 return; 00212 } }


Generated on Sat May 15 19:42:52 2004 for test by doxygen 1.3.7