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