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 153 of file mips/intobj.c.

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

00159 : 00160 00161 This function connects an interrupt object to the interrupt vector 00162 specified by the interrupt object. If the interrupt object is already 00163 connected, or an attempt is made to connect to an interrupt that cannot 00164 be connected, then a value of FALSE is returned. Else the specified 00165 interrupt object is connected to the interrupt vector, the connected 00166 state is set to TRUE, and TRUE is returned as the function value. 00167 00168 Arguments: 00169 00170 Interrupt - Supplies a pointer to a control object of type interrupt. 00171 00172 Return Value: 00173 00174 If the interrupt object is already connected or an attempt is made to 00175 connect to an interrupt vector that cannot be connected, then a value 00176 of FALSE is returned. Else a value of TRUE is returned. 00177 00178 --*/ 00179 00180 { 00181 00182 BOOLEAN Connected; 00183 PKINTERRUPT Interruptx; 00184 KIRQL Irql; 00185 CHAR Number; 00186 KIRQL OldIrql; 00187 KIRQL PreviousIrql; 00188 ULONG Vector; 00189 00190 // 00191 // If the interrupt object is already connected, the interrupt vector 00192 // number is invalid, an attempt is being made to connect to a vector 00193 // that cannot be connected, the interrupt request level is invalid, 00194 // the processor number is invalid, of the interrupt vector is less 00195 // than or equal to the highest level and it not equal to the specified 00196 // IRQL, then do not connect the interrupt object. Else connect interrupt 00197 // object to the specified vector and establish the proper interrupt 00198 // dispatcher. 00199 // 00200 00201 Connected = FALSE; 00202 Irql = Interrupt->Irql; 00203 Number = Interrupt->Number; 00204 Vector = Interrupt->Vector; 00205 if ((((Vector >= MAXIMUM_VECTOR) || (Irql > HIGH_LEVEL) || 00206 ((Vector <= HIGH_LEVEL) && 00207 ((((1 << Vector) & PCR->ReservedVectors) != 0) || (Vector != Irql))) || 00208 (Number >= KeNumberProcessors))) == FALSE) { 00209 00210 // 00211 // Set system affinity to the specified processor. 00212 // 00213 00214 KeSetSystemAffinityThread((KAFFINITY)(1 << Number)); 00215 00216 // 00217 // Raise IRQL to dispatcher level and lock dispatcher database. 00218 // 00219 00220 KiLockDispatcherDatabase(&OldIrql); 00221 00222 // 00223 // If the specified interrupt vector is not connected, then 00224 // connect the interrupt vector to the interrupt object dispatch 00225 // code, establish the dispatcher address, and set the new 00226 // interrupt mode and enable masks. Else if the interrupt is 00227 // already chained, then add the new interrupt object at the end 00228 // of the chain. If the interrupt vector is not chained, then 00229 // start a chain with the previous interrupt object at the front 00230 // of the chain. The interrupt mode of all interrupt objects in 00231 // a chain must be the same. 00232 // 00233 00234 if (Interrupt->Connected == FALSE) { 00235 if (PCR->InterruptRoutine[Vector] == 00236 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode)) { 00237 Connected = TRUE; 00238 Interrupt->Connected = TRUE; 00239 if (Interrupt->FloatingSave != FALSE) { 00240 Interrupt->DispatchAddress = KiFloatingDispatch; 00241 00242 } else { 00243 if (Interrupt->Irql == Interrupt->SynchronizeIrql) { 00244 Interrupt->DispatchAddress = 00245 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00246 00247 } else { 00248 Interrupt->DispatchAddress = 00249 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00250 } 00251 } 00252 00253 PCR->InterruptRoutine[Vector] = 00254 (PKINTERRUPT_ROUTINE)(&Interrupt->DispatchCode); 00255 00256 HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode); 00257 00258 } else { 00259 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00260 KINTERRUPT, 00261 DispatchCode[0]); 00262 00263 if (Interrupt->Mode == Interruptx->Mode) { 00264 Connected = TRUE; 00265 Interrupt->Connected = TRUE; 00266 KeRaiseIrql(max(Irql, (KIRQL)KiSynchIrql), &PreviousIrql); 00267 if (Interruptx->DispatchAddress != KiChainedDispatch) { 00268 InitializeListHead(&Interruptx->InterruptListEntry); 00269 Interruptx->DispatchAddress = KiChainedDispatch; 00270 } 00271 00272 InsertTailList(&Interruptx->InterruptListEntry, 00273 &Interrupt->InterruptListEntry); 00274 00275 KeLowerIrql(PreviousIrql); 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 mips/intobj.c.

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

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 KIRQL PreviousIrql; 00334 ULONG Vector; 00335 00336 // 00337 // Set system affinity to the specified processor. 00338 // 00339 00340 KeSetSystemAffinityThread((KAFFINITY)(1 << Interrupt->Number)); 00341 00342 // 00343 // Raise IRQL to dispatcher level and lock dispatcher database. 00344 // 00345 00346 KiLockDispatcherDatabase(&OldIrql); 00347 00348 // 00349 // If the interrupt object is connected, then disconnect it from the 00350 // specified vector. 00351 // 00352 00353 Connected = Interrupt->Connected; 00354 if (Connected != FALSE) { 00355 Irql = Interrupt->Irql; 00356 Vector = Interrupt->Vector; 00357 00358 // 00359 // If the specified interrupt vector is not connected to the chained 00360 // interrupt dispatcher, then disconnect it by setting its dispatch 00361 // address to the unexpected interrupt routine. Else remove the 00362 // interrupt object from the interrupt chain. If there is only 00363 // one entry remaining in the list, then reestablish the dispatch 00364 // address. 00365 // 00366 00367 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00368 KINTERRUPT, 00369 DispatchCode[0]); 00370 00371 if (Interruptx->DispatchAddress == KiChainedDispatch) { 00372 KeRaiseIrql(max(Irql, (KIRQL)KiSynchIrql), &PreviousIrql); 00373 if (Interrupt == Interruptx) { 00374 Interruptx = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink, 00375 KINTERRUPT, InterruptListEntry); 00376 Interruptx->DispatchAddress = KiChainedDispatch; 00377 PCR->InterruptRoutine[Vector] = 00378 (PKINTERRUPT_ROUTINE)(&Interruptx->DispatchCode); 00379 } 00380 00381 RemoveEntryList(&Interrupt->InterruptListEntry); 00382 Interrupty = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink, 00383 KINTERRUPT, 00384 InterruptListEntry); 00385 00386 if (Interruptx == Interrupty) { 00387 if (Interrupty->FloatingSave != FALSE) { 00388 Interrupty->DispatchAddress = KiFloatingDispatch; 00389 00390 } else { 00391 if (Interrupty->Irql == Interrupty->SynchronizeIrql) { 00392 Interrupty->DispatchAddress = 00393 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00394 00395 } else { 00396 Interrupty->DispatchAddress = 00397 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00398 } 00399 } 00400 00401 PCR->InterruptRoutine[Vector] = 00402 (PKINTERRUPT_ROUTINE)(&Interrupty->DispatchCode); 00403 } 00404 00405 KeLowerIrql(PreviousIrql); 00406 00407 } else { 00408 HalDisableSystemInterrupt(Vector, Irql); 00409 PCR->InterruptRoutine[Vector] = 00410 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode); 00411 } 00412 00413 KeSweepIcache(TRUE); 00414 Interrupt->Connected = FALSE; 00415 } 00416 00417 // 00418 // Unlock dispatcher database and lower IRQL to its previous value. 00419 // 00420 00421 KiUnlockDispatcherDatabase(OldIrql); 00422 00423 // 00424 // Set system affinity back to the original value. 00425 // 00426 00427 KeRevertToUserAffinityThread(); 00428 00429 // 00430 // Return whether interrupt was disconnected from the specified vector. 00431 // 00432 00433 return Connected; 00434 } }

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

References FALSE, Index, InterruptObject, and KeSweepIcache().

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; 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 // Copy the interrupt dispatch code template into the interrupt object 00134 // and flush the dcache on all processors that the current thread can 00135 // run on to ensure that the code is actually in memory. 00136 // 00137 00138 for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) { 00139 Interrupt->DispatchCode[Index] = KiInterruptTemplate[Index]; 00140 } 00141 00142 KeSweepIcache(FALSE); 00143 00144 // 00145 // Set the connected state of the interrupt object to FALSE. 00146 // 00147 00148 Interrupt->Connected = FALSE; 00149 return; 00150 }


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