- Small patch to fix (delayed) loading of floating point state. Enables the special...
[reactos.git] / reactos / ntoskrnl / ke / i386 / ctxswitch.S
index bb4bc0d..3a35a3a 100644 (file)
@@ -3,7 +3,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/ctxswitch.S
  * PURPOSE:         Thread Context Switching
- * 
+ *
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  *                  Gregor Anich (FPU Code)
  */
@@ -63,7 +63,7 @@ PUBLIC @KiSwitchThreads@8
     /* Load the new kernel stack and switch OS to new thread */
     mov esp, edx
     call @KiSwapContextExit@8
-    
+
     /* Now we're on the new thread. Return to the caller to restore registers */
     add esp, 2 * 4
     ret
@@ -112,7 +112,7 @@ _Ki386LargePageIdentityLabel:
     and eax, NOT CR0_PG
     mov cr0, eax
 
-    /* Jump to the next instruction */
+    /* Jump to the next instruction to clear the prefetch queue */
     jmp $+2
 
     /* Enable Page Size Extension in CR4 */
@@ -143,7 +143,7 @@ _Ki386SetupAndExitToV86Mode@4:
 
     /* Enter V8086 mode */
     pushad
-    sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
+    sub esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16)
     mov ecx, esp
     call @KiEnterV86Mode@4
     jmp $
@@ -155,8 +155,32 @@ PUBLIC @Ki386BiosCallReturnAddress@4
     /* Exit V8086 mode */
     call @KiExitV86Mode@4
     mov esp, eax
-    add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH)
+    add esp, (12 + KTRAP_FRAME_LENGTH + NPX_FRAME_LENGTH + 16)
     popad
     ret 4
 
+PUBLIC _FrRestore
+PUBLIC @Ke386LoadFpuState@4
+@Ke386LoadFpuState@4:
+
+    /* Check if we have FXSR and choose which operand to use */
+    test byte ptr [_KeI386FxsrPresent], 1
+    jz _FrRestore
+
+    /* Restore all the FPU, MMX, XMM and MXCSR registers */
+    fxrstor [ecx]
+    ret
+
+    /*
+     * Just restore the basic FPU registers.
+     * This may raise an exception depending
+     * on the status word, which KiNpxHandler will
+     * need to check for and handle during delayed load
+     * to avoid raising an unhandled exception
+     * and crashing the system.
+     */
+_FrRestore:
+    frstor [ecx]
+    ret
+
 END