test: alpha/intobj.c File Reference

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 }