nuclear@51: #include nuclear@51: #include "syscall.h" nuclear@51: #include "intr.h" nuclear@51: #include "proc.h" nuclear@51: #include "sched.h" nuclear@51: #include "timer.h" nuclear@51: nuclear@51: static int (*sys_func[NUM_SYSCALLS])(); nuclear@51: nuclear@52: static void syscall(int inum); nuclear@51: nuclear@51: static int sys_hello(void); nuclear@51: nuclear@51: void init_syscall(void) nuclear@51: { nuclear@51: sys_func[SYS_HELLO] = sys_hello; nuclear@72: sys_func[SYS_SLEEP] = sys_sleep; /* timer.c */ nuclear@72: sys_func[SYS_FORK] = sys_fork; /* proc.c */ nuclear@72: sys_func[SYS_EXIT] = sys_exit; /* proc.c */ nuclear@72: sys_func[SYS_WAITPID] = sys_waitpid; /* proc.c */ nuclear@72: sys_func[SYS_GETPID] = sys_getpid; /* proc.c */ nuclear@72: sys_func[SYS_GETPPID] = sys_getppid; /* proc.c */ nuclear@51: nuclear@51: interrupt(SYSCALL_INT, syscall); nuclear@51: } nuclear@51: nuclear@52: static void syscall(int inum) nuclear@51: { nuclear@52: struct intr_frame *frm; nuclear@52: int idx; nuclear@52: nuclear@52: frm = get_intr_frame(); nuclear@52: idx = frm->regs.eax; nuclear@51: nuclear@51: if(idx < 0 || idx >= NUM_SYSCALLS) { nuclear@51: printf("invalid syscall: %d\n", idx); nuclear@51: return; nuclear@51: } nuclear@51: nuclear@54: /* the return value goes into the interrupt frame copy of the user's eax nuclear@54: * so that it'll be restored into eax before returning to userland. nuclear@54: */ nuclear@51: frm->regs.eax = sys_func[idx](frm->regs.ebx, frm->regs.ecx, frm->regs.edx, frm->regs.esi, frm->regs.edi); nuclear@72: nuclear@72: /* we don't necessarily want to return to the same process nuclear@72: * might have blocked or exited or whatever, so call schedule nuclear@72: * to decide what's going to run next. nuclear@72: */ nuclear@72: schedule(); nuclear@51: } nuclear@51: nuclear@51: static int sys_hello(void) nuclear@51: { nuclear@54: printf("process %d says hello!\n", get_current_pid()); nuclear@51: return 0; nuclear@51: }