--- trunk/reactos/ntoskrnl/ke/i386/fpu.c 2005-10-05 23:24:25 UTC (rev 18285)
+++ trunk/reactos/ntoskrnl/ke/i386/fpu.c 2005-10-05 23:30:39 UTC (rev 18286)
@@ -48,235 +48,227 @@
STATIC USHORT
KiTagWordFnsaveToFxsave(USHORT TagWord)
{
- INT tmp;
+ INT tmp;
- /*
- * Converts the tag-word. 11 (Empty) is converted into 0, everything else into 1
- */
- tmp = ~TagWord; /* Empty is now 00, any 2 bits containing 1 mean valid */
- tmp = (tmp | (tmp >> 1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
- tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
- tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
- tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
+ /*
+ * Converts the tag-word. 11 (Empty) is converted into 0, everything else into 1
+ */
+ tmp = ~TagWord; /* Empty is now 00, any 2 bits containing 1 mean valid */
+ tmp = (tmp | (tmp >> 1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
+ tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
+ tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
+ tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
- return tmp;
+ return tmp;
}
STATIC USHORT
KiTagWordFxsaveToFnsave(PFXSAVE_FORMAT FxSave)
{
- USHORT TagWord = 0;
- UCHAR Tag;
- INT i;
- struct FPREG { USHORT Significand[4]; USHORT Exponent; } *FpReg;
+ USHORT TagWord = 0;
+ UCHAR Tag;
+ INT i;
+ struct FPREG { USHORT Significand[4]; USHORT Exponent; } *FpReg;
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 8; i++)
{
- if (FxSave->TagWord & (1 << i)) /* valid */
+ if (FxSave->TagWord & (1 << i)) /* valid */
{
- FpReg = (struct FPREG *)(FxSave->RegisterArea + (i * 16));
- switch (FpReg->Exponent & 0x00007fff)
+ FpReg = (struct FPREG *)(FxSave->RegisterArea + (i * 16));
+ switch (FpReg->Exponent & 0x00007fff)
{
- case 0x0000:
+ case 0x0000:
if (FpReg->Significand[0] == 0 && FpReg->Significand[1] == 0 &&
FpReg->Significand[2] == 0 && FpReg->Significand[3] == 0)
- {
Tag = 1; /* Zero */
- }
else
- {
Tag = 2; /* Special */
- }
break;
- case 0x7fff:
+ case 0x7fff:
Tag = 2; /* Special */
break;
- default:
+ default:
if (FpReg->Significand[3] & 0x00008000)
- {
Tag = 0; /* Valid */
- }
else
- {
Tag = 2; /* Special */
- }
break;
}
}
- else /* empty */
+ else /* empty */
{
- Tag = 3;
+ Tag = 3;
}
- TagWord |= Tag << (i * 2);
+ TagWord |= Tag << (i * 2);
}
- return TagWord;
+ return TagWord;
}
STATIC VOID
KiFnsaveToFxsaveFormat(PFXSAVE_FORMAT FxSave, CONST PFNSAVE_FORMAT FnSave)
{
- INT i;
+ INT i;
- FxSave->ControlWord = (USHORT)FnSave->ControlWord;
- FxSave->StatusWord = (USHORT)FnSave->StatusWord;
- FxSave->TagWord = KiTagWordFnsaveToFxsave((USHORT)FnSave->TagWord);
- FxSave->ErrorOpcode = (USHORT)(FnSave->ErrorSelector >> 16);
- FxSave->ErrorOffset = FnSave->ErrorOffset;
- FxSave->ErrorSelector = FnSave->ErrorSelector & 0x0000ffff;
- FxSave->DataOffset = FnSave->DataOffset;
- FxSave->DataSelector = FnSave->DataSelector & 0x0000ffff;
- if (XmmSupport)
- FxSave->MXCsr = 0x00001f80 & MxcsrFeatureMask;
- else
- FxSave->MXCsr = 0;
- FxSave->MXCsrMask = MxcsrFeatureMask;
- memset(FxSave->Reserved3, 0, sizeof(FxSave->Reserved3) +
- sizeof(FxSave->Reserved4)); /* XXX - doesnt zero Align16Byte because
- Context->ExtendedRegisters is only 512 bytes, not 520 */
- for (i = 0; i < 8; i++)
+ FxSave->ControlWord = (USHORT)FnSave->ControlWord;
+ FxSave->StatusWord = (USHORT)FnSave->StatusWord;
+ FxSave->TagWord = KiTagWordFnsaveToFxsave((USHORT)FnSave->TagWord);
+ FxSave->ErrorOpcode = (USHORT)(FnSave->ErrorSelector >> 16);
+ FxSave->ErrorOffset = FnSave->ErrorOffset;
+ FxSave->ErrorSelector = FnSave->ErrorSelector & 0x0000ffff;
+ FxSave->DataOffset = FnSave->DataOffset;
+ FxSave->DataSelector = FnSave->DataSelector & 0x0000ffff;
+ if (XmmSupport)
+ FxSave->MXCsr = 0x00001f80 & MxcsrFeatureMask;
+ else
+ FxSave->MXCsr = 0;
+ FxSave->MXCsrMask = MxcsrFeatureMask;
+ memset(FxSave->Reserved3, 0, sizeof(FxSave->Reserved3) +
+ sizeof(FxSave->Reserved4)); /* Don't zero Align16Byte because Context->ExtendedRegisters
+ is only 512 bytes, not 520 */
+ for (i = 0; i < 8; i++)
{
- memcpy(FxSave->RegisterArea + (i * 16), FnSave->RegisterArea + (i * 10), 10);
- memset(FxSave->RegisterArea + (i * 16) + 10, 0, 6);
+ memcpy(FxSave->RegisterArea + (i * 16), FnSave->RegisterArea + (i * 10), 10);
+ memset(FxSave->RegisterArea + (i * 16) + 10, 0, 6);
}
}
STATIC VOID
KiFxsaveToFnsaveFormat(PFNSAVE_FORMAT FnSave, CONST PFXSAVE_FORMAT FxSave)
{
- INT i;
+ INT i;
- FnSave->ControlWord = 0xffff0000 | FxSave->ControlWord;
- FnSave->StatusWord = 0xffff0000 | FxSave->StatusWord;
- FnSave->TagWord = 0xffff0000 | KiTagWordFxsaveToFnsave(FxSave);
- FnSave->ErrorOffset = FxSave->ErrorOffset;
- FnSave->ErrorSelector = FxSave->ErrorSelector & 0x0000ffff;
- FnSave->ErrorSelector |= FxSave->ErrorOpcode << 16;
- FnSave->DataOffset = FxSave->DataOffset;
- FnSave->DataSelector = FxSave->DataSelector | 0xffff0000;
- for (i = 0; i < 8; i++)
+ FnSave->ControlWord = 0xffff0000 | FxSave->ControlWord;
+ FnSave->StatusWord = 0xffff0000 | FxSave->StatusWord;
+ FnSave->TagWord = 0xffff0000 | KiTagWordFxsaveToFnsave(FxSave);
+ FnSave->ErrorOffset = FxSave->ErrorOffset;
+ FnSave->ErrorSelector = FxSave->ErrorSelector & 0x0000ffff;
+ FnSave->ErrorSelector |= FxSave->ErrorOpcode << 16;
+ FnSave->DataOffset = FxSave->DataOffset;
+ FnSave->DataSelector = FxSave->DataSelector | 0xffff0000;
+ for (i = 0; i < 8; i++)
{
- memcpy(FnSave->RegisterArea + (i * 10), FxSave->RegisterArea + (i * 16), 10);
+ memcpy(FnSave->RegisterArea + (i * 10), FxSave->RegisterArea + (i * 16), 10);
}
}
VOID
KiFloatingSaveAreaToFxSaveArea(PFX_SAVE_AREA FxSaveArea, CONST FLOATING_SAVE_AREA *FloatingSaveArea)
{
- if (FxsrSupport)
- {
- KiFnsaveToFxsaveFormat(&FxSaveArea->U.FxArea, (PFNSAVE_FORMAT)FloatingSaveArea);
- }
- else
- {
- memcpy(&FxSaveArea->U.FnArea, FloatingSaveArea, sizeof(FxSaveArea->U.FnArea));
- }
- FxSaveArea->NpxSavedCpu = 0;
- FxSaveArea->Cr0NpxState = FloatingSaveArea->Cr0NpxState;
+ if (FxsrSupport)
+ {
+ KiFnsaveToFxsaveFormat(&FxSaveArea->U.FxArea, (PFNSAVE_FORMAT)FloatingSaveArea);
+ }
+ else
+ {
+ memcpy(&FxSaveArea->U.FnArea, FloatingSaveArea, sizeof(FxSaveArea->U.FnArea));
+ }
+ FxSaveArea->NpxSavedCpu = 0;
+ FxSaveArea->Cr0NpxState = FloatingSaveArea->Cr0NpxState;
}
BOOL
KiContextToFxSaveArea(PFX_SAVE_AREA FxSaveArea, PCONTEXT Context)
{
- BOOL FpuContextChanged = FALSE;
+ BOOL FpuContextChanged = FALSE;
- /* First of all convert the FLOATING_SAVE_AREA into the FX_SAVE_AREA */
- if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
+ /* First of all convert the FLOATING_SAVE_AREA into the FX_SAVE_AREA */
+ if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
{
- KiFloatingSaveAreaToFxSaveArea(FxSaveArea, &Context->FloatSave);
- FpuContextChanged = TRUE;
+ KiFloatingSaveAreaToFxSaveArea(FxSaveArea, &Context->FloatSave);
+ FpuContextChanged = TRUE;
}
- /* Now merge the FX_SAVE_AREA from the context with the destination area */
- if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
+ /* Now merge the FX_SAVE_AREA from the context with the destination area */
+ if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
{
- if (FxsrSupport)
+ if (FxsrSupport)
{
- PFXSAVE_FORMAT src = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
- PFXSAVE_FORMAT dst = &FxSaveArea->U.FxArea;
- dst->MXCsr = src->MXCsr & MxcsrFeatureMask;
- memcpy(dst->Reserved3, src->Reserved3,
- sizeof(src->Reserved3) + sizeof(src->Reserved4));
+ PFXSAVE_FORMAT src = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
+ PFXSAVE_FORMAT dst = &FxSaveArea->U.FxArea;
+ dst->MXCsr = src->MXCsr & MxcsrFeatureMask;
+ memcpy(dst->Reserved3, src->Reserved3,
+ sizeof(src->Reserved3) + sizeof(src->Reserved4));
- if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) != CONTEXT_FLOATING_POINT)
+ if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) != CONTEXT_FLOATING_POINT)
{
- dst->ControlWord = src->ControlWord;
- dst->StatusWord = src->StatusWord;
- dst->TagWord = src->TagWord;
- dst->ErrorOpcode = src->ErrorOpcode;
- dst->ErrorOffset = src->ErrorOffset;
- dst->ErrorSelector = src->ErrorSelector;
- dst->DataOffset = src->DataOffset;
- dst->DataSelector = src->DataSelector;
- memcpy(dst->RegisterArea, src->RegisterArea, sizeof(src->RegisterArea));
+ dst->ControlWord = src->ControlWord;
+ dst->StatusWord = src->StatusWord;
+ dst->TagWord = src->TagWord;
+ dst->ErrorOpcode = src->ErrorOpcode;
+ dst->ErrorOffset = src->ErrorOffset;
+ dst->ErrorSelector = src->ErrorSelector;
+ dst->DataOffset = src->DataOffset;
+ dst->DataSelector = src->DataSelector;
+ memcpy(dst->RegisterArea, src->RegisterArea, sizeof(src->RegisterArea));
- FxSaveArea->NpxSavedCpu = 0;
- FxSaveArea->Cr0NpxState = 0;
+ FxSaveArea->NpxSavedCpu = 0;
+ FxSaveArea->Cr0NpxState = 0;
}
- FpuContextChanged = TRUE;
+ FpuContextChanged = TRUE;
}
}
- return FpuContextChanged;
+ return FpuContextChanged;
}
VOID INIT_FUNCTION
KiCheckFPU(VOID)
{
- unsigned short int status;
- int cr0;
- ULONG Flags;
- PKPRCB Prcb = KeGetCurrentPrcb();
+ unsigned short int status;
+ int cr0;
+ ULONG Flags;
+ PKPRCB Prcb = KeGetCurrentPrcb();
- Ke386SaveFlags(Flags);
- Ke386DisableInterrupts();
+ Ke386SaveFlags(Flags);
+ Ke386DisableInterrupts();
- HardwareMathSupport = 0;
- FxsrSupport = 0;
- XmmSupport = 0;
+ HardwareMathSupport = 0;
+ FxsrSupport = 0;
+ XmmSupport = 0;
- cr0 = Ke386GetCr0();
- cr0 |= X86_CR0_NE | X86_CR0_MP;
- cr0 &= ~(X86_CR0_EM | X86_CR0_TS);
- Ke386SetCr0(cr0);
+ cr0 = Ke386GetCr0();
+ cr0 |= X86_CR0_NE | X86_CR0_MP;
+ cr0 &= ~(X86_CR0_EM | X86_CR0_TS);
+ Ke386SetCr0(cr0);
#if defined(__GNUC__)
- asm volatile("fninit\n\t");
- asm volatile("fstsw %0\n\t" : "=a" (status));
+ asm volatile("fninit\n\t");
+ asm volatile("fstsw %0\n\t" : "=a" (status));
#elif defined(_MSC_VER)
- __asm
- {
+ __asm
+ {
fninit;
fstsw status
- }
+ }
#else
#error Unknown compiler for inline assembler
#endif
- if (status != 0)
- {
- /* Set the EM flag in CR0 so any FPU instructions cause a trap. */
- Ke386SetCr0(Ke386GetCr0() | X86_CR0_EM);
+ if (status != 0)
+ {
+ /* Set the EM flag in CR0 so any FPU instructions cause a trap. */
+ Ke386SetCr0(Ke386GetCr0() | X86_CR0_EM);
Ke386RestoreFlags(Flags);
- return;
- }
+ return;
+ }
- /* fsetpm for i287, ignored by i387 */
+ /* fsetpm for i287, ignored by i387 */
#if defined(__GNUC__)
- asm volatile(".byte 0xDB, 0xE4\n\t");
+ asm volatile(".byte 0xDB, 0xE4\n\t");
#elif defined(_MSC_VER)
- __asm _emit 0xDB __asm _emit 0xe4
+ __asm _emit 0xDB __asm _emit 0xe4
#else
#error Unknown compiler for inline assembler
#endif
- HardwareMathSupport = 1;
+ HardwareMathSupport = 1;
- /* check for and enable MMX/SSE support if possible */
- if ((Prcb->FeatureBits & X86_FEATURE_FXSR) != 0)
- {
+ /* check for and enable MMX/SSE support if possible */
+ if ((Prcb->FeatureBits & X86_FEATURE_FXSR) != 0)
+ {
BYTE DummyArea[sizeof(FX_SAVE_AREA) + 15];
PFX_SAVE_AREA FxSaveArea;
@@ -284,32 +276,28 @@
FxsrSupport = 1;
/* we need a 16 byte aligned FX_SAVE_AREA */
- FxSaveArea = (PFX_SAVE_AREA)DummyArea;
- if ((ULONG_PTR)FxSaveArea & 0x0f)
- {
- FxSaveArea = (PFX_SAVE_AREA)(((ULONG_PTR)FxSaveArea + 0x10) & (~0x0f));
- }
+ FxSaveArea = (PFX_SAVE_AREA)(((ULONG_PTR)DummyArea + 0xf) & (~0x0f));
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR);
memset(&FxSaveArea->U.FxArea, 0, sizeof(FxSaveArea->U.FxArea));
asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
MxcsrFeatureMask = FxSaveArea->U.FxArea.MXCsrMask;
if (MxcsrFeatureMask == 0)
- {
- MxcsrFeatureMask = 0x0000ffbf;
- }
- }
- /* FIXME: Check for SSE3 in Ke386CpuidFlags2! */
- if (Prcb->FeatureBits & (X86_FEATURE_SSE | X86_FEATURE_SSE2))
- {
+ {
+ MxcsrFeatureMask = 0x0000ffbf;
+ }
+ }
+ /* FIXME: Check for SSE3 in Ke386CpuidFlags2! */
+ if (Prcb->FeatureBits & (X86_FEATURE_SSE | X86_FEATURE_SSE2))
+ {
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
/* enable SSE */
XmmSupport = 1;
- }
+ }
- Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
- Ke386RestoreFlags(Flags);
+ Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
+ Ke386RestoreFlags(Flags);
}
/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState
@@ -320,261 +308,260 @@
NTSTATUS STDCALL
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
{
- char *FpState;
+ char *FpState;
- ASSERT_IRQL(DISPATCH_LEVEL); /* FIXME: is this removed for non-debug builds? I hope not! */
+ ASSERT_IRQL(DISPATCH_LEVEL);
- /* check if we are doing software emulation */
- if (!HardwareMathSupport)
+ /* check if we are doing software emulation */
+ if (!HardwareMathSupport)
{
- return STATUS_ILLEGAL_FLOAT_CONTEXT;
+ return STATUS_ILLEGAL_FLOAT_CONTEXT;
}
- FpState = ExAllocatePool(PagedPool, FPU_STATE_SIZE);
- if (NULL == FpState)
+ FpState = ExAllocatePool(NonPagedPool, FPU_STATE_SIZE);
+ if (NULL == FpState)
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- *((PVOID *) Save) = FpState;
+ *((PVOID *) Save) = FpState;
#if defined(__GNUC__)
- asm volatile("fsave %0\n\t" : "=m" (*FpState));
+ asm volatile("fsave %0\n\t" : "=m" (*FpState));
#elif defined(_MSC_VER)
- __asm mov eax, FpState;
- __asm fsave [eax];
+ __asm mov eax, FpState;
+ __asm fsave [eax];
#else
#error Unknown compiler for inline assembler
#endif
- KeGetCurrentThread()->NpxIrql = KeGetCurrentIrql();
+ KeGetCurrentThread()->NpxIrql = KeGetCurrentIrql();
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS STDCALL
KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
{
- char *FpState = *((PVOID *) Save);
+ char *FpState = *((PVOID *) Save);
- if (KeGetCurrentThread()->NpxIrql != KeGetCurrentIrql())
+ if (KeGetCurrentThread()->NpxIrql != KeGetCurrentIrql())
{
- KEBUGCHECK(UNDEFINED_BUG_CODE);
+ KEBUGCHECK(UNDEFINED_BUG_CODE);
}
#if defined(__GNUC__)
- __asm__("frstor %0\n\t" : "=m" (*FpState));
+ __asm__("frstor %0\n\t" : "=m" (*FpState));
#elif defined(_MSC_VER)
- __asm mov eax, FpState;
- __asm frstor [eax];
+ __asm mov eax, FpState;
+ __asm frstor [eax];
#else
#error Unknown compiler for inline assembler
#endif
- ExFreePool(FpState);
+ ExFreePool(FpState);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS
KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
{
- if (ExceptionNr == 7) /* device not present */
+ if (ExceptionNr == 7) /* device not present */
{
- BOOL FpuInitialized = FALSE;
- unsigned int cr0 = Ke386GetCr0();
- PKTHREAD CurrentThread;
- PFX_SAVE_AREA FxSaveArea;
- KIRQL oldIrql;
+ BOOL FpuInitialized = FALSE;
+ unsigned int cr0 = Ke386GetCr0();
+ PKTHREAD CurrentThread;
+ PFX_SAVE_AREA FxSaveArea;
+ KIRQL oldIrql;
#ifndef CONFIG_SMP
- PKTHREAD NpxThread;
+ PKTHREAD NpxThread;
#endif
- (void) cr0;
- ASSERT((cr0 & X86_CR0_TS) == X86_CR0_TS);
- ASSERT((Tf->Eflags & X86_EFLAGS_VM) == 0);
- ASSERT((cr0 & X86_CR0_EM) == 0);
+ (void) cr0;
+ ASSERT((cr0 & X86_CR0_TS) == X86_CR0_TS);
+ ASSERT((Tf->Eflags & X86_EFLAGS_VM) == 0);
+ ASSERT((cr0 & X86_CR0_EM) == 0);
- /* disable scheduler, clear TS in cr0 */
- ASSERT_IRQL(DISPATCH_LEVEL);
- KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
- asm volatile("clts");
+ /* disable scheduler, clear TS in cr0 */
+ ASSERT_IRQL(DISPATCH_LEVEL);
+ KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
+ asm volatile("clts");
- CurrentThread = KeGetCurrentThread();
+ CurrentThread = KeGetCurrentThread();
#ifndef CONFIG_SMP
- NpxThread = KeGetCurrentPrcb()->NpxThread;
+ NpxThread = KeGetCurrentPrcb()->NpxThread;
#endif
- ASSERT(CurrentThread != NULL);
- DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState = 0x%x)\n", cr0, CurrentThread->NpxState);
+ ASSERT(CurrentThread != NULL);
+ DPRINT("Device not present exception happened! (Cr0 = 0x%x, NpxState = 0x%x)\n", cr0, CurrentThread->NpxState);
#ifndef CONFIG_SMP
- /* check if the current thread already owns the FPU */
- if (NpxThread != CurrentThread) /* FIXME: maybe this could be an assertation */
+ /* check if the current thread already owns the FPU */
+ if (NpxThread != CurrentThread) /* FIXME: maybe this could be an assertation */
{
- /* save the FPU state into the owner's save area */
- if (NpxThread != NULL)
+ /* save the FPU state into the owner's save area */
+ if (NpxThread != NULL)
{
- KeGetCurrentPrcb()->NpxThread = NULL;
- FxSaveArea = (PFX_SAVE_AREA)((char *)NpxThread->InitialStack - sizeof (FX_SAVE_AREA));
- /* the fnsave might raise a delayed #MF exception */
- if (FxsrSupport)
+ KeGetCurrentPrcb()->NpxThread = NULL;
+ FxSaveArea = (PFX_SAVE_AREA)((char *)NpxThread->InitialStack - sizeof (FX_SAVE_AREA));
+ /* the fnsave might raise a delayed #MF exception */
+ if (FxsrSupport)
{
- asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
+ asm volatile("fxsave %0" : : "m"(FxSaveArea->U.FxArea));
}
- else
+ else
{
- asm volatile("fnsave %0" : : "m"(FxSaveArea->U.FnArea));
- FpuInitialized = TRUE;
+ asm volatile("fnsave %0" : : "m"(FxSaveArea->U.FnArea));
+ FpuInitialized = TRUE;
}
- NpxThread->NpxState = NPX_STATE_VALID;
+ NpxThread->NpxState = NPX_STATE_VALID;
}
#endif /* !CONFIG_SMP */
- /* restore the state of the current thread */
- ASSERT((CurrentThread->NpxState & NPX_STATE_DIRTY) == 0);
- FxSaveArea = (PFX_SAVE_AREA)((char *)CurrentThread->InitialStack - sizeof (FX_SAVE_AREA));
- if (CurrentThread->NpxState & NPX_STATE_VALID)
+ /* restore the state of the current thread */
+ ASSERT((CurrentThread->NpxState & NPX_STATE_DIRTY) == 0);
+ FxSaveArea = (PFX_SAVE_AREA)((char *)CurrentThread->InitialStack - sizeof (FX_SAVE_AREA));
+ if (CurrentThread->NpxState & NPX_STATE_VALID)
{
- if (FxsrSupport)
+ if (FxsrSupport)
{
FxSaveArea->U.FxArea.MXCsr &= MxcsrFeatureMask;
asm volatile("fxrstor %0" : : "m"(FxSaveArea->U.FxArea));
}
- else
+ else
{
asm volatile("frstor %0" : : "m"(FxSaveArea->U.FnArea));
}
}
- else /* NpxState & NPX_STATE_INVALID */
+ else /* NpxState & NPX_STATE_INVALID */
{
- DPRINT("Setting up clean FPU state\n");
- if (FxsrSupport)
+ DPRINT("Setting up clean FPU state\n");
+ if (FxsrSupport)
{
- memset(&FxSaveArea->U.FxArea, 0, sizeof(FxSaveArea->U.FxArea));
- FxSaveArea->U.FxArea.ControlWord = 0x037f;
- if (XmmSupport)
+ memset(&FxSaveArea->U.FxArea, 0, sizeof(FxSaveArea->U.FxArea));
+ FxSaveArea->U.FxArea.ControlWord = 0x037f;
+ if (XmmSupport)
{
- FxSaveArea->U.FxArea.MXCsr = 0x00001f80 & MxcsrFeatureMask;
+ FxSaveArea->U.FxArea.MXCsr = 0x00001f80 & MxcsrFeatureMask;
}
- asm volatile("fxrstor %0" : : "m"(FxSaveArea->U.FxArea));
+ asm volatile("fxrstor %0" : : "m"(FxSaveArea->U.FxArea));
}
- else if (!FpuInitialized)
+ else if (!FpuInitialized)
{
- asm volatile("finit");
+ asm volatile("finit");
}
}
- KeGetCurrentPrcb()->NpxThread = CurrentThread;
+ KeGetCurrentPrcb()->NpxThread = CurrentThread;
#ifndef CONFIG_SMP
}
#endif
- CurrentThread->NpxState |= NPX_STATE_DIRTY;
- KeLowerIrql(oldIrql);
- DPRINT("Device not present exception handled!\n");
+ CurrentThread->NpxState |= NPX_STATE_DIRTY;
+ KeLowerIrql(oldIrql);
+ DPRINT("Device not present exception handled!\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
- else /* ExceptionNr == 16 || ExceptionNr == 19 */
+ else /* ExceptionNr == 16 || ExceptionNr == 19 */
{
- EXCEPTION_RECORD Er;
- UCHAR DummyContext[sizeof(CONTEXT) + 16];
- PCONTEXT Context;
- KPROCESSOR_MODE PreviousMode;
- PKTHREAD CurrentThread, NpxThread;
- KIRQL oldIrql;
+ EXCEPTION_RECORD Er;
+ UCHAR DummyContext[sizeof(CONTEXT) + 16];
+ PCONTEXT Context;
+ KPROCESSOR_MODE PreviousMode;
+ PKTHREAD CurrentThread, NpxThread;
+ KIRQL oldIrql;
- ASSERT(ExceptionNr == 16 || ExceptionNr == 19); /* math fault or XMM fault*/
+ ASSERT(ExceptionNr == 16 || ExceptionNr == 19); /* math fault or XMM fault*/
- KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
+ KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
- NpxThread = KeGetCurrentPrcb()->NpxThread;
- CurrentThread = KeGetCurrentThread();
- if (NpxThread == NULL)
+ NpxThread = KeGetCurrentPrcb()->NpxThread;
+ CurrentThread = KeGetCurrentThread();
+ if (NpxThread == NULL)
{
- KeLowerIrql(oldIrql);
- DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
- return STATUS_SUCCESS;
+ KeLowerIrql(oldIrql);
+ DPRINT1("!!! Math/Xmm fault ignored! (NpxThread == NULL)\n");
+ return STATUS_SUCCESS;
}
- PreviousMode = ((Tf->Cs & 0xffff) == USER_CS) ? (UserMode) : (KernelMode);
- DPRINT("Math/Xmm fault happened! (PreviousMode = %s)\n",
- (PreviousMode != KernelMode) ? ("UserMode") : ("KernelMode"));
+ PreviousMode = ((Tf->Cs & 0xffff) == USER_CS) ? (UserMode) : (KernelMode);
+ DPRINT("Math/Xmm fault happened! (PreviousMode = %s)\n",
+ (PreviousMode != KernelMode) ? ("UserMode") : ("KernelMode"));
- ASSERT(NpxThread == CurrentThread); /* FIXME: Is not always true I think */
+ ASSERT(NpxThread == CurrentThread); /* FIXME: Is not always true I think */
- /* For fxsave we have to align Context->ExtendedRegisters on 16 bytes */
- Context = (PCONTEXT)DummyContext;
- Context = (PCONTEXT)((ULONG_PTR)Context + 0x10 - ((ULONG_PTR)Context->ExtendedRegisters & 0x0f));
+ /* For fxsave we have to align Context->ExtendedRegisters on 16 bytes */
+ Context = (PCONTEXT)DummyContext;
+ Context = (PCONTEXT)((ULONG_PTR)Context + 0x10 - ((ULONG_PTR)Context->ExtendedRegisters & 0x0f));
- /* Get FPU/XMM state */
- Context->FloatSave.Cr0NpxState = 0;
- if (FxsrSupport)
+ /* Get FPU/XMM state */
+ Context->FloatSave.Cr0NpxState = 0;
+ if (FxsrSupport)
{
- PFXSAVE_FORMAT FxSave = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
- FxSave->MXCsrMask = MxcsrFeatureMask;
- memset(FxSave->RegisterArea, 0, sizeof(FxSave->RegisterArea) +
- sizeof(FxSave->Reserved3) + sizeof(FxSave->Reserved4));
- asm volatile("fxsave %0" : : "m"(*FxSave));
- KeLowerIrql(oldIrql);
- KiFxsaveToFnsaveFormat((PFNSAVE_FORMAT)&Context->FloatSave, FxSave);
+ PFXSAVE_FORMAT FxSave = (PFXSAVE_FORMAT)Context->ExtendedRegisters;
+ FxSave->MXCsrMask = MxcsrFeatureMask;
+ memset(FxSave->RegisterArea, 0, sizeof(FxSave->RegisterArea) +
+ sizeof(FxSave->Reserved3) + sizeof(FxSave->Reserved4));
+ asm volatile("fxsave %0" : : "m"(*FxSave));
+ KeLowerIrql(oldIrql);
+ KiFxsaveToFnsaveFormat((PFNSAVE_FORMAT)&Context->FloatSave, FxSave);
}
- else
+ else
{
- PFNSAVE_FORMAT FnSave = (PFNSAVE_FORMAT)&Context->FloatSave;
- asm volatile("fnsave %0" : : "m"(*FnSave));
- KeLowerIrql(oldIrql);
- KiFnsaveToFxsaveFormat((PFXSAVE_FORMAT)Context->ExtendedRegisters, FnSave);
+ PFNSAVE_FORMAT FnSave = (PFNSAVE_FORMAT)&Context->FloatSave;
+ asm volatile("fnsave %0" : : "m"(*FnSave));
+ KeLowerIrql(oldIrql);
+ KiFnsaveToFxsaveFormat((PFXSAVE_FORMAT)Context->ExtendedRegisters, FnSave);
}
- /* Fill the rest of the context */
- Context->ContextFlags = CONTEXT_FULL;
- KeTrapFrameToContext(Tf, NULL, Context);
- Context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
+ /* Fill the rest of the context */
+ Context->ContextFlags = CONTEXT_FULL;
+ KeTrapFrameToContext(Tf, NULL, Context);
+ Context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
- /* Determine exception code */
- if (ExceptionNr == 16)
+ /* Determine exception code */
+ if (ExceptionNr == 16)
{
- USHORT FpuStatusWord = Context->FloatSave.StatusWord & 0xffff;
- DPRINT("FpuStatusWord = 0x%04x\n", FpuStatusWord);
+ USHORT FpuStatusWord = Context->FloatSave.StatusWord & 0xffff;
+ DPRINT("FpuStatusWord = 0x%04x\n", FpuStatusWord);
- if (FpuStatusWord & X87_SW_IE)
- Er.ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
- else if (FpuStatusWord & X87_SW_DE)
- Er.ExceptionCode = STATUS_FLOAT_DENORMAL_OPERAND;
- else if (FpuStatusWord & X87_SW_ZE)
- Er.ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
- else if (FpuStatusWord & X87_SW_OE)
- Er.ExceptionCode = STATUS_FLOAT_OVERFLOW;
- else if (FpuStatusWord & X87_SW_UE)
- Er.ExceptionCode = STATUS_FLOAT_UNDERFLOW;
- else if (FpuStatusWord & X87_SW_PE)
- Er.ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
- else if (FpuStatusWord & X87_SW_SE)
- Er.ExceptionCode = STATUS_FLOAT_STACK_CHECK;
- else
- ASSERT(0); /* not reached */
- /* FIXME: is this the right way to get the correct EIP of the faulting instruction? */
- Er.ExceptionAddress = (PVOID)Context->FloatSave.ErrorOffset;
+ if (FpuStatusWord & X87_SW_IE)
+ Er.ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
+ else if (FpuStatusWord & X87_SW_DE)
+ Er.ExceptionCode = STATUS_FLOAT_DENORMAL_OPERAND;
+ else if (FpuStatusWord & X87_SW_ZE)
+ Er.ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
+ else if (FpuStatusWord & X87_SW_OE)
+ Er.ExceptionCode = STATUS_FLOAT_OVERFLOW;
+ else if (FpuStatusWord & X87_SW_UE)
+ Er.ExceptionCode = STATUS_FLOAT_UNDERFLOW;
+ else if (FpuStatusWord & X87_SW_PE)
+ Er.ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
+ else if (FpuStatusWord & X87_SW_SE)
+ Er.ExceptionCode = STATUS_FLOAT_STACK_CHECK;
+ else
+ ASSERT(0); /* not reached */
+ /* FIXME: is this the right way to get the correct EIP of the faulting instruction? */
+ Er.ExceptionAddress = (PVOID)Context->FloatSave.ErrorOffset;
}
- else /* ExceptionNr == 19 */
+ else /* ExceptionNr == 19 */
{
- /* FIXME: When should we use STATUS_FLOAT_MULTIPLE_FAULTS? */
- Er.ExceptionCode = STATUS_FLOAT_MULTIPLE_TRAPS;
- Er.ExceptionAddress = (PVOID)Tf->Eip;
+ /* FIXME: When should we use STATUS_FLOAT_MULTIPLE_FAULTS? */
+ Er.ExceptionCode = STATUS_FLOAT_MULTIPLE_TRAPS;
+ Er.ExceptionAddress = (PVOID)Tf->Eip;
}
- Er.ExceptionFlags = 0;
- Er.ExceptionRecord = NULL;
- Er.NumberParameters = 0;
+ Er.ExceptionFlags = 0;
+ Er.ExceptionRecord = NULL;
+ Er.NumberParameters = 0;
- /* Dispatch exception */
- DPRINT("Dispatching exception (ExceptionCode = 0x%08x)\n", Er.ExceptionCode);
- KiDispatchException(&Er, NULL, Tf, PreviousMode, TRUE);
+ /* Dispatch exception */
+ DPRINT("Dispatching exception (ExceptionCode = 0x%08x)\n", Er.ExceptionCode);
+ KiDispatchException(&Er, NULL, Tf, PreviousMode, TRUE);
- DPRINT("Math-fault handled!\n");
- return STATUS_SUCCESS;
+ DPRINT("Math-fault handled!\n");
+ return STATUS_SUCCESS;
}
- return STATUS_UNSUCCESSFUL;
+ return STATUS_UNSUCCESSFUL;
}
-