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…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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?re…
==============================================================================
--- 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 _KeBugCheckWithTf@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 _KeBugCheckWithTf@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.…
==============================================================================
--- 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 */