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... ============================================================================== --- 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/k... ============================================================================== --- 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?rev... ============================================================================== --- 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: