ia64/xen-unstable

view extras/mini-os/x86_32.S @ 10888:5379548bfc79

[NET] Enable TCPv4 segmentation offload in front/back drivers.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Aug 01 11:54:45 2006 +0100 (2006-08-01)
parents b3b5f3ff2100
children
line source
1 #include <os.h>
2 #include <xen/arch-x86_32.h>
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
19 .globl _start, shared_info, hypercall_page
21 _start:
22 cld
23 lss stack_start,%esp
24 push %esi
25 call start_kernel
27 stack_start:
28 .long stack+8192, __KERNEL_SS
30 /* Unpleasant -- the PTE that maps this page is actually overwritten */
31 /* to map the real shared-info page! :-) */
32 .org 0x1000
33 shared_info:
34 .org 0x2000
36 hypercall_page:
37 .org 0x3000
39 ES = 0x20
40 ORIG_EAX = 0x24
41 EIP = 0x28
42 CS = 0x2C
44 #define ENTRY(X) .globl X ; X :
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;
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; \
74 ENTRY(divide_error)
75 pushl $0 # no error code
76 pushl $do_divide_error
77 do_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
103 ret_from_exception:
104 movb CS(%esp),%cl
105 test $2,%cl # slow return to ring 2 or 3
106 jne safesti
107 RESTORE_ALL
109 # A note on the "critical region" in our callback handler.
110 # We want to avoid stacking callback handlers due to events occurring
111 # during handling of the last event. To do this, we keep events disabled
112 # until weve done all processing. HOWEVER, we must enable events before
113 # popping the stack frame (cant be done atomically) and so it would still
114 # be possible to get enough handler activations to overflow the stack.
115 # Although unlikely, bugs of that kind are hard to track down, so wed
116 # like to avoid the possibility.
117 # So, on entry to the handler we detect whether we interrupted an
118 # existing activation in its critical region -- if so, we pop the current
119 # activation and restart the handler using the previous one.
120 ENTRY(hypervisor_callback)
121 pushl %eax
122 SAVE_ALL
123 movl EIP(%esp),%eax
124 cmpl $scrit,%eax
125 jb 11f
126 cmpl $ecrit,%eax
127 jb critical_region_fixup
128 11: push %esp
129 call do_hypervisor_callback
130 add $4,%esp
131 movl HYPERVISOR_shared_info,%esi
132 xorl %eax,%eax
133 movb CS(%esp),%cl
134 test $2,%cl # slow return to ring 2 or 3
135 jne safesti
136 safesti:movb $0,1(%esi) # reenable event callbacks
137 scrit: /**** START OF CRITICAL REGION ****/
138 testb $0xFF,(%esi)
139 jnz 14f # process more events if necessary...
140 RESTORE_ALL
141 14: movb $1,1(%esi)
142 jmp 11b
143 ecrit: /**** END OF CRITICAL REGION ****/
144 # [How we do the fixup]. We want to merge the current stack frame with the
145 # just-interrupted frame. How we do this depends on where in the critical
146 # region the interrupted handler was executing, and so how many saved
147 # registers are in each frame. We do this quickly using the lookup table
148 # 'critical_fixup_table'. For each byte offset in the critical region, it
149 # provides the number of bytes which have already been popped from the
150 # interrupted stack frame.
151 critical_region_fixup:
152 addl $critical_fixup_table-scrit,%eax
153 movzbl (%eax),%eax # %eax contains num bytes popped
154 mov %esp,%esi
155 add %eax,%esi # %esi points at end of src region
156 mov %esp,%edi
157 add $0x34,%edi # %edi points at end of dst region
158 mov %eax,%ecx
159 shr $2,%ecx # convert words to bytes
160 je 16f # skip loop if nothing to copy
161 15: subl $4,%esi # pre-decrementing copy loop
162 subl $4,%edi
163 movl (%esi),%eax
164 movl %eax,(%edi)
165 loop 15b
166 16: movl %edi,%esp # final %edi is top of merged stack
167 jmp 11b
169 critical_fixup_table:
170 .byte 0x00,0x00,0x00 # testb $0xff,(%esi)
171 .byte 0x00,0x00 # jne 14f
172 .byte 0x00 # pop %ebx
173 .byte 0x04 # pop %ecx
174 .byte 0x08 # pop %edx
175 .byte 0x0c # pop %esi
176 .byte 0x10 # pop %edi
177 .byte 0x14 # pop %ebp
178 .byte 0x18 # pop %eax
179 .byte 0x1c # pop %ds
180 .byte 0x20 # pop %es
181 .byte 0x24,0x24,0x24 # add $4,%esp
182 .byte 0x28 # iret
183 .byte 0x00,0x00,0x00,0x00 # movb $1,1(%esi)
184 .byte 0x00,0x00 # jmp 11b
186 # Hypervisor uses this for application faults while it executes.
187 ENTRY(failsafe_callback)
188 pop %ds
189 pop %es
190 pop %fs
191 pop %gs
192 iret
194 ENTRY(coprocessor_error)
195 pushl $0
196 pushl $do_coprocessor_error
197 jmp do_exception
199 ENTRY(simd_coprocessor_error)
200 pushl $0
201 pushl $do_simd_coprocessor_error
202 jmp do_exception
204 ENTRY(device_not_available)
205 iret
207 ENTRY(debug)
208 pushl $0
209 pushl $do_debug
210 jmp do_exception
212 ENTRY(int3)
213 pushl $0
214 pushl $do_int3
215 jmp do_exception
217 ENTRY(overflow)
218 pushl $0
219 pushl $do_overflow
220 jmp do_exception
222 ENTRY(bounds)
223 pushl $0
224 pushl $do_bounds
225 jmp do_exception
227 ENTRY(invalid_op)
228 pushl $0
229 pushl $do_invalid_op
230 jmp do_exception
233 ENTRY(coprocessor_segment_overrun)
234 pushl $0
235 pushl $do_coprocessor_segment_overrun
236 jmp do_exception
239 ENTRY(invalid_TSS)
240 pushl $do_invalid_TSS
241 jmp do_exception
244 ENTRY(segment_not_present)
245 pushl $do_segment_not_present
246 jmp do_exception
249 ENTRY(stack_segment)
250 pushl $do_stack_segment
251 jmp do_exception
254 ENTRY(general_protection)
255 pushl $do_general_protection
256 jmp do_exception
259 ENTRY(alignment_check)
260 pushl $do_alignment_check
261 jmp do_exception
264 ENTRY(page_fault)
265 pushl $do_page_fault
266 jmp do_exception
268 ENTRY(machine_check)
269 pushl $0
270 pushl $do_machine_check
271 jmp do_exception
274 ENTRY(spurious_interrupt_bug)
275 pushl $0
276 pushl $do_spurious_interrupt_bug
277 jmp do_exception
281 ENTRY(thread_starter)
282 popl %eax
283 popl %ebx
284 pushl %eax
285 call *%ebx
286 call exit_thread