parent
782068f068
commit
e9db2b4fab
@ -1,294 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/kernel/system_call.s
|
|
||||||
*
|
|
||||||
* (C) 1991 Linus Torvalds
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* system_call.s contains the system-call low-level handling routines.
|
|
||||||
* This also contains the timer-interrupt handler, as some of the code is
|
|
||||||
* the same. The hd- and flopppy-interrupts are also here.
|
|
||||||
*
|
|
||||||
* NOTE: This code handles signal-recognition, which happens every time
|
|
||||||
* after a timer-interrupt and after each system call. Ordinary interrupts
|
|
||||||
* don't handle signal-recognition, as that would clutter them up totally
|
|
||||||
* unnecessarily.
|
|
||||||
*
|
|
||||||
* Stack layout in 'ret_from_system_call':
|
|
||||||
*
|
|
||||||
* 0(%esp) - %eax
|
|
||||||
* 4(%esp) - %ebx
|
|
||||||
* 8(%esp) - %ecx
|
|
||||||
* C(%esp) - %edx
|
|
||||||
* 10(%esp) - %fs
|
|
||||||
* 14(%esp) - %es
|
|
||||||
* 18(%esp) - %ds
|
|
||||||
* 1C(%esp) - %eip
|
|
||||||
* 20(%esp) - %cs
|
|
||||||
* 24(%esp) - %eflags
|
|
||||||
* 28(%esp) - %oldesp
|
|
||||||
* 2C(%esp) - %oldss
|
|
||||||
*/
|
|
||||||
|
|
||||||
SIG_CHLD = 17
|
|
||||||
|
|
||||||
EAX = 0x00
|
|
||||||
EBX = 0x04
|
|
||||||
ECX = 0x08
|
|
||||||
EDX = 0x0C
|
|
||||||
FS = 0x10
|
|
||||||
ES = 0x14
|
|
||||||
DS = 0x18
|
|
||||||
EIP = 0x1C
|
|
||||||
CS = 0x20
|
|
||||||
EFLAGS = 0x24
|
|
||||||
OLDESP = 0x28
|
|
||||||
OLDSS = 0x2C
|
|
||||||
|
|
||||||
state = 0 # these are offsets into the task-struct.
|
|
||||||
counter = 4
|
|
||||||
priority = 8
|
|
||||||
signal = 12
|
|
||||||
sigaction = 16 # MUST be 16 (=len of sigaction)
|
|
||||||
blocked = (33*16)
|
|
||||||
|
|
||||||
# offsets within sigaction
|
|
||||||
sa_handler = 0
|
|
||||||
sa_mask = 4
|
|
||||||
sa_flags = 8
|
|
||||||
sa_restorer = 12
|
|
||||||
|
|
||||||
nr_system_calls = 90 /* 72 86->90 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ok, I get parallel printer interrupts while using the floppy for some
|
|
||||||
* strange reason. Urgel. Now I just ignore them.
|
|
||||||
*/
|
|
||||||
.globl system_call,sys_fork,timer_interrupt,sys_execve
|
|
||||||
.globl hd_interrupt,floppy_interrupt,parallel_interrupt
|
|
||||||
.globl device_not_available, coprocessor_error
|
|
||||||
.globl sys_execve2
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
bad_sys_call:
|
|
||||||
movl $-1,%eax
|
|
||||||
iret
|
|
||||||
.align 4
|
|
||||||
reschedule:
|
|
||||||
pushl $ret_from_sys_call
|
|
||||||
jmp schedule
|
|
||||||
.align 4
|
|
||||||
system_call:
|
|
||||||
cmpl $nr_system_calls-1,%eax
|
|
||||||
ja bad_sys_call
|
|
||||||
push %ds
|
|
||||||
push %es
|
|
||||||
push %fs
|
|
||||||
pushl %edx
|
|
||||||
pushl %ecx # push %ebx,%ecx,%edx as parameters
|
|
||||||
pushl %ebx # to the system call
|
|
||||||
movl $0x10,%edx # set up ds,es to kernel space
|
|
||||||
mov %dx,%ds
|
|
||||||
mov %dx,%es
|
|
||||||
movl $0x17,%edx # fs points to local data space
|
|
||||||
mov %dx,%fs
|
|
||||||
call sys_call_table(,%eax,4)
|
|
||||||
pushl %eax
|
|
||||||
movl current,%eax
|
|
||||||
cmpl $0,state(%eax) # state
|
|
||||||
jne reschedule
|
|
||||||
cmpl $0,counter(%eax) # counter
|
|
||||||
je reschedule
|
|
||||||
ret_from_sys_call:
|
|
||||||
movl current,%eax # task[0] cannot have signals
|
|
||||||
cmpl task,%eax
|
|
||||||
je 3f
|
|
||||||
cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
|
|
||||||
jne 3f
|
|
||||||
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
|
|
||||||
jne 3f
|
|
||||||
movl signal(%eax),%ebx
|
|
||||||
movl blocked(%eax),%ecx
|
|
||||||
notl %ecx
|
|
||||||
andl %ebx,%ecx
|
|
||||||
bsfl %ecx,%ecx
|
|
||||||
je 3f
|
|
||||||
btrl %ecx,%ebx
|
|
||||||
movl %ebx,signal(%eax)
|
|
||||||
incl %ecx
|
|
||||||
pushl %ecx
|
|
||||||
call do_signal
|
|
||||||
popl %eax
|
|
||||||
3: popl %eax
|
|
||||||
popl %ebx
|
|
||||||
popl %ecx
|
|
||||||
popl %edx
|
|
||||||
pop %fs
|
|
||||||
pop %es
|
|
||||||
pop %ds
|
|
||||||
iret
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
coprocessor_error:
|
|
||||||
push %ds
|
|
||||||
push %es
|
|
||||||
push %fs
|
|
||||||
pushl %edx
|
|
||||||
pushl %ecx
|
|
||||||
pushl %ebx
|
|
||||||
pushl %eax
|
|
||||||
movl $0x10,%eax
|
|
||||||
mov %ax,%ds
|
|
||||||
mov %ax,%es
|
|
||||||
movl $0x17,%eax
|
|
||||||
mov %ax,%fs
|
|
||||||
pushl $ret_from_sys_call
|
|
||||||
jmp math_error
|
|
||||||
|
|
||||||
.align 2
|
|
||||||
device_not_available:
|
|
||||||
push %ds
|
|
||||||
push %es
|
|
||||||
push %fs
|
|
||||||
pushl %edx
|
|
||||||
pushl %ecx
|
|
||||||
pushl %ebx
|
|
||||||
pushl %eax
|
|
||||||
movl $0x10,%eax
|
|
||||||
mov %ax,%ds
|
|
||||||
mov %ax,%es
|
|
||||||
movl $0x17,%eax
|
|
||||||
mov %ax,%fs
|
|
||||||
pushl $ret_from_sys_call
|
|
||||||
clts # clear TS so that we can use math
|
|
||||||
movl %cr0,%eax
|
|
||||||
testl $0x4,%eax # EM (math emulation bit)
|
|
||||||
je math_state_restore
|
|
||||||
pushl %ebp
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
call math_emulate
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
timer_interrupt:
|
|
||||||
push %ds # save ds,es and put kernel data space
|
|
||||||
push %es # into them. %fs is used by _system_call
|
|
||||||
push %fs
|
|
||||||
pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
|
|
||||||
pushl %ecx # save those across function calls. %ebx
|
|
||||||
pushl %ebx # is saved as we use that in ret_sys_call
|
|
||||||
pushl %eax
|
|
||||||
movl $0x10,%eax
|
|
||||||
mov %ax,%ds
|
|
||||||
mov %ax,%es
|
|
||||||
movl $0x17,%eax
|
|
||||||
mov %ax,%fs
|
|
||||||
incl jiffies
|
|
||||||
movb $0x20,%al # EOI to interrupt controller #1
|
|
||||||
outb %al,$0x20
|
|
||||||
movl CS(%esp),%eax
|
|
||||||
andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
|
|
||||||
pushl %eax
|
|
||||||
call do_timer # 'do_timer(long CPL)' does everything from
|
|
||||||
addl $4,%esp # task switching to accounting ...
|
|
||||||
jmp ret_from_sys_call
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
sys_execve:
|
|
||||||
lea EIP(%esp),%eax
|
|
||||||
pushl %eax
|
|
||||||
call do_execve
|
|
||||||
addl $4,%esp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
sys_execve2:
|
|
||||||
lea EIP(%esp),%eax
|
|
||||||
pushl %eax
|
|
||||||
call do_execve
|
|
||||||
addl $4,%esp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
sys_fork:
|
|
||||||
call find_empty_process
|
|
||||||
testl %eax,%eax
|
|
||||||
js 1f
|
|
||||||
push %gs
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
pushl %ebp
|
|
||||||
pushl %eax
|
|
||||||
call copy_process
|
|
||||||
addl $20,%esp
|
|
||||||
1: ret
|
|
||||||
|
|
||||||
hd_interrupt:
|
|
||||||
pushl %eax
|
|
||||||
pushl %ecx
|
|
||||||
pushl %edx
|
|
||||||
push %ds
|
|
||||||
push %es
|
|
||||||
push %fs
|
|
||||||
movl $0x10,%eax
|
|
||||||
mov %ax,%ds
|
|
||||||
mov %ax,%es
|
|
||||||
movl $0x17,%eax
|
|
||||||
mov %ax,%fs
|
|
||||||
movb $0x20,%al
|
|
||||||
outb %al,$0xA0 # EOI to interrupt controller #1
|
|
||||||
jmp 1f # give port chance to breathe
|
|
||||||
1: jmp 1f
|
|
||||||
1: xorl %edx,%edx
|
|
||||||
xchgl do_hd,%edx
|
|
||||||
testl %edx,%edx
|
|
||||||
jne 1f
|
|
||||||
movl $unexpected_hd_interrupt,%edx
|
|
||||||
1: outb %al,$0x20
|
|
||||||
call *%edx # "interesting" way of handling intr.
|
|
||||||
pop %fs
|
|
||||||
pop %es
|
|
||||||
pop %ds
|
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
popl %eax
|
|
||||||
iret
|
|
||||||
|
|
||||||
floppy_interrupt:
|
|
||||||
pushl %eax
|
|
||||||
pushl %ecx
|
|
||||||
pushl %edx
|
|
||||||
push %ds
|
|
||||||
push %es
|
|
||||||
push %fs
|
|
||||||
movl $0x10,%eax
|
|
||||||
mov %ax,%ds
|
|
||||||
mov %ax,%es
|
|
||||||
movl $0x17,%eax
|
|
||||||
mov %ax,%fs
|
|
||||||
movb $0x20,%al
|
|
||||||
outb %al,$0x20 # EOI to interrupt controller #1
|
|
||||||
xorl %eax,%eax
|
|
||||||
xchgl do_floppy,%eax
|
|
||||||
testl %eax,%eax
|
|
||||||
jne 1f
|
|
||||||
movl $unexpected_floppy_interrupt,%eax
|
|
||||||
1: call *%eax # "interesting" way of handling intr.
|
|
||||||
pop %fs
|
|
||||||
pop %es
|
|
||||||
pop %ds
|
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
popl %eax
|
|
||||||
iret
|
|
||||||
|
|
||||||
parallel_interrupt:
|
|
||||||
pushl %eax
|
|
||||||
movb $0x20,%al
|
|
||||||
outb %al,$0x20
|
|
||||||
popl %eax
|
|
||||||
iret
|
|
Loading…
Reference in new issue