Author: fireball
Date: Sat Oct 6 11:22:59 2007
New Revision: 29406
URL:
http://svn.reactos.org/svn/reactos?rev=29406&view=rev
Log:
- Implement KiTrap19 handler (XMMI exceptions, mostly copied KiTrap7 handler and used
mxcsr status word and exceptions there). There will be no weird 0xF BSODs anymore, however
I need to investigate about exceptions masking.
- Dynamically enable it, if CPU supports XMMI (was already done in the kernel, but
#if0-ed).
Modified:
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/ke/i386/cpu.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2940…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Sat Oct 6 11:22:59 2007
@@ -264,6 +264,7 @@
#define FX_ERROR_SELECTOR 0xC
#define FX_DATA_OFFSET 0x10
#define FX_DATA_SELECTOR 0x14
+#define FX_MXCSR 0x18
//
// NPX States
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Sat Oct 6 11:22:59 2007
@@ -142,6 +142,7 @@
extern PKPRCB KiProcessorBlock[];
extern ULONG KiMask32Array[MAXIMUM_PRIORITY];
extern ULONG KiIdleSummary;
+extern VOID __cdecl KiTrap19(VOID);
extern VOID __cdecl KiTrap8(VOID);
extern VOID __cdecl KiTrap2(VOID);
extern VOID __cdecl KiFastCallEntry(VOID);
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Sat Oct 6 11:22:59 2007
@@ -798,20 +798,18 @@
NTAPI
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
{
-#if 0 // needs kitrap13
PKIDTENTRY IdtEntry;
/* Get the IDT Entry for Interrupt 19 */
- IdtEntry = ((PKIPCR)KeGetPcr())->IDT[19];
+ IdtEntry = &((PKIPCR)KeGetPcr())->IDT[19];
/* Set it up */
IdtEntry->Selector = KGDT_R0_CODE;
- IdtEntry->Offset = (KiTrap13 & 0xFFFF);
- IdtEntry->ExtendedOffset = (KiTrap13 >> 16) & 0xFFFF;
+ IdtEntry->Offset = ((ULONG_PTR)KiTrap19 & 0xFFFF);
+ IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap19 >> 16) & 0xFFFF;
((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
-#endif
/* Enable XMMI exceptions */
__writecr4(__readcr4() | CR4_XMMEXCPT);
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 (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Sat Oct 6 11:22:59 2007
@@ -1034,7 +1034,7 @@
sub ecx, NPX_FRAME_LENGTH
/* Check if emulation is enabled */
- test dword ptr [ecx+FN_CR0_NPX_STATE], CR0_EM
+ test byte ptr [ecx+FN_CR0_NPX_STATE], CR0_EM
jnz EmulationEnabled
CheckState:
@@ -2027,6 +2027,180 @@
jmp _KiSystemFatalException
.endfunc
+.globl _KiTrap19
+.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 _DispatchOneParam
+
+1:
+ /* Check for zero divide */
+ test al, 2
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
+ jmp _DispatchOneParam
+
+1:
+ /* Check for denormal */
+ test al, 4
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_TRAPS
+ jmp _DispatchOneParam
+
+1:
+ /* Check for overflow*/
+ test al, 8
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParam
+
+1:
+ /* Check for denormal */
+ test al, 16
+ jz 1f
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParam
+
+1:
+ /* Check for Precision */
+ test al, 32
+ jz UnexpectedXmmi
+
+ /* Raise exception */
+ mov eax, STATUS_FLOAT_MULTIPLE_FAULTS
+ jmp _DispatchOneParam
+
+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_PATH
+
+KernelXmmi:
+ /* Another weird situation */
+ push ebp
+ push 2
+ push 0
+ push eax
+ push 13
+ push TRAP_CAUSE_UNKNOWN
+ call _KeBugCheckWithTf@24
+.endfunc
+
+
.func KiSystemFatalException
_KiSystemFatalException: