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

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
1.1.1.3 ! root       92: .globl _IRQ3_interrupt,_IRQ4_interrupt,_IRQ5_interrupt,_IRQ9_interrupt
1.1       root       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)
1.1.1.2   root      190:        movl %esp,%ebx
                    191:        pushl %ebx
1.1       root      192:        incl %ecx
                    193:        pushl %ecx
                    194:        call _do_signal
                    195:        popl %ecx
1.1.1.2   root      196:        popl %ebx
1.1       root      197:        testl %eax, %eax
                    198:        jne 1b                  # see if we need to switch tasks, or do more signals
                    199: 2:     popl %ebx
                    200:        popl %ecx
                    201:        popl %edx
                    202:        popl %esi
                    203:        popl %edi
                    204:        popl %ebp
                    205:        popl %eax
                    206:        pop %ds
                    207:        pop %es
                    208:        pop %fs
                    209:        pop %gs
                    210:        addl $4,%esp            # skip the orig_eax
                    211:        iret
                    212: 
                    213: .align 2
                    214: _irq13:
                    215:        pushl %eax
                    216:        xorb %al,%al
                    217:        outb %al,$0xF0
                    218:        movb $0x20,%al
                    219:        outb %al,$0x20
                    220:        jmp 1f
                    221: 1:     jmp 1f
                    222: 1:     outb %al,$0xA0
                    223:        popl %eax
                    224: _coprocessor_error:
                    225:        pushl $-1               # mark this as an int. 
                    226:        SAVE_ALL
                    227:        pushl $ret_from_sys_call
                    228:        jmp _math_error
                    229: 
                    230: .align 2
                    231: _device_not_available:
                    232:        pushl $-1               # mark this as an int
                    233:        SAVE_ALL
                    234:        pushl $ret_from_sys_call
                    235:        clts                            # clear TS so that we can use math
                    236:        movl %cr0,%eax
                    237:        testl $0x4,%eax                 # EM (math emulation bit)
                    238:        je _math_state_restore
                    239:        pushl $0                # temporary storage for ORIG_EIP
                    240:        call _math_emulate
                    241:        addl $4,%esp
                    242:        ret
                    243: 
                    244: .align 2
                    245: _keyboard_interrupt:
                    246:        pushl $-1
                    247:        SAVE_ALL
                    248:        ACK_FIRST(0x02)
                    249:        sti
                    250:        call _do_keyboard
                    251:        cli
                    252:        UNBLK_FIRST(0x02)
                    253:        jmp ret_from_sys_call
                    254: 
                    255: .align 2
                    256: _IRQ3_interrupt:
                    257:        pushl $-1
                    258:        SAVE_ALL
                    259:        ACK_FIRST(0x08)
                    260:        sti
1.1.1.3 ! root      261:        pushl $3
        !           262:        call _do_IRQ
        !           263:        addl $4,%esp
1.1       root      264:        cli
                    265:        UNBLK_FIRST(0x08)
                    266:        jmp ret_from_sys_call
                    267: 
                    268: .align 2
                    269: _IRQ4_interrupt:
                    270:        pushl $-1
                    271:        SAVE_ALL
                    272:        ACK_FIRST(0x10)
                    273:        sti
1.1.1.3 ! root      274:        pushl $4
        !           275:        call _do_IRQ
        !           276:        addl $4,%esp
1.1       root      277:        cli
                    278:        UNBLK_FIRST(0x10)
                    279:        jmp ret_from_sys_call
                    280: 
                    281: .align 2
1.1.1.3 ! root      282: _IRQ5_interrupt:
        !           283:        pushl $-1
        !           284:        SAVE_ALL
        !           285:        ACK_FIRST(0x20)
        !           286:        sti
        !           287:        pushl $5
        !           288:        call _do_IRQ
        !           289:        addl $4,%esp
        !           290:        cli
        !           291:        UNBLK_FIRST(0x20)
        !           292:        jmp ret_from_sys_call
        !           293: 
        !           294: .align 2
        !           295: _IRQ9_interrupt:
        !           296:        pushl $-1
        !           297:        SAVE_ALL
        !           298:        ACK_SECOND(0x02)
        !           299:        sti
        !           300:        pushl $9
        !           301:        call _do_IRQ
        !           302:        addl $4,%esp
        !           303:        cli
        !           304:        UNBLK_SECOND(0x02)
        !           305:        jmp ret_from_sys_call
        !           306: 
        !           307: .align 2
1.1       root      308: _timer_interrupt:
                    309:        pushl $-1               # mark this as an int
                    310:        SAVE_ALL
                    311:        ACK_FIRST(0x01)
                    312:        sti
                    313:        incl _jiffies
                    314:        movl CS(%esp),%eax
                    315:        andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
                    316:        pushl %eax
                    317:        call _do_timer          # 'do_timer(long CPL)' does everything from
                    318:        addl $4,%esp            # task switching to accounting ...
                    319:        cli
                    320:        UNBLK_FIRST(0x01)
                    321:        jmp ret_from_sys_call
                    322: 
                    323: .align 2
                    324: _hd_interrupt:
                    325:        pushl $-1
                    326:        SAVE_ALL
                    327:        ACK_SECOND(0x40)
                    328:        andl $0xfffeffff,_timer_active
                    329:        xorl %edx,%edx
                    330:        xchgl _do_hd,%edx
                    331:        testl %edx,%edx
                    332:        jne 1f
                    333:        movl $_unexpected_hd_interrupt,%edx
                    334: 1:     call *%edx              # "interesting" way of handling intr.
                    335:        cli
                    336:        UNBLK_SECOND(0x40)
                    337:        jmp ret_from_sys_call
                    338: 
                    339: .align 2
                    340: _sys_execve:
                    341:        lea (EIP+4)(%esp),%eax  # don't forget about the return address.
                    342:        pushl %eax
                    343:        call _do_execve
                    344:        addl $4,%esp
                    345:        ret
                    346: 
                    347: _divide_error:
                    348:        pushl $0                # no error code
                    349:        pushl $_do_divide_error
                    350: error_code:
                    351:        push %fs
                    352:        push %es
                    353:        push %ds
                    354:        pushl %eax
                    355:        pushl %ebp
                    356:        pushl %edi
                    357:        pushl %esi
                    358:        pushl %edx
                    359:        pushl %ecx
                    360:        pushl %ebx
                    361:        cld
                    362:        movl $-1, %eax
                    363:        xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
                    364:        xorl %ebx,%ebx                  # zero ebx
                    365:        mov %gs,%bx                     # get the lower order bits of gs
                    366:        xchgl %ebx, GS(%esp)            # get the address and save gs.
                    367:        pushl %eax                      # push the error code
                    368:        lea 52(%esp),%edx
                    369:        pushl %edx
                    370:        movl $0x10,%edx
                    371:        mov %dx,%ds
                    372:        mov %dx,%es
                    373:        movl $0x17,%edx
                    374:        mov %dx,%fs
                    375:        call *%ebx
                    376:        addl $8,%esp
                    377:        jmp ret_from_sys_call
                    378: 
                    379: _debug:
                    380:        pushl $0
                    381:        pushl $_do_int3         # _do_debug
                    382:        jmp error_code
                    383: 
                    384: _nmi:
                    385:        pushl $0
                    386:        pushl $_do_nmi
                    387:        jmp error_code
                    388: 
                    389: _int3:
                    390:        pushl $0
                    391:        pushl $_do_int3
                    392:        jmp error_code
                    393: 
                    394: _overflow:
                    395:        pushl $0
                    396:        pushl $_do_overflow
                    397:        jmp error_code
                    398: 
                    399: _bounds:
                    400:        pushl $0
                    401:        pushl $_do_bounds
                    402:        jmp error_code
                    403: 
                    404: _invalid_op:
                    405:        pushl $0
                    406:        pushl $_do_invalid_op
                    407:        jmp error_code
                    408: 
                    409: _coprocessor_segment_overrun:
                    410:        pushl $0
                    411:        pushl $_do_coprocessor_segment_overrun
                    412:        jmp error_code
                    413: 
                    414: _reserved:
                    415:        pushl $0
                    416:        pushl $_do_reserved
                    417:        jmp error_code
                    418: 
                    419: _double_fault:
                    420:        pushl $_do_double_fault
                    421:        jmp error_code
                    422: 
                    423: _invalid_TSS:
                    424:        pushl $_do_invalid_TSS
                    425:        jmp error_code
                    426: 
                    427: _segment_not_present:
                    428:        pushl $_do_segment_not_present
                    429:        jmp error_code
                    430: 
                    431: _stack_segment:
                    432:        pushl $_do_stack_segment
                    433:        jmp error_code
                    434: 
                    435: _general_protection:
                    436:        pushl $_do_general_protection
                    437:        jmp error_code
                    438: 
                    439: _alignment_check:
                    440:        pushl $_do_alignment_check
                    441:        jmp error_code
                    442: 
                    443: _page_fault:
                    444:        pushl $_do_page_fault
                    445:        jmp error_code

unix.superglobalmegacorp.com