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