|
|
1.1 root 1: /*
2: * system_call.s contains the system-call low-level handling routines.
3: * This also contains the timer-interrupt handler, as some of the code is
4: * the same. The hd-interrupt is also here.
5: *
6: * NOTE: This code handles signal-recognition, which happens every time
7: * after a timer-interrupt and after each system call. Ordinary interrupts
8: * don't handle signal-recognition, as that would clutter them up totally
9: * unnecessarily.
10: *
11: * Stack layout in 'ret_from_system_call':
12: *
13: * 0(%esp) - %eax
14: * 4(%esp) - %ebx
15: * 8(%esp) - %ecx
16: * C(%esp) - %edx
17: * 10(%esp) - %fs
18: * 14(%esp) - %es
19: * 18(%esp) - %ds
20: * 1C(%esp) - %eip
21: * 20(%esp) - %cs
22: * 24(%esp) - %eflags
23: * 28(%esp) - %oldesp
24: * 2C(%esp) - %oldss
25: */
26:
27: SIG_CHLD = 17
28: EAX = 0x00
29: EBX = 0x04
30: ECX = 0x08
31: EDX = 0x0C
32: FS = 0x10
33: ES = 0x14
34: DS = 0x18
35: EIP = 0x1C
36: CS = 0x20
37: EFLAGS = 0x24
38: OLDESP = 0x28
39: OLDSS = 0x2C
40:
41: state = 0 # these are offsets into the task-struct.
42: counter = 4
43: priority = 8
44: signal = 12
45: restorer = 16 # address of info-restorer
46: sig_fn = 20 # table of 32 signal addresses
47:
48: nr_system_calls = 67
49:
50: .globl _system_call,_sys_fork,_timer_interrupt,_hd_interrupt,_sys_execve
51:
52: .align 2
53: bad_sys_call:
54: movl $-1,%eax
55: iret
56: .align 2
57: reschedule:
58: pushl $ret_from_sys_call
59: jmp _schedule
60: .align 2
61: _system_call:
62: cmpl $nr_system_calls-1,%eax
63: ja bad_sys_call
64: push %ds
65: push %es
66: push %fs
67: pushl %edx
68: pushl %ecx # push %ebx,%ecx,%edx as parameters
69: pushl %ebx # to the system call
70: movl $0x10,%edx # set up ds,es to kernel space
71: mov %dx,%ds
72: mov %dx,%es
73: movl $0x17,%edx # fs points to local data space
74: mov %dx,%fs
75: call _sys_call_table(,%eax,4)
76: pushl %eax
77: movl _current,%eax
78: cmpl $0,state(%eax) # state
79: jne reschedule
80: cmpl $0,counter(%eax) # counter
81: je reschedule
82: ret_from_sys_call:
83: movl _current,%eax # task[0] cannot have signals
84: cmpl _task,%eax
85: je 3f
86: movl CS(%esp),%ebx # was old code segment supervisor
87: testl $3,%ebx # mode? If so - don't check signals
88: je 3f
89: cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
90: jne 3f
91: 2: movl signal(%eax),%ebx # signals (bitmap, 32 signals)
92: bsfl %ebx,%ecx # %ecx is signal nr, return if none
93: je 3f
94: btrl %ecx,%ebx # clear it
95: movl %ebx,signal(%eax)
96: movl sig_fn(%eax,%ecx,4),%ebx # %ebx is signal handler address
97: cmpl $1,%ebx
98: jb default_signal # 0 is default signal handler - exit
99: je 2b # 1 is ignore - find next signal
100: movl $0,sig_fn(%eax,%ecx,4) # reset signal handler address
101: incl %ecx
102: xchgl %ebx,EIP(%esp) # put new return address on stack
103: subl $28,OLDESP(%esp)
104: movl OLDESP(%esp),%edx # push old return address on stack
105: pushl %eax # but first check that it's ok.
106: pushl %ecx
107: pushl $28
108: pushl %edx
109: call _verify_area
110: popl %edx
111: addl $4,%esp
112: popl %ecx
113: popl %eax
114: movl restorer(%eax),%eax
115: movl %eax,%fs:(%edx) # flag/reg restorer
116: movl %ecx,%fs:4(%edx) # signal nr
117: movl EAX(%esp),%eax
118: movl %eax,%fs:8(%edx) # old eax
119: movl ECX(%esp),%eax
120: movl %eax,%fs:12(%edx) # old ecx
121: movl EDX(%esp),%eax
122: movl %eax,%fs:16(%edx) # old edx
123: movl EFLAGS(%esp),%eax
124: movl %eax,%fs:20(%edx) # old eflags
125: movl %ebx,%fs:24(%edx) # old return addr
126: 3: popl %eax
127: popl %ebx
128: popl %ecx
129: popl %edx
130: pop %fs
131: pop %es
132: pop %ds
133: iret
134:
135: default_signal:
136: incl %ecx
137: cmpl $SIG_CHLD,%ecx
138: je 2b
139: pushl %ecx
140: call _do_exit # remember to set bit 7 when dumping core
141: addl $4,%esp
142: jmp 3b
143:
144: .align 2
145: _timer_interrupt:
146: push %ds # save ds,es and put kernel data space
147: push %es # into them. %fs is used by _system_call
148: push %fs
149: pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
150: pushl %ecx # save those across function calls. %ebx
151: pushl %ebx # is saved as we use that in ret_sys_call
152: pushl %eax
153: movl $0x10,%eax
154: mov %ax,%ds
155: mov %ax,%es
156: movl $0x17,%eax
157: mov %ax,%fs
158: incl _jiffies
159: movb $0x20,%al # EOI to interrupt controller #1
160: outb %al,$0x20
161: movl CS(%esp),%eax
162: andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
163: pushl %eax
164: call _do_timer # 'do_timer(long CPL)' does everything from
165: addl $4,%esp # task switching to accounting ...
166: jmp ret_from_sys_call
167:
168: .align 2
169: _sys_execve:
170: lea EIP(%esp),%eax
171: pushl %eax
172: call _do_execve
173: addl $4,%esp
174: ret
175:
176: .align 2
177: _sys_fork:
178: call _find_empty_process
179: testl %eax,%eax
180: js 1f
181: push %gs
182: pushl %esi
183: pushl %edi
184: pushl %ebp
185: pushl %eax
186: call _copy_process
187: addl $20,%esp
188: 1: ret
189:
190: _hd_interrupt:
191: pushl %eax
192: pushl %ecx
193: pushl %edx
194: push %ds
195: push %es
196: push %fs
197: movl $0x10,%eax
198: mov %ax,%ds
199: mov %ax,%es
200: movl $0x17,%eax
201: mov %ax,%fs
202: movb $0x20,%al
203: outb %al,$0x20 # EOI to interrupt controller #1
204: jmp 1f # give port chance to breathe
205: 1: jmp 1f
206: 1: outb %al,$0xA0 # same to controller #2
207: movl _do_hd,%eax
208: testl %eax,%eax
209: jne 1f
210: movl $_unexpected_hd_interrupt,%eax
211: 1: call *%eax # "interesting" way of handling intr.
212: pop %fs
213: pop %es
214: pop %ds
215: popl %edx
216: popl %ecx
217: popl %eax
218: iret
219:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.