Example #1
0
VOID
FASTCALL
KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame,
                    IN PKINTERRUPT Interrupt)
{       
    KIRQL OldIrql;

    /* Increase interrupt count */
    KeGetCurrentPrcb()->InterruptCount++;
    
    /* Begin the interrupt, making sure it's not spurious */
    if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
                                Interrupt->Vector,
                                &OldIrql))
    {
        /* Acquire interrupt lock */
        KxAcquireSpinLock(Interrupt->ActualLock);
        
        /* Call the ISR */
        Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
        
        /* Release interrupt lock */
        KxReleaseSpinLock(Interrupt->ActualLock);
        
        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
    }
    else
    {
        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
    }
}
Example #2
0
VOID
FASTCALL
KiUnexpectedInterruptTailHandler(IN PKTRAP_FRAME TrapFrame)
{
    KIRQL OldIrql;
    
    /* Enter trap */
    KiEnterInterruptTrap(TrapFrame);
    
    /* Increase interrupt count */
    KeGetCurrentPrcb()->InterruptCount++;
    
    /* Start the interrupt */
    if (HalBeginSystemInterrupt(HIGH_LEVEL, TrapFrame->ErrCode, &OldIrql))
    {
        /* Warn user */
        DPRINT1("\n\x7\x7!!! Unexpected Interrupt 0x%02lx !!!\n", TrapFrame->ErrCode);
        
        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
    }
    else
    {
        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
    }
}
Example #3
0
File: apic.c Project: GYGit/reactos
VOID
DECLSPEC_NORETURN
FASTCALL
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
    KPROCESSOR_MODE ProcessorMode;
    KIRQL OldIrql;
    ASSERT(ApicGetProcessorIrql() == APC_LEVEL);

   /* Enter trap */
    KiEnterInterruptTrap(TrapFrame);

#ifdef APIC_LAZY_IRQL
    if (!HalBeginSystemInterrupt(APC_LEVEL, APC_VECTOR, &OldIrql))
    {
        /* "Spurious" interrupt, exit the interrupt */
        KiEoiHelper(TrapFrame);
    }
#else
    /* Save the old IRQL */
    OldIrql = ApicGetCurrentIrql();
    ASSERT(OldIrql < APC_LEVEL);
#endif

    /* Raise to APC_LEVEL */
    ApicRaiseIrql(APC_LEVEL);

    /* End the interrupt */
    ApicSendEOI();

    /* Kernel or user APC? */
    if (KiUserTrap(TrapFrame)) ProcessorMode = UserMode;
    else if (TrapFrame->EFlags & EFLAGS_V86_MASK) ProcessorMode = UserMode;
    else ProcessorMode = KernelMode;

    /* Enable interrupts and call the kernel's APC interrupt handler */
    _enable();
    KiDeliverApc(ProcessorMode, NULL, TrapFrame);

    /* Disable interrupts */
    _disable();

    /* Restore the old IRQL */
    ApicLowerIrql(OldIrql);

    /* Exit the interrupt */
    KiEoiHelper(TrapFrame);
}
Example #4
0
File: apic.c Project: GYGit/reactos
VOID
DECLSPEC_NORETURN
FASTCALL
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
{
    KIRQL OldIrql;
    ASSERT(ApicGetProcessorIrql() == DISPATCH_LEVEL);

   /* Enter trap */
    KiEnterInterruptTrap(TrapFrame);

#ifdef APIC_LAZY_IRQL
    if (!HalBeginSystemInterrupt(DISPATCH_LEVEL, DISPATCH_VECTOR, &OldIrql))
    {
        /* "Spurious" interrupt, exit the interrupt */
        KiEoiHelper(TrapFrame);
    }
#else
    /* Get the current IRQL */
    OldIrql = ApicGetCurrentIrql();
    ASSERT(OldIrql < DISPATCH_LEVEL);
#endif

    /* Raise to DISPATCH_LEVEL */
    ApicRaiseIrql(DISPATCH_LEVEL);

    /* End the interrupt */
    ApicSendEOI();

    /* Enable interrupts and call the kernel's DPC interrupt handler */
    _enable();
    KiDispatchInterrupt();
    _disable();

    /* Restore the old IRQL */
    ApicLowerIrql(OldIrql);

    /* Exit the interrupt */
    KiEoiHelper(TrapFrame);
}
Example #5
0
VOID
FASTCALL
KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
                  IN PKINTERRUPT Interrupt)
{
    KIRQL OldIrql, OldInterruptIrql = 0;
    BOOLEAN Handled;
    PLIST_ENTRY NextEntry, ListHead;

    /* Increase interrupt count */
    KeGetCurrentPrcb()->InterruptCount++;

    /* Begin the interrupt, making sure it's not spurious */
    if (HalBeginSystemInterrupt(Interrupt->Irql,
                                Interrupt->Vector,
                                &OldIrql))
    {
        /* Get list pointers */
        ListHead = &Interrupt->InterruptListEntry;
        NextEntry = ListHead; /* The head is an entry! */
        while (TRUE)
        {
            /* Check if this interrupt's IRQL is higher than the current one */
            if (Interrupt->SynchronizeIrql > Interrupt->Irql)
            {
                /* Raise to higher IRQL */
                OldInterruptIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
            }
        
            /* Acquire interrupt lock */
            KxAcquireSpinLock(Interrupt->ActualLock);

            /* Call the ISR */
            Handled = Interrupt->ServiceRoutine(Interrupt,
                                                Interrupt->ServiceContext);

            /* Release interrupt lock */
            KxReleaseSpinLock(Interrupt->ActualLock);
        
            /* Check if this interrupt's IRQL is higher than the current one */
            if (Interrupt->SynchronizeIrql > Interrupt->Irql)
            {
                /* Lower the IRQL back */
                ASSERT(OldInterruptIrql == Interrupt->Irql);
                KfLowerIrql(OldInterruptIrql);
            }
        
            /* Check if the interrupt got handled and it's level */
            if ((Handled) && (Interrupt->Mode == LevelSensitive)) break;
            
            /* What's next? */
            NextEntry = NextEntry->Flink;
                
            /* Is this the last one? */
            if (NextEntry == ListHead)
            {
                /* Level should not have gotten here */
                if (Interrupt->Mode == LevelSensitive) break;
                
                /* As for edge, we can only exit once nobody can handle the interrupt */
                if (!Handled) break;
            }
            
            /* Get the interrupt object for the next pass */
            Interrupt = CONTAINING_RECORD(NextEntry, KINTERRUPT, InterruptListEntry);
        }

        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, FALSE);
    }
    else
    {
        /* Now call the epilogue code */
        KiExitInterrupt(TrapFrame, OldIrql, TRUE);
    }
}