1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 SIG_CHLD = 17
41
42 EBX = 0x00
43 ECX = 0x04
44 EDX = 0x08
45 ESI = 0x0C
46 EDI = 0x10
47 EBP = 0x14
48 EAX = 0x18
49 DS = 0x1C
50 ES = 0x20
51 FS = 0x24
52 GS = 0x28
53 ORIG_EAX = 0x2C
54 EIP = 0x30
55 CS = 0x34
56 EFLAGS = 0x38
57 OLDESP = 0x3C
58 OLDSS = 0x40
59
60
61
62
63 state = 0
64 counter = 4
65 priority = 8
66 signal = 12
67 sigaction = 16 # MUST be 16 (=len of sigaction)
68 blocked = (33*16)
69
70
71
72
73 sa_handler = 0
74 sa_mask = 4
75 sa_flags = 8
76 sa_restorer = 12
77
78 ENOSYS = 38
79
80
81
82
83
84 .globl _system_call,_timer_interrupt,_sys_execve
85 .globl _device_not_available, _coprocessor_error
86 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
87 .globl _double_fault,_coprocessor_segment_overrun
88 .globl _invalid_TSS,_segment_not_present,_stack_segment
89 .globl _general_protection,_irq13,_reserved
90 .globl _alignment_check,_page_fault
91 .globl _keyboard_interrupt
92
93 #define SAVE_ALL \
94 cld; \
95 push %gs; \
96 push %fs; \
97 push %es; \
98 push %ds; \
99 pushl %eax; \
100 pushl %ebp; \
101 pushl %edi; \
102 pushl %esi; \
103 pushl %edx; \
104 pushl %ecx; \
105 pushl %ebx; \
106 movl $0x10,%edx; \
107 mov %dx,%ds; \
108 mov %dx,%es; \
109 movl $0x17,%edx; \
110 mov %dx,%fs
111
112 #define ACK_FIRST(mask) \
113 inb $0x21,%al; \
114 jmp 1f; \
115 1: jmp 1f; \
116 1: orb $(mask),%al; \
117 outb %al,$0x21; \
118 jmp 1f; \
119 1: jmp 1f; \
120 1: movb $0x20,%al; \
121 outb %al,$0x20
122
123 #define ACK_SECOND(mask) \
124 inb $0xA1,%al; \
125 jmp 1f; \
126 1: jmp 1f; \
127 1: orb $mask,%al; \
128 outb %al,$0xA1; \
129 jmp 1f; \
130 1: jmp 1f; \
131 1: movb $0x20,%al; \
132 outb %al,$0x20
133 jmp 1f; \
134 1: jmp 1f; \
135 1: outb %al,$0xA0
136
137 #define UNBLK_FIRST(mask) \
138 inb $0x21,%al; \
139 jmp 1f; \
140 1: jmp 1f; \
141 1: andb $~(mask),%al; \
142 outb %al,$0x21
143
144 #define UNBLK_SECOND(mask) \
145 inb $0xA1,%al; \
146 jmp 1f; \
147 1: jmp 1f; \
148 1: andb $~(mask),%al; \
149 outb %al,$0xA1
150
151 .align 2
152 bad_sys_call:
153 movl $-ENOSYS,EAX(%esp)
154 jmp ret_from_sys_call
155 .align 2
156 reschedule:
157 pushl $ret_from_sys_call
158 jmp _schedule
159 .align 2
160 _system_call:
161 pushl %eax # save orig_eax
162 SAVE_ALL
163 cmpl _NR_syscalls,%eax
164 jae bad_sys_call
165 call _sys_call_table(,%eax,4)
166 movl %eax,EAX(%esp) # save the return value
167 ret_from_sys_call:
168 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
169 jne 2f
170 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
171 jne 2f
172 1: movl _current,%eax
173 cmpl _task,%eax # task[0] cannot have signals
174 je 2f
175 cmpl $0,state(%eax) # state
176 jne reschedule
177 cmpl $0,counter(%eax) # counter
178 je reschedule
179 movl signal(%eax),%ebx
180 movl blocked(%eax),%ecx
181 notl %ecx
182 andl %ebx,%ecx
183 bsfl %ecx,%ecx
184 je 2f
185 btrl %ecx,%ebx
186 movl %ebx,signal(%eax)
187 incl %ecx
188 pushl %ecx
189 call _do_signal
190 popl %ecx
191 testl %eax, %eax
192 jne 1b # see if we need to switch tasks, or do more signals
193 2: popl %ebx
194 popl %ecx
195 popl %edx
196 popl %esi
197 popl %edi
198 popl %ebp
199 popl %eax
200 pop %ds
201 pop %es
202 pop %fs
203 pop %gs
204 addl $4,%esp # skip the orig_eax
205 iret
206
207 .align 2
208 _irq13:
209 pushl %eax
210 xorb %al,%al
211 outb %al,$0xF0
212 movb $0x20,%al
213 outb %al,$0x20
214 jmp 1f
215 1: jmp 1f
216 1: outb %al,$0xA0
217 popl %eax
218 _coprocessor_error:
219 pushl $-1 # mark this as an int.
220 SAVE_ALL
221 pushl $ret_from_sys_call
222 jmp _math_error
223
224 .align 2
225 _device_not_available:
226 pushl $-1 # mark this as an int
227 SAVE_ALL
228 pushl $ret_from_sys_call
229 clts # clear TS so that we can use math
230 movl %cr0,%eax
231 testl $0x4,%eax # EM (math emulation bit)
232 je _math_state_restore
233 pushl $0 # temporary storage for ORIG_EIP
234 call _math_emulate
235 addl $4,%esp
236 ret
237
238 .align 2
239 _keyboard_interrupt:
240 pushl $-1
241 SAVE_ALL
242 ACK_FIRST(2)
243 sti
244 call _do_keyboard
245 cli
246 UNBLK_FIRST(2)
247 jmp ret_from_sys_call
248
249 .align 2
250 _timer_interrupt:
251 pushl $-1 # mark this as an int
252 SAVE_ALL
253 incl _jiffies
254 movb $0x20,%al # EOI to interrupt controller #1
255 outb %al,$0x20
256 movl CS(%esp),%eax
257 andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
258 pushl %eax
259 call _do_timer # 'do_timer(long CPL)' does everything from
260 addl $4,%esp # task switching to accounting ...
261 jmp ret_from_sys_call
262
263 .align 2
264 _sys_execve:
265 lea (EIP+4)(%esp),%eax # don't forget about the return address.
266 pushl %eax
267 call _do_execve
268 addl $4,%esp
269 ret
270
271 _divide_error:
272 pushl $0 # no error code
273 pushl $_do_divide_error
274 error_code:
275 push %fs
276 push %es
277 push %ds
278 pushl %eax
279 pushl %ebp
280 pushl %edi
281 pushl %esi
282 pushl %edx
283 pushl %ecx
284 pushl %ebx
285 cld
286 movl $-1, %eax
287 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
288 xorl %ebx,%ebx # zero ebx
289 mov %gs,%bx # get the lower order bits of gs
290 xchgl %ebx, GS(%esp) # get the address and save gs.
291 pushl %eax # push the error code
292 lea 52(%esp),%edx
293 pushl %edx
294 movl $0x10,%edx
295 mov %dx,%ds
296 mov %dx,%es
297 movl $0x17,%edx
298 mov %dx,%fs
299 call *%ebx
300 addl $8,%esp
301 jmp ret_from_sys_call
302
303 _debug:
304 pushl $0
305 pushl $_do_int3 # _do_debug
306 jmp error_code
307
308 _nmi:
309 pushl $0
310 pushl $_do_nmi
311 jmp error_code
312
313 _int3:
314 pushl $0
315 pushl $_do_int3
316 jmp error_code
317
318 _overflow:
319 pushl $0
320 pushl $_do_overflow
321 jmp error_code
322
323 _bounds:
324 pushl $0
325 pushl $_do_bounds
326 jmp error_code
327
328 _invalid_op:
329 pushl $0
330 pushl $_do_invalid_op
331 jmp error_code
332
333 _coprocessor_segment_overrun:
334 pushl $0
335 pushl $_do_coprocessor_segment_overrun
336 jmp error_code
337
338 _reserved:
339 pushl $0
340 pushl $_do_reserved
341 jmp error_code
342
343 _double_fault:
344 pushl $_do_double_fault
345 jmp error_code
346
347 _invalid_TSS:
348 pushl $_do_invalid_TSS
349 jmp error_code
350
351 _segment_not_present:
352 pushl $_do_segment_not_present
353 jmp error_code
354
355 _stack_segment:
356 pushl $_do_stack_segment
357 jmp error_code
358
359 _general_protection:
360 pushl $_do_general_protection
361 jmp error_code
362
363 _alignment_check:
364 pushl $_do_alignment_check
365 jmp error_code
366
367 _page_fault:
368 pushl $_do_page_fault
369 jmp error_code