root/kernel/sys_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  *      ptrace needs to have all regs on the stack.
  19  *      if the order here is changed, it needs to be 
  20  *      updated in fork.c:copy_process, signal.c:do_signal,
  21  *      ptrace.c ptrace.h
  22  *
  23  *       0(%esp) - %ebx
  24  *       4(%esp) - %ecx
  25  *       8(%esp) - %edx
  26  *       C(%esp) - %esi
  27  *      10(%esp) - %edi
  28  *      14(%esp) - %ebp
  29  *      18(%esp) - %eax
  30  *      1C(%esp) - %ds
  31  *      20(%esp) - %es
  32  *      24(%esp) - %fs
  33  *      28(%esp) - %gs
  34  *      2C(%esp) - orig_eax
  35  *      30(%esp) - %eip
  36  *      34(%esp) - %cs
  37  *      38(%esp) - %eflags
  38  *      3C(%esp) - %oldesp
  39  *      40(%esp) - %oldss
  40  */
  41 
  42 SIG_CHLD        = 17
  43 
  44 EBX             = 0x00
  45 ECX             = 0x04
  46 EDX             = 0x08
  47 ESI             = 0x0C
  48 EDI             = 0x10
  49 EBP             = 0x14
  50 EAX             = 0x18
  51 DS              = 0x1C
  52 ES              = 0x20
  53 FS              = 0x24
  54 GS              = 0x28
  55 ORIG_EAX        = 0x2C
  56 EIP             = 0x30
  57 CS              = 0x34
  58 EFLAGS          = 0x38
  59 OLDESP          = 0x3C
  60 OLDSS           = 0x40
  61 
  62 state   = 0             # these are offsets into the task-struct.
  63 counter = 4
  64 priority = 8
  65 signal  = 12
  66 sigaction = 16          # MUST be 16 (=len of sigaction)
  67 blocked = (33*16)
  68 
  69 # offsets within sigaction
  70 sa_handler = 0
  71 sa_mask = 4
  72 sa_flags = 8
  73 sa_restorer = 12
  74 
  75 nr_system_calls = 82
  76 
  77 ENOSYS = 38
  78 
  79 /*
  80  * Ok, I get parallel printer interrupts while using the floppy for some
  81  * strange reason. Urgel. Now I just ignore them.
  82  */
  83 .globl _system_call,_timer_interrupt,_sys_execve
  84 .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
  85 .globl _device_not_available, _coprocessor_error
  86 
  87 .align 2
  88 bad_sys_call:
  89         pushl $-ENOSYS
  90         jmp ret_from_sys_call
  91 .align 2
  92 reschedule:
  93         pushl $ret_from_sys_call
  94         jmp _schedule
  95 .align 2
  96 _system_call:
  97         cld
  98         pushl %eax              # save orig_eax
  99         push %gs
 100         push %fs
 101         push %es
 102         push %ds
 103         pushl %eax              # save eax.  The return value will be put here.
 104         pushl %ebp
 105         pushl %edi
 106         pushl %esi
 107         pushl %edx              
 108         pushl %ecx              # push %ebx,%ecx,%edx as parameters
 109         pushl %ebx              # to the system call
 110         movl $0x10,%edx         # set up ds,es to kernel space
 111         mov %dx,%ds
 112         mov %dx,%es
 113         movl $0x17,%edx         # fs points to local data space
 114         mov %dx,%fs
 115         cmpl _NR_syscalls,%eax
 116         jae bad_sys_call
 117         call _sys_call_table(,%eax,4)
 118         movl %eax,EAX(%esp)             # save the return value
 119 2:      movl _current,%eax
 120         cmpl $0,state(%eax)             # state
 121         jne reschedule
 122         cmpl $0,counter(%eax)           # counter
 123         je reschedule
 124 ret_from_sys_call:
 125         movl _current,%eax
 126         cmpl _task,%eax                 # task[0] cannot have signals
 127         je 3f
 128         cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
 129         jne 3f
 130         cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
 131         jne 3f
 132         movl signal(%eax),%ebx
 133         movl blocked(%eax),%ecx
 134         notl %ecx
 135         andl %ebx,%ecx
 136         bsfl %ecx,%ecx
 137         je 3f
 138         btrl %ecx,%ebx
 139         movl %ebx,signal(%eax)
 140         incl %ecx
 141         pushl %ecx
 142         call _do_signal
 143         popl %ecx
 144         testl %eax, %eax
 145         jne 2b          # see if we need to switch tasks, or do more signals
 146 3:
 147         popl %ebx
 148         popl %ecx
 149         popl %edx
 150         popl %esi
 151         popl %edi
 152         popl %ebp
 153         popl %eax
 154         pop %ds
 155         pop %es
 156         pop %fs
 157         pop %gs
 158         addl $4,%esp            # skip the orig_eax
 159         iret
 160 
 161 .align 2
 162 _coprocessor_error:
 163         cld
 164         pushl $-1               # mark this as an int. 
 165         push %gs
 166         push %fs
 167         push %es
 168         push %ds
 169         pushl %eax              # save eax.
 170         pushl %ebp
 171         pushl %edi
 172         pushl %esi
 173         pushl %edx
 174         pushl %ecx
 175         pushl %ebx
 176         movl $0x10,%eax
 177         mov %ax,%ds
 178         mov %ax,%es
 179         movl $0x17,%eax
 180         mov %ax,%fs
 181         pushl $ret_from_sys_call
 182         jmp _math_error
 183 
 184 .align 2
 185 _device_not_available:
 186         cld
 187         pushl $-1               # mark this as an int
 188         push %gs
 189         push %fs
 190         push %es
 191         push %ds
 192         pushl %eax              
 193         pushl %ebp
 194         pushl %edi
 195         pushl %esi
 196         pushl %edx
 197         pushl %ecx
 198         pushl %ebx
 199         movl $0x10,%eax
 200         mov %ax,%ds
 201         mov %ax,%es
 202         movl $0x17,%eax
 203         mov %ax,%fs
 204         pushl $ret_from_sys_call
 205         clts                            # clear TS so that we can use math
 206         movl %cr0,%eax
 207         testl $0x4,%eax                 # EM (math emulation bit)
 208         je _math_state_restore
 209         pushl $0                # temporary storage for ORIG_EIP
 210         call _math_emulate
 211         addl $4,%esp
 212         ret
 213 
 214 .align 2
 215 _timer_interrupt:
 216         cld
 217         pushl $-1               # mark this as an int
 218         push %gs
 219         push %fs
 220         push %es
 221         push %ds
 222         pushl %eax
 223         pushl %ebp
 224         pushl %edi
 225         pushl %esi
 226         pushl %edx              
 227         pushl %ecx
 228         pushl %ebx
 229         movl $0x10,%eax
 230         mov %ax,%ds
 231         mov %ax,%es
 232         movl $0x17,%eax
 233         mov %ax,%fs
 234         incl _jiffies
 235         movb $0x20,%al          # EOI to interrupt controller #1
 236         outb %al,$0x20
 237         movl CS(%esp),%eax
 238         andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
 239         pushl %eax
 240         call _do_timer          # 'do_timer(long CPL)' does everything from
 241         addl $4,%esp            # task switching to accounting ...
 242         jmp ret_from_sys_call
 243 
 244 .align 2
 245 _sys_execve:
 246         lea (EIP+4)(%esp),%eax  # don't forget about the return address.
 247         pushl %eax
 248         call _do_execve
 249         addl $4,%esp
 250         ret
 251 
 252 _hd_interrupt:
 253         cld
 254         pushl %eax
 255         pushl %ecx
 256         pushl %edx
 257         push %ds
 258         push %es
 259         push %fs
 260         movl $0x10,%eax
 261         mov %ax,%ds
 262         mov %ax,%es
 263         movl $0x17,%eax
 264         mov %ax,%fs
 265         movb $0x20,%al
 266         outb %al,$0xA0          # EOI to interrupt controller #1
 267         jmp 1f                  # give port chance to breathe
 268 1:      jmp 1f
 269 1:      outb %al,$0x20
 270         andl $0xfffeffff,_timer_active
 271         xorl %edx,%edx
 272         xchgl _do_hd,%edx
 273         testl %edx,%edx
 274         jne 1f
 275         movl $_unexpected_hd_interrupt,%edx
 276 1:      call *%edx              # "interesting" way of handling intr.
 277         pop %fs
 278         pop %es
 279         pop %ds
 280         popl %edx
 281         popl %ecx
 282         popl %eax
 283         iret
 284 
 285 _floppy_interrupt:
 286         cld
 287         pushl %eax
 288         pushl %ecx
 289         pushl %edx
 290         push %ds
 291         push %es
 292         push %fs
 293         movl $0x10,%eax
 294         mov %ax,%ds
 295         mov %ax,%es
 296         movl $0x17,%eax
 297         mov %ax,%fs
 298         movb $0x20,%al
 299         outb %al,$0x20          # EOI to interrupt controller #1
 300         xorl %eax,%eax
 301         xchgl _do_floppy,%eax
 302         testl %eax,%eax
 303         jne 1f
 304         movl $_unexpected_floppy_interrupt,%eax
 305 1:      call *%eax              # "interesting" way of handling intr.
 306         pop %fs
 307         pop %es
 308         pop %ds
 309         popl %edx
 310         popl %ecx
 311         popl %eax
 312         iret
 313 
 314 _parallel_interrupt:
 315         cld
 316         pushl %eax
 317         movb $0x20,%al
 318         outb %al,$0x20
 319         popl %eax
 320         iret

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