예제 #1
0
VOID
KiGetVectorInfo (
    IN  ULONG                Vector,
    OUT PDISPATCH_INFO       DispatchInfo
    )
{
    PKINTERRUPT_ROUTINE Dispatch;
    ULONG CurrentDispatch;
    ULONG DispatchType;
    UCHAR IDTEntry;

    //
    // Get second level dispatch point
    //


    DispatchType = HalSystemVectorDispatchEntry (
                        Vector,
                        &DispatchInfo->FlatDispatch,
                        &DispatchInfo->NoDispatch
                        );

    //
    // Get vector info
    //

    switch (DispatchType) {
        case 0:
            //
            // Primary dispatch
            //

            IDTEntry = HalVectorToIDTEntry(Vector);
            DispatchInfo->NoDispatch = (PKINTERRUPT_ROUTINE) (((ULONG) &KiStartUnexpectedRange) +
                                     (IDTEntry - PRIMARY_VECTOR_BASE) * KiUnexpectedEntrySize);

            DispatchInfo->InterruptDispatch = KiInterruptDispatch;
            DispatchInfo->FloatingDispatch = KiFloatingDispatch;
            DispatchInfo->ChainedDispatch = KiChainedDispatch;
            DispatchInfo->FlatDispatch = NULL;

            CurrentDispatch = (ULONG) KiReturnHandlerAddressFromIDT(Vector);
            DispatchInfo->Interrupt = CONTAINING_RECORD (
                                        CurrentDispatch,
                                        KINTERRUPT,
                                        DispatchCode
                                        );
            break;

        case 1:
            //
            // Secondary dispatch.
            //

            DispatchInfo->InterruptDispatch = KiInterruptDispatch2ndLvl;
            DispatchInfo->FloatingDispatch = KiInterruptDispatch2ndLvl;
            DispatchInfo->ChainedDispatch = KiChainedDispatch2ndLvl;

            CurrentDispatch = (ULONG) *DispatchInfo->FlatDispatch;
            DispatchInfo->Interrupt = (PKINTERRUPT) ( (PUCHAR) CurrentDispatch -
                                            (PUCHAR) KiInterruptTemplate +
                                            (PUCHAR) &KiInterruptTemplate2ndDispatch
                                            );
            break;

        default:
            // Other values reserved
            KeBugCheck (MISMATCHED_HAL);
    }


    //
    // Determine dispatch type
    //

    if (((PKINTERRUPT_ROUTINE) CurrentDispatch) == DispatchInfo->NoDispatch) {

        //
        // Is connected to the NoDispatch function
        //

        DispatchInfo->Type = NoConnect;

    } else {
        Dispatch = DispatchInfo->Interrupt->DispatchAddress;

        if (Dispatch == DispatchInfo->ChainedDispatch) {
            //
            // Is connected to the chained handler
            //

            DispatchInfo->Type = ChainConnect;

        } else if (Dispatch == DispatchInfo->InterruptDispatch ||
                   Dispatch == DispatchInfo->FloatingDispatch) {
            //
            // If connection to the non-chained handler
            //

            DispatchInfo->Type = NormalConnect;

        } else {

            //
            // Unknown connection
            //

            DispatchInfo->Type = UnknownConnect;
#if DBG
            DbgPrint ("KiGetVectorInfo not understood\n");
#endif
        }
    }
}
예제 #2
0
파일: irqobj.c 프로젝트: hackbunny/reactos
VOID
NTAPI
KiGetVectorDispatch(IN ULONG Vector,
                    IN PDISPATCH_INFO Dispatch)
{
    PKINTERRUPT_ROUTINE Handler;
    PVOID Current;
    UCHAR Type;
    UCHAR Entry;

    /* Check if this is a primary or 2nd-level dispatch */
    Type = HalSystemVectorDispatchEntry(Vector,
                                        &Dispatch->FlatDispatch,
                                        &Dispatch->NoDispatch);
    ASSERT(Type == 0);

    /* Get the IDT entry for this vector */
    Entry = HalVectorToIDTEntry(Vector);

    /* Setup the unhandled dispatch */
    Dispatch->NoDispatch = (PVOID)(((ULONG_PTR)&KiStartUnexpectedRange) +
                                   (Entry - PRIMARY_VECTOR_BASE) *
                                   KiUnexpectedEntrySize);

    /* Setup the handlers */
    Dispatch->InterruptDispatch = (PVOID)KiInterruptDispatch;
    Dispatch->FloatingDispatch = NULL; // Floating Interrupts are not supported
    Dispatch->ChainedDispatch = (PVOID)KiChainedDispatch;
    Dispatch->FlatDispatch = NULL;

    /* Get the current handler */
    Current = KeQueryInterruptHandler(Vector);

    /* Set the interrupt */
    Dispatch->Interrupt = CONTAINING_RECORD(Current,
                                            KINTERRUPT,
                                            DispatchCode);

    /* Check what this interrupt is connected to */
    if ((PKINTERRUPT_ROUTINE)Current == Dispatch->NoDispatch)
    {
        /* Not connected */
        Dispatch->Type = NoConnect;
    }
    else
    {
        /* Get the handler */
        Handler = Dispatch->Interrupt->DispatchAddress;
        if (Handler == Dispatch->ChainedDispatch)
        {
            /* It's a chained interrupt */
            Dispatch->Type = ChainConnect;
        }
        else if ((Handler == Dispatch->InterruptDispatch) ||
                 (Handler == Dispatch->FloatingDispatch))
        {
            /* It's unchained */
            Dispatch->Type = NormalConnect;
        }
        else
        {
            /* Unknown */
            Dispatch->Type = UnknownConnect;
        }
    }
}