|
|
1.1 root 1: /*
2: * linux/kernel/sys_call.S
3: *
1.1.1.4 ! root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1 root 5: */
6:
7: /*
8: * sys_call.S contains the system-call and fault low-level handling routines.
9: * This also contains the timer-interrupt handler, as well as all interrupts
10: * and faults that can result in a task-switch.
11: *
12: * NOTE: This code handles signal-recognition, which happens every time
13: * after a timer-interrupt and after each system call.
14: *
15: * Stack layout in 'ret_from_system_call':
16: * ptrace needs to have all regs on the stack.
17: * if the order here is changed, it needs to be
18: * updated in fork.c:copy_process, signal.c:do_signal,
19: * ptrace.c and ptrace.h
20: *
21: * 0(%esp) - %ebx
22: * 4(%esp) - %ecx
23: * 8(%esp) - %edx
24: * C(%esp) - %esi
25: * 10(%esp) - %edi
26: * 14(%esp) - %ebp
27: * 18(%esp) - %eax
28: * 1C(%esp) - %ds
29: * 20(%esp) - %es
30: * 24(%esp) - %fs
31: * 28(%esp) - %gs
32: * 2C(%esp) - orig_eax
33: * 30(%esp) - %eip
34: * 34(%esp) - %cs
35: * 38(%esp) - %eflags
36: * 3C(%esp) - %oldesp
37: * 40(%esp) - %oldss
38: */
39:
40: EBX = 0x00
41: ECX = 0x04
42: EDX = 0x08
43: ESI = 0x0C
44: EDI = 0x10
45: EBP = 0x14
46: EAX = 0x18
47: DS = 0x1C
48: ES = 0x20
49: FS = 0x24
50: GS = 0x28
51: ORIG_EAX = 0x2C
52: EIP = 0x30
53: CS = 0x34
54: EFLAGS = 0x38
55: OLDESP = 0x3C
56: OLDSS = 0x40
57:
58: /*
59: * these are offsets into the task-struct.
60: */
61: state = 0
62: counter = 4
63: priority = 8
64: signal = 12
65: sigaction = 16 # MUST be 16 (=len of sigaction)
66: blocked = (33*16)
67:
68: /*
69: * offsets within sigaction
70: */
71: sa_handler = 0
72: sa_mask = 4
73: sa_flags = 8
74: sa_restorer = 12
75:
76: ENOSYS = 38
77:
78: /*
79: * Ok, I get parallel printer interrupts while using the floppy for some
80: * strange reason. Urgel. Now I just ignore them.
81: */
1.1.1.4 ! root 82: .globl _system_call,_sys_execve
1.1 root 83: .globl _device_not_available, _coprocessor_error
84: .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
85: .globl _double_fault,_coprocessor_segment_overrun
86: .globl _invalid_TSS,_segment_not_present,_stack_segment
1.1.1.4 ! root 87: .globl _general_protection,_reserved
1.1 root 88: .globl _alignment_check,_page_fault
1.1.1.4 ! root 89: .globl ret_from_sys_call
1.1 root 90:
91: #define SAVE_ALL \
92: cld; \
93: push %gs; \
94: push %fs; \
95: push %es; \
96: push %ds; \
97: pushl %eax; \
98: pushl %ebp; \
99: pushl %edi; \
100: pushl %esi; \
101: pushl %edx; \
102: pushl %ecx; \
103: pushl %ebx; \
104: movl $0x10,%edx; \
105: mov %dx,%ds; \
106: mov %dx,%es; \
107: movl $0x17,%edx; \
108: mov %dx,%fs
109:
110: .align 2
111: reschedule:
112: pushl $ret_from_sys_call
113: jmp _schedule
114: .align 2
115: _system_call:
1.1.1.4 ! root 116: pushl %eax # save orig_eax
1.1 root 117: SAVE_ALL
1.1.1.4 ! root 118: movl $-ENOSYS,EAX(%esp)
1.1 root 119: cmpl _NR_syscalls,%eax
1.1.1.4 ! root 120: jae ret_from_sys_call
1.1 root 121: call _sys_call_table(,%eax,4)
122: movl %eax,EAX(%esp) # save the return value
123: ret_from_sys_call:
124: cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
125: jne 2f
126: cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
127: jne 2f
1.1.1.4 ! root 128: 1: cmpl $0,_need_resched
1.1 root 129: jne reschedule
1.1.1.4 ! root 130: movl _current,%eax
1.1 root 131: cmpl $0,state(%eax) # state
132: jne reschedule
133: cmpl $0,counter(%eax) # counter
134: je reschedule
1.1.1.4 ! root 135: movl $1,_need_resched
! 136: cmpl _task,%eax # task[0] cannot have signals
! 137: je 2f
! 138: movl $0,_need_resched
1.1 root 139: movl signal(%eax),%ebx
140: movl blocked(%eax),%ecx
141: notl %ecx
142: andl %ebx,%ecx
143: bsfl %ecx,%ecx
144: je 2f
145: btrl %ecx,%ebx
146: movl %ebx,signal(%eax)
1.1.1.2 root 147: movl %esp,%ebx
148: pushl %ebx
1.1 root 149: incl %ecx
150: pushl %ecx
151: call _do_signal
152: popl %ecx
1.1.1.2 root 153: popl %ebx
1.1 root 154: testl %eax, %eax
155: jne 1b # see if we need to switch tasks, or do more signals
156: 2: popl %ebx
157: popl %ecx
158: popl %edx
159: popl %esi
160: popl %edi
161: popl %ebp
162: popl %eax
163: pop %ds
164: pop %es
165: pop %fs
166: pop %gs
167: addl $4,%esp # skip the orig_eax
168: iret
169:
170: .align 2
171: _sys_execve:
172: lea (EIP+4)(%esp),%eax # don't forget about the return address.
173: pushl %eax
174: call _do_execve
175: addl $4,%esp
176: ret
177:
178: _divide_error:
179: pushl $0 # no error code
180: pushl $_do_divide_error
181: error_code:
182: push %fs
183: push %es
184: push %ds
185: pushl %eax
186: pushl %ebp
187: pushl %edi
188: pushl %esi
189: pushl %edx
190: pushl %ecx
191: pushl %ebx
192: cld
193: movl $-1, %eax
194: xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
195: xorl %ebx,%ebx # zero ebx
196: mov %gs,%bx # get the lower order bits of gs
197: xchgl %ebx, GS(%esp) # get the address and save gs.
198: pushl %eax # push the error code
199: lea 52(%esp),%edx
200: pushl %edx
201: movl $0x10,%edx
202: mov %dx,%ds
203: mov %dx,%es
204: movl $0x17,%edx
205: mov %dx,%fs
206: call *%ebx
207: addl $8,%esp
208: jmp ret_from_sys_call
209:
1.1.1.4 ! root 210: .align 2
! 211: _coprocessor_error:
! 212: pushl $0
! 213: pushl $_do_coprocessor_error
! 214: jmp error_code
! 215:
! 216: .align 2
! 217: _device_not_available:
! 218: pushl $-1 # mark this as an int
! 219: SAVE_ALL
! 220: pushl $ret_from_sys_call
! 221: clts # clear TS so that we can use math
! 222: movl %cr0,%eax
! 223: testl $0x4,%eax # EM (math emulation bit)
! 224: je _math_state_restore
! 225: pushl $0 # temporary storage for ORIG_EIP
! 226: call _math_emulate
! 227: addl $4,%esp
! 228: ret
! 229:
1.1 root 230: _debug:
231: pushl $0
1.1.1.4 ! root 232: pushl $_do_debug
1.1 root 233: jmp error_code
234:
235: _nmi:
236: pushl $0
237: pushl $_do_nmi
238: jmp error_code
239:
240: _int3:
241: pushl $0
242: pushl $_do_int3
243: jmp error_code
244:
245: _overflow:
246: pushl $0
247: pushl $_do_overflow
248: jmp error_code
249:
250: _bounds:
251: pushl $0
252: pushl $_do_bounds
253: jmp error_code
254:
255: _invalid_op:
256: pushl $0
257: pushl $_do_invalid_op
258: jmp error_code
259:
260: _coprocessor_segment_overrun:
261: pushl $0
262: pushl $_do_coprocessor_segment_overrun
263: jmp error_code
264:
265: _reserved:
266: pushl $0
267: pushl $_do_reserved
268: jmp error_code
269:
270: _double_fault:
271: pushl $_do_double_fault
272: jmp error_code
273:
274: _invalid_TSS:
275: pushl $_do_invalid_TSS
276: jmp error_code
277:
278: _segment_not_present:
279: pushl $_do_segment_not_present
280: jmp error_code
281:
282: _stack_segment:
283: pushl $_do_stack_segment
284: jmp error_code
285:
286: _general_protection:
287: pushl $_do_general_protection
288: jmp error_code
289:
290: _alignment_check:
291: pushl $_do_alignment_check
292: jmp error_code
293:
294: _page_fault:
295: pushl $_do_page_fault
296: jmp error_code
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.