diff options
Diffstat (limited to 'src/kernel/system_call.s')
-rw-r--r-- | src/kernel/system_call.s | 285 |
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 | |||
33 | SIG_CHLD = 17 | ||
34 | |||
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 | ||
52 | sigaction = 16 # MUST be 16 (=len of sigaction) | ||
53 | blocked = (33*16) | ||
54 | |||
55 | # offsets within sigaction | ||
56 | sa_handler = 0 | ||
57 | sa_mask = 4 | ||
58 | sa_flags = 8 | ||
59 | sa_restorer = 12 | ||
60 | |||
61 | nr_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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
236 | 1: jmp 1f | ||
237 | 1: xorl %edx,%edx | ||
238 | xchgl do_hd,%edx | ||
239 | testl %edx,%edx | ||
240 | jne 1f | ||
241 | movl $unexpected_hd_interrupt,%edx | ||
242 | 1: 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 | |||
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 | ||
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 | ||
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 | ||