branch update for HEAD-2003050101
[reactos.git] / 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 <ddk/status.h>
30 #include <internal/i386/segment.h>
31 #include <internal/ps.h>
32 #include <ddk/defines.h>
33
34 /* FUNCTIONS *****************************************************************/
35
36 /*
37  * Epilog for exception handlers
38  */
39 _KiTrapEpilog:
40         cmpl    $1, %eax       /* Check for v86 recovery */
41         jne     _KiTrapRet
42         jmp     _KiV86Complete
43 _KiTrapRet:                             
44         /* Skip debug information and unsaved registers */
45         addl    $0x30, %esp
46         popl    %gs
47         popl    %es
48         popl    %ds
49         popl    %edx
50         popl    %ecx
51         popl    %eax
52
53         /* Restore the old previous mode */
54         popl    %ebx
55         movb    %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
56
57         /* Restore the old exception handler list */
58         popl    %ebx
59         movl    %ebx, %fs:KPCR_EXCEPTION_LIST
60         
61         popl    %fs 
62         popl    %edi
63         popl    %esi
64         popl    %ebx
65         popl    %ebp
66         addl    $0x4, %esp  /* Ignore error code */
67                 
68         iret
69
70 .globl _KiTrapProlog
71 _KiTrapProlog:  
72         pushl   %edi
73         pushl   %fs
74
75         /* 
76          * Check that the PCR exists, very early in the boot process it may 
77          * not 
78          */
79         cmpl    $0, %ss:_KiPcrInitDone
80         je      .L5
81         
82         /* Load the PCR selector into fs */
83         movl    $PCR_SELECTOR, %ebx
84         movl    %ebx, %fs
85
86         /* Save the old exception list */
87         movl    %fs:KPCR_EXCEPTION_LIST, %ebx
88         pushl   %ebx
89         
90         /* Put the exception handler chain terminator */
91         movl    $0xffffffff, %fs:KPCR_EXCEPTION_LIST
92         
93         /* Get a pointer to the current thread */
94         movl    %fs:KPCR_CURRENT_THREAD, %edi
95
96         /* The current thread may be NULL early in the boot process */
97         cmpl    $0, %edi
98         je      .L4
99                 
100         /* Save the old previous mode */
101         movl    $0, %ebx
102         movb    %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl
103         pushl   %ebx
104         
105         /* Set the new previous mode based on the saved CS selector */
106         movl     0x24(%esp), %ebx
107         andl     $0x0000FFFF, %ebx
108         cmpl     $KERNEL_CS, %ebx
109         jne      .L1
110         movb     $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
111         jmp      .L3
112 .L1:
113         movb     $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
114 .L3:
115         
116         /* Save other registers */      
117         pushl   %eax
118         pushl   %ecx
119         pushl   %edx
120         pushl   %ds
121         pushl   %es
122         pushl   %gs
123         pushl   $0     /* DR7 */
124         pushl   $0     /* DR6 */
125         pushl   $0     /* DR3 */
126         pushl   $0     /* DR2 */
127         pushl   $0     /* DR1 */
128         pushl   $0     /* DR0 */
129         pushl   $0     /* XXX: TempESP */
130         pushl   $0     /* XXX: TempCS */
131         pushl   $0     /* XXX: DebugPointer */
132         pushl   $0     /* XXX: DebugArgMark */
133         movl    0x60(%esp), %ebx
134         pushl   %ebx   /* XXX: DebugEIP */
135         pushl   %ebp   /* XXX: DebugEBP */      
136                 
137         /* Load the segment registers */
138         movl    $KERNEL_DS, %ebx
139         movl    %ebx, %ds
140         movl    %ebx, %es
141         movl    %ebx, %gs
142         
143         /*  Set ES to kernel segment  */
144         movw    $KERNEL_DS,%bx
145         movw    %bx,%es
146
147         movl    %esp, %ebx
148         movl    %esp, %ebp              
149
150         /* Save the old trap frame. */
151         cmpl    $0, %edi
152         je      .L7
153         movl    %ss:KTHREAD_TRAP_FRAME(%edi), %edx
154         pushl   %edx
155         jmp     .L8
156 .L7:
157         pushl   $0
158 .L8:    
159
160         /* Save a pointer to the trap frame in the current KTHREAD */
161         cmpl    $0, %edi
162         je      .L6
163         movl    %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
164 .L6:    
165         
166         /* Call the C exception handler */
167         pushl   %esi
168         pushl   %ebx
169         call    _KiTrapHandler
170         addl    $4, %esp
171         addl    $4, %esp
172
173         /* Get a pointer to the current thread */
174         movl    %fs:KPCR_CURRENT_THREAD, %esi
175         
176         /* Restore the old trap frame pointer */
177         popl    %ebx
178         movl    %ebx, KTHREAD_TRAP_FRAME(%esi)
179         
180         /* Return to the caller */
181         jmp     _KiTrapEpilog
182
183         /* Handle the no-pcr case out of line */
184 .L5:    
185         pushl   $0
186                 
187         /* Handle the no-thread case out of line */
188 .L4:
189         pushl   $0      
190         jmp     .L3     
191                                         
192 .globl _KiTrap0
193 _KiTrap0:
194         /* No error code */
195         pushl   $0
196         pushl   %ebp
197         pushl   %ebx
198         pushl   %esi
199         movl    $0, %esi
200         jmp     _KiTrapProlog
201                                 
202 .globl _KiTrap1
203 _KiTrap1:
204         /* No error code */
205         pushl   $0
206         pushl   %ebp
207         pushl   %ebx
208         pushl   %esi
209         movl    $1, %esi
210         jmp     _KiTrapProlog
211         
212 .globl _KiTrap2
213 _KiTrap2:
214         pushl   $0
215         pushl   %ebp
216         pushl   %ebx
217         pushl   %esi
218         movl    $2, %esi
219         jmp     _KiTrapProlog
220
221 .globl _KiTrap3
222 _KiTrap3:
223         pushl   $0
224         pushl   %ebp
225         pushl   %ebx
226         pushl   %esi
227         movl    $3, %esi
228         jmp     _KiTrapProlog
229
230 .globl _KiTrap4
231 _KiTrap4:
232         pushl   $0
233         pushl   %ebp
234         pushl   %ebx
235         pushl   %esi
236         movl    $4, %esi
237         jmp     _KiTrapProlog
238
239 .globl _KiTrap5
240 _KiTrap5:
241         pushl   $0
242         pushl   %ebp
243         pushl   %ebx
244         pushl   %esi
245         movl    $5, %esi
246         jmp     _KiTrapProlog
247
248 .globl _KiTrap6
249 _KiTrap6:
250         pushl   $0
251         pushl   %ebp
252         pushl   %ebx
253         pushl   %esi
254         movl    $6, %esi
255         jmp     _KiTrapProlog
256
257 .globl _KiTrap7
258 _KiTrap7:
259         pushl   $0
260         pushl   %ebp
261         pushl   %ebx
262         pushl   %esi
263         movl    $7, %esi
264         jmp     _KiTrapProlog
265
266 .globl _KiTrap8
267 _KiTrap8:
268         call    _KiDoubleFaultHandler
269         iret
270
271 .globl _KiTrap9
272 _KiTrap9:
273         pushl   $0
274         pushl   %ebp
275         pushl   %ebx
276         pushl   %esi
277         movl    $9, %esi
278         jmp     _KiTrapProlog
279
280 .globl _KiTrap10
281 _KiTrap10:
282         pushl   %ebp
283         pushl   %ebx
284         pushl   %esi
285         movl    $10, %esi
286         jmp     _KiTrapProlog
287
288 .globl _KiTrap11
289 _KiTrap11:
290         pushl   %ebp
291         pushl   %ebx
292         pushl   %esi
293         movl    $11, %esi
294         jmp     _KiTrapProlog
295
296 .globl _KiTrap12
297 _KiTrap12:
298         pushl   %ebp
299         pushl   %ebx
300         pushl   %esi
301         movl    $12, %esi
302         jmp     _KiTrapProlog
303
304 .globl _KiTrap13
305 _KiTrap13:
306         pushl   %ebp
307         pushl   %ebx
308         pushl   %esi
309         movl    $13, %esi
310         jmp     _KiTrapProlog
311
312 .globl _KiTrap14
313 _KiTrap14:
314         pushl   %ebp
315         pushl   %ebx
316         pushl   %esi
317         movl    $14, %esi
318         jmp     _KiTrapProlog
319
320 .globl _KiTrap15
321 _KiTrap15:
322         pushl   $0
323         pushl   %ebp
324         pushl   %ebx
325         pushl   %esi
326         movl    $15, %esi
327         jmp     _KiTrapProlog
328
329 .globl _KiTrap16
330 _KiTrap16:
331         pushl   $0
332         pushl   %ebp
333         pushl   %ebx
334         pushl   %esi
335         movl    $16, %esi
336         jmp     _KiTrapProlog
337          
338 .globl _KiTrapUnknown
339 _KiTrapUnknown:
340         pushl   $0
341         pushl   %ebp
342         pushl   %ebx
343         pushl   %esi
344         movl    $255, %esi
345         jmp     _KiTrapProlog
346
347
348 /* EOF */