2003-08-11 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / ntoskrnl / ke / i386 / v86m_sup.S
index 0baa997..a9c7190 100644 (file)
  */
 
 #include <internal/v86m.h>
-#include <ddk/i386/tss.h>
+#include <ntos/tss.h>
 #include <internal/trap.h>
-               
+#include <internal/ps.h>
+                       
 .globl _Ki386RetToV86Mode
 .globl _KiV86Complete
        
@@ -65,14 +66,32 @@ _Ki386RetToV86Mode:
         * use to handle exceptions
         */
        pushl   %ebx
+
+       /*
+        * Since we are going to fiddle with the stack pointer this must be
+        * a critical section for this processor
+        */
+       
+       /*
+        * Save the old initial stack
+        */
+       movl    %fs:KPCR_CURRENT_THREAD, %esi
+       movl    KTHREAD_INITIAL_STACK(%esi), %edi
+       pushl   %edi
+
+       /*
+        * We also need to set the stack in the kthread structure
+        */
+       movl    %esp, KTHREAD_INITIAL_STACK(%esi)
        
        /*
         * The stack used for handling exceptions from v86 mode in this thread
         * will be the current stack adjusted so we don't overwrite the 
         * existing stack frames
         */
+       movl    %fs:KPCR_TSS, %esi
        movl    %esp, KTSS_ESP0(%esi)
-
+       
        /*
         * Create the stack frame for an iret to v86 mode
         */
@@ -108,24 +127,41 @@ _Ki386RetToV86Mode:
         * exception on the stack.
         */
 _KiV86Complete:
-        addl    $4, %esp        /* Ignore pointer to trap frame */    
-
        /* Restore the original ebp */
        movl    TF_ORIG_EBP(%esp), %ebp
        
        /* Get a pointer to the OUT_REGS structure */
        movl    12(%ebp), %ebx
-       
+
+       /* Skip debug information and unsaved registers */
+       addl    $0x30, %esp     
+
+       /* Ignore 32-bit segment registers */
+       addl    $12, %esp
+
        /* Save the vm86 registers into the OUT_REGS structure */
-       popl    KV86M_REGISTERS_EDI(%ebx)
-       popl    KV86M_REGISTERS_ESI(%ebx)
-       popl    KV86M_REGISTERS_EBP(%ebx)
-       popl    KV86M_REGISTERS_EBX(%ebx)
        popl    KV86M_REGISTERS_EDX(%ebx)
        popl    KV86M_REGISTERS_ECX(%ebx)
        popl    KV86M_REGISTERS_EAX(%ebx)
-       addl    $16, %esp       /* Ignore 32-bit segment registers */
-       addl    $4, %esp        /* Ignore error code */
+
+       /* Restore the old previous mode */
+       popl    %eax
+       movb    %al, %ss:KTHREAD_PREVIOUS_MODE(%esi)
+
+       /* Restore the old exception handler list */
+       popl    %eax
+       movl    %eax, %fs:KPCR_EXCEPTION_LIST
+       
+       /* Ignore the 32-bit fs register */
+       addl    $4, %esp
+
+       popl    KV86M_REGISTERS_EDI(%ebx)
+       popl    KV86M_REGISTERS_ESI(%ebx)
+       popl    KV86M_REGISTERS_EBX(%ebx)
+       popl    KV86M_REGISTERS_EBP(%ebx)
+
+       /* Ignore error code */
+       addl    $4, %esp
 
        popl    KV86M_REGISTERS_EIP(%ebx)
        popl    KV86M_REGISTERS_CS(%ebx)
@@ -137,6 +173,29 @@ _KiV86Complete:
        popl    KV86M_REGISTERS_FS(%ebx)
        popl    KV86M_REGISTERS_GS(%ebx)
 
+       /*
+        * We are going to fiddle with the stack so this must be a critical
+        * section for this process
+        */
+       cli
+
+       /*
+        * Restore the initial stack
+        */
+       popl    %eax
+       movl    %fs:KPCR_TSS, %esi
+       movl    %eax, KTSS_ESP0(%esi)
+
+       /*
+        * We also need to set the stack in the kthread structure
+        */
+       movl    %fs:KPCR_CURRENT_THREAD, %esi
+       movl    KTHREAD_INITIAL_STACK(%esi), %edi
+       movl    %eax, KTHREAD_INITIAL_STACK(%esi)       
+
+       /* Exit the critical section */
+       sti
+       
        /* Ignore IN_REGS pointer */
        addl    $4, %esp