Definition at line 228 of file traphdlr.c. Referenced by KiTrap07Handler(), and KiTrap10Handler(). {
ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Check for kernel trap */
if (!KiUserTrap(TrapFrame))
{
/* Kernel might've tripped a delayed error */
SaveArea->Cr0NpxState |= CR0_TS;
/* Only valid if it happened during a restore */
//if ((PVOID)TrapFrame->Eip == FrRestore)
{
/* It did, so just skip the instruction */
//TrapFrame->Eip += 3; /* sizeof(FRSTOR) */
//KiEoiHelper(TrapFrame);
}
}
/* User or kernel trap -- get ready to issue an exception */
//if (Thread->NpxState == NPX_STATE_NOT_LOADED)
{
/* 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;
__writecr0(Cr0);
/* 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();
/* Check if we should get the FN or FX error */
if (KeI386FxsrPresent)
{
/* Get it from FX */
Mask = SaveArea->U.FxArea.ControlWord;
Error = SaveArea->U.FxArea.StatusWord;
/* Get the FPU exception address too */
ErrorOffset = SaveArea->U.FxArea.ErrorOffset;
DataOffset = SaveArea->U.FxArea.DataOffset;
}
else
{
/* Get it from FN */
Mask = SaveArea->U.FnArea.ControlWord;
Error = SaveArea->U.FnArea.StatusWord;
/* Get the FPU exception address too */
ErrorOffset = SaveArea->U.FnArea.ErrorOffset;
DataOffset = SaveArea->U.FnArea.DataOffset;
}
/* Get legal exceptions that software should handle */
/* We do this by first masking off from the Mask the bits we need, */
/* This is done so we can keep the FSW_STACK_FAULT bit in Error. */
Mask &= (FSW_INVALID_OPERATION |
FSW_DENORMAL |
FSW_ZERO_DIVIDE |
FSW_OVERFLOW |
FSW_UNDERFLOW |
FSW_PRECISION);
Error &= ~Mask;
/* Check for invalid operation */
if (Error & FSW_INVALID_OPERATION)
{
/* NOTE: Stack fault is handled differently than any other case. */
/* 1. It's only raised for invalid operation. */
/* 2. It's only raised if invalid operation is not masked. */
if (Error & FSW_STACK_FAULT)
{
/* Issue stack check fault */
KiDispatchException2Args(STATUS_FLOAT_STACK_CHECK,
ErrorOffset,
0,
DataOffset,
TrapFrame);
}
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
ErrorOffset,
0,
TrapFrame);
}
/* Check for divide by zero */
if (Error & FSW_ZERO_DIVIDE)
{
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_DIVIDE_BY_ZERO,
ErrorOffset,
0,
TrapFrame);
}
/* Check for denormal */
if (Error & FSW_DENORMAL)
{
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
ErrorOffset,
0,
TrapFrame);
}
/* Check for overflow */
if (Error & FSW_OVERFLOW)
{
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_OVERFLOW,
ErrorOffset,
0,
TrapFrame);
}
/* Check for underflow */
if (Error & FSW_UNDERFLOW)
{
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_UNDERFLOW,
ErrorOffset,
0,
TrapFrame);
}
/* Check for precision fault */
if (Error & FSW_PRECISION)
{
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_INEXACT_RESULT,
ErrorOffset,
0,
TrapFrame);
}
/* Unknown FPU fault */
KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 1, Error, 0, 0, TrapFrame);
}
|