ia64/xen-unstable

view extras/mini-os/entry.S @ 2743:df9ad701dbce

bitkeeper revision 1.1159.1.282 (417e5b60oXUOPTWl81d5zD6oq1tOTQ)

Clean up docs dir layout.
author kaf24@freefall.cl.cam.ac.uk
date Tue Oct 26 14:12:48 2004 +0000 (2004-10-26)
parents 71f9c171157e
children
line source
2 #include <os.h>
4 ES = 0x20
5 ORIG_EAX = 0x24
6 EIP = 0x28
7 CS = 0x2C
9 #define ENTRY(X) .globl X ; X :
11 #define SAVE_ALL \
12 cld; \
13 pushl %es; \
14 pushl %ds; \
15 pushl %eax; \
16 pushl %ebp; \
17 pushl %edi; \
18 pushl %esi; \
19 pushl %edx; \
20 pushl %ecx; \
21 pushl %ebx; \
22 movl $(__KERNEL_DS),%edx; \
23 movl %edx,%ds; \
24 movl %edx,%es;
26 #define RESTORE_ALL \
27 popl %ebx; \
28 popl %ecx; \
29 popl %edx; \
30 popl %esi; \
31 popl %edi; \
32 popl %ebp; \
33 popl %eax; \
34 popl %ds; \
35 popl %es; \
36 addl $4,%esp; \
37 iret; \
39 ENTRY(divide_error)
40 pushl $0 # no error code
41 pushl $do_divide_error
42 do_exception:
43 pushl %ds
44 pushl %eax
45 xorl %eax,%eax
46 pushl %ebp
47 pushl %edi
48 pushl %esi
49 pushl %edx
50 decl %eax # eax = -1
51 pushl %ecx
52 pushl %ebx
53 cld
54 movl %es,%ecx
55 movl ORIG_EAX(%esp), %esi # get the error code
56 movl ES(%esp), %edi # get the function address
57 movl %eax, ORIG_EAX(%esp)
58 movl %ecx, ES(%esp)
59 movl %esp,%edx
60 pushl %esi # push the error code
61 pushl %edx # push the pt_regs pointer
62 movl $(__KERNEL_DS),%edx
63 movl %edx,%ds
64 movl %edx,%es
65 call *%edi
66 addl $8,%esp
69 ret_from_exception:
70 movb CS(%esp),%cl
71 test $2,%cl # slow return to ring 2 or 3
72 jne safesti
73 RESTORE_ALL
75 # A note on the "critical region" in our callback handler.
76 # We want to avoid stacking callback handlers due to events occurring
77 # during handling of the last event. To do this, we keep events disabled
78 # until weve done all processing. HOWEVER, we must enable events before
79 # popping the stack frame (cant be done atomically) and so it would still
80 # be possible to get enough handler activations to overflow the stack.
81 # Although unlikely, bugs of that kind are hard to track down, so wed
82 # like to avoid the possibility.
83 # So, on entry to the handler we detect whether we interrupted an
84 # existing activation in its critical region -- if so, we pop the current
85 # activation and restart the handler using the previous one.
86 ENTRY(hypervisor_callback)
87 pushl %eax
88 SAVE_ALL
89 movl EIP(%esp),%eax
90 cmpl $scrit,%eax
91 jb 11f
92 cmpl $ecrit,%eax
93 jb critical_region_fixup
94 11: push %esp
95 call do_hypervisor_callback
96 add $4,%esp
97 movl HYPERVISOR_shared_info,%esi
98 xorl %eax,%eax
99 movb CS(%esp),%cl
100 test $2,%cl # slow return to ring 2 or 3
101 jne safesti
102 safesti:btsl $31,4(%esi) # reenable event callbacks
103 scrit: /**** START OF CRITICAL REGION ****/
104 cmpl %eax,(%esi)
105 jne 14f # process more events if necessary...
106 RESTORE_ALL
107 14: btrl %eax,4(%esi)
108 jmp 11b
109 ecrit: /**** END OF CRITICAL REGION ****/
110 # [How we do the fixup]. We want to merge the current stack frame with the
111 # just-interrupted frame. How we do this depends on where in the critical
112 # region the interrupted handler was executing, and so how many saved
113 # registers are in each frame. We do this quickly using the lookup table
114 # 'critical_fixup_table'. For each byte offset in the critical region, it
115 # provides the number of bytes which have already been popped from the
116 # interrupted stack frame.
117 critical_region_fixup:
118 addl $critical_fixup_table-scrit,%eax
119 movzbl (%eax),%eax # %eax contains num bytes popped
120 mov %esp,%esi
121 add %eax,%esi # %esi points at end of src region
122 mov %esp,%edi
123 add $0x34,%edi # %edi points at end of dst region
124 mov %eax,%ecx
125 shr $2,%ecx # convert words to bytes
126 je 16f # skip loop if nothing to copy
127 15: subl $4,%esi # pre-decrementing copy loop
128 subl $4,%edi
129 movl (%esi),%eax
130 movl %eax,(%edi)
131 loop 15b
132 16: movl %edi,%esp # final %edi is top of merged stack
133 jmp 11b
135 critical_fixup_table:
136 .byte 0x00,0x00 # cmpl %eax,(%esi)
137 .byte 0x00,0x00 # jne 14f
138 .byte 0x00 # pop %ebx
139 .byte 0x04 # pop %ecx
140 .byte 0x08 # pop %edx
141 .byte 0x0c # pop %esi
142 .byte 0x10 # pop %edi
143 .byte 0x14 # pop %ebp
144 .byte 0x18 # pop %eax
145 .byte 0x1c # pop %ds
146 .byte 0x20 # pop %es
147 .byte 0x24,0x24,0x24 # add $4,%esp
148 .byte 0x28 # iret
149 .byte 0x00,0x00,0x00,0x00,0x00 # btrl $31,4(%esi)
150 .byte 0x00,0x00 # jmp 11b
152 # Hypervisor uses this for application faults while it executes.
153 ENTRY(failsafe_callback)
154 pop %ds
155 pop %es
156 pop %fs
157 pop %gs
158 iret
160 ENTRY(coprocessor_error)
161 pushl $0
162 pushl $do_coprocessor_error
163 jmp do_exception
165 ENTRY(simd_coprocessor_error)
166 pushl $0
167 pushl $do_simd_coprocessor_error
168 jmp do_exception
170 ENTRY(device_not_available)
171 iret
173 ENTRY(debug)
174 pushl $0
175 pushl $do_debug
176 jmp do_exception
178 ENTRY(int3)
179 pushl $0
180 pushl $do_int3
181 jmp do_exception
183 ENTRY(overflow)
184 pushl $0
185 pushl $do_overflow
186 jmp do_exception
188 ENTRY(bounds)
189 pushl $0
190 pushl $do_bounds
191 jmp do_exception
193 ENTRY(invalid_op)
194 pushl $0
195 pushl $do_invalid_op
196 jmp do_exception
198 ENTRY(coprocessor_segment_overrun)
199 pushl $0
200 pushl $do_coprocessor_segment_overrun
201 jmp do_exception
203 ENTRY(double_fault)
204 pushl $do_double_fault
205 jmp do_exception
207 ENTRY(invalid_TSS)
208 pushl $do_invalid_TSS
209 jmp do_exception
211 ENTRY(segment_not_present)
212 pushl $do_segment_not_present
213 jmp do_exception
215 ENTRY(stack_segment)
216 pushl $do_stack_segment
217 jmp do_exception
219 ENTRY(general_protection)
220 pushl $do_general_protection
221 jmp do_exception
223 ENTRY(alignment_check)
224 pushl $do_alignment_check
225 jmp do_exception
227 # This handler is special, because it gets an extra value on its stack,
228 # which is the linear faulting address.
229 ENTRY(page_fault)
230 pushl %ds
231 pushl %eax
232 xorl %eax,%eax
233 pushl %ebp
234 pushl %edi
235 pushl %esi
236 pushl %edx
237 decl %eax # eax = -1
238 pushl %ecx
239 pushl %ebx
240 cld
241 movl %es,%ecx
242 movl ORIG_EAX(%esp), %esi # get the error code
243 movl ES(%esp), %edi # get the faulting address
244 movl %eax, ORIG_EAX(%esp)
245 movl %ecx, ES(%esp)
246 movl %esp,%edx
247 pushl %edi # push the faulting address
248 pushl %esi # push the error code
249 pushl %edx # push the pt_regs pointer
250 movl $(__KERNEL_DS),%edx
251 movl %edx,%ds
252 movl %edx,%es
253 call do_page_fault
254 addl $12,%esp
255 jmp ret_from_exception
257 ENTRY(machine_check)
258 pushl $0
259 pushl $do_machine_check
260 jmp do_exception
262 ENTRY(spurious_interrupt_bug)
263 pushl $0
264 pushl $do_spurious_interrupt_bug
265 jmp do_exception