Little KDB update ;-) If you have any problems and/or questions let me know. I hope...
[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$
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 <roscfg.h>
30 #include <ddk/status.h>
31 #include <internal/i386/ke.h>
32 #include <internal/i386/segment.h>
33 #include <internal/ps.h>
34 #include <ddk/defines.h>
35
36 /* FUNCTIONS *****************************************************************/
37
38 /*
39 * Epilog for exception handlers
40 */
41 _KiTrapEpilog:
42 cmpl $1, %eax /* Check for v86 recovery */
43 jne _KiTrapRet
44 jmp _KiV86Complete
45 _KiTrapRet:
46 /* Skip debug information and unsaved registers */
47 addl $0x18, %esp
48 popl %eax /* Dr0 */
49 movl %eax, %dr0
50 popl %eax /* Dr1 */
51 movl %eax, %dr1
52 popl %eax /* Dr2 */
53 movl %eax, %dr2
54 popl %eax /* Dr3 */
55 movl %eax, %dr3
56 popl %eax /* Dr6 */
57 movl %eax, %dr6
58 popl %eax /* Dr7 */
59 movl %eax, %dr7
60 popl %gs
61 popl %es
62 popl %ds
63 popl %edx
64 popl %ecx
65 popl %eax
66
67 /* Restore the old previous mode */
68 popl %ebx
69 movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
70
71 /* Restore the old exception handler list */
72 popl %ebx
73 movl %ebx, %fs:KPCR_EXCEPTION_LIST
74
75 popl %fs
76 popl %edi
77 popl %esi
78 popl %ebx
79
80 #ifdef DBG
81 /*
82 * Cleanup the stack which was used to setup a trapframe with SS:ESP when called
83 * from kmode.
84 */
85 movw 0xC(%esp), %bp /* Get CS from trapframe */
86 cmpw $KERNEL_CS, %bp
87 jne 0f
88
89 /* Copy EBP, CS:EIP and EFLAGS from the trapframe back onto the top of our stack. */
90 movl 0x00(%esp), %ebp /* EBP */
91 movl %ebp, 0x24(%esp)
92 movl 0x08(%esp), %ebp /* EIP */
93 movl %ebp, 0x2C(%esp)
94 movl 0x0C(%esp), %ebp /* CS */
95 movl %ebp, 0x30(%esp)
96 movl 0x10(%esp), %ebp /* EFLAGS */
97 movl %ebp, 0x34(%esp)
98
99 addl $0x24, %esp
100 0:
101 #endif /* DBG */
102 popl %ebp
103 addl $0x4, %esp /* Ignore error code */
104
105 iret
106
107 .globl _KiTrapProlog
108 _KiTrapProlog:
109 #ifdef DBG
110 /*
111 * If we were called from kmode we start setting up a new trapframe (with SS:ESP at the end)
112 */
113 movw 0x14(%esp), %bx /* Get old CS */
114 cmpw $KERNEL_CS, %bx
115
116 jne 0f
117
118 leal 0x1C(%esp), %ebp
119 pushl %ss /* Old SS */
120 pushl %ebp /* Old ESP */
121 pushl 0x20(%esp) /* Old EFLAGS */
122 pushl 0x20(%esp) /* Old CS */
123 pushl 0x20(%esp) /* Old EIP */
124 pushl 0x20(%esp) /* ErrorCode */
125 pushl 0x20(%esp) /* Ebp */
126 pushl 0x20(%esp) /* Ebx */
127 pushl 0x20(%esp) /* Esi */
128 0:
129 #endif /* DBG */
130
131 pushl %edi
132 pushl %fs
133
134 /*
135 * Check that the PCR exists, very early in the boot process it may
136 * not
137 */
138 cmpl $0, %ss:_KiPcrInitDone
139 je .L5
140
141 /* Load the PCR selector into fs */
142 movl $PCR_SELECTOR, %ebx
143 movl %ebx, %fs
144
145 /* Save the old exception list */
146 movl %fs:KPCR_EXCEPTION_LIST, %ebx
147 pushl %ebx
148
149 /* Get a pointer to the current thread */
150 movl %fs:KPCR_CURRENT_THREAD, %edi
151
152 /* The current thread may be NULL early in the boot process */
153 cmpl $0, %edi
154 je .L4
155
156 /* Save the old previous mode */
157 movl $0, %ebx
158 movb %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl
159 pushl %ebx
160
161 /* Set the new previous mode based on the saved CS selector */
162 movl 0x24(%esp), %ebx
163 andl $0x0000FFFF, %ebx
164 cmpl $KERNEL_CS, %ebx
165 jne .L1
166 movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
167 jmp .L3
168 .L1:
169 movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
170 .L3:
171
172 /* Save other registers */
173 pushl %eax
174 pushl %ecx
175 pushl %edx
176 pushl %ds
177 pushl %es
178 pushl %gs
179 movl %dr7, %eax
180 pushl %eax /* Dr7 */
181 /* Clear all breakpoint enables in dr7. */
182 andl $0xFFFF0000, %eax
183 movl %eax, %dr7
184 movl %dr6, %eax
185 pushl %eax /* Dr6 */
186 movl %dr3, %eax
187 pushl %eax /* Dr3 */
188 movl %dr2, %eax
189 pushl %eax /* Dr2 */
190 movl %dr1, %eax
191 pushl %eax /* Dr1 */
192 movl %dr0, %eax
193 pushl %eax /* Dr0 */
194 pushl $0 /* XXX: TempESP */
195 pushl $0 /* XXX: TempCS */
196 pushl $0 /* XXX: DebugPointer */
197 pushl $0 /* XXX: DebugArgMark */
198 movl 0x60(%esp), %ebx
199 pushl %ebx /* XXX: DebugEIP */
200 pushl %ebp /* XXX: DebugEBP */
201
202 /* Load the segment registers */
203 movl $KERNEL_DS, %ebx
204 movl %ebx, %ds
205 movl %ebx, %es
206 movl %ebx, %gs
207
208 /* Set ES to kernel segment */
209 movw $KERNEL_DS,%bx
210 movw %bx,%es
211
212 movl %esp, %ebx
213 movl %esp, %ebp
214
215 /* Save the old trap frame. */
216 cmpl $0, %edi
217 je .L7
218 movl %ss:KTHREAD_TRAP_FRAME(%edi), %edx
219 pushl %edx
220 jmp .L8
221 .L7:
222 pushl $0
223 .L8:
224
225 /* Save a pointer to the trap frame in the current KTHREAD */
226 cmpl $0, %edi
227 je .L6
228 movl %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
229 .L6:
230
231 /* Call the C exception handler */
232 pushl %esi
233 pushl %ebx
234 call _KiTrapHandler
235 addl $4, %esp
236 addl $4, %esp
237
238 /* Get a pointer to the current thread */
239 movl %fs:KPCR_CURRENT_THREAD, %esi
240
241 /* Restore the old trap frame pointer */
242 popl %ebx
243 movl %ebx, KTHREAD_TRAP_FRAME(%esi)
244
245 /* Return to the caller */
246 jmp _KiTrapEpilog
247
248 /* Handle the no-pcr case out of line */
249 .L5:
250 pushl $0
251
252 /* Handle the no-thread case out of line */
253 .L4:
254 pushl $0
255 jmp .L3
256
257 .globl _KiTrap0
258 _KiTrap0:
259 /* No error code */
260 pushl $0
261 pushl %ebp
262 pushl %ebx
263 pushl %esi
264 movl $0, %esi
265 jmp _KiTrapProlog
266
267 .globl _KiTrap1
268 _KiTrap1:
269 /* No error code */
270 pushl $0
271 pushl %ebp
272 pushl %ebx
273 pushl %esi
274 movl $1, %esi
275 jmp _KiTrapProlog
276
277 .globl _KiTrap2
278 _KiTrap2:
279 pushl $0
280 pushl %ebp
281 pushl %ebx
282 pushl %esi
283 movl $2, %esi
284 jmp _KiTrapProlog
285
286 .globl _KiTrap3
287 _KiTrap3:
288 pushl $0
289 pushl %ebp
290 pushl %ebx
291 pushl %esi
292 movl $3, %esi
293 jmp _KiTrapProlog
294
295 .globl _KiTrap4
296 _KiTrap4:
297 pushl $0
298 pushl %ebp
299 pushl %ebx
300 pushl %esi
301 movl $4, %esi
302 jmp _KiTrapProlog
303
304 .globl _KiTrap5
305 _KiTrap5:
306 pushl $0
307 pushl %ebp
308 pushl %ebx
309 pushl %esi
310 movl $5, %esi
311 jmp _KiTrapProlog
312
313 .globl _KiTrap6
314 _KiTrap6:
315 pushl $0
316 pushl %ebp
317 pushl %ebx
318 pushl %esi
319 movl $6, %esi
320 jmp _KiTrapProlog
321
322 .globl _KiTrap7
323 _KiTrap7:
324 pushl $0
325 pushl %ebp
326 pushl %ebx
327 pushl %esi
328 movl $7, %esi
329 jmp _KiTrapProlog
330
331 .globl _KiTrap8
332 _KiTrap8:
333 call _KiDoubleFaultHandler
334 iret
335
336 .globl _KiTrap9
337 _KiTrap9:
338 pushl $0
339 pushl %ebp
340 pushl %ebx
341 pushl %esi
342 movl $9, %esi
343 jmp _KiTrapProlog
344
345 .globl _KiTrap10
346 _KiTrap10:
347 pushl %ebp
348 pushl %ebx
349 pushl %esi
350 movl $10, %esi
351 jmp _KiTrapProlog
352
353 .globl _KiTrap11
354 _KiTrap11:
355 pushl %ebp
356 pushl %ebx
357 pushl %esi
358 movl $11, %esi
359 jmp _KiTrapProlog
360
361 .globl _KiTrap12
362 _KiTrap12:
363 pushl %ebp
364 pushl %ebx
365 pushl %esi
366 movl $12, %esi
367 jmp _KiTrapProlog
368
369 .globl _KiTrap13
370 _KiTrap13:
371 pushl %ebp
372 pushl %ebx
373 pushl %esi
374 movl $13, %esi
375 jmp _KiTrapProlog
376
377 .globl _KiTrap14
378 _KiTrap14:
379 pushl %ebp
380 pushl %ebx
381 pushl %esi
382 movl $14, %esi
383 jmp _KiTrapProlog
384
385 .globl _KiTrap15
386 _KiTrap15:
387 pushl $0
388 pushl %ebp
389 pushl %ebx
390 pushl %esi
391 movl $15, %esi
392 jmp _KiTrapProlog
393
394 .globl _KiTrap16
395 _KiTrap16:
396 pushl $0
397 pushl %ebp
398 pushl %ebx
399 pushl %esi
400 movl $16, %esi
401 jmp _KiTrapProlog
402
403 .globl _KiTrap17
404 _KiTrap17:
405 pushl $0
406 pushl %ebp
407 pushl %ebx
408 pushl %esi
409 movl $17, %esi
410 jmp _KiTrapProlog
411
412 .globl _KiTrap18
413 _KiTrap18:
414 pushl $0
415 pushl %ebp
416 pushl %ebx
417 pushl %esi
418 movl $18, %esi
419 jmp _KiTrapProlog
420
421 .globl _KiTrap19
422 _KiTrap19:
423 pushl $0
424 pushl %ebp
425 pushl %ebx
426 pushl %esi
427 movl $19, %esi
428 jmp _KiTrapProlog
429
430 .globl _KiTrapUnknown
431 _KiTrapUnknown:
432 pushl $0
433 pushl %ebp
434 pushl %ebx
435 pushl %esi
436 movl $255, %esi
437 jmp _KiTrapProlog
438
439
440 /* EOF */