diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 3457aa2afd0..6395651d15a 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -227,12 +227,13 @@ Author: // // KINTERRUPT Offsets // +#define KINTERRUPT_INTERRUPT_LIST_HEAD 0x04 #define KINTERRUPT_SERVICE_ROUTINE 0x0C #define KINTERRUPT_SERVICE_CONTEXT 0x10 #define KINTERRUPT_TICK_COUNT 0x18 #define KINTERRUPT_ACTUAL_LOCK 0x1C -#define KINTERRUPT_IRQL 0x20 #define KINTERRUPT_VECTOR 0x24 +#define KINTERRUPT_IRQL 0x28 #define KINTERRUPT_SYNCHRONIZE_IRQL 0x29 #define KINTERRUPT_DISPATCH_COUNT 0x38 diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index d97adbec6f2..3d9ebf6636d 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -1334,7 +1334,7 @@ VfOvr_&Label: mov [edi+KINTERRUPT_TICK_COUNT], eax jmp VfRstDef_&Label -.1: +1: /* Check if the debugger is enabled */ cmp byte ptr __KdDebuggerEnabled, 0 jnz 1f diff --git a/reactos/ntoskrnl/ke/i386/irqobj.c b/reactos/ntoskrnl/ke/i386/irqobj.c index 282d195b820..1a417c8d0f3 100644 --- a/reactos/ntoskrnl/ke/i386/irqobj.c +++ b/reactos/ntoskrnl/ke/i386/irqobj.c @@ -281,13 +281,17 @@ KeConnectInterrupt(IN PKINTERRUPT Interrupt) (Dispatch.Interrupt->Mode == Interrupt->Mode)) { /* The vector is shared and the interrupts are compatible */ - ASSERT(FALSE); // FIXME: NOT YET SUPPORTED/TESTED Interrupt->Connected = Connected = TRUE; - ASSERT(Irql <= SYNCH_LEVEL); + + /* FIXME */ + // ASSERT(Irql <= SYNCH_LEVEL); /* Check if this is the first chain */ if (Dispatch.Type != ChainConnect) { + /* This is not supported */ + ASSERT(Dispatch.Interrupt->Mode != Latched); + /* Setup the chainned handler */ KiConnectVectorToInterrupt(Dispatch.Interrupt, ChainConnect); } diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index d438650c2f3..95a97a69e31 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -2533,8 +2533,81 @@ TRAP_FIXUPS kit_a, kit_t, DoFixupV86, DoFixupAbios .func KiChainedDispatch2ndLvl@0 _KiChainedDispatch2ndLvl@0: - /* Not yet supported */ - UNHANDLED_PATH +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 @@ -2599,8 +2672,8 @@ _KiInterruptDispatch@0: jz SpuriousInt /* Acquire the lock */ -GetIntLock: mov esi, [edi+KINTERRUPT_ACTUAL_LOCK] +GetIntLock: ACQUIRE_SPINLOCK(esi, IntSpin) /* Make sure that this interrupt isn't storming */