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