mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[NTOS]: The last big step. Now that the HAL is in C, we can handle interrupts in C. Do so using the proposed model that was #if'ed out, but with some improvements.
[NTOS]: Implement KiUnexpectedInterruptTail and KiUnexpectedInterrupt in C as well. This is [PERF] too since the C interrupt handling code is a lot more efficient than the ASM one. Numbers look good here. svn path=/trunk/; revision=45304
This commit is contained in:
parent
ac9c20ac0f
commit
5b14ade9f8
5 changed files with 128 additions and 410 deletions
|
@ -197,7 +197,7 @@ idt _KiUnexpectedInterrupt&Number, INT_32_DPL0
|
|||
.macro GENERATE_INT_HANDLER Number
|
||||
.func KiUnexpectedInterrupt&Number
|
||||
_KiUnexpectedInterrupt&Number:
|
||||
push PRIMARY_VECTOR_BASE + Number
|
||||
mov eax, PRIMARY_VECTOR_BASE + Number
|
||||
jmp _KiEndUnexpectedRange@0
|
||||
.endfunc
|
||||
.endm
|
||||
|
|
|
@ -954,19 +954,6 @@ KiServiceExit2(
|
|||
IN PKTRAP_FRAME TrapFrame
|
||||
);
|
||||
|
||||
#ifndef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
VOID
|
||||
NTAPI
|
||||
KiInterruptDispatch(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiChainedDispatch(
|
||||
VOID
|
||||
);
|
||||
#else
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInterruptDispatch(
|
||||
|
@ -980,7 +967,6 @@ KiChainedDispatch(
|
|||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt
|
||||
);
|
||||
#endif
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
|
|
@ -97,9 +97,6 @@ KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt,
|
|||
{
|
||||
DISPATCH_INFO Dispatch;
|
||||
PKINTERRUPT_ROUTINE Handler;
|
||||
#ifndef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
PULONG Patch = &Interrupt->DispatchCode[0];
|
||||
#endif
|
||||
|
||||
/* Get vector data */
|
||||
KiGetVectorDispatch(Interrupt->Vector, &Dispatch);
|
||||
|
@ -122,15 +119,6 @@ KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt,
|
|||
Interrupt->DispatchAddress = Handler;
|
||||
|
||||
/* Read note in trap.s -- patching not needed since JMP is static */
|
||||
#ifndef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
/* Jump to the last 4 bytes */
|
||||
Patch = (PULONG)((ULONG_PTR)Patch +
|
||||
((ULONG_PTR)&KiInterruptTemplateDispatch -
|
||||
(ULONG_PTR)KiInterruptTemplate) - 4);
|
||||
|
||||
/* Apply the patch */
|
||||
*Patch = (ULONG)((ULONG_PTR)Handler - ((ULONG_PTR)Patch + 4));
|
||||
#endif
|
||||
|
||||
/* Now set the final handler address */
|
||||
ASSERT(Dispatch.FlatDispatch == NULL);
|
||||
|
@ -141,6 +129,130 @@ KiConnectVectorToInterrupt(IN PKINTERRUPT Interrupt,
|
|||
KeRegisterInterruptHandler(Interrupt->Vector, Handler);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
DECLSPEC_NORETURN
|
||||
KiExitInterrupt(IN PKTRAP_FRAME TrapFrame,
|
||||
IN KIRQL OldIrql,
|
||||
IN BOOLEAN Spurious)
|
||||
{
|
||||
/* Check if this was a real interrupt */
|
||||
if (!Spurious)
|
||||
{
|
||||
/* Set nested trap frame */
|
||||
KeGetPcr()->VdmAlert = (ULONG_PTR)TrapFrame;
|
||||
|
||||
/* It was, disable interrupts and restore the IRQL */
|
||||
_disable();
|
||||
HalEndSystemInterrupt(OldIrql, 0);
|
||||
}
|
||||
|
||||
/* Now exit the trap */
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
|
||||
VOID
|
||||
KiUnexpectedInterrupt(VOID)
|
||||
{
|
||||
/* Crash the machine */
|
||||
KeBugCheck(TRAP_CAUSE_UNKNOWN);
|
||||
}
|
||||
|
||||
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->Eax, &OldIrql))
|
||||
{
|
||||
/* Warn user */
|
||||
DPRINT1("\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n");
|
||||
|
||||
/* Now call the epilogue code */
|
||||
KiExitInterrupt(TrapFrame, OldIrql, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Now call the epilogue code */
|
||||
KiExitInterrupt(TrapFrame, OldIrql, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
typedef
|
||||
FASTCALL
|
||||
VOID
|
||||
(PKI_INTERRUPT_DISPATCH)(
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
/* Increase interrupt count */
|
||||
KeGetCurrentPrcb()->InterruptCount++;
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
/* Enter interrupt frame */
|
||||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* Call the correct dispatcher */
|
||||
((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
|
||||
}
|
||||
|
||||
KiTrap(KiUnexpectedInterruptTail, KI_PUSH_FAKE_ERROR_CODE);
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -199,12 +311,6 @@ KeInitializeInterrupt(IN PKINTERRUPT Interrupt,
|
|||
*DispatchCode++ = KiInterruptTemplate[i];
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
#ifndef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
ASSERT((ULONG_PTR)&KiChainedDispatch2ndLvl -
|
||||
(ULONG_PTR)KiInterruptTemplate <= (KINTERRUPT_DISPATCH_CODES * 4));
|
||||
#endif
|
||||
|
||||
/* Jump to the last 4 bytes */
|
||||
Patch = (PULONG)((ULONG_PTR)Patch +
|
||||
((ULONG_PTR)&KiInterruptTemplateObject -
|
||||
|
|
|
@ -152,58 +152,8 @@ GENERATE_INT_HANDLERS
|
|||
_KiEndUnexpectedRange@0:
|
||||
jmp _KiUnexpectedInterruptTail
|
||||
|
||||
.func KiUnexpectedInterruptTail
|
||||
TRAP_FIXUPS kui_a, kui_t, DoFixupV86, DoFixupAbios
|
||||
_KiUnexpectedInterruptTail:
|
||||
|
||||
/* Enter interrupt trap */
|
||||
INT_PROLOG kui_a, kui_t, DoNotPushFakeErrorCode
|
||||
|
||||
/* Increase interrupt count */
|
||||
inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
|
||||
|
||||
/* Put vector in EBX and make space for KIRQL */
|
||||
mov ebx, [esp]
|
||||
sub esp, 4
|
||||
|
||||
/* Begin interrupt */
|
||||
push esp
|
||||
push ebx
|
||||
push HIGH_LEVEL
|
||||
call _HalBeginSystemInterrupt@12
|
||||
|
||||
/* Check if it was spurious or not */
|
||||
or al, al
|
||||
jnz Handled
|
||||
|
||||
/* Spurious, ignore it */
|
||||
add esp, 8
|
||||
jmp _Kei386EoiHelper@0
|
||||
|
||||
Handled:
|
||||
/* Unexpected interrupt, print a message on debug builds */
|
||||
#if DBG
|
||||
push [esp+4]
|
||||
push offset _UnexpectedMsg
|
||||
call _DbgPrint
|
||||
add esp, 8
|
||||
#endif
|
||||
|
||||
/* Exit the interrupt */
|
||||
mov esi, $
|
||||
cli
|
||||
call _HalEndSystemInterrupt@8
|
||||
jmp _Kei386EoiHelper@0
|
||||
.endfunc
|
||||
|
||||
.globl _KiUnexpectedInterrupt
|
||||
_KiUnexpectedInterrupt:
|
||||
|
||||
/* Bugcheck with invalid interrupt code */
|
||||
push TRAP_CAUSE_UNKNOWN
|
||||
call _KeBugCheck@4
|
||||
|
||||
/* INTERRUPT HANDLERS ********************************************************/
|
||||
/* DPC INTERRUPT HANDLER ******************************************************/
|
||||
|
||||
.func KiDispatchInterrupt@0
|
||||
_KiDispatchInterrupt@0:
|
||||
|
@ -321,10 +271,8 @@ QuantumEnd:
|
|||
.endfunc
|
||||
|
||||
/*
|
||||
* This is how the new-style interrupt template will look like.
|
||||
*
|
||||
* We setup the stack for a trap frame in the KINTERRUPT DispatchCode itself and
|
||||
* then mov the stack address in ECX, since the handlers are FASTCALL. We also
|
||||
* then move the stack address in ECX, since the handlers are FASTCALL. We also
|
||||
* need to know the address of the KINTERRUPT. To do this, we maintain the old
|
||||
* dynamic patching technique (EDX instead of EDI, however) and let the C API
|
||||
* up in KeInitializeInterrupt replace the 0 with the address. Since this is in
|
||||
|
@ -343,13 +291,9 @@ QuantumEnd:
|
|||
* use EDI to store the absolute offset, and jump to that instead.
|
||||
*
|
||||
*/
|
||||
#ifdef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
.func KiInterruptTemplate
|
||||
_KiInterruptTemplate:
|
||||
push 0
|
||||
pushad
|
||||
sub esp, KTRAP_FRAME_LENGTH - KTRAP_FRAME_PREVIOUS_MODE
|
||||
mov ecx, esp
|
||||
TRAP_HANDLER_PROLOG 1, 0
|
||||
|
||||
_KiInterruptTemplate2ndDispatch:
|
||||
/* Dummy code, will be replaced by the address of the KINTERRUPT */
|
||||
|
@ -363,221 +307,3 @@ _KiInterruptTemplateObject:
|
|||
_KiInterruptTemplateDispatch:
|
||||
/* Marks the end of the template so that the jump above can be edited */
|
||||
.endfunc
|
||||
|
||||
#else
|
||||
|
||||
.func KiInterruptTemplate
|
||||
_KiInterruptTemplate:
|
||||
|
||||
/* Enter interrupt trap */
|
||||
INT_PROLOG kit_a, kit_t, DoPushFakeErrorCode
|
||||
|
||||
_KiInterruptTemplate2ndDispatch:
|
||||
/* Dummy code, will be replaced by the address of the KINTERRUPT */
|
||||
mov edi, 0
|
||||
|
||||
_KiInterruptTemplateObject:
|
||||
/* Dummy jump, will be replaced by the actual jump */
|
||||
jmp _KeSynchronizeExecution@12
|
||||
|
||||
_KiInterruptTemplateDispatch:
|
||||
/* Marks the end of the template so that the jump above can be edited */
|
||||
|
||||
TRAP_FIXUPS kit_a, kit_t, DoFixupV86, DoFixupAbios
|
||||
.endfunc
|
||||
|
||||
.func KiChainedDispatch2ndLvl@0
|
||||
_KiChainedDispatch2ndLvl@0:
|
||||
|
||||
NextSharedInt:
|
||||
/* Raise IRQL if necessary */
|
||||
mov cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
|
||||
cmp cl, [edi+KINTERRUPT_IRQL]
|
||||
je 1f
|
||||
call @KfRaiseIrql@4
|
||||
|
||||
1:
|
||||
/* Acquire the lock */
|
||||
mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
|
||||
GetIntLock2:
|
||||
ACQUIRE_SPINLOCK(esi, IntSpin2)
|
||||
|
||||
/* Make sure that this interrupt isn't storming */
|
||||
VERIFY_INT kid2
|
||||
|
||||
/* Save the tick count */
|
||||
mov esi, _KeTickCount
|
||||
|
||||
/* Call the ISR */
|
||||
mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
|
||||
push eax
|
||||
push edi
|
||||
call [edi+KINTERRUPT_SERVICE_ROUTINE]
|
||||
|
||||
/* Save the ISR result */
|
||||
mov bl, al
|
||||
|
||||
/* Check if the ISR timed out */
|
||||
add esi, _KiISRTimeout
|
||||
cmp _KeTickCount, esi
|
||||
jnc ChainedIsrTimeout
|
||||
|
||||
ReleaseLock2:
|
||||
/* Release the lock */
|
||||
mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
|
||||
RELEASE_SPINLOCK(esi)
|
||||
|
||||
/* Lower IRQL if necessary */
|
||||
mov cl, [edi+KINTERRUPT_IRQL]
|
||||
cmp cl, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
|
||||
je 1f
|
||||
call @KfLowerIrql@4
|
||||
|
||||
1:
|
||||
/* Check if the interrupt is handled */
|
||||
or bl, bl
|
||||
jnz 1f
|
||||
|
||||
/* Try the next shared interrupt handler */
|
||||
mov eax, [edi+KINTERRUPT_INTERRUPT_LIST_HEAD]
|
||||
lea edi, [eax-KINTERRUPT_INTERRUPT_LIST_HEAD]
|
||||
jmp NextSharedInt
|
||||
|
||||
1:
|
||||
ret
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
IntSpin2:
|
||||
SPIN_ON_LOCK(esi, GetIntLock2)
|
||||
#endif
|
||||
|
||||
ChainedIsrTimeout:
|
||||
/* Print warning message */
|
||||
push [edi+KINTERRUPT_SERVICE_ROUTINE]
|
||||
push offset _IsrTimeoutMsg
|
||||
call _DbgPrint
|
||||
add esp,8
|
||||
|
||||
/* Break into debugger, then continue */
|
||||
int 3
|
||||
jmp ReleaseLock2
|
||||
|
||||
/* Cleanup verification */
|
||||
VERIFY_INT_END kid2, 0
|
||||
.endfunc
|
||||
|
||||
.func KiChainedDispatch@0
|
||||
_KiChainedDispatch@0:
|
||||
|
||||
/* Increase interrupt count */
|
||||
inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
|
||||
|
||||
/* Save trap frame */
|
||||
mov ebp, esp
|
||||
|
||||
/* Save vector and IRQL */
|
||||
mov eax, [edi+KINTERRUPT_VECTOR]
|
||||
mov ecx, [edi+KINTERRUPT_IRQL]
|
||||
|
||||
/* Save old irql */
|
||||
push eax
|
||||
sub esp, 4
|
||||
|
||||
/* Begin interrupt */
|
||||
push esp
|
||||
push eax
|
||||
push ecx
|
||||
call _HalBeginSystemInterrupt@12
|
||||
|
||||
/* Check if it was handled */
|
||||
or al, al
|
||||
jz SpuriousInt
|
||||
|
||||
/* Call the 2nd-level handler */
|
||||
call _KiChainedDispatch2ndLvl@0
|
||||
|
||||
/* Exit the interrupt */
|
||||
INT_EPILOG 0
|
||||
.endfunc
|
||||
|
||||
.func KiInterruptDispatch@0
|
||||
_KiInterruptDispatch@0:
|
||||
|
||||
/* Increase interrupt count */
|
||||
inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
|
||||
|
||||
/* Save trap frame */
|
||||
mov ebp, esp
|
||||
|
||||
/* Save vector and IRQL */
|
||||
mov eax, [edi+KINTERRUPT_VECTOR]
|
||||
mov ecx, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
|
||||
|
||||
/* Save old irql */
|
||||
push eax
|
||||
sub esp, 4
|
||||
|
||||
/* Begin interrupt */
|
||||
push esp
|
||||
push eax
|
||||
push ecx
|
||||
call _HalBeginSystemInterrupt@12
|
||||
|
||||
/* Check if it was handled */
|
||||
or al, al
|
||||
jz SpuriousInt
|
||||
|
||||
/* Acquire the lock */
|
||||
mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
|
||||
GetIntLock:
|
||||
ACQUIRE_SPINLOCK(esi, IntSpin)
|
||||
|
||||
/* Make sure that this interrupt isn't storming */
|
||||
VERIFY_INT kid
|
||||
|
||||
/* Save the tick count */
|
||||
mov ebx, _KeTickCount
|
||||
|
||||
/* Call the ISR */
|
||||
mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
|
||||
push eax
|
||||
push edi
|
||||
call [edi+KINTERRUPT_SERVICE_ROUTINE]
|
||||
|
||||
/* Check if the ISR timed out */
|
||||
add ebx, _KiISRTimeout
|
||||
cmp _KeTickCount, ebx
|
||||
jnc IsrTimeout
|
||||
|
||||
ReleaseLock:
|
||||
/* Release the lock */
|
||||
RELEASE_SPINLOCK(esi)
|
||||
|
||||
/* Exit the interrupt */
|
||||
INT_EPILOG 0
|
||||
|
||||
SpuriousInt:
|
||||
/* Exit the interrupt */
|
||||
add esp, 8
|
||||
INT_EPILOG 1
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
IntSpin:
|
||||
SPIN_ON_LOCK(esi, GetIntLock)
|
||||
#endif
|
||||
|
||||
IsrTimeout:
|
||||
/* Print warning message */
|
||||
push [edi+KINTERRUPT_SERVICE_ROUTINE]
|
||||
push offset _IsrTimeoutMsg
|
||||
call _DbgPrint
|
||||
add esp,8
|
||||
|
||||
/* Break into debugger, then continue */
|
||||
int 3
|
||||
jmp ReleaseLock
|
||||
|
||||
/* Cleanup verification */
|
||||
VERIFY_INT_END kid, 0
|
||||
.endfunc
|
||||
#endif
|
||||
|
|
|
@ -1601,104 +1601,4 @@ KiTrap(KiDebugService, KI_PUSH_FAKE_ERROR_CODE);
|
|||
KiTrap(KiSystemService, KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
|
||||
KiTrap(KiFastCallEntry, KI_FAST_SYSTEM_CALL);
|
||||
|
||||
/* HARDWARE INTERRUPTS ********************************************************/
|
||||
|
||||
/*
|
||||
* This code can only be used once the HAL handles system interrupt code in C.
|
||||
*
|
||||
* This is because the HAL, when ending a system interrupt, might see pending
|
||||
* DPC or APC interrupts, and attempt to piggyback on the interrupt context in
|
||||
* order to deliver them. Once they have been devlivered, it will then "end" the
|
||||
* interrupt context by doing a call to the ASM EOI Handler which naturally will
|
||||
* throw up on our C-style KTRAP_FRAME.
|
||||
*
|
||||
* Once it works, expect a noticeable speed boost during hardware interrupts.
|
||||
*/
|
||||
#ifdef HAL_INTERRUPT_SUPPORT_IN_C
|
||||
|
||||
typedef
|
||||
FASTCALL
|
||||
VOID
|
||||
(PKI_INTERRUPT_DISPATCH)(
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt
|
||||
);
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiExitInterrupt(IN PKTRAP_FRAME TrapFrame,
|
||||
IN KIRQL OldIrql,
|
||||
IN BOOLEAN Spurious)
|
||||
{
|
||||
if (Spurious) KiEoiHelper(TrapFrame);
|
||||
|
||||
_disable();
|
||||
|
||||
DPRINT1("Calling HAL to restore IRQL to: %d\n", OldIrql);
|
||||
HalEndSystemInterrupt(OldIrql, 0);
|
||||
|
||||
DPRINT1("Exiting trap\n");
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInterruptDispatch(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
KeGetCurrentPrcb()->InterruptCount++;
|
||||
|
||||
DPRINT1("Calling HAL with %lx %lx\n", Interrupt->SynchronizeIrql, Interrupt->Vector);
|
||||
if (HalBeginSystemInterrupt(Interrupt->SynchronizeIrql,
|
||||
Interrupt->Vector,
|
||||
&OldIrql))
|
||||
{
|
||||
/* Acquire interrupt lock */
|
||||
KxAcquireSpinLock(Interrupt->ActualLock);
|
||||
|
||||
/* Call the ISR */
|
||||
DPRINT1("Calling ISR: %p with context: %p\n", Interrupt->ServiceRoutine, Interrupt->ServiceContext);
|
||||
Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
|
||||
|
||||
/* Release interrupt lock */
|
||||
KxReleaseSpinLock(Interrupt->ActualLock);
|
||||
|
||||
/* Now call the epilogue code */
|
||||
DPRINT1("Exiting interrupt\n");
|
||||
KiExitInterrupt(TrapFrame, OldIrql, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Now call the epilogue code */
|
||||
DPRINT1("Exiting Spurious interrupt\n");
|
||||
KiExitInterrupt(TrapFrame, OldIrql, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
KeGetCurrentPrcb()->InterruptCount++;
|
||||
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKINTERRUPT Interrupt)
|
||||
{
|
||||
/* Enter interrupt frame */
|
||||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* Call the correct dispatcher */
|
||||
((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue