*/
#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
* 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
*/
* 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)
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