summaryrefslogtreecommitdiffstats
path: root/src/kernel/system_call.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/system_call.s')
-rw-r--r--src/kernel/system_call.s285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/kernel/system_call.s b/src/kernel/system_call.s
new file mode 100644
index 0000000..c602cd8
--- /dev/null
+++ b/src/kernel/system_call.s
@@ -0,0 +1,285 @@
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) - %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
33SIG_CHLD = 17
34
35EAX = 0x00
36EBX = 0x04
37ECX = 0x08
38EDX = 0x0C
39FS = 0x10
40ES = 0x14
41DS = 0x18
42EIP = 0x1C
43CS = 0x20
44EFLAGS = 0x24
45OLDESP = 0x28
46OLDSS = 0x2C
47
48state = 0 # these are offsets into the task-struct.
49counter = 4
50priority = 8
51signal = 12
52sigaction = 16 # MUST be 16 (=len of sigaction)
53blocked = (33*16)
54
55# offsets within sigaction
56sa_handler = 0
57sa_mask = 4
58sa_flags = 8
59sa_restorer = 12
60
61nr_system_calls = 72
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
69.globl device_not_available, coprocessor_error
70
71.align 2
72bad_sys_call:
73 movl $-1,%eax
74 iret
75.align 2
76reschedule:
77 pushl $ret_from_sys_call
78 jmp schedule
79.align 2
80system_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
101ret_from_sys_call:
102 movl current,%eax # task[0] cannot have signals
103 cmpl task,%eax
104 je 3f
105 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
106 jne 3f
107 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
108 jne 3f
109 movl signal(%eax),%ebx
110 movl blocked(%eax),%ecx
111 notl %ecx
112 andl %ebx,%ecx
113 bsfl %ecx,%ecx
114 je 3f
115 btrl %ecx,%ebx
116 movl %ebx,signal(%eax)
117 incl %ecx
118 pushl %ecx
119 call do_signal
120 popl %eax
1213: 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
131coprocessor_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
148device_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
176timer_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
200sys_execve:
201 lea EIP(%esp),%eax
202 pushl %eax
203 call do_execve
204 addl $4,%esp
205 ret
206
207.align 2
208sys_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
2191: ret
220
221hd_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
231 movl $0x17,%eax
232 mov %ax,%fs
233 movb $0x20,%al
234 outb %al,$0xA0 # EOI to interrupt controller #1
235 jmp 1f # give port chance to breathe
2361: jmp 1f
2371: xorl %edx,%edx
238 xchgl do_hd,%edx
239 testl %edx,%edx
240 jne 1f
241 movl $unexpected_hd_interrupt,%edx
2421: outb %al,$0x20
243 call *%edx # "interesting" way of handling intr.
244 pop %fs
245 pop %es
246 pop %ds
247 popl %edx
248 popl %ecx
249 popl %eax
250 iret
251
252floppy_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
262 movl $0x17,%eax
263 mov %ax,%fs
264 movb $0x20,%al
265 outb %al,$0x20 # EOI to interrupt controller #1
266 xorl %eax,%eax
267 xchgl do_floppy,%eax
268 testl %eax,%eax
269 jne 1f
270 movl $unexpected_floppy_interrupt,%eax
2711: 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
280parallel_interrupt:
281 pushl %eax
282 movb $0x20,%al
283 outb %al,$0x20
284 popl %eax
285 iret