Annotation of linux/kernel/sys_call.s, revision 1.1.1.2

1.1       root        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':
1.1.1.2 ! root       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
1.1       root       22:  *
1.1.1.2 ! root       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
1.1       root       30:  *     1C(%esp) - %ds
1.1.1.2 ! root       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
1.1       root       40:  */
                     41: 
                     42: SIG_CHLD       = 17
                     43: 
1.1.1.2 ! root       44: EBX            = 0x00
        !            45: ECX            = 0x04
        !            46: EDX            = 0x08
        !            47: ESI            = 0x0C
        !            48: EDI            = 0x10
        !            49: EBP            = 0x14
        !            50: EAX            = 0x18
1.1       root       51: DS             = 0x1C
1.1.1.2 ! root       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
1.1       root       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:  */
1.1.1.2 ! root       83: .globl _system_call,_timer_interrupt,_sys_execve
1.1       root       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:
1.1.1.2 ! root       97:        cld
        !            98:        pushl %eax              # save orig_eax
        !            99:        push %gs
1.1       root      100:        push %fs
1.1.1.2 ! root      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
1.1       root      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)
1.1.1.2 ! root      118:        movl %eax,EAX(%esp)             # save the return value
        !           119: 2:     movl _current,%eax
1.1       root      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
1.1.1.2 ! root      146: 3:
1.1       root      147:        popl %ebx
                    148:        popl %ecx
                    149:        popl %edx
1.1.1.2 ! root      150:        popl %esi
        !           151:        popl %edi
        !           152:        popl %ebp
        !           153:        popl %eax
1.1       root      154:        pop %ds
1.1.1.2 ! root      155:        pop %es
        !           156:        pop %fs
        !           157:        pop %gs
        !           158:        addl $4,%esp            # skip the orig_eax
1.1       root      159:        iret
                    160: 
                    161: .align 2
                    162: _coprocessor_error:
1.1.1.2 ! root      163:        cld
        !           164:        pushl $-1               # mark this as an int. 
        !           165:        push %gs
1.1       root      166:        push %fs
1.1.1.2 ! root      167:        push %es
        !           168:        push %ds
        !           169:        pushl %eax              # save eax.
        !           170:        pushl %ebp
        !           171:        pushl %edi
        !           172:        pushl %esi
1.1       root      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:
1.1.1.2 ! root      186:        cld
        !           187:        pushl $-1               # mark this as an int
        !           188:        push %gs
1.1       root      189:        push %fs
1.1.1.2 ! root      190:        push %es
        !           191:        push %ds
        !           192:        pushl %eax              
        !           193:        pushl %ebp
        !           194:        pushl %edi
        !           195:        pushl %esi
1.1       root      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:
1.1.1.2 ! root      216:        cld
        !           217:        pushl $-1               # mark this as an int
        !           218:        push %gs
1.1       root      219:        push %fs
1.1.1.2 ! root      220:        push %es
        !           221:        push %ds
1.1       root      222:        pushl %eax
1.1.1.2 ! root      223:        pushl %ebp
        !           224:        pushl %edi
        !           225:        pushl %esi
        !           226:        pushl %edx              
        !           227:        pushl %ecx
        !           228:        pushl %ebx
1.1       root      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:
1.1.1.2 ! root      246:        lea (EIP+4)(%esp),%eax  # don't forget about the return address.
1.1       root      247:        pushl %eax
                    248:        call _do_execve
                    249:        addl $4,%esp
                    250:        ret
                    251: 
                    252: _hd_interrupt:
1.1.1.2 ! root      253:        cld
1.1       root      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
1.1.1.2 ! root      269: 1:     outb %al,$0x20
        !           270:        andl $0xfffeffff,_timer_active
        !           271:        xorl %edx,%edx
1.1       root      272:        xchgl _do_hd,%edx
                    273:        testl %edx,%edx
                    274:        jne 1f
                    275:        movl $_unexpected_hd_interrupt,%edx
1.1.1.2 ! root      276: 1:     call *%edx              # "interesting" way of handling intr.
1.1       root      277:        pop %fs
                    278:        pop %es
                    279:        pop %ds
                    280:        popl %edx
                    281:        popl %ecx
                    282:        popl %eax
                    283:        iret
                    284: 
                    285: _floppy_interrupt:
1.1.1.2 ! root      286:        cld
1.1       root      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:
1.1.1.2 ! root      315:        cld
1.1       root      316:        pushl %eax
                    317:        movb $0x20,%al
                    318:        outb %al,$0x20
                    319:        popl %eax
                    320:        iret

unix.superglobalmegacorp.com