Annotation of linux/kernel/sys_call.S, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  linux/kernel/sys_call.S
                      3:  *
                      4:  *  (C) 1991  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: SIG_CHLD       = 17
                     41: 
                     42: EBX            = 0x00
                     43: ECX            = 0x04
                     44: EDX            = 0x08
                     45: ESI            = 0x0C
                     46: EDI            = 0x10
                     47: EBP            = 0x14
                     48: EAX            = 0x18
                     49: DS             = 0x1C
                     50: ES             = 0x20
                     51: FS             = 0x24
                     52: GS             = 0x28
                     53: ORIG_EAX       = 0x2C
                     54: EIP            = 0x30
                     55: CS             = 0x34
                     56: EFLAGS         = 0x38
                     57: OLDESP         = 0x3C
                     58: OLDSS          = 0x40
                     59: 
                     60: /*
                     61:  * these are offsets into the task-struct.
                     62:  */
                     63: state          = 0
                     64: counter                = 4
                     65: priority       = 8
                     66: signal         = 12
                     67: sigaction      = 16            # MUST be 16 (=len of sigaction)
                     68: blocked                = (33*16)
                     69: 
                     70: /*
                     71:  * offsets within sigaction
                     72:  */
                     73: sa_handler     = 0
                     74: sa_mask                = 4
                     75: sa_flags       = 8
                     76: sa_restorer    = 12
                     77: 
                     78: ENOSYS = 38
                     79: 
                     80: /*
                     81:  * Ok, I get parallel printer interrupts while using the floppy for some
                     82:  * strange reason. Urgel. Now I just ignore them.
                     83:  */
                     84: .globl _system_call,_timer_interrupt,_sys_execve
                     85: .globl _device_not_available, _coprocessor_error
                     86: .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
                     87: .globl _double_fault,_coprocessor_segment_overrun
                     88: .globl _invalid_TSS,_segment_not_present,_stack_segment
                     89: .globl _general_protection,_irq13,_reserved
                     90: .globl _alignment_check,_page_fault
                     91: .globl _keyboard_interrupt,_hd_interrupt
                     92: .globl _IRQ3_interrupt,_IRQ4_interrupt
                     93: 
                     94: #define SAVE_ALL \
                     95:        cld; \
                     96:        push %gs; \
                     97:        push %fs; \
                     98:        push %es; \
                     99:        push %ds; \
                    100:        pushl %eax; \
                    101:        pushl %ebp; \
                    102:        pushl %edi; \
                    103:        pushl %esi; \
                    104:        pushl %edx; \
                    105:        pushl %ecx; \
                    106:        pushl %ebx; \
                    107:        movl $0x10,%edx; \
                    108:        mov %dx,%ds; \
                    109:        mov %dx,%es; \
                    110:        movl $0x17,%edx; \
                    111:        mov %dx,%fs
                    112: 
                    113: #define ACK_FIRST(mask) \
                    114:        inb $0x21,%al; \
                    115:        jmp 1f; \
                    116: 1:     jmp 1f; \
                    117: 1:     orb $(mask),%al; \
                    118:        outb %al,$0x21; \
                    119:        jmp 1f; \
                    120: 1:     jmp 1f; \
                    121: 1:     movb $0x20,%al; \
                    122:        outb %al,$0x20
                    123: 
                    124: #define ACK_SECOND(mask) \
                    125:        inb $0xA1,%al; \
                    126:        jmp 1f; \
                    127: 1:     jmp 1f; \
                    128: 1:     orb $(mask),%al; \
                    129:        outb %al,$0xA1; \
                    130:        jmp 1f; \
                    131: 1:     jmp 1f; \
                    132: 1:     movb $0x20,%al; \
                    133:        outb %al,$0xA0 \
                    134:        jmp 1f; \
                    135: 1:     jmp 1f; \
                    136: 1:     outb %al,$0x20
                    137: 
                    138: #define UNBLK_FIRST(mask) \
                    139:        inb $0x21,%al; \
                    140:        jmp 1f; \
                    141: 1:     jmp 1f; \
                    142: 1:     andb $~(mask),%al; \
                    143:        outb %al,$0x21
                    144: 
                    145: #define UNBLK_SECOND(mask) \
                    146:        inb $0xA1,%al; \
                    147:        jmp 1f; \
                    148: 1:     jmp 1f; \
                    149: 1:     andb $~(mask),%al; \
                    150:        outb %al,$0xA1
                    151: 
                    152: .align 2
                    153: bad_sys_call:
                    154:        movl $-ENOSYS,EAX(%esp)
                    155:        jmp ret_from_sys_call
                    156: .align 2
                    157: reschedule:
                    158:        pushl $ret_from_sys_call
                    159:        jmp _schedule
                    160: .align 2
                    161: _system_call:
                    162:        pushl %eax              # save orig_eax
                    163:        SAVE_ALL
                    164:        cmpl _NR_syscalls,%eax
                    165:        jae bad_sys_call
                    166:        call _sys_call_table(,%eax,4)
                    167:        movl %eax,EAX(%esp)             # save the return value
                    168: ret_from_sys_call:
                    169:        cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
                    170:        jne 2f
                    171:        cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
                    172:        jne 2f
                    173: 1:     movl _current,%eax
                    174:        cmpl _task,%eax                 # task[0] cannot have signals
                    175:        je 2f
                    176:        cmpl $0,_need_resched
                    177:        jne reschedule
                    178:        cmpl $0,state(%eax)             # state
                    179:        jne reschedule
                    180:        cmpl $0,counter(%eax)           # counter
                    181:        je reschedule
                    182:        movl signal(%eax),%ebx
                    183:        movl blocked(%eax),%ecx
                    184:        notl %ecx
                    185:        andl %ebx,%ecx
                    186:        bsfl %ecx,%ecx
                    187:        je 2f
                    188:        btrl %ecx,%ebx
                    189:        movl %ebx,signal(%eax)
                    190:        incl %ecx
                    191:        pushl %ecx
                    192:        call _do_signal
                    193:        popl %ecx
                    194:        testl %eax, %eax
                    195:        jne 1b                  # see if we need to switch tasks, or do more signals
                    196: 2:     popl %ebx
                    197:        popl %ecx
                    198:        popl %edx
                    199:        popl %esi
                    200:        popl %edi
                    201:        popl %ebp
                    202:        popl %eax
                    203:        pop %ds
                    204:        pop %es
                    205:        pop %fs
                    206:        pop %gs
                    207:        addl $4,%esp            # skip the orig_eax
                    208:        iret
                    209: 
                    210: .align 2
                    211: _irq13:
                    212:        pushl %eax
                    213:        xorb %al,%al
                    214:        outb %al,$0xF0
                    215:        movb $0x20,%al
                    216:        outb %al,$0x20
                    217:        jmp 1f
                    218: 1:     jmp 1f
                    219: 1:     outb %al,$0xA0
                    220:        popl %eax
                    221: _coprocessor_error:
                    222:        pushl $-1               # mark this as an int. 
                    223:        SAVE_ALL
                    224:        pushl $ret_from_sys_call
                    225:        jmp _math_error
                    226: 
                    227: .align 2
                    228: _device_not_available:
                    229:        pushl $-1               # mark this as an int
                    230:        SAVE_ALL
                    231:        pushl $ret_from_sys_call
                    232:        clts                            # clear TS so that we can use math
                    233:        movl %cr0,%eax
                    234:        testl $0x4,%eax                 # EM (math emulation bit)
                    235:        je _math_state_restore
                    236:        pushl $0                # temporary storage for ORIG_EIP
                    237:        call _math_emulate
                    238:        addl $4,%esp
                    239:        ret
                    240: 
                    241: .align 2
                    242: _keyboard_interrupt:
                    243:        pushl $-1
                    244:        SAVE_ALL
                    245:        ACK_FIRST(0x02)
                    246:        sti
                    247:        call _do_keyboard
                    248:        cli
                    249:        UNBLK_FIRST(0x02)
                    250:        jmp ret_from_sys_call
                    251: 
                    252: .align 2
                    253: _IRQ3_interrupt:
                    254:        pushl $-1
                    255:        SAVE_ALL
                    256:        ACK_FIRST(0x08)
                    257:        sti
                    258:        call _do_IRQ3
                    259:        cli
                    260:        UNBLK_FIRST(0x08)
                    261:        jmp ret_from_sys_call
                    262: 
                    263: .align 2
                    264: _IRQ4_interrupt:
                    265:        pushl $-1
                    266:        SAVE_ALL
                    267:        ACK_FIRST(0x10)
                    268:        sti
                    269:        call _do_IRQ4
                    270:        cli
                    271:        UNBLK_FIRST(0x10)
                    272:        jmp ret_from_sys_call
                    273: 
                    274: .align 2
                    275: _timer_interrupt:
                    276:        pushl $-1               # mark this as an int
                    277:        SAVE_ALL
                    278:        ACK_FIRST(0x01)
                    279:        sti
                    280:        incl _jiffies
                    281:        movl CS(%esp),%eax
                    282:        andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
                    283:        pushl %eax
                    284:        call _do_timer          # 'do_timer(long CPL)' does everything from
                    285:        addl $4,%esp            # task switching to accounting ...
                    286:        cli
                    287:        UNBLK_FIRST(0x01)
                    288:        jmp ret_from_sys_call
                    289: 
                    290: .align 2
                    291: _hd_interrupt:
                    292:        pushl $-1
                    293:        SAVE_ALL
                    294:        ACK_SECOND(0x40)
                    295:        andl $0xfffeffff,_timer_active
                    296:        xorl %edx,%edx
                    297:        xchgl _do_hd,%edx
                    298:        testl %edx,%edx
                    299:        jne 1f
                    300:        movl $_unexpected_hd_interrupt,%edx
                    301: 1:     call *%edx              # "interesting" way of handling intr.
                    302:        cli
                    303:        UNBLK_SECOND(0x40)
                    304:        jmp ret_from_sys_call
                    305: 
                    306: .align 2
                    307: _sys_execve:
                    308:        lea (EIP+4)(%esp),%eax  # don't forget about the return address.
                    309:        pushl %eax
                    310:        call _do_execve
                    311:        addl $4,%esp
                    312:        ret
                    313: 
                    314: _divide_error:
                    315:        pushl $0                # no error code
                    316:        pushl $_do_divide_error
                    317: error_code:
                    318:        push %fs
                    319:        push %es
                    320:        push %ds
                    321:        pushl %eax
                    322:        pushl %ebp
                    323:        pushl %edi
                    324:        pushl %esi
                    325:        pushl %edx
                    326:        pushl %ecx
                    327:        pushl %ebx
                    328:        cld
                    329:        movl $-1, %eax
                    330:        xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
                    331:        xorl %ebx,%ebx                  # zero ebx
                    332:        mov %gs,%bx                     # get the lower order bits of gs
                    333:        xchgl %ebx, GS(%esp)            # get the address and save gs.
                    334:        pushl %eax                      # push the error code
                    335:        lea 52(%esp),%edx
                    336:        pushl %edx
                    337:        movl $0x10,%edx
                    338:        mov %dx,%ds
                    339:        mov %dx,%es
                    340:        movl $0x17,%edx
                    341:        mov %dx,%fs
                    342:        call *%ebx
                    343:        addl $8,%esp
                    344:        jmp ret_from_sys_call
                    345: 
                    346: _debug:
                    347:        pushl $0
                    348:        pushl $_do_int3         # _do_debug
                    349:        jmp error_code
                    350: 
                    351: _nmi:
                    352:        pushl $0
                    353:        pushl $_do_nmi
                    354:        jmp error_code
                    355: 
                    356: _int3:
                    357:        pushl $0
                    358:        pushl $_do_int3
                    359:        jmp error_code
                    360: 
                    361: _overflow:
                    362:        pushl $0
                    363:        pushl $_do_overflow
                    364:        jmp error_code
                    365: 
                    366: _bounds:
                    367:        pushl $0
                    368:        pushl $_do_bounds
                    369:        jmp error_code
                    370: 
                    371: _invalid_op:
                    372:        pushl $0
                    373:        pushl $_do_invalid_op
                    374:        jmp error_code
                    375: 
                    376: _coprocessor_segment_overrun:
                    377:        pushl $0
                    378:        pushl $_do_coprocessor_segment_overrun
                    379:        jmp error_code
                    380: 
                    381: _reserved:
                    382:        pushl $0
                    383:        pushl $_do_reserved
                    384:        jmp error_code
                    385: 
                    386: _double_fault:
                    387:        pushl $_do_double_fault
                    388:        jmp error_code
                    389: 
                    390: _invalid_TSS:
                    391:        pushl $_do_invalid_TSS
                    392:        jmp error_code
                    393: 
                    394: _segment_not_present:
                    395:        pushl $_do_segment_not_present
                    396:        jmp error_code
                    397: 
                    398: _stack_segment:
                    399:        pushl $_do_stack_segment
                    400:        jmp error_code
                    401: 
                    402: _general_protection:
                    403:        pushl $_do_general_protection
                    404:        jmp error_code
                    405: 
                    406: _alignment_check:
                    407:        pushl $_do_alignment_check
                    408:        jmp error_code
                    409: 
                    410: _page_fault:
                    411:        pushl $_do_page_fault
                    412:        jmp error_code

unix.superglobalmegacorp.com