]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/32/entry.S
update
[l4.git] / kernel / fiasco / src / kern / ia32 / 32 / entry.S
1 /*
2  * This file contains a 'gate_init' initialization table
3  * to initialize the x86 processor trap vectors to default entrypoints.
4  * These entrypoints simply push a standard trap_state frame
5  * and jump to the 'trap_handler' routine.
6  */
7
8 #include "config_tcbsize.h"
9 #include "config_gdt.h"
10 #include "globalconfig.h"
11 #include "idt_init.h"
12 #include <low_level.h>
13 #include "shortcut.h"
14 #include "tcboffset.h"
15 #include "regdefs.h"
16
17 #include "asm.h"
18
19 /* We make the trap handler an interrupt gate, because for debugging
20    purposes, we don't want any interrupts to occur until they're
21    explicitly enabled in the base_trap_handler (usually
22    Thread::handle_slow_trap). */
23
24 /*
25  * No error code.  Clear error code and push trap number.
26  */
27 #define EXCEPTION(n,name)                                       \
28         GATE_ENTRY(n,entry_##name,ACC_PL_K | ACC_INTR_GATE)     ;\
29         .p2align 3                                              ;\
30 entry_##name:                                                   ;\
31         pushl   $(0)                                            ;\
32         pushl   $(n)                                            ;\
33         pusha                                                   ;\
34         jmp     _slowtraps
35
36 /*
37  * User-accessible exception.  Otherwise, same as above.
38  */
39 #define EXCEP_USR(n,name)                                       \
40         GATE_ENTRY(n,entry_##name,ACC_PL_U | ACC_INTR_GATE)     ;\
41         .p2align 3                                              ;\
42 entry_##name:                                                   ;\
43         pushl   $(0)                                            ;\
44         pushl   $(n)                                            ;\
45         pusha                                                   ;\
46         jmp     _slowtraps
47
48 /*
49  * Error code has been pushed.  Just push trap number.
50  */
51 #define EXCEP_ERR(n,name)                                       \
52         GATE_ENTRY(n,entry_##name,ACC_PL_K | ACC_INTR_GATE)     ;\
53         .p2align 3                                              ;\
54 entry_##name:                                                   ;\
55         pushl   $(n)                                            ;\
56         pusha                                                   ;\
57         jmp     _slowtraps
58
59 .macro  PRE_ALIEN_IPC
60         btrl    $17, OFS__THREAD__STATE (%ebx) /* Thread_dis_alien */
61         jc      1f
62         RESTORE_STATE
63         sub     $2, 4(%esp)                /* Correct EIP to point to insn */
64         popl    %eax
65         pushl   $(0x30 << 3 | 2)
66         pushl   $(0xd)
67         pusha
68         jmp     _slowtraps
69
70 1:      /* do alien IPC and raise a trap afterwards */  
71         RESET_THREAD_CANCEL_AT %ebx
72 .endm
73
74 .macro  POST_ALIEN_IPC
75         CHECK_SANITY $3                 /* scratches ecx */
76         RESTORE_STATE_AFTER_IPC
77         popl    %eax
78         pushl   $(0x30 << 3 | 6)
79         pushl   $(0xd)
80         pusha
81         jmp     _slowtraps
82 .endm
83
84 GATE_INITTAB_BEGIN(idt_init_table)
85
86 EXCEPTION(0x00,vec00_zero_div)
87 #ifdef CONFIG_PF_UX
88 EXCEPTION(0x01,vec01_debug)
89 #else
90 /* IA32 has to handle breakpoint exceptions if occured exactly at 
91    entry_sys_fast_ipc -- see ia32/entry-ia32.S */
92 GATE_ENTRY(0x01,entry_vec01_debug,ACC_PL_K | ACC_INTR_GATE)
93 #endif
94 /* XXX IA32 has to handle NMI occured exactly at entry_sys_fast_ipc */
95 EXCEP_USR(0x02,vec02_nmi)
96 EXCEP_USR(0x03,vec03_breakpoint)
97 EXCEP_USR(0x04,vec04_into)
98 EXCEP_USR(0x05,vec05_bounds)
99 EXCEPTION(0x06,vec06_invop)
100 /* EXCEPTION(0x07,nofpu) */
101 #ifdef CONFIG_PF_UX
102 EXCEP_ERR(0x08,vec08_dbl_fault)
103 #else
104 GATE_ENTRY(0x08, GDT_TSS_DBF, ACC_PL_K | ACC_TASK_GATE)
105 #endif
106 EXCEPTION(0x09,vec09_fpu_ovfl)
107 /* EXCEP_ERR(0x0a,vec0a_inv_tss) */
108 EXCEP_ERR(0x0b,vec0b_segnp)
109 EXCEP_ERR(0x0c,vec0c_stack_fault)
110 EXCEP_ERR(0x0d,vec0d_gen_prot)
111 /* EXCEP_ERR(0x0e,vec0e_page_fault) */
112 /* EXCEPTION(0x0f,vec0f_trap_0f) */
113 EXCEPTION(0x10,vec10_fpu_err)
114 EXCEP_ERR(0x11,vec11_align)
115 EXCEPTION(0x12,vec12_mcheck)
116 EXCEPTION(0x13,vec13_simd_err)
117
118
119         .p2align 4
120         .type   slowtraps,@function
121         .globl  slowtraps
122         /* We have to introduce the label _slowtraps besides the label
123            slowtraps to achive that jmps from exception entry points
124            are optimized to two-byte jmps. The label slowtraps is visible
125            from outside. */
126 _slowtraps:
127 slowtraps:
128 #ifdef CONFIG_PF_UX
129 # define REG_GS CPU_GS
130 # define REG_FS CPU_FS
131 #else
132 # define REG_GS %gs
133 # define REG_FS %fs
134 #endif
135
136         pushl   REG_FS          /* we save the segment regs in the trap   */
137         pushl   REG_GS          /* state, but we do not restore them.  We */
138         pushl   %ds             /* rather reload them using               */
139         pushl   %es             /* RESET_{KERNEL,USER}_SEGMENTS           */
140
141         cld
142
143         /* Load the kernel's segment registers.  */
144         RESET_KERNEL_SEGMENTS_FORCE_DS_ES /* scratches ecx, edx */
145         
146         /* Note: we do not use RESET_THREAD_CANCEL_* here as that is
147            needed only when an I/O-page-fault IPC is sent and when the
148            thread is killed. Resetting Thread_cancel here could
149            be harmful when using this trap handler in debugging.
150            Instead, we clear this flag in Thread::handle_slow_trap()
151            just before sending the IPC message or before killing the
152            thread.  That's OK, because it is still atomic -- we never
153            enable IRQs (sti) before that point. */
154
155         movl    %esp,%eax               /* ARG1: address of trap_state */
156         xorl    %edx,%edx               /* ARG2: default CPU = 0 */
157 #ifndef CONFIG_NO_FRAME_PTR
158         pushl   56(%esp)                /* create artificial stack frame */
159         pushl   %ebp
160         leal    (%esp),%ebp
161 #endif
162
163         /* Call the C handler function if one has been installed.  */
164         movl    BASE_TRAP_HANDLER, %ecx
165         orl     %ecx,%ecx
166         jz      unexpected_trap_pop
167         call    *%ecx
168 in_slowtrap:
169
170 #ifndef CONFIG_NO_FRAME_PTR
171         leal    8(%esp),%esp
172 #endif
173
174         /* If the handler function returned zero (success),
175            then resume execution as if the trap never happened.
176            Otherwise, just panic.  */
177         orl     %eax,%eax
178         jnz     unexpected_trap
179
180         CHECK_SANITY 60(%esp)           /* scratches ecx */
181
182         addl    $4*2,%esp               /* Pop ds, es segment registers */
183         popl    REG_GS
184         popl    REG_FS                  /* Restore segment registers */
185         popa
186         addl    $4*2,%esp               /* Pop trap number and error code */
187         iret
188
189 unexpected_trap_pop:
190 #ifndef CONFIG_NO_FRAME_PTR
191         leal    8(%esp), %esp
192 #endif
193
194 unexpected_trap:
195         movw    %ss,%ax
196         movw    %ax,%ds
197         movw    %ax,%es
198         movl    %esp,%eax
199         call    trap_dump_panic
200
201 GATE_ENTRY(0x0e,entry_vec0e_page_fault,ACC_PL_K | ACC_INTR_GATE)
202
203 /* we must save %cr2 before we can be preempted -- therefore we're an
204    interrupt gate (invoked with interrupts turned off).  Also, we
205    don't turn them on again here, but only after checking for
206    page-ins from the global page directory in thread_page_fault().
207    XXX: If you make changes to stack layout here, fix thread_page_fault */
208
209 /* XXX slow version - sets up nice stack frame for debugger */
210
211         .p2align 4
212         .type   entry_vec0e_page_fault,@function
213 entry_vec0e_page_fault:
214         cld
215         SAVE_SCRATCH
216         RESET_KERNEL_SEGMENTS_FORCE_DS_ES
217         movl    12(%esp),%edx           /* save error code in ARG2 ... */
218         movl    PAGE_FAULT_ADDR,%eax    /* save page fault address in ARG1 */
219
220 /* We must reset the cancel flag here atomically 
221    if we are entering fresh from user mode and an IPC might occur. 
222    NOTE: We cannot test the user-mode bit in the error code because
223    it will flag "kernel" in case an I/O-bitmap page is not mapped
224    during an I/O access. */
225
226         movl    20(%esp),%ecx   /* get CS from stack */
227         andb    $3,%cl          /* retrieve current privilege level (CPL) */
228         jz      1f              /* CPL == 0 -> kernel, skip resetting state */
229         ESP_TO_TCB_AT %ecx
230         RESET_THREAD_CANCEL_AT %ecx
231 1:      movl    %ebp,12(%esp)   /* save frame pointer */
232         leal    12(%esp),%ebp   /* load new frame pointer */
233         pushl   %eax            /* save pf address */
234         pushl   %edx            /* save error code */
235         leal    24(%esp),%ecx   /* ARG5: ptr to Return_frame */
236         pushl   %ecx
237         pushl   36(%esp)        /* ARG4: eflags */
238         movl    32(%esp),%ecx   /* ARG3: eip */
239         call    thread_page_fault
240 in_page_fault:
241
242         orl     %eax,%eax
243         jz      bad_page_fault
244         lea     16(%esp),%esp
245         CHECK_SANITY 20(%esp)                   /* scratches ecx */
246         RESTORE_SCRATCH
247         popl    %ebp
248         iret
249
250 /* recover from a bad page fault by invoking the slow_trap handler */
251         .p2align 4
252 bad_page_fault:
253         cli
254         addl    $8,%esp         /* pop ARG4 and ARG5 */
255         movl    (%ebp),%eax     /* old ebp */
256         popl    (%ebp)          /* error code */
257         popl    %edx            /* page fault address */
258         movl    %eax,%ebp
259
260         /* we have on stack: error code, eax, ecx, edx
261            move registers down to make room for trap number */
262         subl    $4,%esp
263         movl    4(%esp),%eax
264         movl    %eax,(%esp)
265         movl    8(%esp),%eax
266         movl    %eax,4(%esp)
267         movl    12(%esp),%eax
268         movl    %eax,8(%esp)
269         movl    $0x0e,12(%esp)  /* error code */
270         pushl   %ebx            /* rest of trap state */
271         pushl   %edx            /* page fault address */
272         pushl   %ebp
273         pushl   %esi
274         pushl   %edi
275         jmp     slowtraps
276
277
278 /* FPU not available in this context. */
279 GATE_ENTRY(0x07,entry_vec07_fpu_unavail, ACC_PL_K | ACC_INTR_GATE)
280
281 /* do all of this with disabled interrupts */
282         .p2align 4
283         .type   entry_vec07_fpu_unavail,@function
284 entry_vec07_fpu_unavail:
285         cld
286         SAVE_SCRATCH
287         call    thread_handle_fputrap
288 in_handle_fputrap:
289         CHECK_SANITY 16(%esp)                   /* scratches ecx */
290         test    %eax, %eax
291         jz      real_fpu_exception
292         RESTORE_SCRATCH
293         iret 
294 real_fpu_exception:
295         RESTORE_SCRATCH
296         pushl   $(0)
297         pushl   $(7)
298         pusha                                                   
299         jmp     _slowtraps
300
301
302 /* timer interrupt */
303 #ifdef CONFIG_SCHED_PIT
304 GATE_ENTRY(0x20,entry_int_timer,ACC_PL_K | ACC_INTR_GATE)
305 #endif
306 #ifdef CONFIG_SCHED_RTC
307 GATE_ENTRY(0x28,entry_int_timer,ACC_PL_K | ACC_INTR_GATE)
308 #endif
309 #ifdef CONFIG_SCHED_APIC
310 GATE_ENTRY(APIC_IRQ_BASE, entry_int_timer,ACC_PL_K | ACC_INTR_GATE)
311 #endif
312 #ifdef CONFIG_SCHED_HPET
313 /* HPET is set at startup */
314 #endif
315
316         .p2align 4
317         .globl  entry_int_timer
318 entry_int_timer:
319 #ifndef CONFIG_NO_FRAME_PTR
320         pushl   %ebp
321         movl    %esp,%ebp
322 #endif
323         SAVE_SCRATCH
324 do_timer_interrupt:
325         cld
326 #ifdef CONFIG_NO_FRAME_PTR
327         movl    12(%esp), %eax                  /* ARG1: eip for logging */
328 #else
329         movl    16(%esp), %eax                  /* ARG1: eip for logging */
330 #endif
331         call    thread_timer_interrupt          /* enter with disabled irqs */
332 in_timer_interrupt:
333 #ifndef CONFIG_NO_FRAME_PTR
334         CHECK_SANITY 20(%esp)                   /* scratches ecx */
335 #else
336         CHECK_SANITY 16(%esp)                   /* scratches ecx */
337 #endif
338         RESTORE_SCRATCH
339 #ifndef CONFIG_NO_FRAME_PTR
340         popl    %ebp
341 #endif
342         iret
343
344         .p2align 4
345         .globl  entry_int_timer_slow
346 entry_int_timer_slow:
347 #ifndef CONFIG_NO_FRAME_PTR
348         pushl   %ebp
349         movl    %esp,%ebp
350 #endif
351         SAVE_SCRATCH
352         cld
353
354         call    thread_timer_interrupt_slow     /* enter with disabled irqs */
355 in_timer_interrupt_slow:
356         jmp     do_timer_interrupt
357
358         
359         .p2align 4
360         .globl  entry_int_timer_stop
361 entry_int_timer_stop:
362 #ifndef CONFIG_NO_FRAME_PTR
363         pushl   %ebp
364         movl    %esp,%ebp
365 #endif
366         SAVE_SCRATCH
367         cld
368         call    thread_timer_interrupt_stop
369 #ifndef CONFIG_NO_FRAME_PTR
370         CHECK_SANITY 20(%esp)                   /* scratches ecx */
371 #else
372         CHECK_SANITY 16(%esp)                   /* scratches ecx */
373 #endif
374         RESTORE_SCRATCH
375 #ifndef CONFIG_NO_FRAME_PTR
376         popl    %ebp
377 #endif
378         iret
379
380
381 /* other interrupts */
382
383 #define INTERRUPT(int,name)                                     \
384         GATE_ENTRY(int,entry_##name,ACC_PL_K | ACC_INTR_GATE)   ;\
385         .p2align 3                                              ;\
386 entry_##name:                                                   ;\
387         pushl   %eax                                            ;\
388         movl    $ (int - 0x20), %eax    /* ARG1: irqnum */      ;\
389         jmp     all_irqs
390
391 #ifndef CONFIG_SCHED_PIT
392 INTERRUPT(0x20,int0)
393 #endif
394 /* spurious IRQ handlers */
395 GATE_ENTRY(0x27,entry_int_pic_ignore,ACC_PL_K | ACC_INTR_GATE)
396 GATE_ENTRY(0x2f,entry_int_pic_ignore,ACC_PL_K | ACC_INTR_GATE)  
397 #ifndef CONFIG_SCHED_RTC
398 INTERRUPT(0x28,int8)
399 #endif
400
401         .p2align 4
402         .type   all_irqs,@function
403         .type   __generic_irq_entry,@function
404         .global __generic_irq_entry
405 all_irqs:
406 __generic_irq_entry:
407         cld
408         pushl   %edx
409         pushl   %ecx
410         movl    12(%esp), %edx                  /* ARG2: eip */
411         call    irq_interrupt                   /* enter with disabled irqs */
412 in_interrupt:
413         CHECK_SANITY 16(%esp)                   /* scratches ecx */
414         popl    %ecx
415         popl    %edx
416         popl    %eax
417
418 entry_int_pic_ignore:
419         iret
420
421         .global entry_int_pic_ignore
422         .global entry_int7
423         .global entry_intf
424
425 /****************************************************************************/
426 /* system calls                                                             */
427 /****************************************************************************/
428
429 #ifdef CONFIG_ASSEMBLER_IPC_SHORTCUT
430 GATE_ENTRY(0x30,entry_sys_ipc,ACC_PL_U | ACC_INTR_GATE);
431 #else
432 GATE_ENTRY(0x30,entry_sys_ipc_c,ACC_PL_U | ACC_INTR_GATE);
433 #endif
434
435 #if defined (CONFIG_JDB_LOGGING) || !defined(CONFIG_ASSEMBLER_IPC_SHORTCUT)
436         .p2align 4
437         .globl  entry_sys_ipc_c
438 entry_sys_ipc_c:
439         cld
440         pushl   %eax
441         SAVE_STATE
442         ESP_TO_TCB_AT %ebx
443         testl   $Thread_alien_or_vcpu_user, OFS__THREAD__STATE (%ebx)
444         jnz     alien_sys_ipc_c
445         RESET_THREAD_CANCEL_AT %ebx
446         call    sys_ipc_wrapper //ipc_short_cut_wrapper
447 in_sc_ipc1:
448         CHECK_SANITY $3                 /* scratches ecx */
449         RESTORE_STATE_AFTER_IPC
450         popl    %eax
451         iret
452
453         .globl  in_sc_ipc1
454 #endif
455
456 #ifdef CONFIG_JDB
457         /* The slow variant of sys_ipc_entry is used when logging IPC */
458         .p2align 4
459         .globl  entry_sys_ipc_log
460 entry_sys_ipc_log:
461         cld
462         pushl   %eax
463         SAVE_STATE
464         ESP_TO_TCB_AT %ebx
465         testl   $Thread_alien_or_vcpu_user, OFS__THREAD__STATE (%ebx)
466         jnz     alien_sys_ipc_log
467         RESET_THREAD_CANCEL_AT %ebx
468         call    *syscall_table
469 in_slow_ipc4:
470         CHECK_SANITY $3                 /* scratches ecx */
471         RESTORE_STATE_AFTER_IPC
472         popl    %eax
473         iret
474
475         .globl  in_slow_ipc4
476 #endif // CONFIG_JDB
477
478         // these labels help show_tcb to guess the thread state
479         .globl  in_syscall
480         .globl  in_slowtrap
481         .globl  in_page_fault
482         .globl  in_handle_fputrap
483         .globl  in_interrupt  
484         .globl  in_timer_interrupt
485         .globl  in_timer_interrupt_slow
486
487 #define SYSTEM_CALL(int,name)                                   \
488         GATE_ENTRY(int,entry_##name,ACC_PL_U | ACC_INTR_GATE)   ;\
489         .p2align 3                                              ;\
490 entry_##name:                                                   ;\
491         pushl   %eax                                            ;\
492         movl    $(syscall_table+4*(int-0x30)), %eax             ;\
493         jmp     all_syscalls
494
495         .p2align 4
496         .type   all_syscalls,@function
497 all_syscalls:
498         SAVE_STATE                                              ;\
499         cld
500         ESP_TO_TCB_AT %ebx
501         testl   $Thread_alien_or_vcpu_user, OFS__THREAD__STATE (%ebx)
502         jnz     alien_sys_call
503         RESET_THREAD_CANCEL_AT %ebx
504         call    *(%eax)                 /* interrupts enabled in wrappers */
505 in_syscall:
506
507 ret_from_syscall:
508         CHECK_SANITY $3                 /* scratches ecx */
509         RESTORE_STATE
510         popl    %eax
511         iret
512
513
514 SYSTEM_CALL(0x32,sys_invoke_debug)
515
516 #ifndef CONFIG_PF_UX
517 /* these functions are implemented in entry-native.S */
518 GATE_ENTRY(0x0a,entry_vec0a_invalid_tss,ACC_PL_K | ACC_INTR_GATE)
519 GATE_ENTRY(0x0f,entry_vec0f_apic_spurious_interrupt_bug,ACC_PL_K | ACC_INTR_GATE)
520 GATE_ENTRY(APIC_IRQ_BASE + 3,entry_apic_error_interrupt,ACC_PL_K | ACC_INTR_GATE)
521 GATE_ENTRY(APIC_IRQ_BASE + 0xf,entry_apic_spurious_interrupt,ACC_PL_K | ACC_INTR_GATE)
522 #endif
523
524 #ifdef CONFIG_MP
525 GATE_ENTRY(APIC_IRQ_BASE + 2, entry_ipi, ACC_PL_K | ACC_INTR_GATE)
526 GATE_ENTRY(APIC_IRQ_BASE - 2, entry_debug_ipi, ACC_PL_K | ACC_INTR_GATE)
527 GATE_ENTRY(APIC_IRQ_BASE - 1, entry_ipi_remote_request, ACC_PL_K | ACC_INTR_GATE)
528 #endif
529
530 GATE_INITTAB_END
531
532         .globl alien_sys_ipc_c /* Also used in shortcut */
533 alien_sys_ipc_c:
534         cld
535         PRE_ALIEN_IPC
536         call    sys_ipc_wrapper
537         POST_ALIEN_IPC
538
539 #if defined (CONFIG_JDB)
540 alien_sys_ipc_log:
541         cld
542         PRE_ALIEN_IPC
543         call    *syscall_table
544         POST_ALIEN_IPC
545 #endif
546
547 /*
548  * input:  eax: address to syscall function
549  * output: eax: error code
550  */
551 .macro SC_ADDR_TO_ERR val
552         sub     $syscall_table , %eax   /* eax = byte offset to syscall */
553         shr     $2, %eax                /* convert eax to syscall nr */
554         add     $0x30, %eax             /* convert eax to syscall int nr */
555         shl     $3, %eax                /* construct error code */
556         orl     $\val, %eax             /* -"- */
557 .endm
558
559 alien_sys_call:
560         btrl    $17, OFS__THREAD__STATE (%ebx) /* Thread_dis_alien */
561         jc      1f
562         RESTORE_STATE
563         sub     $2, 4(%esp)             /* Correct EIP to point to insn */
564         SC_ADDR_TO_ERR 2
565 2:      pushl   $0xd
566         xchgl   4(%esp), %eax
567         pusha
568         jmp     _slowtraps
569
570 1:      /* do alien syscall and trap afterwards */
571         RESET_THREAD_CANCEL_AT %ebx
572         pushl   %eax
573         call    *(%eax)                 /* call with ENABLED interrupts */
574         cli
575         CHECK_SANITY $3                 /* scratches ecx */
576         popl    %eax
577         RESTORE_STATE
578         SC_ADDR_TO_ERR 6
579         jmp     2b
580
581
582         .p2align
583         .globl  leave_by_trigger_exception
584 leave_by_trigger_exception:
585         cli
586         subl    $12,%esp                /* clean up stack from previous
587                                          * CPL0-CPL0 iret */
588         SAVE_SCRATCH
589         call    thread_restore_exc_state
590         RESTORE_SCRATCH
591         pushl   $0x00
592         pushl   $0xff
593         pusha
594         jmp     _slowtraps
595
596         .p2align
597         .globl  leave_by_vcpu_upcall
598 leave_by_vcpu_upcall:
599         cli
600         subl    $12,%esp                /* clean up stack from previous
601                                          * CPL0-CPL0 iret */
602         SAVE_SCRATCH
603         call    thread_restore_exc_state
604
605         ESP_TO_TCB_AT %ecx
606         mov OFS__THREAD__USER_VCPU(%ecx), %eax /* vcpu state pointer from TCB */
607         mov OFS__THREAD__VCPU_STATE(%ecx), %ecx /* vcpu state pointer from TCB */
608         addl $(VAL__SIZEOF_TRAP_STATE - 20), %ecx /* skip return frame */
609         mov SCRATCH_REGISTER_SIZE(%esp),  %edx
610         mov %edx, (%ecx)                                /* EIP */
611         mov 8 + SCRATCH_REGISTER_SIZE(%esp),  %edx
612         mov %edx, 8(%ecx)                               /* EFLAGS */
613         mov 12 + SCRATCH_REGISTER_SIZE(%esp), %edx
614         mov %edx, 12(%ecx)                              /* ESP */
615         mov 16 + SCRATCH_REGISTER_SIZE(%esp), %edx
616         mov %edx, 16(%ecx)                              /* SS */
617
618         mov 0(%esp), %edx    /* EDX */
619         mov %edx, -20(%ecx)
620         mov 4(%esp), %edx    /* ECX */
621         mov %edx, -16(%ecx)
622         mov 8(%esp), %edx    /* EAX */
623         mov %edx, -12(%ecx)
624
625         lea 12(%esp), %edx
626         lea -20(%ecx), %esp
627
628         push %ebx            /* EBX */
629         sub $4, %esp         /* SKIP PFA */
630         push %ebp            /* EBP */
631         push %esi            /* ESI */
632         push %edi            /* EDI */
633
634         /*add SCRATCH_REGISTER_SIZE, %esp*/
635
636         pushl   REG_FS          /* we save the segment regs in the trap   */
637         pushl   REG_GS          /* state, but we do not restore them.  We */
638         pushl   %ds             /* rather reload them using               */
639         pushl   %es             /* RESET_{KERNEL,USER}_SEGMENTS           */
640
641         mov %edx, %esp
642         mov -VAL__SIZEOF_TRAP_STATE + 20 + OFS__VCPU_STATE__ENTRY_SP(%ecx), %edx
643         mov %edx, 12(%esp)
644         mov -VAL__SIZEOF_TRAP_STATE + 20 + OFS__VCPU_STATE__ENTRY_IP(%ecx), %edx
645         mov %edx, 0(%esp)
646         movl $EFLAGS_IF, 8(%esp)
647         iret
648         
649         .p2align
650         .globl  vcpu_resume
651 vcpu_resume:
652         mov %eax, %esp
653         addl $(2*4), %esp // skip es and ds for now
654         //popl %es
655         //popl %ds
656         popl REG_GS
657         popl REG_FS
658         popa
659         addl $(2*4), %esp
660         iret
661
662         // fast return from Dirq::hit
663         .align  16
664         .globl  fast_ret_from_irq
665 fast_ret_from_irq:
666         CHECK_SANITY $3                         // scratches ecx
667         RESTORE_STATE_AFTER_IPC
668         popl    %eax
669         andl    $0x7f, 4(%esp)                  // if entered using sysenter
670         orl     $EFLAGS_IF, 8(%esp)             // if entered using sysenter
671         iret
672
673
674
675
676