source: trunk/packages/xen-common/xen-common/extras/mini-os/arch/x86/x86_32.S @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 6.8 KB
Line 
1#include <os.h>
2#include <xen/arch-x86_32.h>
3
4.section __xen_guest
5        .ascii  "GUEST_OS=Mini-OS"
6        .ascii  ",XEN_VER=xen-3.0"
7        .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
8        .ascii  ",ELF_PADDR_OFFSET=0x0"
9        .ascii  ",HYPERCALL_PAGE=0x2"
10#ifdef CONFIG_X86_PAE
11        .ascii  ",PAE=yes"
12#else
13        .ascii  ",PAE=no"
14#endif
15        .ascii  ",LOADER=generic"
16        .byte   0
17.text
18
19.globl _start, shared_info, hypercall_page
20                       
21_start:
22        cld
23        lss stack_start,%esp
24        push %esi
25        call start_kernel
26
27stack_start:
28        .long stack+8192, __KERNEL_SS
29
30        /* Unpleasant -- the PTE that maps this page is actually overwritten */
31        /* to map the real shared-info page! :-)                             */
32        .org 0x1000
33shared_info:
34        .org 0x2000
35
36hypercall_page:
37        .org 0x3000
38
39ES              = 0x20
40ORIG_EAX        = 0x24
41EIP             = 0x28
42CS              = 0x2C
43
44#define ENTRY(X) .globl X ; X :
45
46#define SAVE_ALL \
47        cld; \
48        pushl %es; \
49        pushl %ds; \
50        pushl %eax; \
51        pushl %ebp; \
52        pushl %edi; \
53        pushl %esi; \
54        pushl %edx; \
55        pushl %ecx; \
56        pushl %ebx; \
57        movl $(__KERNEL_DS),%edx; \
58        movl %edx,%ds; \
59        movl %edx,%es;
60
61#define RESTORE_ALL     \
62        popl %ebx;      \
63        popl %ecx;      \
64        popl %edx;      \
65        popl %esi;      \
66        popl %edi;      \
67        popl %ebp;      \
68        popl %eax;      \
69        popl %ds;       \
70        popl %es;       \
71        addl $4,%esp;   \
72        iret;           
73
74ENTRY(divide_error)
75        pushl $0                # no error code
76        pushl $do_divide_error
77do_exception:
78    pushl %ds
79        pushl %eax
80        xorl %eax, %eax
81        pushl %ebp
82        pushl %edi
83        pushl %esi
84        pushl %edx
85        decl %eax                       # eax = -1
86        pushl %ecx
87        pushl %ebx
88        cld
89        movl %es, %ecx
90        movl ES(%esp), %edi             # get the function address
91        movl ORIG_EAX(%esp), %edx       # get the error code
92        movl %eax, ORIG_EAX(%esp)
93        movl %ecx, ES(%esp)
94        movl $(__KERNEL_DS), %ecx
95        movl %ecx, %ds
96        movl %ecx, %es
97        movl %esp,%eax                  # pt_regs pointer
98    pushl %edx
99    pushl %eax
100        call *%edi
101    jmp ret_from_exception
102   
103ret_from_exception:
104    movb CS(%esp),%cl
105    addl $8,%esp
106    RESTORE_ALL
107
108# A note on the "critical region" in our callback handler.
109# We want to avoid stacking callback handlers due to events occurring
110# during handling of the last event. To do this, we keep events disabled
111# until weve done all processing. HOWEVER, we must enable events before
112# popping the stack frame (cant be done atomically) and so it would still
113# be possible to get enough handler activations to overflow the stack.
114# Although unlikely, bugs of that kind are hard to track down, so wed
115# like to avoid the possibility.
116# So, on entry to the handler we detect whether we interrupted an
117# existing activation in its critical region -- if so, we pop the current
118# activation and restart the handler using the previous one.
119ENTRY(hypervisor_callback)
120        pushl %eax
121        SAVE_ALL
122        movl EIP(%esp),%eax
123        cmpl $scrit,%eax
124        jb   11f
125        cmpl $ecrit,%eax
126        jb   critical_region_fixup
12711:     push %esp
128        call do_hypervisor_callback
129        add  $4,%esp
130        movl HYPERVISOR_shared_info,%esi
131        xorl %eax,%eax
132        movb CS(%esp),%cl
133        test $2,%cl          # slow return to ring 2 or 3
134        jne  safesti
135safesti:movb $0,1(%esi)     # reenable event callbacks
136scrit:  /**** START OF CRITICAL REGION ****/
137        testb $0xFF,(%esi)
138        jnz  14f              # process more events if necessary...
139        RESTORE_ALL
14014:     movb $1,1(%esi)
141        jmp  11b
142ecrit:  /**** END OF CRITICAL REGION ****/
143# [How we do the fixup]. We want to merge the current stack frame with the
144# just-interrupted frame. How we do this depends on where in the critical
145# region the interrupted handler was executing, and so how many saved
146# registers are in each frame. We do this quickly using the lookup table
147# 'critical_fixup_table'. For each byte offset in the critical region, it
148# provides the number of bytes which have already been popped from the
149# interrupted stack frame.
150critical_region_fixup:
151        addl $critical_fixup_table-scrit,%eax
152        movzbl (%eax),%eax    # %eax contains num bytes popped
153        mov  %esp,%esi
154        add  %eax,%esi        # %esi points at end of src region
155        mov  %esp,%edi
156        add  $0x34,%edi       # %edi points at end of dst region
157        mov  %eax,%ecx
158        shr  $2,%ecx          # convert words to bytes
159        je   16f              # skip loop if nothing to copy
16015:     subl $4,%esi          # pre-decrementing copy loop
161        subl $4,%edi
162        movl (%esi),%eax
163        movl %eax,(%edi)
164        loop 15b
16516:     movl %edi,%esp        # final %edi is top of merged stack
166        jmp  11b
167         
168critical_fixup_table:       
169        .byte 0x00,0x00,0x00                  # testb $0xff,(%esi)
170        .byte 0x00,0x00                       # jne  14f
171        .byte 0x00                            # pop  %ebx
172        .byte 0x04                            # pop  %ecx
173        .byte 0x08                            # pop  %edx
174        .byte 0x0c                            # pop  %esi
175        .byte 0x10                            # pop  %edi
176        .byte 0x14                            # pop  %ebp
177        .byte 0x18                            # pop  %eax
178        .byte 0x1c                            # pop  %ds
179        .byte 0x20                            # pop  %es
180        .byte 0x24,0x24,0x24                  # add  $4,%esp
181        .byte 0x28                            # iret
182        .byte 0x00,0x00,0x00,0x00             # movb $1,1(%esi)
183        .byte 0x00,0x00                       # jmp  11b
184       
185# Hypervisor uses this for application faults while it executes.
186ENTRY(failsafe_callback)
187      pop  %ds
188      pop  %es
189      pop  %fs
190      pop  %gs
191      iret
192               
193ENTRY(coprocessor_error)
194        pushl $0
195        pushl $do_coprocessor_error
196        jmp do_exception
197
198ENTRY(simd_coprocessor_error)
199        pushl $0
200        pushl $do_simd_coprocessor_error
201        jmp do_exception
202
203ENTRY(device_not_available)
204        iret
205
206ENTRY(debug)
207        pushl $0
208        pushl $do_debug
209        jmp do_exception
210
211ENTRY(int3)
212        pushl $0
213        pushl $do_int3
214        jmp do_exception
215
216ENTRY(overflow)
217        pushl $0
218        pushl $do_overflow
219        jmp do_exception
220
221ENTRY(bounds)
222        pushl $0
223        pushl $do_bounds
224        jmp do_exception
225
226ENTRY(invalid_op)
227        pushl $0
228        pushl $do_invalid_op
229        jmp do_exception
230
231
232ENTRY(coprocessor_segment_overrun)
233        pushl $0
234        pushl $do_coprocessor_segment_overrun
235        jmp do_exception
236
237
238ENTRY(invalid_TSS)
239        pushl $do_invalid_TSS
240        jmp do_exception
241
242
243ENTRY(segment_not_present)
244        pushl $do_segment_not_present
245        jmp do_exception
246
247
248ENTRY(stack_segment)
249        pushl $do_stack_segment
250        jmp do_exception
251
252
253ENTRY(general_protection)
254        pushl $do_general_protection
255        jmp do_exception
256
257
258ENTRY(alignment_check)
259        pushl $do_alignment_check
260        jmp do_exception
261
262
263ENTRY(page_fault)
264    pushl $do_page_fault
265    jmp do_exception
266   
267ENTRY(machine_check)
268        pushl $0
269        pushl $do_machine_check
270        jmp do_exception
271
272
273ENTRY(spurious_interrupt_bug)
274        pushl $0
275        pushl $do_spurious_interrupt_bug
276        jmp do_exception
277
278
279
280ENTRY(thread_starter)
281    popl %eax
282    popl %ebx
283    pushl %eax
284    call *%ebx
285    call exit_thread
286   
Note: See TracBrowser for help on using the repository browser.