|
|
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': ! 18: * ! 19: * 0(%esp) - %eax ! 20: * 4(%esp) - %ebx ! 21: * 8(%esp) - %ecx ! 22: * C(%esp) - %edx ! 23: * 10(%esp) - original %eax (-1 if not system call) ! 24: * 14(%esp) - %fs ! 25: * 18(%esp) - %es ! 26: * 1C(%esp) - %ds ! 27: * 20(%esp) - %eip ! 28: * 24(%esp) - %cs ! 29: * 28(%esp) - %eflags ! 30: * 2C(%esp) - %oldesp ! 31: * 30(%esp) - %oldss ! 32: */ ! 33: ! 34: SIG_CHLD = 17 ! 35: ! 36: EAX = 0x00 ! 37: EBX = 0x04 ! 38: ECX = 0x08 ! 39: EDX = 0x0C ! 40: ORIG_EAX = 0x10 ! 41: FS = 0x14 ! 42: ES = 0x18 ! 43: DS = 0x1C ! 44: EIP = 0x20 ! 45: CS = 0x24 ! 46: EFLAGS = 0x28 ! 47: OLDESP = 0x2C ! 48: OLDSS = 0x30 ! 49: ! 50: state = 0 # these are offsets into the task-struct. ! 51: counter = 4 ! 52: priority = 8 ! 53: signal = 12 ! 54: sigaction = 16 # MUST be 16 (=len of sigaction) ! 55: blocked = (33*16) ! 56: ! 57: # offsets within sigaction ! 58: sa_handler = 0 ! 59: sa_mask = 4 ! 60: sa_flags = 8 ! 61: sa_restorer = 12 ! 62: ! 63: nr_system_calls = 82 ! 64: ! 65: ENOSYS = 38 ! 66: ! 67: /* ! 68: * Ok, I get parallel printer interrupts while using the floppy for some ! 69: * strange reason. Urgel. Now I just ignore them. ! 70: */ ! 71: .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve ! 72: .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt ! 73: .globl _device_not_available, _coprocessor_error ! 74: ! 75: .align 2 ! 76: bad_sys_call: ! 77: pushl $-ENOSYS ! 78: jmp ret_from_sys_call ! 79: .align 2 ! 80: reschedule: ! 81: pushl $ret_from_sys_call ! 82: jmp _schedule ! 83: .align 2 ! 84: _system_call: ! 85: push %ds ! 86: push %es ! 87: push %fs ! 88: pushl %eax # save the orig_eax ! 89: pushl %edx ! 90: pushl %ecx # push %ebx,%ecx,%edx as parameters ! 91: pushl %ebx # to the system call ! 92: movl $0x10,%edx # set up ds,es to kernel space ! 93: mov %dx,%ds ! 94: mov %dx,%es ! 95: movl $0x17,%edx # fs points to local data space ! 96: mov %dx,%fs ! 97: cmpl _NR_syscalls,%eax ! 98: jae bad_sys_call ! 99: call _sys_call_table(,%eax,4) ! 100: pushl %eax ! 101: 2: ! 102: movl _current,%eax ! 103: cmpl $0,state(%eax) # state ! 104: jne reschedule ! 105: cmpl $0,counter(%eax) # counter ! 106: je reschedule ! 107: ret_from_sys_call: ! 108: movl _current,%eax ! 109: cmpl _task,%eax # task[0] cannot have signals ! 110: je 3f ! 111: cmpw $0x0f,CS(%esp) # was old code segment supervisor ? ! 112: jne 3f ! 113: cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? ! 114: jne 3f ! 115: movl signal(%eax),%ebx ! 116: movl blocked(%eax),%ecx ! 117: notl %ecx ! 118: andl %ebx,%ecx ! 119: bsfl %ecx,%ecx ! 120: je 3f ! 121: btrl %ecx,%ebx ! 122: movl %ebx,signal(%eax) ! 123: incl %ecx ! 124: pushl %ecx ! 125: call _do_signal ! 126: popl %ecx ! 127: testl %eax, %eax ! 128: jne 2b # see if we need to switch tasks, or do more signals ! 129: 3: popl %eax ! 130: popl %ebx ! 131: popl %ecx ! 132: popl %edx ! 133: addl $4, %esp # skip orig_eax ! 134: pop %fs ! 135: pop %es ! 136: pop %ds ! 137: iret ! 138: ! 139: .align 2 ! 140: _coprocessor_error: ! 141: push %ds ! 142: push %es ! 143: push %fs ! 144: pushl $-1 # fill in -1 for orig_eax ! 145: pushl %edx ! 146: pushl %ecx ! 147: pushl %ebx ! 148: pushl %eax ! 149: movl $0x10,%eax ! 150: mov %ax,%ds ! 151: mov %ax,%es ! 152: movl $0x17,%eax ! 153: mov %ax,%fs ! 154: pushl $ret_from_sys_call ! 155: jmp _math_error ! 156: ! 157: .align 2 ! 158: _device_not_available: ! 159: push %ds ! 160: push %es ! 161: push %fs ! 162: pushl $-1 # fill in -1 for orig_eax ! 163: pushl %edx ! 164: pushl %ecx ! 165: pushl %ebx ! 166: pushl %eax ! 167: movl $0x10,%eax ! 168: mov %ax,%ds ! 169: mov %ax,%es ! 170: movl $0x17,%eax ! 171: mov %ax,%fs ! 172: pushl $ret_from_sys_call ! 173: clts # clear TS so that we can use math ! 174: movl %cr0,%eax ! 175: testl $0x4,%eax # EM (math emulation bit) ! 176: je _math_state_restore ! 177: pushl %ebp ! 178: pushl %esi ! 179: pushl %edi ! 180: pushl $0 # temporary storage for ORIG_EIP ! 181: call _math_emulate ! 182: addl $4,%esp ! 183: popl %edi ! 184: popl %esi ! 185: popl %ebp ! 186: ret ! 187: ! 188: .align 2 ! 189: _timer_interrupt: ! 190: push %ds # save ds,es and put kernel data space ! 191: push %es # into them. %fs is used by _system_call ! 192: push %fs ! 193: pushl $-1 # fill in -1 for orig_eax ! 194: pushl %edx # we save %eax,%ecx,%edx as gcc doesn't ! 195: pushl %ecx # save those across function calls. %ebx ! 196: pushl %ebx # is saved as we use that in ret_sys_call ! 197: pushl %eax ! 198: movl $0x10,%eax ! 199: mov %ax,%ds ! 200: mov %ax,%es ! 201: movl $0x17,%eax ! 202: mov %ax,%fs ! 203: incl _jiffies ! 204: movb $0x20,%al # EOI to interrupt controller #1 ! 205: outb %al,$0x20 ! 206: movl CS(%esp),%eax ! 207: andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor) ! 208: pushl %eax ! 209: call _do_timer # 'do_timer(long CPL)' does everything from ! 210: addl $4,%esp # task switching to accounting ... ! 211: jmp ret_from_sys_call ! 212: ! 213: .align 2 ! 214: _sys_execve: ! 215: lea EIP(%esp),%eax ! 216: pushl %eax ! 217: call _do_execve ! 218: addl $4,%esp ! 219: ret ! 220: ! 221: .align 2 ! 222: _sys_fork: ! 223: call _find_empty_process ! 224: testl %eax,%eax ! 225: js 1f ! 226: push %gs ! 227: pushl %esi ! 228: pushl %edi ! 229: pushl %ebp ! 230: pushl %eax ! 231: call _copy_process ! 232: addl $20,%esp ! 233: 1: ret ! 234: ! 235: _hd_interrupt: ! 236: pushl %eax ! 237: pushl %ecx ! 238: pushl %edx ! 239: push %ds ! 240: push %es ! 241: push %fs ! 242: movl $0x10,%eax ! 243: mov %ax,%ds ! 244: mov %ax,%es ! 245: movl $0x17,%eax ! 246: mov %ax,%fs ! 247: movb $0x20,%al ! 248: outb %al,$0xA0 # EOI to interrupt controller #1 ! 249: jmp 1f # give port chance to breathe ! 250: 1: jmp 1f ! 251: 1: xorl %edx,%edx ! 252: movl %edx,_hd_timeout ! 253: xchgl _do_hd,%edx ! 254: testl %edx,%edx ! 255: jne 1f ! 256: movl $_unexpected_hd_interrupt,%edx ! 257: 1: outb %al,$0x20 ! 258: call *%edx # "interesting" way of handling intr. ! 259: pop %fs ! 260: pop %es ! 261: pop %ds ! 262: popl %edx ! 263: popl %ecx ! 264: popl %eax ! 265: iret ! 266: ! 267: _floppy_interrupt: ! 268: pushl %eax ! 269: pushl %ecx ! 270: pushl %edx ! 271: push %ds ! 272: push %es ! 273: push %fs ! 274: movl $0x10,%eax ! 275: mov %ax,%ds ! 276: mov %ax,%es ! 277: movl $0x17,%eax ! 278: mov %ax,%fs ! 279: movb $0x20,%al ! 280: outb %al,$0x20 # EOI to interrupt controller #1 ! 281: xorl %eax,%eax ! 282: xchgl _do_floppy,%eax ! 283: testl %eax,%eax ! 284: jne 1f ! 285: movl $_unexpected_floppy_interrupt,%eax ! 286: 1: call *%eax # "interesting" way of handling intr. ! 287: pop %fs ! 288: pop %es ! 289: pop %ds ! 290: popl %edx ! 291: popl %ecx ! 292: popl %eax ! 293: iret ! 294: ! 295: _parallel_interrupt: ! 296: pushl %eax ! 297: movb $0x20,%al ! 298: outb %al,$0x20 ! 299: popl %eax ! 300: iret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.