Author: sir_richard
Date: Fri Jan  8 20:24:10 2010
New Revision: 45010

URL: http://svn.reactos.org/svn/reactos?rev=45010&view=rev
Log:
Trap handlers in C Patch 5 of X:
    [NDK]:  Add FSW defines for FPU exception bits.
    [NTOS]: Convert trap 19 (XMMI exception) to C.

Modified:
    trunk/reactos/include/ndk/i386/ketypes.h
    trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h
    trunk/reactos/ntoskrnl/include/internal/trap_x.h
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c

Modified: trunk/reactos/include/ndk/i386/ketypes.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/ketypes.h?rev=45010&r1=45009&r2=45010&view=diff
==============================================================================
--- trunk/reactos/include/ndk/i386/ketypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/i386/ketypes.h [iso-8859-1] Fri Jan  8 20:24:10 
2010
@@ -104,6 +104,17 @@
 #define EFLAGS_USER_SANITIZE    0x3F4DD7
 #define EFLAG_SIGN              0x8000
 #define EFLAG_ZERO              0x4000
+
+//
+// Legacy floating status word bit masks.
+//
+#define FSW_INVALID_OPERATION   0x1
+#define FSW_DENORMAL            0x2
+#define FSW_ZERO_DIVIDE         0x4
+#define FSW_OVERFLOW            0x8
+#define FSW_UNDERFLOW           0x10
+#define FSW_PRECISION           0x20
+#define FSW_STACK_FAULT         0x40
 
 //
 // IPI Types

Modified: trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h?rev=45010&r1=45009&r2=45010&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] 
(original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/intrin_i.h [iso-8859-1] Fri 
Jan  8 20:24:10 2010
@@ -13,6 +13,22 @@
     : "=m" (*X) \
     : /* no input */ \
     : "memory");
+
+FORCEINLINE
+VOID
+Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
+{
+    extern ULONG KeI386FxsrPresent;
+    if (KeI386FxsrPresent)
+    {
+        __asm__ __volatile__ ("fxsave %0\n" : : "m"(SaveArea));
+    }
+    else
+    {
+        __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(SaveArea));
+    }
+
+}
 
 FORCEINLINE
 USHORT

Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/trap_x.h?rev=45010&r1=45009&r2=45010&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Fri Jan  8 
20:24:10 2010
@@ -222,6 +222,17 @@
 
 VOID
 FORCEINLINE
