Changed the trap prolog, each exception can have its own trap handler.
[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 cmpl $0, %esi
70 je .L7
71 movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
72 .L7:
73 /* Restore the old exception handler list */
74 popl %ebx
75 movl %ebx, %fs:KPCR_EXCEPTION_LIST
76
77 popl %fs
78 popl %edi
79 popl %esi
80 popl %ebx
81 popl %ebp
82 addl $0x4, %esp /* Ignore error code */
83
84 iret
85
86 .globl _KiTrapProlog
87 _KiTrapProlog:
88 movl $_KiTrapHandler, %ebx
89
90 .global _KiTrapProlog2
91 _KiTrapProlog2:
92 pushl %edi
93 pushl %fs
94
95 /* Make room for the previous mode and the exception list */
96 subl $8, %esp
97
98 /* Save other registers */
99 pushl %eax
100 pushl %ecx
101 pushl %edx
102 pushl %ds
103 pushl %es
104 pushl %gs
105 movl %dr7, %eax
106 pushl %eax /* Dr7 */
107 /* Clear all breakpoint enables in dr7. */
108 andl $0xFFFF0000, %eax
109 movl %eax, %dr7
110 movl %dr6, %eax
111 pushl %eax /* Dr6 */
112 movl %dr3, %eax
113 pushl %eax /* Dr3 */
114 movl %dr2, %eax
115 pushl %eax /* Dr2 */
116 movl %dr1, %eax
117 pushl %eax /* Dr1 */
118 movl %dr0, %eax
119 pushl %eax /* Dr0 */
120 leal 0x64(%esp), %eax
121 pushl %eax /* XXX: TempESP */
122 pushl %ss /* XXX: TempSS */
123 pushl $0 /* XXX: DebugPointer */
124 pushl $0 /* XXX: DebugArgMark */
125 movl 0x60(%esp), %eax
126 pushl %eax /* XXX: DebugEIP */
127 pushl %ebp /* XXX: DebugEBP */
128
129 /* Load the segment registers */
130 movl $KERNEL_DS, %eax
131 movl %eax, %ds
132 movl %eax, %es
133 movl %eax, %gs
134
135 /* save the trap frame */
136 movl %esp, %ebp
137
138 /* Load the PCR selector into fs */
139 movl $PCR_SELECTOR, %eax
140 movl %eax, %fs
141
142 /* Save the old exception list */
143 movl %fs:KPCR_EXCEPTION_LIST, %eax
144 movl %eax, KTRAP_FRAME_EXCEPTION_LIST(%ebp)
145
146 /* Get a pointer to the current thread */
147 movl %fs:KPCR_CURRENT_THREAD, %edi
148
149 /* The current thread may be NULL early in the boot process */
150 cmpl $0, %edi
151 je .L4
152
153 /* Save the old previous mode */
154 movl $0, %eax
155 movb KTHREAD_PREVIOUS_MODE(%edi), %al
156 movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
157
158 /* Set the new previous mode based on the saved CS selector */
159 movl KTRAP_FRAME_CS(%ebp), %eax
160 andl $0x0000FFFF, %eax
161 cmpl $KERNEL_CS, %eax
162 jne .L1
163 movb $KernelMode, KTHREAD_PREVIOUS_MODE(%edi)
164 jmp .L3
165 .L1:
166 movb $UserMode, KTHREAD_PREVIOUS_MODE(%edi)
167 .L3:
168
169 /* Save the old trap frame. */
170 movl KTHREAD_TRAP_FRAME(%edi), %edx
171 pushl %edx
172
173 /* Save a pointer to the trap frame in the current KTHREAD */
174 movl %ebp, KTHREAD_TRAP_FRAME(%edi)
175 .L6:
176
177 /* Call the C exception handler */
178 pushl %esi
179 pushl %ebp
180 call *%ebx
181 addl $8, %esp
182
183 /* Get a pointer to the current thread */
184 movl %fs:KPCR_CURRENT_THREAD, %esi
185
186 /* Restore the old trap frame pointer */
187 popl %ebx
188 cmpl $0, %esi
189 je _KiTrapEpilog
190 movl %ebx, KTHREAD_TRAP_FRAME(%esi)
191
192 /* Return to the caller */
193 jmp _KiTrapEpilog
194
195 /* Handle the no-thread case out of line */
196 .L4:
197 movl $0, %eax /* previous mode */
198 movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
199 pushl %eax /* old trap frame */
200 jmp .L6
201
202 .globl _KiTrap0
203 _KiTrap0:
204 /* No error code */
205 pushl $0
206 pushl %ebp
207 pushl %ebx
208 pushl %esi
209 movl $0, %esi
210 jmp _KiTrapProlog
211
212 .globl _KiTrap1
213 _KiTrap1:
214 /* No error code */
215 pushl $0
216 pushl %ebp
217 pushl %ebx
218 pushl %esi
219 movl $1, %esi
220 jmp _KiTrapProlog
221
222 .globl _KiTrap2
223 _KiTrap2:
224 pushl $0
225 pushl %ebp
226 pushl %ebx
227 pushl %esi
228 movl $2, %esi
229 jmp _KiTrapProlog
230
231 .globl _KiTrap3
232 _KiTrap3:
233 pushl $0
234 pushl %ebp
235 pushl %ebx
236 pushl %esi
237 movl $3, %esi
238 jmp _KiTrapProlog
239
240 .globl _KiTrap4
241 _KiTrap4:
242 pushl $0
243 pushl %ebp
244 pushl %ebx
245 pushl %esi
246 movl $4, %esi
247 jmp _KiTrapProlog
248
249 .globl _KiTrap5
250 _KiTrap5:
251 pushl $0
252 pushl %ebp
253 pushl %ebx
254 pushl %esi
255 movl $5, %esi
256 jmp _KiTrapProlog
257
258 .globl _KiTrap6
259 _KiTrap6:
260 pushl $0
261 pushl %ebp
262 pushl %ebx
263 pushl %esi
264 movl $6, %esi
265 jmp _KiTrapProlog
266
267 .globl _KiTrap7
268 _KiTrap7:
269 pushl $0
270 pushl %ebp
271 pushl %ebx
272 pushl %esi
273 movl $7, %esi
274 jmp _KiTrapProlog
275
276 .globl _KiTrap8
277 _KiTrap8:
278 call _KiDoubleFaultHandler
279 iret
280
281 .globl _KiTrap9
282 _KiTrap9:
283 pushl $0
284 pushl %ebp
285 pushl %ebx
286 pushl %esi
287 movl $9, %esi
288 jmp _KiTrapProlog
289
290 .globl _KiTrap10
291 _KiTrap10:
292 pushl %ebp
293 pushl %ebx
294 pushl %esi
295 movl $10, %esi
296 jmp _KiTrapProlog
297
298 .globl _KiTrap11
299 _KiTrap11:
300 pushl %ebp
301 pushl %ebx
302 pushl %esi
303 movl $11, %esi
304 jmp _KiTrapProlog
305
306 .globl _KiTrap12
307 _KiTrap12:
308 pushl %ebp
309 pushl %ebx
310 pushl %esi
311 movl $12, %esi
312 jmp _KiTrapProlog
313
314 .globl _KiTrap13
315 _KiTrap13:
316 pushl %ebp
317 pushl %ebx
318 pushl %esi
319 movl $13, %esi
320 jmp _KiTrapProlog
321
322 .globl _KiTrap14
323 _KiTrap14:
324 pushl %ebp
325 pushl %ebx
326 pushl %esi
327 movl $14, %esi
328 movl $_KiTrapHandler, %ebx
329 jmp _KiTrapProlog2
330
331 .globl _KiTrap15
332 _KiTrap15:
333 pushl $0
334 pushl %ebp
335 pushl %ebx
336 pushl %esi
337 movl $15, %esi
338 jmp _KiTrapProlog
339
340 .globl _KiTrap16
341 _KiTrap16:
342 pushl $0
343 pushl %ebp
344 pushl %ebx
345 pushl %esi
346 movl $16, %esi
347 jmp _KiTrapProlog
348
349 .globl _KiTrap17
350 _KiTrap17:
351 pushl $0
352 pushl %ebp
353 pushl %ebx
354 pushl %esi
355 movl $17, %esi
356 jmp _KiTrapProlog
357
358 .globl _KiTrap18
359 _KiTrap18:
360 pushl $0
361 pushl %ebp
362 pushl %ebx
363 pushl %esi
364 movl $18, %esi
365 jmp _KiTrapProlog
366
367 .globl _KiTrap19
368 _KiTrap19:
369 pushl $0
370 pushl %ebp
371 pushl %ebx
372 pushl %esi
373 movl $19, %esi
374 jmp _KiTrapProlog
375
376 .globl _KiTrapUnknown
377 _KiTrapUnknown:
378 pushl $0
379 pushl %ebp
380 pushl %ebx
381 pushl %esi
382 movl $255, %esi
383 jmp _KiTrapProlog
384
385
386 /* EOF */