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

intobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KeInitializeInterrupt (IN PKINTERRUPT Interrupt, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock OPTIONAL, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN CCHAR ProcessorNumber, IN BOOLEAN FloatingSave)
BOOLEAN KeConnectInterrupt (IN PKINTERRUPT Interrupt)
BOOLEAN KeDisconnectInterrupt (IN PKINTERRUPT Interrupt)


Function Documentation

BOOLEAN KeConnectInterrupt IN PKINTERRUPT  Interrupt  ) 
 

Definition at line 141 of file ppc/intobj.c.

References CHAR, _KINTERRUPT::DispatchAddress, _KINTERRUPT::DispatchCode, FALSE, HalEnableSystemInterrupt(), HIGH_LEVEL, _KINTERRUPT::InterruptListEntry, KeLowerIrql(), KeNumberProcessors, KeRaiseIrql(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KiChainedDispatch(), KiFloatingDispatch(), KiInterruptDispatchRaise(), KiInterruptDispatchSame(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), max, _KINTERRUPT::Mode, _KINTERRUPT::ShareVector, SYNCH_LEVEL, and TRUE.

Referenced by IoConnectInterrupt().

00147 : 00148 00149 This function connects an interrupt object to the interrupt vector 00150 specified by the interrupt object. If the interrupt object is already 00151 connected, or an attempt is made to connect to an interrupt that cannot 00152 be connected, then a value of FALSE is returned. Else the specified 00153 interrupt object is connected to the interrupt vector, the connected 00154 state is set to TRUE, and TRUE is returned as the function value. 00155 00156 Arguments: 00157 00158 Interrupt - Supplies a pointer to a control object of type interrupt. 00159 00160 Return Value: 00161 00162 If the interrupt object is already connected or an attempt is made to 00163 connect to an interrupt vector that cannot be connected, then a value 00164 of FALSE is returned. Else a value of TRUE is returned. 00165 00166 --*/ 00167 00168 { 00169 00170 BOOLEAN Connected; 00171 PKINTERRUPT Interruptx; 00172 KIRQL Irql; 00173 CHAR Number; 00174 KIRQL OldIrql; 00175 KIRQL PreviousIrql; 00176 ULONG Vector; 00177 00178 // 00179 // If the interrupt object is already connected, the interrupt vector 00180 // number is invalid, an attempt is being made to connect to a vector 00181 // that cannot be connected, the interrupt request level is invalid, 00182 // the processor number is invalid, of the interrupt vector is less 00183 // than or equal to the highest level and it not equal to the specified 00184 // IRQL, then do not connect the interrupt object. Else connect interrupt 00185 // object to the specified vector and establish the proper interrupt 00186 // dispatcher. 00187 // 00188 00189 Connected = FALSE; 00190 Irql = Interrupt->Irql; 00191 Number = Interrupt->Number; 00192 Vector = Interrupt->Vector; 00193 if ( 00194 (Vector < MAXIMUM_VECTOR) && // will fit in interrupt table 00195 (Irql <= HIGH_LEVEL) && // is at a reasonable priority 00196 (Number < KeNumberProcessors) && // can run on a cpu we have 00197 ( 00198 (Vector > HIGH_LEVEL) || // and is either EISA or 00199 ((PCR->ReservedVectors & (1 << Vector)) == 0) // is NOT reserved 00200 ) 00201 ) { 00202 00203 // 00204 // 00205 // Set system affinity to the specified processor. 00206 // 00207 00208 KeSetSystemAffinityThread((KAFFINITY)(1 << Number)); 00209 00210 // 00211 // Raise IRQL to dispatcher level and lock dispatcher database. 00212 // 00213 00214 KiLockDispatcherDatabase(&OldIrql); 00215 00216 // 00217 // If the specified interrupt vector is not connected, then 00218 // connect the interrupt vector to the interrupt dispatcher 00219 // and set the new interrupt mode and enable masks. 00220 // Else if the interrupt is 00221 // already chained, then add the new interrupt object at the end 00222 // of the chain. If the interrupt vector is not chained, then 00223 // start a chain with the previous interrupt object at the front 00224 // of the chain. The interrupt mode of all interrupt objects in 00225 // a chain must be the same. 00226 // 00227 00228 if (Interrupt->Connected == FALSE) { 00229 if (PCR->InterruptRoutine[Vector] == 00230 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode)) { 00231 Connected = TRUE; 00232 Interrupt->Connected = TRUE; 00233 if (Interrupt->FloatingSave) { 00234 Interrupt->DispatchAddress = KiFloatingDispatch; 00235 00236 } else { 00237 if (Interrupt->Irql == Interrupt->SynchronizeIrql) { 00238 #if defined(NT_UP) 00239 Interrupt->DispatchAddress = 00240 (PKINTERRUPT_ROUTINE)Interrupt->ServiceRoutine; 00241 #else 00242 Interrupt->DispatchAddress = 00243 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00244 #endif 00245 00246 } else { 00247 Interrupt->DispatchAddress = 00248 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00249 } 00250 } 00251 00252 // 00253 // Copy the function descriptor for the Dispatch routine 00254 // into DispatchCode. This will be used by KiInterruptEx- 00255 // ception to dispatch the interrupt. 00256 // 00257 00258 Interrupt->DispatchCode[0] = 00259 *(PULONG)(Interrupt->DispatchAddress); 00260 Interrupt->DispatchCode[1] = 00261 *(((PULONG)(Interrupt->DispatchAddress))+1); 00262 PCR->InterruptRoutine[Vector] = 00263 (PKINTERRUPT_ROUTINE)Interrupt->DispatchCode; 00264 00265 HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode); 00266 00267 } else if (Interrupt->ShareVector) { 00268 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00269 KINTERRUPT, 00270 DispatchCode[0]); 00271 if (Interruptx->ShareVector && 00272 Interrupt->Mode == Interruptx->Mode) { 00273 Connected = TRUE; 00274 Interrupt->Connected = TRUE; 00275 KeRaiseIrql((KIRQL)(max(Irql, SYNCH_LEVEL)), &PreviousIrql); 00276 if (Interruptx->DispatchAddress != 00277 (PKINTERRUPT_ROUTINE)KiChainedDispatch) { 00278 InitializeListHead(&Interruptx->InterruptListEntry); 00279 Interruptx->DispatchAddress = 00280 (PKINTERRUPT_ROUTINE)KiChainedDispatch; 00281 Interruptx->DispatchCode[0] = 00282 *(PULONG)KiChainedDispatch; 00283 Interruptx->DispatchCode[1] = 00284 *(((PULONG)KiChainedDispatch)+1); 00285 } 00286 00287 InsertTailList(&Interruptx->InterruptListEntry, 00288 &Interrupt->InterruptListEntry); 00289 KeLowerIrql(PreviousIrql); 00290 } 00291 } 00292 } 00293 00294 // 00295 // Unlock dispatcher database and lower IRQL to its previous value. 00296 // 00297 00298 KiUnlockDispatcherDatabase(OldIrql); 00299 00300 // 00301 // Set system affinity back to the original value. 00302 // 00303 00304 KeRevertToUserAffinityThread(); 00305 } 00306 00307 // 00308 // Return whether interrupt was connected to the specified vector. 00309 // 00310 00311 return Connected; 00312 }

BOOLEAN KeDisconnectInterrupt IN PKINTERRUPT  Interrupt  ) 
 

Definition at line 315 of file ppc/intobj.c.

References _KINTERRUPT::DispatchAddress, _KINTERRUPT::DispatchCode, FALSE, HalDisableSystemInterrupt(), _KINTERRUPT::InterruptListEntry, KeLowerIrql(), KeRaiseIrql(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KeSweepIcache(), KiChainedDispatch(), KiFloatingDispatch(), KiInterruptDispatchRaise(), KiInterruptDispatchSame(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), max, SYNCH_LEVEL, and TRUE.

Referenced by IoDisconnectInterrupt(), and KeConnectInterrupt().

00321 : 00322 00323 This function disconnects an interrupt object from the interrupt vector 00324 specified by the interrupt object. If the interrupt object is not 00325 connected, then a value of FALSE is returned. Else the specified interrupt 00326 object is disconnected from the interrupt vector, the connected state is 00327 set to FALSE, and TRUE is returned as the function value. 00328 00329 Arguments: 00330 00331 Interrupt - Supplies a pointer to a control object of type interrupt. 00332 00333 Return Value: 00334 00335 If the interrupt object is not connected, then a value of FALSE is 00336 returned. Else a value of TRUE is returned. 00337 00338 --*/ 00339 00340 { 00341 00342 BOOLEAN Connected; 00343 PKINTERRUPT Interruptx; 00344 PKINTERRUPT Interrupty; 00345 KIRQL Irql; 00346 KIRQL OldIrql; 00347 KIRQL PreviousIrql; 00348 ULONG Vector; 00349 00350 // 00351 // Set system affinity to the specified processor. 00352 // 00353 00354 KeSetSystemAffinityThread((KAFFINITY)(1 << Interrupt->Number)); 00355 00356 // 00357 // Raise IRQL to dispatcher level and lock dispatcher database. 00358 // 00359 00360 KiLockDispatcherDatabase(&OldIrql); 00361 00362 // 00363 // If the interrupt object is connected, then disconnect it from the 00364 // specified vector. 00365 // 00366 00367 Connected = Interrupt->Connected; 00368 if (Connected != FALSE) { 00369 Irql = Interrupt->Irql; 00370 Vector = Interrupt->Vector; 00371 00372 // 00373 // If the specified interrupt vector is not connected to the chained 00374 // interrupt dispatcher, then disconnect it by setting its dispatch 00375 // address to the unexpected interrupt routine. Else remove the 00376 // interrupt object from the interrupt chain. If there is only 00377 // one entry remaining in the list, then reestablish the dispatch 00378 // address. 00379 // 00380 00381 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00382 KINTERRUPT, 00383 DispatchCode[0]); 00384 00385 if (Interruptx->DispatchAddress == 00386 (PKINTERRUPT_ROUTINE)KiChainedDispatch) { 00387 KeRaiseIrql((KIRQL)(max(Irql, SYNCH_LEVEL)), &PreviousIrql); 00388 if (Interrupt == Interruptx) { 00389 Interruptx = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink, 00390 KINTERRUPT, InterruptListEntry); 00391 Interruptx->DispatchAddress = 00392 (PKINTERRUPT_ROUTINE)KiChainedDispatch; 00393 Interruptx->DispatchCode[0] = *(PULONG)KiChainedDispatch; 00394 Interruptx->DispatchCode[1] = *(((PULONG)KiChainedDispatch)+1); 00395 PCR->InterruptRoutine[Vector] = 00396 (PKINTERRUPT_ROUTINE)Interruptx->DispatchCode; 00397 00398 } 00399 00400 RemoveEntryList(&Interrupt->InterruptListEntry); 00401 Interrupty = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink, 00402 KINTERRUPT, 00403 InterruptListEntry); 00404 00405 if (Interruptx == Interrupty) { 00406 if (Interrupt->FloatingSave) { 00407 Interrupt->DispatchAddress = KiFloatingDispatch; 00408 00409 } else { 00410 if (Interrupt->Irql == Interrupt->SynchronizeIrql) { 00411 #if defined(NT_UP) 00412 Interrupt->DispatchAddress = 00413 (PKINTERRUPT_ROUTINE)Interrupt->ServiceRoutine; 00414 #else 00415 Interrupt->DispatchAddress = 00416 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00417 #endif 00418 00419 } else { 00420 Interrupt->DispatchAddress = 00421 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00422 } 00423 } 00424 00425 // 00426 // Copy the function descriptor for the Dispatch routine 00427 // into DispatchCode. This will be used by KiInterruptEx- 00428 // ception to dispatch the interrupt. 00429 // 00430 Interrupty->DispatchCode[0] = 00431 *(PULONG)(Interrupty->DispatchAddress); 00432 Interrupty->DispatchCode[1] = 00433 *(((PULONG)(Interrupty->DispatchAddress))+1); 00434 PCR->InterruptRoutine[Vector] = 00435 (PKINTERRUPT_ROUTINE)Interrupty->DispatchCode; 00436 00437 } 00438 00439 KeLowerIrql(PreviousIrql); 00440 00441 } else { 00442 HalDisableSystemInterrupt(Vector, Irql); 00443 PCR->InterruptRoutine[Vector] = 00444 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode); 00445 } 00446 #ifdef NOTDEF 00447 KeSweepIcache(TRUE); 00448 #endif 00449 Interrupt->Connected = FALSE; 00450 } 00451 00452 // 00453 // Unlock dispatcher database and lower IRQL to its previous value. 00454 // 00455 00456 KiUnlockDispatcherDatabase(OldIrql); 00457 00458 // 00459 // Set system affinity back to the original value. 00460 // 00461 00462 KeRevertToUserAffinityThread(); 00463 00464 // 00465 // Return whether interrupt was disconnected from the specified vector. 00466 // 00467 00468 return Connected; 00469 } }

VOID KeInitializeInterrupt IN PKINTERRUPT  Interrupt,
IN PKSERVICE_ROUTINE  ServiceRoutine,
IN PVOID  ServiceContext,
IN PKSPIN_LOCK SpinLock  OPTIONAL,
IN ULONG  Vector,
IN KIRQL  Irql,
IN KIRQL  SynchronizeIrql,
IN KINTERRUPT_MODE  InterruptMode,
IN BOOLEAN  ShareVector,
IN CCHAR  ProcessorNumber,
IN BOOLEAN  FloatingSave
 

Definition at line 33 of file ppc/intobj.c.

References FALSE, and InterruptObject.

Referenced by IoConnectInterrupt().

00049 : 00050 00051 This function initializes a kernel interrupt object. The service routine, 00052 service context, spin lock, vector, IRQL, Synchronized IRQL, and floating 00053 context save flag are initialized. 00054 00055 Arguments: 00056 00057 Interrupt - Supplies a pointer to a control object of type interrupt. 00058 00059 ServiceRoutine - Supplies a pointer to a function that is to be 00060 executed when an interrupt occurs via the specified interrupt 00061 vector. 00062 00063 ServiceContext - Supplies a pointer to an arbitrary data structure which is 00064 to be passed to the function specified by the ServiceRoutine parameter. 00065 00066 SpinLock - Supplies a pointer to an executive spin lock. 00067 00068 Vector - Supplies the index of the entry in the Interrupt Dispatch Table 00069 that is to be associated with the ServiceRoutine function. 00070 00071 Irql - Supplies the request priority of the interrupting source. 00072 00073 SynchronizeIrql - The request priority that the interrupt should be 00074 synchronized with. 00075 00076 InterruptMode - Supplies the mode of the interrupt; LevelSensitive or 00077 Latched. 00078 00079 ShareVector - Supplies a boolean value that specifies whether the 00080 vector can be shared with other interrupt objects or not. If FALSE 00081 then the vector may not be shared, if TRUE it may be. 00082 Latched. 00083 00084 ProcessorNumber - Supplies the number of the processor to which the 00085 interrupt will be connected. 00086 00087 FloatingSave - Supplies a boolean value that determines whether the 00088 floating point registers and pipe line are to be saved before calling 00089 the ServiceRoutine function. 00090 (currently ignored on PowerPC). 00091 00092 Return Value: 00093 00094 None. 00095 00096 --*/ 00097 00098 { 00099 // 00100 // Initialize standard control object header. 00101 // 00102 00103 Interrupt->Type = InterruptObject; 00104 Interrupt->Size = sizeof(KINTERRUPT); 00105 00106 // 00107 // Initialize the address of the service routine, the service context, 00108 // the address of the spin lock, the address of the actual spin lock 00109 // that will be used, the vector number, the IRQL of the interrupting 00110 // source, the Synchronized IRQL of the interrupt object, the interrupt 00111 // mode, the processor number, and the floating context save flag. 00112 // 00113 00114 Interrupt->ServiceRoutine = ServiceRoutine; 00115 Interrupt->ServiceContext = ServiceContext; 00116 00117 Interrupt->SpinLock = 0; 00118 if (ARGUMENT_PRESENT(SpinLock)) { 00119 Interrupt->ActualLock = SpinLock; 00120 } else { 00121 Interrupt->ActualLock = &Interrupt->SpinLock; 00122 } 00123 00124 Interrupt->Vector = Vector; 00125 Interrupt->Irql = Irql; 00126 Interrupt->SynchronizeIrql = SynchronizeIrql; 00127 Interrupt->Mode = InterruptMode; 00128 Interrupt->ShareVector = ShareVector; 00129 Interrupt->Number = ProcessorNumber; 00130 Interrupt->FloatingSave = FloatingSave; 00131 00132 // 00133 // Set the connected state of the interrupt object to FALSE. 00134 // 00135 00136 Interrupt->Connected = FALSE; 00137 return; 00138 }


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