Some work-in-progress improvements and rethought of system-level code...notable impro...
[reactos.git] / reactos / ntoskrnl / ke / i386 / trap.s
1 /* $Id$
2 *
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/i386/trap.s
5 * PURPOSE: Exception handlers
6 * PROGRAMMER: David Welch <welch@cwcom.net>
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <roscfg.h>
12 #include <ndk/asm.h>
13 #include <internal/i386/ke.h>
14 #include <ndk/i386/segment.h>
15
16 #define KernelMode 0
17 #define UserMode 1
18
19 /* FUNCTIONS *****************************************************************/
20
21 /*
22 * Epilog for exception handlers
23 */
24 _KiTrapEpilog:
25 cmpl $1, %eax /* Check for v86 recovery */
26 jne _KiTrapRet
27 jmp _KiV86Complete
28 _KiTrapRet:
29 /* Skip debug information and unsaved registers */
30 addl $0x18, %esp
31 popl %eax /* Dr0 */
32 movl %eax, %dr0
33 popl %eax /* Dr1 */
34 movl %eax, %dr1
35 popl %eax /* Dr2 */
36 movl %eax, %dr2
37 popl %eax /* Dr3 */
38 movl %eax, %dr3
39 popl %eax /* Dr6 */
40 movl %eax, %dr6
41 popl %eax /* Dr7 */
42 movl %eax, %dr7
43 popl %gs
44 popl %es
45 popl %ds
46 popl %edx
47 popl %ecx
48 popl %eax
49 popl %ebx
50
51 /* Restore the old exception handler list */
52 popl %ebx
53 movl %ebx, %fs:KPCR_EXCEPTION_LIST
54
55 popl %fs
56 popl %edi
57 popl %esi
58 popl %ebx
59 popl %ebp
60 addl $0x4, %esp /* Ignore error code */
61
62 iret
63
64 .globl _KiTrapProlog
65 _KiTrapProlog:
66 movl $_KiTrapHandler, %ebx
67
68 .global _KiTrapProlog2
69 _KiTrapProlog2:
70 pushl %edi
71 pushl %fs
72
73 /* Make room for the previous mode and the exception list */
74 subl $8, %esp
75
76 /* Save other registers */
77 pushl %eax
78 pushl %ecx
79 pushl %edx
80 pushl %ds
81 pushl %es
82 pushl %gs
83 movl %dr7, %eax
84 pushl %eax /* Dr7 */
85 /* Clear all breakpoint enables in dr7. */
86 andl $0xFFFF0000, %eax
87 movl %eax, %dr7
88 movl %dr6, %eax
89 pushl %eax /* Dr6 */
90 movl %dr3, %eax
91 pushl %eax /* Dr3 */
92 movl %dr2, %eax
93 pushl %eax /* Dr2 */
94 movl %dr1, %eax
95 pushl %eax /* Dr1 */
96 movl %dr0, %eax
97 pushl %eax /* Dr0 */
98 leal 0x64(%esp), %eax
99 pushl %eax /* XXX: TempESP */
100 pushl %ss /* XXX: TempSS */
101 pushl $0 /* XXX: DebugPointer */
102 pushl $0 /* XXX: DebugArgMark */
103 movl 0x60(%esp), %eax
104 pushl %eax /* XXX: DebugEIP */
105 pushl %ebp /* XXX: DebugEBP */
106
107 /* Load the segment registers */
108 movl $KERNEL_DS, %eax
109 movl %eax, %ds
110 movl %eax, %es
111 movl %eax, %gs
112
113 /* save the trap frame */
114 movl %esp, %ebp
115
116 /* Load the PCR selector into fs */
117 movl $PCR_SELECTOR, %eax
118 movl %eax, %fs
119
120 /* Save the old exception list */
121 movl %fs:KPCR_EXCEPTION_LIST, %eax
122 movl %eax, KTRAP_FRAME_EXCEPTION_LIST(%ebp)
123
124 /* Get a pointer to the current thread */
125 movl %fs:KPCR_CURRENT_THREAD, %edi
126
127 /* The current thread may be NULL early in the boot process */
128 cmpl $0, %edi
129 je .L4
130
131 /* Save the old previous mode */
132 movl $0, %eax
133 movb KTHREAD_PREVIOUS_MODE(%edi), %al
134 movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
135
136 /* Set the new previous mode based on the saved CS selector */
137 movl KTRAP_FRAME_CS(%ebp), %eax
138 andl $0x0000FFFF, %eax
139
140 /* Save the old trap frame. */
141 movl KTHREAD_TRAP_FRAME(%edi), %edx
142 pushl %edx
143
144 /* Save a pointer to the trap frame in the current KTHREAD */
145 movl %ebp, KTHREAD_TRAP_FRAME(%edi)
146 .L6:
147
148 /* Call the C exception handler */
149 pushl %esi
150 pushl %ebp
151 call *%ebx
152 addl $8, %esp
153
154 /* Get a pointer to the current thread */
155 movl %fs:KPCR_CURRENT_THREAD, %esi
156
157 /* Restore the old trap frame pointer */
158 popl %ebx
159 cmpl $0, %esi
160 je _KiTrapEpilog
161 movl %ebx, KTHREAD_TRAP_FRAME(%esi)
162
163 /* Return to the caller */
164 jmp _KiTrapEpilog
165
166 /* Handle the no-thread case out of line */
167 .L4:
168 movl $0, %eax /* previous mode */
169 movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
170 pushl %eax /* old trap frame */
171 jmp .L6
172
173 .globl _KiTrap0
174 _KiTrap0:
175 /* No error code */
176 pushl $0
177 pushl %ebp
178 pushl %ebx
179 pushl %esi
180 movl $0, %esi
181 jmp _KiTrapProlog
182
183 .globl _KiTrap1
184 _KiTrap1:
185 /* No error code */
186 pushl $0
187 pushl %ebp
188 pushl %ebx
189 pushl %esi
190 movl $1, %esi
191 jmp _KiTrapProlog
192
193 .globl _KiTrap2
194 _KiTrap2:
195 pushl $0
196 pushl %ebp
197 pushl %ebx
198 pushl %esi
199 movl $2, %esi
200 jmp _KiTrapProlog
201
202 .globl _KiTrap3
203 _KiTrap3:
204 pushl $0
205 pushl %ebp
206 pushl %ebx
207 pushl %esi
208 movl $3, %esi
209 jmp _KiTrapProlog
210
211 .globl _KiTrap4
212 _KiTrap4:
213 pushl $0
214 pushl %ebp
215 pushl %ebx
216 pushl %esi
217 movl $4, %esi
218 jmp _KiTrapProlog
219
220 .globl _KiTrap5
221 _KiTrap5:
222 pushl $0
223 pushl %ebp
224 pushl %ebx
225 pushl %esi
226 movl $5, %esi
227 jmp _KiTrapProlog
228
229 .globl _KiTrap6
230 _KiTrap6:
231 pushl $0
232 pushl %ebp
233 pushl %ebx
234 pushl %esi
235 movl $6, %esi
236 jmp _KiTrapProlog
237
238 .globl _KiTrap7
239 _KiTrap7:
240 pushl $0
241 pushl %ebp
242 pushl %ebx
243 pushl %esi
244 movl $7, %esi
245 jmp _KiTrapProlog
246
247 .globl _KiTrap8
248 _KiTrap8:
249 call _KiDoubleFaultHandler
250 iret
251
252 .globl _KiTrap9
253 _KiTrap9:
254 pushl $0
255 pushl %ebp
256 pushl %ebx
257 pushl %esi
258 movl $9, %esi
259 jmp _KiTrapProlog
260
261 .globl _KiTrap10
262 _KiTrap10:
263 pushl %ebp
264 pushl %ebx
265 pushl %esi
266 movl $10, %esi
267 jmp _KiTrapProlog
268
269 .globl _KiTrap11
270 _KiTrap11:
271 pushl %ebp
272 pushl %ebx
273 pushl %esi
274 movl $11, %esi
275 jmp _KiTrapProlog
276
277 .globl _KiTrap12
278 _KiTrap12:
279 pushl %ebp
280 pushl %ebx
281 pushl %esi
282 movl $12, %esi
283 jmp _KiTrapProlog
284
285 .globl _KiTrap13
286 _KiTrap13:
287 pushl %ebp
288 pushl %ebx
289 pushl %esi
290 movl $13, %esi
291 jmp _KiTrapProlog
292
293 .globl _KiTrap14
294 _KiTrap14:
295 pushl %ebp
296 pushl %ebx
297 pushl %esi
298 movl $14, %esi
299 movl $_KiPageFaultHandler, %ebx
300 jmp _KiTrapProlog2
301
302 .globl _KiTrap15
303 _KiTrap15:
304 pushl $0
305 pushl %ebp
306 pushl %ebx
307 pushl %esi
308 movl $15, %esi
309 jmp _KiTrapProlog
310
311 .globl _KiTrap16
312 _KiTrap16:
313 pushl $0
314 pushl %ebp
315 pushl %ebx
316 pushl %esi
317 movl $16, %esi
318 jmp _KiTrapProlog
319
320 .globl _KiTrap17
321 _KiTrap17:
322 pushl $0
323 pushl %ebp
324 pushl %ebx
325 pushl %esi
326 movl $17, %esi
327 jmp _KiTrapProlog
328
329 .globl _KiTrap18
330 _KiTrap18:
331 pushl $0
332 pushl %ebp
333 pushl %ebx
334 pushl %esi
335 movl $18, %esi
336 jmp _KiTrapProlog
337
338 .globl _KiTrap19
339 _KiTrap19:
340 pushl $0
341 pushl %ebp
342 pushl %ebx
343 pushl %esi
344 movl $19, %esi
345 jmp _KiTrapProlog
346
347 .globl _KiTrapUnknown
348 _KiTrapUnknown:
349 pushl $0
350 pushl %ebp
351 pushl %ebx
352 pushl %esi
353 movl $255, %esi
354 jmp _KiTrapProlog
355
356 .intel_syntax noprefix
357 .globl _KiCoprocessorError@0
358 _KiCoprocessorError@0:
359
360 /* Get the NPX Thread's Initial stack */
361 mov eax, [fs:KPCR_NPX_THREAD]
362 mov eax, [eax+KTHREAD_INITIAL_STACK]
363
364 /* Make space for the FPU Save area */
365 sub eax, SIZEOF_FX_SAVE_AREA
366
367 /* Set the CR0 State */
368 mov dword ptr [eax+FN_CR0_NPX_STATE], 8
369
370 /* Update it */
371 mov eax, cr0
372 or eax, 8
373 mov cr0, eax
374
375 /* Return to caller */
376 ret
377
378 .globl _Ki386AdjustEsp0@4
379 _Ki386AdjustEsp0@4:
380
381 /* Get the current thread */
382 mov eax, [fs:KPCR_CURRENT_THREAD]
383
384 /* Get trap frame and stack */
385 mov edx, [esp+4]
386 mov eax, [eax+KTHREAD_INITIAL_STACK]
387
388 /* Check if V86 */
389 test dword ptr [edx+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
390 jnz NoAdjust
391
392 /* Bias the stack */
393 sub eax, KTRAP_FRAME_V86_GS - KTRAP_FRAME_SS
394
395 NoAdjust:
396 /* Skip FX Save Area */
397 sub eax, SIZEOF_FX_SAVE_AREA
398
399 /* Disable interrupts */
400 pushf
401 cli
402
403 /* Adjust ESP0 */
404 mov edx, [fs:KPCR_TSS]
405 mov ss:[edx+KTSS_ESP0], eax
406
407 /* Enable interrupts and return */
408 popf
409 ret 4
410
411 /* EOF */