- Fix another V86 Mode exit bug which could cause non-volatiles to be incorrectly...
[reactos.git] / reactos / ntoskrnl / ke / i386 / trap.s
1 /*
2 * PROJECT: ReactOS kernel
3 * FILE: ntoskrnl/ke/i386/trap.s
4 * PURPOSE: Exception handlers
5 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
6 * David Welch <welch@cwcom.net>
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ndk/asm.h>
12
13 /* NOTES:
14 * The prologue is currently a duplication of the trap enter code in KiDebugService.
15 * It will be made a macro and shared later.
16 */
17
18 /* FUNCTIONS *****************************************************************/
19
20 /*
21 * Epilog for exception handlers
22 */
23 _KiTrapEpilog:
24 cmpl $1, %eax /* Check for v86 recovery */
25 jne Kei386EoiHelper@0
26 jmp _KiV86Complete
27
28 .globl _KiTrapProlog
29 _KiTrapProlog:
30 movl $_KiTrapHandler, %ebx
31
32 .global _KiTrapProlog2
33 _KiTrapProlog2:
34 pushl %edi
35 pushl %fs
36
37 .intel_syntax noprefix
38 /* Load the PCR selector into fs */
39 mov edi, KGDT_R0_PCR
40 mov fs, di
41
42 /* Push exception list and previous mode (invalid) */
43 push fs:[KPCR_EXCEPTION_LIST]
44 push -1
45
46 /* Push volatiles and segments */
47 push eax
48 push ecx
49 push edx
50 push ds
51 push es
52 push gs
53
54 /* Set the R3 data segment */
55 mov ax, KGDT_R3_DATA + RPL_MASK
56
57 /* Skip debug registers and debug stuff */
58 sub esp, 0x30
59
60 /* Load the segment registers */
61 mov ds, ax
62 mov es, ax
63
64 /* Set up frame */
65 mov ebp, esp
66
67 /* Check if this was from V86 Mode */
68 test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
69 //jnz V86_kids
70
71 /* Get current thread */
72 mov ecx, [fs:KPCR_CURRENT_THREAD]
73 cld
74
75 /* Flush DR7 */
76 and dword ptr [ebp+KTRAP_FRAME_DR7], 0
77
78 /* Check if the thread was being debugged */
79 //test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF
80 //jnz Dr_kids
81
82 /* Get the Debug Trap Frame EBP/EIP */
83 mov ecx, [ebp+KTRAP_FRAME_EBP]
84 mov edi, [ebp+KTRAP_FRAME_EIP]
85
86 /* Write the debug data */
87 mov [ebp+KTRAP_FRAME_DEBUGPOINTER], edx
88 mov dword ptr [ebp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
89 mov [ebp+KTRAP_FRAME_DEBUGEBP], ecx
90 mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
91 .att_syntax
92
93 .L6:
94
95 /* Call the C exception handler */
96 pushl %esi
97 pushl %ebp
98 call *%ebx
99 addl $8, %esp
100
101 /* Return to the caller */
102 jmp _KiTrapEpilog
103
104 .globl _KiTrap0
105 _KiTrap0:
106 /* No error code */
107 pushl $0
108 pushl %ebp
109 pushl %ebx
110 pushl %esi
111 movl $0, %esi
112 jmp _KiTrapProlog
113
114 .globl _KiTrap1
115 _KiTrap1:
116 /* No error code */
117 pushl $0
118 pushl %ebp
119 pushl %ebx
120 pushl %esi
121 movl $1, %esi
122 jmp _KiTrapProlog
123
124 .globl _KiTrap2
125 _KiTrap2:
126 pushl $0
127 pushl %ebp
128 pushl %ebx
129 pushl %esi
130 movl $2, %esi
131 jmp _KiTrapProlog
132
133 .globl _KiTrap3
134 _KiTrap3:
135 pushl $0
136 pushl %ebp
137 pushl %ebx
138 pushl %esi
139 movl $3, %esi
140 jmp _KiTrapProlog
141
142 .globl _KiTrap4
143 _KiTrap4:
144 pushl $0
145 pushl %ebp
146 pushl %ebx
147 pushl %esi
148 movl $4, %esi
149 jmp _KiTrapProlog
150
151 .globl _KiTrap5
152 _KiTrap5:
153 pushl $0
154 pushl %ebp
155 pushl %ebx
156 pushl %esi
157 movl $5, %esi
158 jmp _KiTrapProlog
159
160 .globl _KiTrap6
161 _KiTrap6:
162 pushl $0
163 pushl %ebp
164 pushl %ebx
165 pushl %esi
166 movl $6, %esi
167 jmp _KiTrapProlog
168
169 .globl _KiTrap7
170 _KiTrap7:
171 pushl $0
172 pushl %ebp
173 pushl %ebx
174 pushl %esi
175 movl $7, %esi
176 jmp _KiTrapProlog
177
178 .globl _KiTrap8
179 _KiTrap8:
180 call _KiDoubleFaultHandler
181 iret
182
183 .globl _KiTrap9
184 _KiTrap9:
185 pushl $0
186 pushl %ebp
187 pushl %ebx
188 pushl %esi
189 movl $9, %esi
190 jmp _KiTrapProlog
191
192 .globl _KiTrap10
193 _KiTrap10:
194 pushl %ebp
195 pushl %ebx
196 pushl %esi
197 movl $10, %esi
198 jmp _KiTrapProlog
199
200 .globl _KiTrap11
201 _KiTrap11:
202 pushl %ebp
203 pushl %ebx
204 pushl %esi
205 movl $11, %esi
206 jmp _KiTrapProlog
207
208 .globl _KiTrap12
209 _KiTrap12:
210 pushl %ebp
211 pushl %ebx
212 pushl %esi
213 movl $12, %esi
214 jmp _KiTrapProlog
215
216 .globl _KiTrap13
217 _KiTrap13:
218 pushl %ebp
219 pushl %ebx
220 pushl %esi
221 movl $13, %esi
222 jmp _KiTrapProlog
223
224 .globl _KiTrap14
225 _KiTrap14:
226 pushl %ebp
227 pushl %ebx
228 pushl %esi
229 movl $14, %esi
230 movl $_KiPageFaultHandler, %ebx
231 jmp _KiTrapProlog2
232
233 .globl _KiTrap15
234 _KiTrap15:
235 pushl $0
236 pushl %ebp
237 pushl %ebx
238 pushl %esi
239 movl $15, %esi
240 jmp _KiTrapProlog
241
242 .globl _KiTrap16
243 _KiTrap16:
244 pushl $0
245 pushl %ebp
246 pushl %ebx
247 pushl %esi
248 movl $16, %esi
249 jmp _KiTrapProlog
250
251 .globl _KiTrap17
252 _KiTrap17:
253 pushl $0
254 pushl %ebp
255 pushl %ebx
256 pushl %esi
257 movl $17, %esi
258 jmp _KiTrapProlog
259
260 .globl _KiTrap18
261 _KiTrap18:
262 pushl $0
263 pushl %ebp
264 pushl %ebx
265 pushl %esi
266 movl $18, %esi
267 jmp _KiTrapProlog
268
269 .globl _KiTrap19
270 _KiTrap19:
271 pushl $0
272 pushl %ebp
273 pushl %ebx
274 pushl %esi
275 movl $19, %esi
276 jmp _KiTrapProlog
277
278 .globl _KiTrapUnknown
279 _KiTrapUnknown:
280 pushl $0
281 pushl %ebp
282 pushl %ebx
283 pushl %esi
284 movl $255, %esi
285 jmp _KiTrapProlog
286
287 .intel_syntax noprefix
288 .globl _KiCoprocessorError@0
289 _KiCoprocessorError@0:
290
291 /* Get the NPX Thread's Initial stack */
292 mov eax, [fs:KPCR_NPX_THREAD]
293 mov eax, [eax+KTHREAD_INITIAL_STACK]
294
295 /* Make space for the FPU Save area */
296 sub eax, SIZEOF_FX_SAVE_AREA
297
298 /* Set the CR0 State */
299 mov dword ptr [eax+FN_CR0_NPX_STATE], 8
300
301 /* Update it */
302 mov eax, cr0
303 or eax, 8
304 mov cr0, eax
305
306 /* Return to caller */
307 ret
308
309 .globl _Ki386AdjustEsp0@4
310 _Ki386AdjustEsp0@4:
311
312 /* Get the current thread */
313 mov eax, [fs:KPCR_CURRENT_THREAD]
314
315 /* Get trap frame and stack */
316 mov edx, [esp+4]
317 mov eax, [eax+KTHREAD_INITIAL_STACK]
318
319 /* Check if V86 */
320 test dword ptr [edx+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
321 jnz NoAdjust
322
323 /* Bias the stack */
324 sub eax, KTRAP_FRAME_V86_GS - KTRAP_FRAME_SS
325
326 NoAdjust:
327 /* Skip FX Save Area */
328 sub eax, SIZEOF_FX_SAVE_AREA
329
330 /* Disable interrupts */
331 pushf
332 cli
333
334 /* Adjust ESP0 */
335 mov edx, [fs:KPCR_TSS]
336 mov ss:[edx+KTSS_ESP0], eax
337
338 /* Enable interrupts and return */
339 popf
340 ret 4
341
342 /* EOF */