root/kernel/system_call.s

/* [previous][next][first][last][top][bottom][index][help] */
   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 = 70
  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 
  70 .align 2
  71 bad_sys_call:
  72         movl $-1,%eax
  73         iret
  74 .align 2
  75 reschedule:
  76         pushl $ret_from_sys_call
  77         jmp _schedule
  78 .align 2
  79 _system_call:
  80         cmpl $nr_system_calls-1,%eax
  81         ja bad_sys_call
  82         push %ds
  83         push %es
  84         push %fs
  85         pushl %edx
  86         pushl %ecx              # push %ebx,%ecx,%edx as parameters
  87         pushl %ebx              # to the system call
  88         movl $0x10,%edx         # set up ds,es to kernel space
  89         mov %dx,%ds
  90         mov %dx,%es
  91         movl $0x17,%edx         # fs points to local data space
  92         mov %dx,%fs
  93         call _sys_call_table(,%eax,4)
  94         pushl %eax
  95         movl _current,%eax
  96         cmpl $0,state(%eax)             # state
  97         jne reschedule
  98         cmpl $0,counter(%eax)           # counter
  99         je reschedule
 100 ret_from_sys_call:
 101         movl _current,%eax              # task[0] cannot have signals
 102         cmpl _task,%eax
 103         je 3f
 104         cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
 105         jne 3f
 106         cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
 107         jne 3f
 108         movl signal(%eax),%ebx
 109         movl blocked(%eax),%ecx
 110         notl %ecx
 111         andl %ebx,%ecx
 112         bsfl %ecx,%ecx
 113         je 3f
 114         btrl %ecx,%ebx
 115         movl %ebx,signal(%eax)
 116         incl %ecx
 117         pushl %ecx
 118         call _do_signal
 119         popl %eax
 120 3:      popl %eax
 121         popl %ebx
 122         popl %ecx
 123         popl %edx
 124         pop %fs
 125         pop %es
 126         pop %ds
 127         iret
 128 
 129 .align 2
 130 _timer_interrupt:
 131         push %ds                # save ds,es and put kernel data space
 132         push %es                # into them. %fs is used by _system_call
 133         push %fs
 134         pushl %edx              # we save %eax,%ecx,%edx as gcc doesn't
 135         pushl %ecx              # save those across function calls. %ebx
 136         pushl %ebx              # is saved as we use that in ret_sys_call
 137         pushl %eax
 138         movl $0x10,%eax
 139         mov %ax,%ds
 140         mov %ax,%es
 141         movl $0x17,%eax
 142         mov %ax,%fs
 143         incl _jiffies
 144         movb $0x20,%al          # EOI to interrupt controller #1
 145         outb %al,$0x20
 146         movl CS(%esp),%eax
 147         andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
 148         pushl %eax
 149         call _do_timer          # 'do_timer(long CPL)' does everything from
 150         addl $4,%esp            # task switching to accounting ...
 151         jmp ret_from_sys_call
 152 
 153 .align 2
 154 _sys_execve:
 155         lea EIP(%esp),%eax
 156         pushl %eax
 157         call _do_execve
 158         addl $4,%esp
 159         ret
 160 
 161 .align 2
 162 _sys_fork:
 163         call _find_empty_process
 164         testl %eax,%eax
 165         js 1f
 166         push %gs
 167         pushl %esi
 168         pushl %edi
 169         pushl %ebp
 170         pushl %eax
 171         call _copy_process
 172         addl $20,%esp
 173 1:      ret
 174 
 175 _hd_interrupt:
 176         pushl %eax
 177         pushl %ecx
 178         pushl %edx
 179         push %ds
 180         push %es
 181         push %fs
 182         movl $0x10,%eax
 183         mov %ax,%ds
 184         mov %ax,%es
 185         mov %ax,%fs
 186         movb $0x20,%al
 187         outb %al,$0x20          # EOI to interrupt controller #1
 188         jmp 1f                  # give port chance to breathe
 189 1:      jmp 1f
 190 1:      outb %al,$0xA0          # same to controller #2
 191         movl _do_hd,%eax
 192         testl %eax,%eax
 193         jne 1f
 194         movl $_unexpected_hd_interrupt,%eax
 195 1:      call *%eax              # "interesting" way of handling intr.
 196         pop %fs
 197         pop %es
 198         pop %ds
 199         popl %edx
 200         popl %ecx
 201         popl %eax
 202         iret
 203 
 204 _floppy_interrupt:
 205         pushl %eax
 206         pushl %ecx
 207         pushl %edx
 208         push %ds
 209         push %es
 210         push %fs
 211         movl $0x10,%eax
 212         mov %ax,%ds
 213         mov %ax,%es
 214         mov %ax,%fs
 215         movb $0x20,%al
 216         outb %al,$0x20          # EOI to interrupt controller #1
 217         movl _do_floppy,%eax
 218         testl %eax,%eax
 219         jne 1f
 220         movl $_unexpected_floppy_interrupt,%eax
 221 1:      call *%eax              # "interesting" way of handling intr.
 222         pop %fs
 223         pop %es
 224         pop %ds
 225         popl %edx
 226         popl %ecx
 227         popl %eax
 228         iret
 229 
 230 _parallel_interrupt:
 231         pushl %eax
 232         movb $0x20,%al
 233         outb %al,$0x20
 234         popl %eax
 235         iret

/* [previous][next][first][last][top][bottom][index][help] */