+FSCTL_DISMOUNT_VOLUME define
[reactos.git] / ntoskrnl / ke / i386 / v86m_sup.S
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2000 David Welch <welch@cwcom.net>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*
20  * FILE:            ntoskrnl/ke/i386/vm86_sup.S
21  * PURPOSE:         V86 mode support
22  * PROGRAMMER:      David Welch (welch@cwcom.net)
23  * UPDATE HISTORY:
24  *                  Created 09/10/00
25  */
26
27 #include <internal/v86m.h>
28 #include <ddk/i386/tss.h>
29 #include <internal/trap.h>
30 #include <internal/ps.h>
31                         
32 .globl _Ki386RetToV86Mode
33 .globl _KiV86Complete
34         
35         /*
36          * VOID Ki386RetToV86Mode(KV86M_REGISTERS* InRegs,
37          *                        KV86M_REGISTERS* OutRegs);
38          *
39          * Starts in v86 mode with the registers set to the
40          * specified values.
41          */             
42 _Ki386RetToV86Mode:
43         /*
44          * Setup a stack frame
45          */
46         pushl   %ebp
47         movl    %esp, %ebp
48         
49         /*
50          * Save registers
51          */
52         pusha
53         
54         /*
55          * Get a pointer to IN_REGS
56          */
57         movl    8(%ebp), %ebx
58
59         /*
60          * Save ebp
61          */
62         pushl   %ebp
63         
64         /*
65          * Save a pointer to IN_REGS which the v86m exception handler will
66          * use to handle exceptions
67          */
68         pushl   %ebx
69
70         /*
71          * Since we are going to fiddle with the stack pointer this must be
72          * a critical section for this processor
73          */
74         
75         /*
76          * Save the old initial stack
77          */
78         movl    %fs:KPCR_CURRENT_THREAD, %esi
79         movl    KTHREAD_INITIAL_STACK(%esi), %edi
80         pushl   %edi
81
82         /*
83          * We also need to set the stack in the kthread structure
84          */
85         movl    %esp, KTHREAD_INITIAL_STACK(%esi)
86         
87         /*
88          * The stack used for handling exceptions from v86 mode in this thread
89          * will be the current stack adjusted so we don't overwrite the 
90          * existing stack frames
91          */
92         movl    %fs:KPCR_TSS, %esi
93         movl    %esp, KTSS_ESP0(%esi)
94         
95         /*
96          * Create the stack frame for an iret to v86 mode
97          */
98         pushl   KV86M_REGISTERS_GS(%ebx)
99         pushl   KV86M_REGISTERS_FS(%ebx)
100         pushl   KV86M_REGISTERS_DS(%ebx)
101         pushl   KV86M_REGISTERS_ES(%ebx)
102         pushl   KV86M_REGISTERS_SS(%ebx)
103         pushl   KV86M_REGISTERS_ESP(%ebx)
104         pushl   KV86M_REGISTERS_EFLAGS(%ebx)
105         pushl   KV86M_REGISTERS_CS(%ebx)
106         pushl   KV86M_REGISTERS_EIP(%ebx)
107
108         /*
109          * Setup the CPU registers
110          */
111         movl    KV86M_REGISTERS_EAX(%ebx), %eax
112         movl    KV86M_REGISTERS_ECX(%ebx), %ecx
113         movl    KV86M_REGISTERS_EDX(%ebx), %edx
114         movl    KV86M_REGISTERS_ESI(%ebx), %esi
115         movl    KV86M_REGISTERS_EDI(%ebx), %edi
116         movl    KV86M_REGISTERS_EBP(%ebx), %ebp
117         movl    KV86M_REGISTERS_EBX(%ebx), %ebx
118
119         /*
120          * Go to v86 mode
121          */
122         iret
123                 
124         /*
125          * Handle the completion of a vm86 routine. We are called from
126          * an exception handler with the registers at the point of the
127          * exception on the stack.
128          */
129 _KiV86Complete:
130         /* Restore the original ebp */
131         movl    TF_ORIG_EBP(%esp), %ebp
132         
133         /* Get a pointer to the OUT_REGS structure */
134         movl    12(%ebp), %ebx
135
136         /* Skip debug information and unsaved registers */
137         addl    $0x30, %esp     
138
139         /* Ignore 32-bit segment registers */
140         addl    $12, %esp
141
142         /* Save the vm86 registers into the OUT_REGS structure */
143         popl    KV86M_REGISTERS_EDX(%ebx)
144         popl    KV86M_REGISTERS_ECX(%ebx)
145         popl    KV86M_REGISTERS_EAX(%ebx)
146
147         /* Ignore the previous mode */
148         addl    $4, %esp
149
150         /* Ignore old exception handler list */
151         addl    $4, %esp
152         
153         /* Ignore the 32-bit fs register */
154         addl    $4, %esp
155
156         popl    KV86M_REGISTERS_EDI(%ebx)
157         popl    KV86M_REGISTERS_ESI(%ebx)
158         popl    KV86M_REGISTERS_EBX(%ebx)
159         popl    KV86M_REGISTERS_EBP(%ebx)
160
161         /* Ignore error code */
162         addl    $4, %esp
163
164         popl    KV86M_REGISTERS_EIP(%ebx)
165         popl    KV86M_REGISTERS_CS(%ebx)
166         popl    KV86M_REGISTERS_EFLAGS(%ebx)
167         popl    KV86M_REGISTERS_ESP(%ebx)
168         popl    KV86M_REGISTERS_SS(%ebx)
169         popl    KV86M_REGISTERS_ES(%ebx)
170         popl    KV86M_REGISTERS_DS(%ebx)
171         popl    KV86M_REGISTERS_FS(%ebx)
172         popl    KV86M_REGISTERS_GS(%ebx)
173
174         /*
175          * We are going to fiddle with the stack so this must be a critical
176          * section for this process
177          */
178         cli
179
180         /*
181          * Restore the initial stack
182          */
183         popl    %eax
184         movl    %fs:KPCR_TSS, %esi
185         movl    %eax, KTSS_ESP0(%esi)
186
187         /*
188          * We also need to set the stack in the kthread structure
189          */
190         movl    %fs:KPCR_CURRENT_THREAD, %esi
191         movl    KTHREAD_INITIAL_STACK(%esi), %edi
192         movl    %eax, KTHREAD_INITIAL_STACK(%esi)       
193
194         /* Exit the critical section */
195         sti
196         
197         /* Ignore IN_REGS pointer */
198         addl    $4, %esp
199         
200         /* Ignore ebp restored above */
201         addl    $4, %esp
202         
203         /* Return to caller */
204         popa
205         movl    %ebp, %esp      
206         popl    %ebp
207         ret
208         
209                 
210
211
212
213