+KiDispatchException1Args(IN NTSTATUS Code,
+                         IN ULONG_PTR Address,
+                         IN ULONG P1,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    /* Helper for exceptions with no arguments */
+    KiDispatchExceptionFromTrapFrame(Code, Address, 1, P1, 0, 0, TrapFrame);
+}
+
+VOID
+FORCEINLINE
 KiDispatchException2Args(IN NTSTATUS Code,
                          IN ULONG_PTR Address,
                          IN ULONG P1,

Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev=45010&r1=45009&r2=45010&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Fri Jan  8 20:24:10 2010
@@ -1524,178 +1524,7 @@
 .endfunc
 
 GENERATE_TRAP_HANDLER KiTrap17, 1
-
-.func KiTrap19
-TRAP_FIXUPS kit19_a, kit19_t, DoFixupV86, DoNotFixupAbios
-_KiTrap19:
-    /* Push error code */
-    push 0
-
-    /* Enter trap */
-    TRAP_PROLOG kit19_a, kit19_t
-
-    /* Check if this is the NPX Thread */
-    mov eax, PCR[KPCR_CURRENT_THREAD]
-    cmp eax, PCR[KPCR_NPX_THREAD]
-
-    /* If this is a valid fault, handle it */
-    jz HandleXmmiFault
-
-    /* Otherwise, bugcheck */
-    mov eax, 19
-    jmp _KiSystemFatalException
-
-HandleXmmiFault:
-    /* Get the initial stack and NPX frame */
-    mov ecx, [eax+KTHREAD_INITIAL_STACK]
-    lea ecx, [ecx-NPX_FRAME_LENGTH]
-
-    /* Check if the trap came from V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
-    jnz V86Xmmi
-
-    /* Check if it came from kernel mode */
-    test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
-    jz KernelXmmi
-
-    /* Check if it came from a VDM */
-    cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
-    jne VdmXmmi
-
-HandleUserXmmi:
-    /* Set new CR0 */
-    mov ebx, cr0
-    and ebx, ~(CR0_MP + CR0_EM + CR0_TS)
-    mov cr0, ebx
-
-    /* Check if we have FX support */
-    test byte ptr _KeI386FxsrPresent, 1
-    jz XmmiFnSave2
-
-    /* Save the state */
-    fxsave [ecx]
-    jmp XmmiMakeCr0Dirty
-XmmiFnSave2:
-    fnsave [ecx]
-    wait
-
-XmmiMakeCr0Dirty:
-    /* Make CR0 state not loaded */
-    or ebx, NPX_STATE_NOT_LOADED
-    or ebx, [ecx+FN_CR0_NPX_STATE]
-    mov cr0, ebx
-
-    /* Update NPX state */
-    mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-    mov dword ptr PCR[KPCR_NPX_THREAD], 0
-
-    /* Clear the TS bit and re-enable interrupts */
-    and dword ptr [ecx+FN_CR0_NPX_STATE], ~CR0_TS
-
-    /* Re-enable interrupts for user-mode and send the exception */
-    sti
-    mov ebx, [ebp+KTRAP_FRAME_EIP]
-
-    /* Get MxCSR and get current mask (bits 7-12) */
-    movzx eax, word ptr [ecx+FX_MXCSR]
-    mov edx, eax
-    shr edx, 7
-    not edx
-
-    /* Set faulting opcode address to 0 */
-    mov esi, 0
-
-    /* Apply legal exceptions mask */
-    and eax, 0x3f
-
-    /* Apply the mask we got in MXCSR itself */
-    and eax, edx
-
-    /* Check for invalid operation */
-    test al, 1
-    jz 1f
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
-    jmp _DispatchOneParamZero
-
-1:
-    /* Check for zero divide */
-    test al, 2
-    jz 1f
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
-    jmp _DispatchOneParamZero
-
-1:
-    /* Check for denormal */
-    test al, 4
-    jz 1f
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
-    jmp _DispatchOneParamZero
-
-1:
-    /* Check for overflow*/
-    test al, 8
-    jz 1f
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
-    jmp _DispatchOneParamZero
-
-1:
-    /* Check for denormal */
-    test al, 16
-    jz 1f
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
-    jmp _DispatchOneParamZero
-
-1:
-    /* Check for Precision */
-    test al, 32
-    jz UnexpectedXmmi
-
-    /* Raise exception */
-    mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
-    jmp _DispatchOneParamZero
-
-UnexpectedXmmi:
-    /* Strange result, bugcheck the OS */
-    sti
-    push ebp
-    push 1
-    push 0
-    push eax
-    push 13
-    push TRAP_CAUSE_UNKNOWN
-    call _kebugcheckwit...@24
-
-VdmXmmi:
-    /* Check if this is a VDM */
-    mov eax, PCR[KPCR_CURRENT_THREAD]
-    mov ebx, [eax+KTHREAD_APCSTATE_PROCESS]
-    cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
-    jz HandleUserXmmi
-
-V86Xmmi:
-    /* V86 XMMI not handled */
-    UNHANDLED_V86_PATH
-
-KernelXmmi:
-    /* Another weird situation */
-    push ebp
-    push 2
-    push 0
-    push eax
-    push 13
-    push TRAP_CAUSE_UNKNOWN
-    call _kebugcheckwit...@24
-.endfunc
+GENERATE_TRAP_HANDLER KiTrap19, 1
 
 .func KiSystemFatalException
 _KiSystemFatalException:

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45010&r1=45009&r2=45010&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Fri Jan  8 20:24:10 
2010
@@ -595,6 +595,89 @@
 
 VOID
 FASTCALL
+KiTrap19Handler(IN PKTRAP_FRAME TrapFrame)
+{
+    PKTHREAD Thread;
+    PFX_SAVE_AREA SaveArea;
+    ULONG Cr0, MxCsrMask, Error;
+    
+    /* Save trap frame */
+    KiEnterTrap(TrapFrame);
+
+    /* Check if this is the NPX thrad */
+    Thread = KeGetCurrentThread();
+    if (Thread != KeGetCurrentPrcb()->NpxThread)
+    {
+        /* It isn't, kill the system */
+        KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, (ULONG_PTR)Thread, 0, 0, 
TrapFrame);
+    }
+
+    /* Get the NPX frame */
+    SaveArea = (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - 
sizeof(FX_SAVE_AREA));
+
+    /* Check for VDM trap */
+    ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
+
+    /* Check for user trap */
+    if (!KiUserTrap(TrapFrame))
+    {
+        /* Kernel should not fault on XMMI */
+        KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 2, TrapFrame);
+    }
+    
+    /* Update CR0 */
+    Cr0 = __readcr0();
+    Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
+    __writecr0(Cr0);
+    
+    /* Save FPU state */
+    Ke386SaveFpuState(SaveArea);
+    
+    /* Mark CR0 state dirty */
+    Cr0 |= NPX_STATE_NOT_LOADED;
+    Cr0 |= SaveArea->Cr0NpxState;
+    
+    /* Update NPX state */
+    Thread->NpxState = NPX_STATE_NOT_LOADED;
+    KeGetCurrentPrcb()->NpxThread = NULL;
+    
+    /* Clear the TS bit and re-enable interrupts */
+    SaveArea->Cr0NpxState &= ~CR0_TS;
+    _enable();
+
+    /* Now look at MxCsr to get the mask of errors we should care about */
+    MxCsrMask = ~((USHORT)SaveArea->U.FxArea.MXCsr >> 7);
+    
+    /* Get legal exceptions that software should handle */
+    Error = (USHORT)SaveArea->U.FxArea.MXCsr & (FSW_INVALID_OPERATION |
+                                                FSW_DENORMAL |
+                                                FSW_ZERO_DIVIDE |
+                                                FSW_OVERFLOW |
+                                                FSW_UNDERFLOW |
+                                                FSW_PRECISION);
+    Error &= MxCsrMask;
+    
+    /* Now handle any of those legal errors */
+    if (Error & (FSW_INVALID_OPERATION |
+                 FSW_DENORMAL |
+                 FSW_ZERO_DIVIDE |
+                 FSW_OVERFLOW |
+                 FSW_UNDERFLOW |
+                 FSW_PRECISION))
+    {
+        /* By issuing an exception */
+        KiDispatchException1Args(STATUS_FLOAT_MULTIPLE_TRAPS,
+                                 TrapFrame->Eip,
+                                 0,
+                                 TrapFrame);
+    }
+    
+    /* Unknown XMMI fault */
+    KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
+}
+
+VOID
+FASTCALL
 KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */


Reply via email to