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)
PKTRAP_FRAME KeGetInterruptTrapFrame (VOID)


Function Documentation

BOOLEAN KeConnectInterrupt IN PKINTERRUPT  Interrupt  ) 
 

Definition at line 154 of file alpha/intobj.c.

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

00160 : 00161 00162 This function connects an interrupt object to the interrupt vector 00163 specified by the interrupt object. If the interrupt object is already 00164 connected, or an attempt is made to connect to an interrupt that cannot 00165 be connected, then a value of FALSE is returned. Else the specified 00166 interrupt object is connected to the interrupt vector, the connected 00167 state is set to TRUE, and TRUE is returned as the function value. 00168 00169 Arguments: 00170 00171 Interrupt - Supplies a pointer to a control object of type interrupt. 00172 00173 Return Value: 00174 00175 If the interrupt object is already connected or an attempt is made to 00176 connect to an interrupt vector that cannot be connected, then a value 00177 of FALSE is returned. Else a value of TRUE is returned. 00178 00179 --*/ 00180 00181 { 00182 00183 BOOLEAN Connected; 00184 PKINTERRUPT Interruptx; 00185 KIRQL Irql; 00186 CHAR Number; 00187 KIRQL OldIrql; 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))) || 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) { 00240 Interrupt->DispatchAddress = KiFloatingDispatch; 00241 00242 } else { 00243 if (Interrupt->Irql == Interrupt->SynchronizeIrql) { 00244 Interrupt->DispatchAddress = 00245 (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame; 00246 } else { 00247 Interrupt->DispatchAddress = 00248 (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise; 00249 } 00250 } 00251 00252 PCR->InterruptRoutine[Vector] = 00253 (PKINTERRUPT_ROUTINE)(&Interrupt->DispatchCode); 00254 00255 HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode); 00256 00257 } else { 00258 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector], 00259 KINTERRUPT, 00260 DispatchCode[0]); 00261 00262 if (Interrupt->Mode == Interruptx->Mode) { 00263 Connected = TRUE; 00264 Interrupt->Connected = TRUE; 00265 ASSERT (Irql <= KiSynchIrql); 00266 if (Interruptx->DispatchAddress != KiChainedDispatch) { 00267 InitializeListHead(&Interruptx->InterruptListEntry); 00268 Interruptx->DispatchAddress = KiChainedDispatch; 00269 } 00270 00271 InsertTailList(&Interruptx->InterruptListEntry, 00272 &Interrupt->InterruptListEntry); 00273 } 00274 } 00275 } 00276 00277 // 00278 // Unlock dispatcher database and lower IRQL to its previous value. 00279 // 00280 00281 KiUnlockDispatcherDatabase(OldIrql); 00282 00283 // 00284 // Set system affinity back to the original value. 00285 // 00286 00287 KeRevertToUserAffinityThread(); 00288 } 00289 00290 // 00291 // Return whether interrupt was connected to the specified vector. 00292 // 00293 00294 return Connected; 00295 }

BOOLEAN KeDisconnectInterrupt IN PKINTERRUPT  Interrupt  ) 
 

Definition at line 298 of file alpha/intobj.c.

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

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

PKTRAP_FRAME KeGetInterruptTrapFrame VOID   ) 
 

Definition at line 434 of file alpha/intobj.c.

References ASSERT, DEVICE_LEVEL, KeGetCurrentPrcb, and NULL.

00439 : 00440 00441 Returns a pointer to the last interrupt trap frame on the 00442 current stack. This allows the machine check handlers in 00443 the HAL to inspect the trap frame without having to pass 00444 the PKTRAP_FRAME to every interrupt handler. 00445 00446 Arguments: 00447 00448 None. 00449 00450 Return Value: 00451 00452 Pointer to the last interrupt trap frame on the stack. 00453 00454 --*/ 00455 00456 { 00457 ASSERT(KeGetCurrentIrql() >= DEVICE_LEVEL); 00458 ASSERT(KeGetCurrentPrcb()->InterruptTrapFrame != NULL); 00459 00460 return(KeGetCurrentPrcb()->InterruptTrapFrame); 00461 00462 } }

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 32 of file alpha/intobj.c.

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

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


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