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 ia64/intobj.c.

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

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 ULONG Vector; 00176 00177 // 00178 // If the interrupt object is already connected, the interrupt vector 00179 // number is invalid, an attempt is being made to connect to a vector 00180 // that cannot be connected, the interrupt request level is invalid, 00181 // the processor number is invalid, of the interrupt vector is less 00182 // than or equal to the highest level and it not equal to the specified 00183 // IRQL, then do not connect the interrupt object. Else connect interrupt 00184 // object to the specified vector and establish the proper interrupt 00185 // dispatcher. 00186 // 00187 00188 Connected = FALSE; 00189 Irql = Interrupt->Irql; 00190 Number = Interrupt->Number; 00191 Vector = Interrupt->Vector; 00192 if ((((Vector >= MAXIMUM_VECTOR) || (Irql > HIGH_LEVEL) || 00193 ((Vector <= HIGH_LEVEL) && 00194 ((((1 << Vector) & PCR->ReservedVectors) != 0) || (Vector != Irql))) || 00195 (Number >= KeNumberProcessors))) == FALSE) { 00196 00197 // 00198 // Set system affinity to the specified processor. 00199 // 00200 00201 KeSetSystemAffinityThread((KAFFINITY)(1 << Number)); 00202 00203 // 00204 // Raise IRQL to dispatcher level and lock dispatcher database. 00205 // 00206 00207 KiLockDispatcherDatabase(&OldIrql); 00208 00209 // 00210 // If the specified interrupt vector is not connected, then 00211 // connect the interrupt vector to the interrupt object dispatch 00212 // code, establish the dispatcher address, and set the new 00213 // interrupt mode and enable masks. Else if the interrupt is 00214 // already chained, then add the new interrupt object at the end 00215 // of the chain. If the interrupt vector is not chained, then 00216 // start a chain with the previous interrupt object at the front 00217 // of the chain. The interrupt mode of all interrupt objects in 00218 // a chain must be the same. 00219 // 00220 00221 if (Interrupt->Connected == FALSE) { 00222 if (PCR->InterruptRoutine[Vector] == 00223 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode)) { 00224 Connected = TRUE; 00225 Interrupt->Connected = TRUE; 00226 if (Interrupt->FloatingSave != FALSE) { 00227 Interrupt->DispatchAddress = KiFloatingDispatch; 00228 00229 } else { 00230 if (Interrupt->Irql == Interrupt->SynchronizeIrql) { 00231 Interrupt->DispatchAddress = 00232 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00233 00234 } else { 00235 Interrupt->DispatchAddress = 00236 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00237 } 00238 } 00239 00240 // 00241 // Copy the plabel for the Dispatch routine into DispatchCode. 00242 // This will be used by KiExternalInterruptHandler to 00243 // dispatch the interrupt. 00244 // 00245 00246 00247 RtlMoveMemory(Interrupt->DispatchCode, 00248 Interrupt->DispatchAddress, 00249 DISPATCH_LENGTH*4); 00250 00251 PCR->InterruptRoutine[Vector] = 00252 (PKINTERRUPT_ROUTINE)(&Interrupt->DispatchCode); 00253 00254 HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode); 00255 00256 } else { 00257 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00258 KINTERRUPT, 00259 DispatchCode[0]); 00260 00261 if (Interrupt->Mode == Interruptx->Mode) { 00262 Connected = TRUE; 00263 Interrupt->Connected = TRUE; 00264 ASSERT (Irql <= KiSynchIrql); 00265 if (Interruptx->DispatchAddress != KiChainedDispatch) { 00266 InitializeListHead(&Interruptx->InterruptListEntry); 00267 Interruptx->DispatchAddress = KiChainedDispatch; 00268 00269 RtlMoveMemory(Interruptx->DispatchCode, 00270 Interruptx->DispatchAddress, 00271 DISPATCH_LENGTH*4); 00272 } 00273 00274 InsertTailList(&Interruptx->InterruptListEntry, 00275 &Interrupt->InterruptListEntry); 00276 } 00277 } 00278 } 00279 00280 // 00281 // Unlock dispatcher database and lower IRQL to its previous value. 00282 // 00283 00284 KiUnlockDispatcherDatabase(OldIrql); 00285 00286 // 00287 // Set system affinity back to the original value. 00288 // 00289 00290 KeRevertToUserAffinityThread(); 00291 } 00292 00293 // 00294 // Return whether interrupt was connected to the specified vector. 00295 // 00296 00297 return Connected; 00298 }

BOOLEAN KeDisconnectInterrupt IN PKINTERRUPT  Interrupt  ) 
 

Definition at line 301 of file ia64/intobj.c.

References ASSERT, _KINTERRUPT::DispatchAddress, _KINTERRUPT::DispatchCode, FALSE, _KINTERRUPT::FloatingSave, HalDisableSystemInterrupt(), _KINTERRUPT::InterruptListEntry, _KINTERRUPT::Irql, KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KiChainedDispatch(), KiFloatingDispatch(), KiInterruptDispatchRaise(), KiInterruptDispatchSame(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and _KINTERRUPT::SynchronizeIrql.

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

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 30 of file ia64/intobj.c.

References FALSE, Index, and InterruptObject.

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