[ros-diffs] [fireball] 29406: - 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).

fireball at svn.reactos.org fireball at svn.reactos.org
Sat Oct 6 09:22:59 CEST 2007


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=29406&r1=29405&r2=29406&view=diff
==============================================================================
--- 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/ke.h?rev=29406&r1=29405&r2=29406&view=diff
==============================================================================
--- 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=29406&r1=29405&r2=29406&view=diff
==============================================================================
--- 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?rev=29406&r1=29405&r2=29406&view=diff
==============================================================================
--- 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 at 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 at 24
+.endfunc
+
+
 .func KiSystemFatalException
 _KiSystemFatalException:
 




More information about the Ros-diffs mailing list