root/kernel/sys_call.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  *  linux/kernel/sys_call.S
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   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  */
  82 .globl _system_call,_sys_execve
  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
  87 .globl _general_protection,_reserved
  88 .globl _alignment_check,_page_fault
  89 .globl ret_from_sys_call
  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:
 116         pushl %eax                      # save orig_eax
 117         SAVE_ALL
 118         movl $-ENOSYS,EAX(%esp)
 119         cmpl _NR_syscalls,%eax
 120         jae ret_from_sys_call
 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
 128 1:      cmpl $0,_need_resched
 129         jne reschedule
 130         movl _current,%eax
 131         cmpl $0,state(%eax)             # state
 132         jne reschedule
 133         cmpl $0,counter(%eax)           # counter
 134         je reschedule
 135         movl $1,_need_resched
 136         cmpl _task,%eax                 # task[0] cannot have signals
 137         je 2f
 138         movl $0,_need_resched
 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)
 147         movl %esp,%ebx
 148         pushl %ebx
 149         incl %ecx
 150         pushl %ecx
 151         call _do_signal
 152         popl %ecx
 153         popl %ebx
 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 
 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 
 230 _debug:
 231         pushl $0
 232         pushl $_do_debug
 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

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