|
|
1.1 root 1: /*
2: * linux/kernel/system_call.s
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
7: /*
8: * system_call.s contains the system-call low-level handling routines.
9: * This also contains the timer-interrupt handler, as some of the code is
10: * the same. The hd- and flopppy-interrupts are also here.
11: *
12: * NOTE: This code handles signal-recognition, which happens every time
13: * after a timer-interrupt and after each system call. Ordinary interrupts
14: * don't handle signal-recognition, as that would clutter them up totally
15: * unnecessarily.
16: *
17: * Stack layout in 'ret_from_system_call':
18: *
19: * 0(%esp) - %eax
20: * 4(%esp) - %ebx
21: * 8(%esp) - %ecx
22: * C(%esp) - %edx
23: * 10(%esp) - original %eax (-1 if not system call)
24: * 14(%esp) - %fs
25: * 18(%esp) - %es
26: * 1C(%esp) - %ds
27: * 20(%esp) - %eip
28: * 24(%esp) - %cs
29: * 28(%esp) - %eflags
30: * 2C(%esp) - %oldesp
31: * 30(%esp) - %oldss
32: */
33:
34: SIG_CHLD = 17
35:
36: EAX = 0x00
37: EBX = 0x04
38: ECX = 0x08
39: EDX = 0x0C
40: ORIG_EAX = 0x10
41: FS = 0x14
42: ES = 0x18
43: DS = 0x1C
44: EIP = 0x20
45: CS = 0x24
46: EFLAGS = 0x28
47: OLDESP = 0x2C
48: OLDSS = 0x30
49:
50: state = 0 # these are offsets into the task-struct.
51: counter = 4
52: priority = 8
53: signal = 12
54: sigaction = 16 # MUST be 16 (=len of sigaction)
55: blocked = (33*16)
56:
57: # offsets within sigaction
58: sa_handler = 0
59: sa_mask = 4
60: sa_flags = 8
61: sa_restorer = 12
62:
63: nr_system_calls = 82
64:
65: ENOSYS = 38
66:
67: /*
68: * Ok, I get parallel printer interrupts while using the floppy for some
69: * strange reason. Urgel. Now I just ignore them.
70: */
71: .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve
72: .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
73: .globl _device_not_available, _coprocessor_error
74:
75: .align 2
76: bad_sys_call:
77: pushl $-ENOSYS
78: jmp ret_from_sys_call
79: .align 2
80: reschedule:
81: pushl $ret_from_sys_call
82: jmp _schedule
83: .align 2
84: _system_call:
85: push %ds
86: push %es
87: push %fs
88: pushl %eax # save the orig_eax
89: pushl %edx
90: pushl %ecx # push %ebx,%ecx,%edx as parameters
91: pushl %ebx # to the system call
92: movl $0x10,%edx # set up ds,es to kernel space
93: mov %dx,%ds
94: mov %dx,%es
95: movl $0x17,%edx # fs points to local data space
96: mov %dx,%fs
97: cmpl _NR_syscalls,%eax
98: jae bad_sys_call
99: call _sys_call_table(,%eax,4)
100: pushl %eax
101: 2:
102: movl _current,%eax
103: cmpl $0,state(%eax) # state
104: jne reschedule
105: cmpl $0,counter(%eax) # counter
106: je reschedule
107: ret_from_sys_call:
108: movl _current,%eax
109: cmpl _task,%eax # task[0] cannot have signals
110: je 3f
111: cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
112: jne 3f
113: cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
114: jne 3f
115: movl signal(%eax),%ebx
116: movl blocked(%eax),%ecx
117: notl %ecx
118: andl %ebx,%ecx
119: bsfl %ecx,%ecx
120: je 3f
121: btrl %ecx,%ebx
122: movl %ebx,signal(%eax)
123: incl %ecx
124: pushl %ecx
125: call _do_signal
126: popl %ecx
127: testl %eax, %eax
128: jne 2b # see if we need to switch tasks, or do more signals
129: 3: popl %eax
130: popl %ebx
131: popl %ecx
132: popl %edx
133: addl $4, %esp # skip orig_eax
134: pop %fs
135: pop %es
136: pop %ds
137: iret
138:
139: .align 2
140: _coprocessor_error:
141: push %ds
142: push %es
143: push %fs
144: pushl $-1 # fill in -1 for orig_eax
145: pushl %edx
146: pushl %ecx
147: pushl %ebx
148: pushl %eax
149: movl $0x10,%eax
150: mov %ax,%ds
151: mov %ax,%es
152: movl $0x17,%eax
153: mov %ax,%fs
154: pushl $ret_from_sys_call
155: jmp _math_error
156:
157: .align 2
158: _device_not_available:
159: push %ds
160: push %es
161: push %fs
162: pushl $-1 # fill in -1 for orig_eax
163: pushl %edx
164: pushl %ecx
165: pushl %ebx
166: pushl %eax
167: movl $0x10,%eax
168: mov %ax,%ds
169: mov %ax,%es
170: movl $0x17,%eax
171: mov %ax,%fs
172: pushl $ret_from_sys_call
173: clts # clear TS so that we can use math
174: movl %cr0,%eax
175: testl $0x4,%eax # EM (math emulation bit)
176: je _math_state_restore
177: pushl %ebp
178: pushl %esi
179: pushl %edi
180: pushl $0 # temporary storage for ORIG_EIP
181: call _math_emulate
182: addl $4,%esp
183: popl %edi
184: popl %esi
185: popl %ebp
186: ret
187:
188: .align 2
189: _timer_interrupt:
190: push %ds # save ds,es and put kernel data space
191: push %es # into them. %fs is used by _system_call
192: push %fs
193: pushl $-1 # fill in -1 for orig_eax
194: pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
195: pushl %ecx # save those across function calls. %ebx
196: pushl %ebx # is saved as we use that in ret_sys_call
197: pushl %eax
198: movl $0x10,%eax
199: mov %ax,%ds
200: mov %ax,%es
201: movl $0x17,%eax
202: mov %ax,%fs
203: incl _jiffies
204: movb $0x20,%al # EOI to interrupt controller #1
205: outb %al,$0x20
206: movl CS(%esp),%eax
207: andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
208: pushl %eax
209: call _do_timer # 'do_timer(long CPL)' does everything from
210: addl $4,%esp # task switching to accounting ...
211: jmp ret_from_sys_call
212:
213: .align 2
214: _sys_execve:
215: lea EIP(%esp),%eax
216: pushl %eax
217: call _do_execve
218: addl $4,%esp
219: ret
220:
221: .align 2
222: _sys_fork:
223: call _find_empty_process
224: testl %eax,%eax
225: js 1f
226: push %gs
227: pushl %esi
228: pushl %edi
229: pushl %ebp
230: pushl %eax
231: call _copy_process
232: addl $20,%esp
233: 1: ret
234:
235: _hd_interrupt:
236: pushl %eax
237: pushl %ecx
238: pushl %edx
239: push %ds
240: push %es
241: push %fs
242: movl $0x10,%eax
243: mov %ax,%ds
244: mov %ax,%es
245: movl $0x17,%eax
246: mov %ax,%fs
247: movb $0x20,%al
248: outb %al,$0xA0 # EOI to interrupt controller #1
249: jmp 1f # give port chance to breathe
250: 1: jmp 1f
251: 1: xorl %edx,%edx
252: movl %edx,_hd_timeout
253: xchgl _do_hd,%edx
254: testl %edx,%edx
255: jne 1f
256: movl $_unexpected_hd_interrupt,%edx
257: 1: outb %al,$0x20
258: call *%edx # "interesting" way of handling intr.
259: pop %fs
260: pop %es
261: pop %ds
262: popl %edx
263: popl %ecx
264: popl %eax
265: iret
266:
267: _floppy_interrupt:
268: pushl %eax
269: pushl %ecx
270: pushl %edx
271: push %ds
272: push %es
273: push %fs
274: movl $0x10,%eax
275: mov %ax,%ds
276: mov %ax,%es
277: movl $0x17,%eax
278: mov %ax,%fs
279: movb $0x20,%al
280: outb %al,$0x20 # EOI to interrupt controller #1
281: xorl %eax,%eax
282: xchgl _do_floppy,%eax
283: testl %eax,%eax
284: jne 1f
285: movl $_unexpected_floppy_interrupt,%eax
286: 1: call *%eax # "interesting" way of handling intr.
287: pop %fs
288: pop %es
289: pop %ds
290: popl %edx
291: popl %ecx
292: popl %eax
293: iret
294:
295: _parallel_interrupt:
296: pushl %eax
297: movb $0x20,%al
298: outb %al,$0x20
299: popl %eax
300: iret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.