2 * FILE: ntoskrnl/ke/i386/vm86_sup.S
3 * PURPOSE: V86 mode support
4 * PROGRAMMER: David Welch (welch@cwcom.net)
9 #include <internal/asm.h>
11 .globl _Ki386RetToV86Mode
15 * VOID Ki386RetToV86Mode(KV86M_REGISTERS* InRegs,
16 * KV86M_REGISTERS* OutRegs);
18 * Starts in v86 mode with the registers set to the
34 * Get a pointer to IN_REGS
44 * Save a pointer to IN_REGS which the v86m exception handler will
45 * use to handle exceptions
50 * Since we are going to fiddle with the stack pointer this must be
51 * a critical section for this processor
56 * Save the exception handler stack from the TSS
58 movl %fs:KPCR_TSS, %esi
62 * The stack used for handling exceptions from v86 mode in this thread
63 * will be the current stack adjusted so we don't overwrite the
64 * existing stack frames
66 movl %esp, KTSS_ESP0(%esi)
69 * Create the stack frame for an iret to v86 mode
71 pushl KV86M_REGISTERS_GS(%ebx)
72 pushl KV86M_REGISTERS_FS(%ebx)
73 pushl KV86M_REGISTERS_DS(%ebx)
74 pushl KV86M_REGISTERS_ES(%ebx)
75 pushl KV86M_REGISTERS_SS(%ebx)
76 pushl KV86M_REGISTERS_ESP(%ebx)
77 pushl KV86M_REGISTERS_EFLAGS(%ebx)
78 pushl KV86M_REGISTERS_CS(%ebx)
79 pushl KV86M_REGISTERS_EIP(%ebx)
82 * Setup the CPU registers
84 movl KV86M_REGISTERS_EAX(%ebx), %eax
85 movl KV86M_REGISTERS_ECX(%ebx), %ecx
86 movl KV86M_REGISTERS_EDX(%ebx), %edx
87 movl KV86M_REGISTERS_ESI(%ebx), %esi
88 movl KV86M_REGISTERS_EDI(%ebx), %edi
89 movl KV86M_REGISTERS_EBP(%ebx), %ebp
90 movl KV86M_REGISTERS_EBX(%ebx), %ebx
98 * Handle the completion of a vm86 routine. We are called from
99 * an exception handler with the registers at the point of the
100 * exception on the stack.
103 /* Restore the original ebp */
104 movl TF_ORIG_EBP(%esp), %ebp
106 /* Get a pointer to the OUT_REGS structure */
109 /* Skip debug information and unsaved registers */
112 /* Ignore 32-bit segment registers */
115 /* Save the vm86 registers into the OUT_REGS structure */
116 popl KV86M_REGISTERS_EDX(%ebx)
117 popl KV86M_REGISTERS_ECX(%ebx)
118 popl KV86M_REGISTERS_EAX(%ebx)
120 /* Restore the old previous mode */
122 movb %al, %ss:KTHREAD_PREVIOUS_MODE(%esi)
124 /* Restore the old exception handler list */
126 movl %eax, %fs:KPCR_EXCEPTION_LIST
128 /* Ignore the 32-bit fs register */
131 popl KV86M_REGISTERS_EDI(%ebx)
132 popl KV86M_REGISTERS_ESI(%ebx)
133 popl KV86M_REGISTERS_EBX(%ebx)
134 popl KV86M_REGISTERS_EBP(%ebx)
136 /* Ignore error code */
139 popl KV86M_REGISTERS_EIP(%ebx)
140 popl KV86M_REGISTERS_CS(%ebx)
141 popl KV86M_REGISTERS_EFLAGS(%ebx)
142 popl KV86M_REGISTERS_ESP(%ebx)
143 popl KV86M_REGISTERS_SS(%ebx)
144 popl KV86M_REGISTERS_ES(%ebx)
145 popl KV86M_REGISTERS_DS(%ebx)
146 popl KV86M_REGISTERS_FS(%ebx)
147 popl KV86M_REGISTERS_GS(%ebx)
150 * We are going to fiddle with the stack so this must be a critical
151 * section for this process
156 * Restore the exception handler stack in the TSS
158 movl %fs:KPCR_TSS, %esi
161 /* Exit the critical section */
164 /* Ignore IN_REGS pointer */
167 /* Ignore ebp restored above */
170 /* Return to caller */