- In Win32 DBG is defined to 0 for a non-debug build and to 1 for a debug build....
[reactos.git] / reactos / ntoskrnl / ke / i386 / trap.s
index 2f3aec9..594a8f4 100644 (file)
@@ -200,7 +200,7 @@ NotWin32K:
     /* Increase total syscall count */
     inc dword ptr PCR[KPCR_SYSTEM_CALLS]
 
-#ifdef DBG
+#if DBG
     /* Increase per-syscall count */
     mov ecx, [edi+SERVICE_DESCRIPTOR_COUNT]
     jecxz NoCountTable
@@ -239,7 +239,7 @@ CopyParams:
     call ebx
 
 AfterSysCall:
-#ifdef DBG
+#if DBG
     /* Make sure the user-mode call didn't return at elevated IRQL */
     test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
     jz SkipCheck
@@ -377,7 +377,7 @@ BadStack:
     push 0
     jmp _KiTrap6
 
-#ifdef DBG
+#if DBG
 InvalidIrql:
     /* Save current IRQL */
     push PCR[KPCR_IRQL]
@@ -1924,14 +1924,14 @@ _KiTrap14:
 NoFixUp:
     mov edi, cr2
 
-    /* ROS HACK: Sometimes we get called with INTS DISABLED! WTF? */
+    /* REACTOS Mm Hack of Doom */
     test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
     je HandlePf
 
     /* Enable interrupts and check if we got here with interrupts disabled */
     sti
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
-    jz IllegalState
+    /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
+    jz IllegalState */
 
 HandlePf:
     /* Send trap frame and check if this is kernel-mode or usermode */
@@ -2455,9 +2455,20 @@ CheckQuantum:
     mov edi, [ebx+KPCR_CURRENT_THREAD]
 
 #ifdef CONFIG_SMP
-    #error SMP Interrupt not handled!
+    /* Raise to synch level */
+    call _KeRaiseIrqlToSynchLevel@0
+
+    /* Set context swap busy */
+    mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
+
+    /* Acquire the PRCB Lock */
+    lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
+    jnb GetNext
+    lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
+    call @KefAcquireSpinLockAtDpcLevel@4
 #endif
 
+GetNext:
     /* Get the next thread and clear it */
     mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
     and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
@@ -2476,6 +2487,12 @@ CheckQuantum:
     mov cl, APC_LEVEL
     call @KiSwapContextInternal@0
 
+#ifdef CONFIG_SMP
+    /* Lower IRQL back to dispatch */
+    mov cl, DISPATCH_LEVEL
+    call @KfLowerIrql@4
+#endif
+
     /* Restore registers */
     mov ebp, [esp+0]
     mov edi, [esp+4]
@@ -2516,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
@@ -2582,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 */
@@ -2617,7 +2707,7 @@ SpuriousInt:
 
 #ifdef CONFIG_SMP
 IntSpin:
-    SPIN_ON_LOCK esi, GetIntLock
+    SPIN_ON_LOCK(esi, GetIntLock)
 #endif
 
 IsrTimeout: