V86 mode fixes
[reactos.git] / reactos / ntoskrnl / ke / i386 / trap.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 /* $Id: trap.s,v 1.9 2001/03/25 02:34:28 dwelch Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/i386/trap.s
23 * PURPOSE: Exception handlers
24 * PROGRAMMER: David Welch <welch@cwcom.net>
25 */
26
27 /* INCLUDES ******************************************************************/
28
29 #include <ddk/status.h>
30 #include <internal/i386/segment.h>
31 #include <internal/ps.h>
32 #include <ddk/defines.h>
33
34 /* FUNCTIONS *****************************************************************/
35
36 /*
37 * Epilog for exception handlers
38 */
39 _KiTrapEpilog:
40 cmpl $1, %eax /* Check for v86 recovery */
41 jne _KiTrapRet
42 jmp _KiV86Complete
43 _KiTrapRet:
44 /* Get a pointer to the current thread */
45 movl %fs:0x124, %esi
46
47 /* Restore the old trap frame pointer */
48 movl 0x3c(%esp), %ebx
49 movl %ebx, KTHREAD_TRAP_FRAME(%esi)
50
51 /* Skip debug information and unsaved registers */
52 addl $0x30, %esp
53 popl %gs
54 popl %es
55 popl %ds
56 popl %edx
57 popl %ecx
58 popl %eax
59
60 /* Restore the old previous mode */
61 popl %ebx
62 movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
63
64 /* Restore the old exception handler list */
65 popl %ebx
66 movl %ebx, %fs:KPCR_EXCEPTION_LIST
67
68 popl %fs
69 popl %edi
70 popl %esi
71 popl %ebx
72 popl %ebp
73 addl $0x4, %esp /* Ignore error code */
74
75 iret
76
77 .globl _KiTrapProlog
78 _KiTrapProlog:
79 pushl %edi
80 pushl %fs
81
82 /*
83 * Check that the PCR exists, very early in the boot process it may
84 * not
85 */
86 cmpl $0, %ss:_KiPcrInitDone
87 je .L5
88
89 /* Load the PCR selector into fs */
90 movl $PCR_SELECTOR, %ebx
91 movl %ebx, %fs
92
93 /* Save the old exception list */
94 movl %fs:KPCR_EXCEPTION_LIST, %ebx
95 pushl %ebx
96
97 /* Put the exception handler chain terminator */
98 movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
99
100 /* Get a pointer to the current thread */
101 movl %fs:KPCR_CURRENT_THREAD, %edi
102
103 /* The current thread may be NULL early in the boot process */
104 cmpl $0, %edi
105 je .L4
106
107 /* Save the old previous mode */
108 movl $0, %ebx
109 movb %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl
110 pushl %ebx
111
112 /* Set the new previous mode based on the saved CS selector */
113 movl 0x24(%esp), %ebx
114 cmpl $KERNEL_CS, %ebx
115 jne .L1
116 movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
117 jmp .L3
118 .L1:
119 movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
120 .L3:
121
122 /* Save other registers */
123 pushl %eax
124 pushl %ecx
125 pushl %edx
126 pushl %ds
127 pushl %es
128 pushl %gs
129 pushl $0 /* DR7 */
130 pushl $0 /* DR6 */
131 pushl $0 /* DR3 */
132 pushl $0 /* DR2 */
133 pushl $0 /* DR1 */
134 pushl $0 /* DR0 */
135 pushl $0 /* XXX: TempESP */
136 pushl $0 /* XXX: TempCS */
137 pushl $0 /* XXX: DebugPointer */
138 pushl $0 /* XXX: DebugArgMark */
139 pushl $0 /* XXX: DebugEIP */
140 pushl $0 /* XXX: DebugEBP */
141
142 /* Load the segment registers */
143 movl $KERNEL_DS, %ebx
144 movl %ebx, %ds
145 movl %ebx, %es
146 movl %ebx, %gs
147
148 /* Set ES to kernel segment */
149 movw $KERNEL_DS,%bx
150 movw %bx,%es
151
152 /* Call the C exception handler */
153 movl %esp, %ebx
154 pushl %esi
155 pushl %ebx
156 call _KiTrapHandler
157 addl $4, %esp
158 addl $4, %esp
159
160 /* Return to the caller */
161 jmp _KiTrapEpilog
162
163 /* Handle the no-pcr case out of line */
164 .L5:
165 pushl $0
166
167 /* Handle the no-thread case out of line */
168 .L4:
169 pushl $0
170 jmp .L3
171
172 .globl _KiTrap0
173 _KiTrap0:
174 /* No error code */
175 pushl $0
176 pushl %ebp
177 pushl %ebx
178 pushl %esi
179 movl $0, %esi
180 jmp _KiTrapProlog
181
182 .globl _KiTrap1
183 _KiTrap1:
184 /* No error code */
185 pushl $0
186 pushl %ebp
187 pushl %ebx
188 pushl %esi
189 movl $1, %esi
190 jmp _KiTrapProlog
191
192 .globl _KiTrap2
193 _KiTrap2:
194 pushl $0
195 pushl %ebp
196 pushl %ebx
197 pushl %esi
198 movl $2, %esi
199 jmp _KiTrapProlog
200
201 .globl _KiTrap3
202 _KiTrap3:
203 pushl $0
204 pushl %ebp
205 pushl %ebx
206 pushl %esi
207 movl $3, %esi
208 jmp _KiTrapProlog
209
210 .globl _KiTrap4
211 _KiTrap4:
212 pushl $0
213 pushl %ebp
214 pushl %ebx
215 pushl %esi
216 movl $4, %esi
217 jmp _KiTrapProlog
218
219 .globl _KiTrap5
220 _KiTrap5:
221 pushl $0
222 pushl %ebp
223 pushl %ebx
224 pushl %esi
225 movl $5, %esi
226 jmp _KiTrapProlog
227
228 .globl _KiTrap6
229 _KiTrap6:
230 pushl $0
231 pushl %ebp
232 pushl %ebx
233 pushl %esi
234 movl $6, %esi
235 jmp _KiTrapProlog
236
237 .globl _KiTrap7
238 _KiTrap7:
239 pushl $0
240 pushl %ebp
241 pushl %ebx
242 pushl %esi
243 movl $7, %esi
244 jmp _KiTrapProlog
245
246 .globl _KiTrap8
247 _KiTrap8:
248 pushl %ebp
249 pushl %ebx
250 pushl %esi
251 movl $8, %esi
252 jmp _KiTrapProlog
253
254 .globl _KiTrap9
255 _KiTrap9:
256 pushl $0
257 pushl %ebp
258 pushl %ebx
259 pushl %esi
260 movl $9, %esi
261 jmp _KiTrapProlog
262
263 .globl _KiTrap10
264 _KiTrap10:
265 pushl %ebp
266 pushl %ebx
267 pushl %esi
268 movl $10, %esi
269 jmp _KiTrapProlog
270
271 .globl _KiTrap11
272 _KiTrap11:
273 pushl %ebp
274 pushl %ebx
275 pushl %esi
276 movl $11, %esi
277 jmp _KiTrapProlog
278
279 .globl _KiTrap12
280 _KiTrap12:
281 pushl %ebp
282 pushl %ebx
283 pushl %esi
284 movl $12, %esi
285 jmp _KiTrapProlog
286
287 .globl _KiTrap13
288 _KiTrap13:
289 pushl %ebp
290 pushl %ebx
291 pushl %esi
292 movl $13, %esi
293 jmp _KiTrapProlog
294
295 .globl _KiTrap14
296 _KiTrap14:
297 pushl %ebp
298 pushl %ebx
299 pushl %esi
300 movl $14, %esi
301 jmp _KiTrapProlog
302
303 .globl _KiTrap15
304 _KiTrap15:
305 pushl %ebp
306 pushl %ebx
307 pushl %esi
308 movl $15, %esi
309 jmp _KiTrapProlog
310
311 .globl _KiTrap16
312 _KiTrap16:
313 pushl %ebp
314 pushl %ebx
315 pushl %esi
316 movl $16, %esi
317 jmp _KiTrapProlog
318
319 .globl _KiTrapUnknown
320 _KiTrapUnknown:
321 pushl $0
322 pushl %ebp
323 pushl %ebx
324 pushl %esi
325 movl $255, %esi
326 jmp _KiTrapProlog
327
328
329 /* EOF */