Author: ion
Date: Sat Jul 23 16:26:03 2011
New Revision: 52809

URL: http://svn.reactos.org/svn/reactos?rev=52809&view=rev
Log:
Thanks to Timo Kreuzer for discovering what led to these:
[KERNEL32]: BasepInitializeContext was not creating a correct CONTEXT record 
for fibers: the stack return address was not set (EIP was being used instead), 
and support for FPU-compatible Fibers was non-existent.
[KERNEL32]: CreateFiberEx was not passing the correct context flags to 
BasepInitializeContext to notify it that this is an FPU-fiber.
[KERNEL32]: SwitchToFiber was using some weird "FXSR" constant that maps to 
checking of PowerPC 64-bit Move instructions are available. We actually want to 
check for XMMI.

Modified:
    trunk/reactos/dll/win32/kernel32/client/fiber.c
    trunk/reactos/dll/win32/kernel32/client/i386/fiber.S
    trunk/reactos/dll/win32/kernel32/client/utils.c

Modified: trunk/reactos/dll/win32/kernel32/client/fiber.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/fiber.c?rev=52809&r1=52808&r2=52809&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] Sat Jul 23 
16:26:03 2011
@@ -223,11 +223,8 @@
     Fiber->ActivationContextStack = ActivationContextStack;
     Fiber->Context.ContextFlags = CONTEXT_FULL;
 
-    /* Save FPU State if requsted */
-    if (dwFlags & FIBER_FLAG_FLOAT_SWITCH)
-    {
-        Fiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT;
-    }
+    /* Save FPU State if requested */
+    Fiber->Context.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ? 
CONTEXT_FLOATING_POINT : 0;
 
     /* initialize the context for the fiber */
     BasepInitializeContext(&Fiber->Context,

Modified: trunk/reactos/dll/win32/kernel32/client/i386/fiber.S
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/i386/fiber.S?rev=52809&r1=52808&r2=52809&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/i386/fiber.S [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/i386/fiber.S [iso-8859-1] Sat Jul 
23 16:26:03 2011
@@ -35,7 +35,7 @@
     fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
     
     /* Check if the CPU supports SIMD MXCSR State Save */
-    cmp byte ptr ds:[PROCESSOR_FEATURE_FXSR], 1
+    cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
     jnz NoFpuStateSave
     stmxcsr [eax+FIBER_CONTEXT_DR6]
     
@@ -99,7 +99,7 @@
 ControlWordEqual:
 
     /* Load the new one */
-    cmp byte ptr ds:[PROCESSOR_FEATURE_FXSR], 1
+    cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
     jnz NoFpuStateRestore
     ldmxcsr [ecx+FIBER_CONTEXT_DR6]
     

Modified: trunk/reactos/dll/win32/kernel32/client/utils.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/utils.c?rev=52809&r1=52808&r2=52809&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] Sat Jul 23 
16:26:03 2011
@@ -336,8 +336,9 @@
                        IN ULONG ContextType)
 {
 #ifdef _M_IX86
+    ULONG ContextFlags;
     DPRINT("BasepInitializeContext: %p\n", Context);
-    
+
     /* Setup the Initial Win32 Thread Context */
     Context->Eax = (ULONG)StartAddress;
     Context->Ebx = (ULONG)Parameter;
@@ -352,30 +353,53 @@
     Context->SegSs = KGDT_R3_DATA | RPL_MASK;
     Context->SegGs = 0;
 
+    /* Set the Context Flags */
+    ContextFlags = Context->ContextFlags;
+    Context->ContextFlags = CONTEXT_FULL;
+
+    /* Give it some room for the Parameter */
+    Context->Esp -= sizeof(PVOID);
+
     /* Set the EFLAGS */
     Context->EFlags = 0x3000; /* IOPL 3 */
 
-    if (ContextType == 1)      /* For Threads */
-    {
+    /* What kind of context is being created? */
+    if (ContextType == 1)
+    {
+        /* For Threads */
         Context->Eip = (ULONG)BaseThreadStartupThunk;
     }
-    else if (ContextType == 2) /* For Fibers */
-    {
-        Context->Eip = (ULONG)BaseFiberStartup;
-    }
-    else                       /* For first thread in a Process */
-    {
+    else if (ContextType == 2)
+    {
+        /* This is a fiber: make space for the return address */
+        Context->Esp -= sizeof(PVOID);
+        *((PVOID*)Context->Esp) = BaseFiberStartup;
+
+        /* Is FPU state required? */
+        Context->ContextFlags |= ContextFlags;
+        if (ContextFlags == CONTEXT_FLOATING_POINT)
+        {
+            /* Set an initial state */
+            Context->FloatSave.ControlWord = 0x27F;
+            Context->FloatSave.StatusWord = 0;
+            Context->FloatSave.TagWord = 0xFFFF;
+            Context->FloatSave.ErrorOffset = 0;
+            Context->FloatSave.ErrorSelector = 0;
+            Context->FloatSave.DataOffset = 0;
+            Context->FloatSave.DataSelector = 0;
+            if 
(SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE])
+                Context->Dr6 = 0x1F80;
+        }
+    }
+    else
+    {
+        /* For first thread in a Process */
         Context->Eip = (ULONG)BaseProcessStartThunk;
     }
-    
-    /* Set the Context Flags */
-    Context->ContextFlags = CONTEXT_FULL;
-    
-    /* Give it some room for the Parameter */
-    Context->Esp -= sizeof(PVOID);
+
 #elif defined(_M_AMD64)
     DPRINT("BasepInitializeContext: %p\n", Context);
-    
+
     /* Setup the Initial Win32 Thread Context */
     Context->Rax = (ULONG_PTR)StartAddress;
     Context->Rbx = (ULONG_PTR)Parameter;
@@ -405,10 +429,10 @@
     {
         Context->Rip = (ULONG_PTR)BaseProcessStartThunk;
     }
-    
+
     /* Set the Context Flags */
     Context->ContextFlags = CONTEXT_FULL;
-    
+
     /* Give it some room for the Parameter */
     Context->Rsp -= sizeof(PVOID);
 #else


Reply via email to