Annotation of linux/kernel/sys_call.S, revision 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