Initial revision
[reactos.git] / msvc6 / ntoskrnl / ke_i386_trap.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
4 *
5 * Moved to MSVC-compatible inline assembler by Mike Nordell, 2003-12-26
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 /*
22 * FILE: ntoskrnl/ke/i386/vm86_sup.S
23 * PURPOSE: V86 mode support
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * UPDATE HISTORY:
26 * Created 09/10/00
27 */
28
29 /* INCLUDES ******************************************************************/
30
31 #pragma hdrstop
32
33 #include <ddk/ntddk.h>
34 #include <ddk/status.h>
35 #include <internal/i386/segment.h>
36 #include <internal/i386/fpu.h>
37 #include <internal/ps.h>
38 #include <ddk/defines.h>
39 #include <internal/v86m.h>
40 #include <ntos/tss.h>
41 #include <internal/trap.h>
42 #include <internal/ps.h>
43
44 #include <roscfg.h>
45 #include <internal/ntoskrnl.h>
46 #include <internal/i386/segment.h>
47
48
49 void KiV86Complete(void);
50 void KiTrapHandler(void);
51 void KiDoubleFaultHandler(void);
52
53 extern int KiPcrInitDone;
54
55 /*
56 * Epilog for exception handlers
57 */
58 __declspec(naked)
59 void KiTrapEpilog()
60 {
61 __asm
62 {
63 cmp eax, 1 /* Check for v86 recovery */
64 jne _KiTrapRet
65 jmp KiV86Complete
66 _KiTrapRet:
67 /* Skip debug information and unsaved registers */
68 add esp, 0x30
69 pop gs
70 pop es
71 pop ds
72 pop edx
73 pop ecx
74 pop eax
75
76 /* Restore the old previous mode */
77 pop ebx
78 mov ss:KTHREAD_PREVIOUS_MODE[esi], bl
79
80 /* Restore the old exception handler list */
81 pop ebx
82 mov fs:KPCR_EXCEPTION_LIST, ebx
83
84 pop fs
85 pop edi
86 pop esi
87 pop ebx
88 pop ebp
89 add esp, 4 /* Ignore error code */
90
91 iretd
92 }
93 }
94
95 __declspec(naked)
96 void KiTrapProlog()
97 {
98 __asm
99 {
100 push edi
101 push fs
102
103 /*
104 * Check that the PCR exists, very early in the boot process it may
105 * not
106 */
107 cmp ss:KiPcrInitDone, 0
108 je L5_
109
110 /* Load the PCR selector into fs */
111 mov ebx, PCR_SELECTOR
112 mov fs, bx
113
114 /* Save the old exception list */
115 mov ebx, fs:KPCR_EXCEPTION_LIST
116 push ebx
117
118 /* Put the exception handler chain terminator */
119 mov dword ptr fs:KPCR_EXCEPTION_LIST, 0xffffffff
120
121 /* Get a pointer to the current thread */
122 mov edi, fs:KPCR_CURRENT_THREAD
123
124 /* The current thread may be NULL early in the boot process */
125 cmp edi, 0
126 je L4_
127
128 /* Save the old previous mode */
129 xor ebx, ebx
130 mov bl, ss:KTHREAD_PREVIOUS_MODE[edi]
131 push ebx
132
133 /* Set the new previous mode based on the saved CS selector */
134 mov ebx, 0x24[esp]
135 and ebx, 0x0000FFFF
136 cmp ebx, KERNEL_CS
137 jne L1_
138 mov ss:KTHREAD_PREVIOUS_MODE[edi], KernelMode
139 jmp L3_
140 L1_:
141 mov ss:KTHREAD_PREVIOUS_MODE[edi], UserMode
142 L3_:
143
144 /* Save other registers */
145 push eax
146 push ecx
147 push edx
148 push ds
149 push es
150 push gs
151 push 0 /* DR7 */
152 push 0 /* DR6 */
153 push 0 /* DR3 */
154 push 0 /* DR2 */
155 push 0 /* DR1 */
156 push 0 /* DR0 */
157 push 0 /* XXX: TempESP */
158 push 0 /* XXX: TempCS */
159 push 0 /* XXX: DebugPointer */
160 push 0 /* XXX: DebugArgMark */
161 mov ebx, 0x60[esp]
162 push ebx /* XXX: DebugEIP */
163 push ebp /* XXX: DebugEBP */
164
165 /* Load the segment registers */
166 mov ebx, KERNEL_DS
167 mov ds, bx
168 mov es, bx
169 mov gs, bx
170
171 /* Set ES to kernel segment */
172 mov bx, KERNEL_DS
173 mov es, bx
174
175 mov ebx, esp
176 mov ebp, esp
177
178 /* Save the old trap frame. */
179 cmp edi, 0
180 je L7_
181 mov edx, ss:KTHREAD_TRAP_FRAME[edi]
182 push edx
183 jmp L8_
184 L7_:
185 push 0
186 L8_:
187
188 /* Save a pointer to the trap frame in the current KTHREAD */
189 cmp edi, 0
190 je L6_
191 mov ss:KTHREAD_TRAP_FRAME[edi], ebx
192 L6_:
193
194 /* Call the C exception handler */
195 push esi
196 push ebx
197 call KiTrapHandler
198 add esp, 8
199
200 /* Get a pointer to the current thread */
201 mov esi, fs:KPCR_CURRENT_THREAD
202
203 /* Restore the old trap frame pointer */
204 pop ebx
205 mov KTHREAD_TRAP_FRAME[esi], ebx
206
207 /* Return to the caller */
208 jmp KiTrapEpilog
209
210 /* Handle the no-pcr case out of line */
211 L5_:
212 push 0
213
214 /* Handle the no-thread case out of line */
215 L4_:
216 push 0
217 jmp L3_
218
219 } // end of __asm block
220 }
221
222
223 __declspec(naked)
224 void KiTrap0()
225 {
226 __asm
227 {
228 /* No error code */
229 push 0
230 push ebp
231 push ebx
232 push esi
233 mov esi, 0
234 jmp KiTrapProlog
235 }
236 }
237
238 __declspec(naked)
239 void KiTrap1()
240 {
241 __asm
242 {
243 /* No error code */
244 push 0
245 push ebp
246 push ebx
247 push esi
248 mov esi, 1
249 jmp KiTrapProlog
250 }
251 }
252
253 __declspec(naked)
254 void KiTrap2()
255 {
256 __asm
257 {
258 push 0
259 push ebp
260 push ebx
261 push esi
262 mov esi, 2
263 jmp KiTrapProlog
264 }
265 }
266
267 __declspec(naked)
268 void KiTrap3()
269 {
270 __asm
271 {
272 push 0
273 push ebp
274 push ebx
275 push esi
276 mov esi, 3
277 jmp KiTrapProlog
278 }
279 }
280
281 __declspec(naked)
282 void KiTrap4()
283 {
284 __asm
285 {
286 push 0
287 push ebp
288 push ebx
289 push esi
290 mov esi, 4
291 jmp KiTrapProlog
292 }
293 }
294
295 __declspec(naked)
296 void KiTrap5()
297 {
298 __asm
299 {
300 push 0
301 push ebp
302 push ebx
303 push esi
304 mov esi, 5
305 jmp KiTrapProlog
306 }
307 }
308
309 __declspec(naked)
310 void KiTrap6()
311 {
312 __asm
313 {
314 push 0
315 push ebp
316 push ebx
317 push esi
318 mov esi, 6
319 jmp KiTrapProlog
320 }
321 }
322
323 __declspec(naked)
324 void KiTrap7()
325 {
326 __asm
327 {
328 push 0
329 push ebp
330 push ebx
331 push esi
332 mov esi, 7
333 jmp KiTrapProlog
334 }
335 }
336
337 __declspec(naked)
338 void KiTrap8()
339 {
340 __asm
341 {
342 call KiDoubleFaultHandler
343 iretd
344 }
345 }
346
347 __declspec(naked)
348 void KiTrap9()
349 {
350 __asm
351 {
352 push 0
353 push ebp
354 push ebx
355 push esi
356 mov esi, 9
357 jmp KiTrapProlog
358 }
359 }
360
361 __declspec(naked)
362 void KiTrap10()
363 {
364 __asm
365 {
366 push ebp
367 push ebx
368 push esi
369 mov esi, 10
370 jmp KiTrapProlog
371 }
372 }
373
374 __declspec(naked)
375 void KiTrap11()
376 {
377 __asm
378 {
379 push ebp
380 push ebx
381 push esi
382 mov esi, 11
383 jmp KiTrapProlog
384 }
385 }
386
387 __declspec(naked)
388 void KiTrap12()
389 {
390 __asm
391 {
392 push ebp
393 push ebx
394 push esi
395 mov esi, 12
396 jmp KiTrapProlog
397 }
398 }
399
400 __declspec(naked)
401 void KiTrap13()
402 {
403 __asm
404 {
405 push ebp
406 push ebx
407 push esi
408 mov esi, 13
409 jmp KiTrapProlog
410 }
411 }
412
413 __declspec(naked)
414 void KiTrap14()
415 {
416 __asm
417 {
418 push ebp
419 push ebx
420 push esi
421 mov esi, 14
422 jmp KiTrapProlog
423 }
424 }
425
426 __declspec(naked)
427 void KiTrap15()
428 {
429 __asm
430 {
431 push 0
432 push ebp
433 push ebx
434 push esi
435 mov esi, 15
436 jmp KiTrapProlog
437 }
438 }
439
440 __declspec(naked)
441 void KiTrap16()
442 {
443 __asm
444 {
445 push 0
446 push ebp
447 push ebx
448 push esi
449 mov esi, 16
450 jmp KiTrapProlog
451 }
452 }
453
454 __declspec(naked)
455 void KiTrapUnknown()
456 {
457 __asm
458 {
459 push 0
460 push ebp
461 push ebx
462 push esi
463 mov esi, 255
464 jmp KiTrapProlog
465 }
466 }
467
468 /* EOF */