- Finish the work around for the Pentium cmpxchg8b lock errata: We detected the errat...
[reactos.git] / reactos / ntoskrnl / ke / i386 / trap.s
index e46dfea..c8458c3 100644 (file)
@@ -132,7 +132,6 @@ _KiTrapIoTable:
 
 _KiGetTickCount:
 _KiCallbackReturn:
-_KiRaiseAssertion:
     /* FIXME: TODO */
     UNHANDLED_PATH
 
@@ -461,6 +460,29 @@ AbiosExit:
     /* FIXME: TODO */
     UNHANDLED_PATH
 
+.func KiRaiseAssertion
+TRAP_FIXUPS kira_a, kira_t, DoFixupV86, DoFixupAbios
+_KiRaiseAssertion:
+
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG kira_a, kira_t
+
+    /*
+     * Modify EIP so it points to the faulting instruction and set it as the
+     * exception address. Note that the 'int 2C' instruction used for this call
+     * is 2 bytes long as opposed to 1 byte 'int 3'.
+     */
+    sub dword ptr [ebp+KTRAP_FRAME_EIP], 2
+    mov ebx, [ebp+KTRAP_FRAME_EIP]
+
+    /* Raise an assertion failure */
+    mov eax, STATUS_ASSERTION_FAILURE
+    jmp _DispatchNoParam
+.endfunc
+
 .func KiDebugService
 TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
 _KiDebugService:
@@ -780,8 +802,11 @@ _KiTrap3:
     /* Enter trap */
     TRAP_PROLOG kit3_a, kit3_t
 
-    /* Set status code */
-    mov eax, 0 //STATUS_SUCCESS
+    /*
+     * Set the special code to indicate that this is a software breakpoint
+     * and not a debug service call
+     */
+    mov eax, BREAKPOINT_BREAK
 
     /* Check for V86 */
 PrepareInt3:
@@ -922,6 +947,7 @@ _KiTrap6:
     /* Enter V86 Trap */
     V86_TRAP_PROLOG kit6_a, kit6_v
 
+VdmOpCodeFault:
     /* Not yet supported (Invalid OPCODE from V86) */
     UNHANDLED_PATH
 
@@ -932,6 +958,7 @@ NotV86UD:
     /* Enter trap */
     TRAP_PROLOG kit6_a, kit6_t
 
+DispatchLockErrata:
     /* Check if this happened in kernel mode */
     test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
     jz KmodeOpcode
@@ -1924,14 +1951,21 @@ _KiTrap14:
 NoFixUp:
     mov edi, cr2
 
-    /* REACTOS Mm Hack of Doom */
+    /* Check if this processor has the cmpxchg8b lock errata */
+    cmp byte ptr _KiI386PentiumLockErrataPresent, 0
+    jnz HandleLockErrata
+
+NotLockErrata:
+    /* HACK: Handle page faults with interrupts disabled */
     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 */
+#ifdef HACK_ABOVE_FIXED
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
+    jz IllegalState
+#endif
 
 HandlePf:
     /* Send trap frame and check if this is kernel-mode or usermode */
@@ -2050,6 +2084,33 @@ VdmAlertGpf:
 
     /* FIXME: NOT SUPPORTED */
     UNHANDLED_PATH
+
+HandleLockErrata:
+
+    /* Fail if this isn't a write fault */
+    test word ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0x4
+    jnz NotLockErrata
+
+    /* Also make sure the page fault is for IDT entry 6 */
+    mov eax, PCR[KPCR_IDT]
+    add eax, 0x30
+    cmp eax, edi
+    jne NotLockErrata
+
+    /*
+     * This is a write fault to the Invalid Opcode handler entry.
+     * We assume this is the lock errata and not a real write fault.
+     */
+
+    /* Clear the error code */
+    and dword ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0
+
+    /* Check if this happened in V86 mode */
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+    jnz VdmOpCodeFault
+
+    /* Dispatch this to the invalid opcode handler */
+    jmp DispatchLockErrata
 .endfunc
 
 .func KiTrap0F