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

mpipi.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1993 Microsoft Corporation 00004 00005 Module Name: 00006 00007 mpipi.c 00008 00009 Abstract: 00010 00011 This module implements MIPS specific MP routine. 00012 00013 Author: 00014 00015 Bernard Lint 26-Jun-1996 00016 00017 Environment: 00018 00019 Kernel mode only. 00020 00021 Revision History: 00022 00023 Based on version of David N. Cutler 24-Apr-1993 00024 00025 --*/ 00026 00027 #include "ki.h" 00028 00029 VOID 00030 KiFlushUserRseState ( 00031 IN PKTRAP_FRAME TrapFrame 00032 ); 00033 00034 VOID 00035 KiRestoreProcessorState ( 00036 IN PKTRAP_FRAME TrapFrame, 00037 IN PKEXCEPTION_FRAME ExceptionFrame 00038 ) 00039 00040 /*++ 00041 00042 Routine Description: 00043 00044 This function moves processor register state from the current 00045 processor context structure in the processor block to the 00046 specified trap and exception frames. 00047 00048 Arguments: 00049 00050 TrapFrame - Supplies a pointer to a trap frame. 00051 00052 ExceptionFrame - Supplies a pointer to an exception frame. 00053 00054 Return Value: 00055 00056 None. 00057 00058 --*/ 00059 00060 { 00061 00062 #if !defined(NT_UP) 00063 00064 PKPRCB Prcb; 00065 00066 // 00067 // Get the address of the current processor block and move the 00068 // specified register state from the processor context structure 00069 // to the specified trap and exception frames 00070 // 00071 00072 Prcb = KeGetCurrentPrcb(); 00073 KeContextToKframes(TrapFrame, 00074 ExceptionFrame, 00075 &Prcb->ProcessorState.ContextFrame, 00076 CONTEXT_FULL, 00077 (KPROCESSOR_MODE)TrapFrame->PreviousMode); 00078 00079 #endif 00080 00081 return; 00082 } 00083 00084 VOID 00085 KiSaveProcessorState ( 00086 IN PKTRAP_FRAME TrapFrame, 00087 IN PKEXCEPTION_FRAME ExceptionFrame 00088 ) 00089 00090 /*++ 00091 00092 Routine Description: 00093 00094 This function moves processor register state from the specified trap 00095 and exception frames to the processor context structure in the current 00096 processor block. 00097 00098 Arguments: 00099 00100 TrapFrame - Supplies a pointer to a trap frame. 00101 00102 ExceptionFrame - Supplies a pointer to an exception frame. 00103 00104 Return Value: 00105 00106 None. 00107 00108 --*/ 00109 00110 { 00111 00112 #if !defined(NT_UP) 00113 00114 PKPRCB Prcb; 00115 00116 // 00117 // Get the address of the current processor block and move the 00118 // specified register state from specified trap and exception 00119 // frames to the current processor context structure. 00120 // 00121 00122 Prcb = KeGetCurrentPrcb(); 00123 Prcb->ProcessorState.ContextFrame.ContextFlags = CONTEXT_FULL; 00124 KeContextFromKframes(TrapFrame, 00125 ExceptionFrame, 00126 &Prcb->ProcessorState.ContextFrame); 00127 00128 if (TrapFrame->PreviousMode == UserMode) 00129 KiFlushUserRseState(TrapFrame); 00130 00131 // 00132 // Save ISR in special registers 00133 // 00134 00135 Prcb->ProcessorState.SpecialRegisters.StISR = TrapFrame->StISR; 00136 00137 // 00138 // Save the current processor control state. 00139 // 00140 00141 KiSaveProcessorControlState(&Prcb->ProcessorState); 00142 00143 #endif 00144 00145 return; 00146 } 00147 00148 BOOLEAN 00149 KiIpiServiceRoutine ( 00150 IN PKTRAP_FRAME TrapFrame, 00151 IN PKEXCEPTION_FRAME ExceptionFrame 00152 ) 00153 00154 /*++ 00155 00156 Routine Description: 00157 00158 00159 This function is called at IPI_LEVEL to process any outstanding 00160 interprocess request for the current processor. 00161 00162 Arguments: 00163 00164 TrapFrame - Supplies a pointer to a trap frame. 00165 00166 ExceptionFrame - Supplies a pointer to an exception frame 00167 00168 Return Value: 00169 00170 A value of TRUE is returned, if one of more requests were service. 00171 Otherwise, FALSE is returned. 00172 00173 --*/ 00174 00175 { 00176 ULONG RequestSummary; 00177 00178 // 00179 // Process any outstanding IPI requests 00180 // 00181 00182 RequestSummary = KiIpiProcessRequests(); 00183 00184 // 00185 // If freeze is requested, then freeze target execution. 00186 // 00187 00188 if ((RequestSummary & IPI_FREEZE) != 0) { 00189 KiFreezeTargetExecution(TrapFrame, ExceptionFrame); 00190 } 00191 00192 return ((RequestSummary & ~IPI_FREEZE) != 0); 00193 } 00194 00195 ULONG 00196 KiIpiProcessRequests ( 00197 VOID 00198 ) 00199 00200 /*++ 00201 00202 Routine Description: 00203 00204 This routine processes interprocessor requests and returns a summary 00205 of the requests that were processed. 00206 00207 Arguments: 00208 00209 None. 00210 00211 Return Value: 00212 00213 The request summary is returned as the function value. 00214 00215 --*/ 00216 { 00217 ULONG RequestSummary; 00218 PKPRCB SignalDone; 00219 PKPRCB Prcb = KeGetCurrentPrcb(); 00220 00221 RequestSummary = (ULONG)InterlockedExchange((PLONG)&Prcb->RequestSummary, 0); 00222 00223 // 00224 // If a packet is ready, then get the address of the requested function 00225 // and call the function passing the address of the packet address as a 00226 // parameter. 00227 // 00228 00229 SignalDone = (PKPRCB)Prcb->SignalDone; 00230 00231 if (SignalDone != 0) { 00232 00233 Prcb->SignalDone = 0; 00234 00235 (*SignalDone->WorkerRoutine) ((PKIPI_CONTEXT)SignalDone, 00236 SignalDone->CurrentPacket[0], 00237 SignalDone->CurrentPacket[1], 00238 SignalDone->CurrentPacket[2]); 00239 00240 } 00241 00242 if ((RequestSummary & IPI_APC) != 0) { 00243 KiRequestSoftwareInterrupt (APC_LEVEL); 00244 } else if ((RequestSummary & IPI_DPC) != 0) { 00245 KiRequestSoftwareInterrupt (DISPATCH_LEVEL); 00246 } 00247 00248 return RequestSummary; 00249 } 00250 00251 00252 VOID 00253 KiIpiSend ( 00254 IN KAFFINITY TargetProcessors, 00255 IN KIPI_REQUEST IpiRequest 00256 ) 00257 00258 /*++ 00259 00260 Routine Description: 00261 00262 This routine requests the specified operation on the target set of 00263 processors. 00264 00265 Arguments: 00266 00267 TargetProcessors (a0) - Supplies the set of processors on which the 00268 specified operation is to be executed. 00269 00270 IpiRequest (a1) - Supplies the request operation mask. 00271 00272 Return Value: 00273 00274 None. 00275 00276 --*/ 00277 00278 { 00279 #if !defined(NT_UP) 00280 ULONG RequestSummary; 00281 KAFFINITY NextProcessors; 00282 ULONG Next; 00283 00284 // 00285 // Loop through the target processors and send the packet to the specified 00286 // recipients. 00287 // 00288 00289 NextProcessors = TargetProcessors; 00290 Next = 0; 00291 00292 while (NextProcessors != 0) { 00293 00294 if ((NextProcessors & 1) != 0) { 00295 00296 do { 00297 00298 RequestSummary = KiProcessorBlock[Next]->RequestSummary; 00299 00300 } while(InterlockedCompareExchange( 00301 (PLONG) &KiProcessorBlock[Next]->RequestSummary, 00302 (LONG) (RequestSummary | IpiRequest), 00303 (LONG) RequestSummary) != (LONG) RequestSummary); 00304 } 00305 00306 NextProcessors = NextProcessors >> 1; 00307 00308 Next = Next + 1; 00309 00310 } 00311 HalRequestIpi (TargetProcessors); 00312 #endif 00313 00314 return; 00315 } 00316 00317 00318 VOID 00319 KiIpiSendPacket ( 00320 IN KAFFINITY TargetProcessors, 00321 IN PKIPI_WORKER WorkerFunction, 00322 IN PVOID Parameter1, 00323 IN PVOID Parameter2, 00324 IN PVOID Parameter3 00325 ) 00326 00327 /*++ 00328 00329 Routine Description: 00330 00331 This routine executes the specified worker function on the specified 00332 set of processors. 00333 00334 Arguments: 00335 00336 TargetProcessors (a0) - Supplies the set of processors on which the 00337 specified operation is to be executed. 00338 00339 WorkerFunction (a1) - Supplies the address of the worker function. 00340 00341 Parameter1 - Parameter3 (a2, a3, 4 * 4(sp)) - Supplies worker 00342 function specific parameters. 00343 00344 Return Value: 00345 00346 None. 00347 00348 --*/ 00349 { 00350 #if !defined(NT_UP) 00351 PKPRCB Prcb; 00352 KAFFINITY NextProcessors; 00353 ULONG Next; 00354 00355 Prcb = KeGetCurrentPrcb(); 00356 Prcb->TargetSet = TargetProcessors; 00357 Prcb->WorkerRoutine = WorkerFunction; 00358 Prcb->CurrentPacket[0] = Parameter1; 00359 Prcb->CurrentPacket[1] = Parameter2; 00360 Prcb->CurrentPacket[2] = Parameter3; 00361 00362 // 00363 // synchronize memory access 00364 // 00365 00366 __mf(); 00367 00368 // 00369 // Loop through the target processors and send the packet to the specified 00370 // recipients. 00371 // 00372 00373 NextProcessors = TargetProcessors; 00374 Next = 0; 00375 00376 while (NextProcessors != 0) { 00377 00378 if ((NextProcessors & 1) != 0) { 00379 00380 while(InterlockedCompareExchangePointer( 00381 (PVOID)&KiProcessorBlock[Next]->SignalDone, 00382 (PVOID)Prcb, 00383 (PVOID)0) != (PVOID)0); 00384 00385 } 00386 00387 NextProcessors = NextProcessors >> 1; 00388 00389 Next = Next + 1; 00390 00391 } 00392 HalRequestIpi (TargetProcessors); 00393 #endif 00394 } 00395 00396 00397 #if !defined(NT_UP) 00398 00399 VOID 00400 KiIpiSignalPacketDone ( 00401 IN PKPRCB SignalDone 00402 ) 00403 00404 /*++ 00405 00406 Routine Description: 00407 00408 This routine signals that a processor has completed a packet by 00409 clearing the calling processor's set member of the requesting 00410 processor's packet. 00411 00412 Arguments: 00413 00414 SignalDone (a0) - Supplies a pointer to the processor block of the 00415 sending processor. 00416 00417 Return Value: 00418 00419 None. 00420 00421 --*/ 00422 { 00423 PKPRCB Prcb = KeGetCurrentPrcb(); 00424 00425 KAFFINITY TargetSet; 00426 00427 do { 00428 00429 TargetSet = SignalDone->TargetSet; 00430 00431 } while (InterlockedCompareExchange( 00432 (PLONG) &SignalDone->TargetSet, 00433 (LONG) (TargetSet ^ Prcb->SetMember), 00434 (LONG) TargetSet) != (LONG)TargetSet); 00435 } 00436 00437 #endif // !defined(NT_UP)

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