#include #include #include #include #include #include #include void syscall_handler(trapframe_t *regs) { thread_t *th = get_current(); th->process->regs = regs; switch (regs->x8) { case 0: // int32_t getpid(void) regs->x0 = sys_getpid(); break; case 1: // size_t uart_read(char buf[], size_t size) regs->x0 = sys_uart_read((char *)regs->x0, (size_t)regs->x1); break; case 2: // size_t uart_write(const char buf[], size_t size) regs->x0 = sys_uart_write((const char *)regs->x0, (size_t)regs->x1); break; case 3: // int32_t exec(const char *name, char *const argv[]) regs->x0 = sys_exec((const char *)regs->x0, (char *const *)regs->x1); break; case 4: // int32_t fork(void) regs->x0 = sys_fork(); break; case 5: // void exit(int32_t status) sys_exit((int32_t)regs->x0); break; case 6: // int32_t mbox_call(uint8_t ch, uint32_t *mbox) regs->x0 = sys_mbox_call((uint8_t)regs->x0, (uint32_t *)regs->x1); break; case 7: // void kill_by_id(int32_t pid) sys_kill_by_id((int32_t)regs->x0); break; case 8: // void signal(int32_t SIGNAL, signal_handler_t handler) sys_signal((int32_t)regs->x0, (signal_handler_t)regs->x1); break; case 9: // void kill(int32_t pid, int32_t SIGNAL) sys_kill((int32_t)regs->x0, (int32_t)regs->x1); break; case 10: // void sigreturn(void) sys_sigreturn(); break; default: LOG("unsupported syscall"); ERROR(regs->x8); } } int32_t sys_getpid(void) { thread_t *th = get_current(); if (th->process == 0x0) return -1; return th->process->pid; } size_t sys_uart_read(char buf[], size_t size) { return uart_getb((uint8_t *)buf, size); } size_t sys_uart_write(const char buf[], size_t size) { return uart_putb((const uint8_t *)buf, size); } int32_t sys_exec(const char *name, char *const argv[]) { return run_process_by_name((uint64_t)name); /* ignore argv for now */ } int32_t sys_fork(void) { thread_t *cur = get_current(); process_t *newproc = fork_process(cur->process); run_thread(run_process, (uint64_t)newproc); return newproc->pid; } void sys_exit(int32_t status) { thread_t *th = get_current(); th->status = THREAD_STATUS_ZOMBIE; } int32_t sys_mbox_call(uint8_t ch, uint32_t *mbox) { return mbox_call(ch, mbox); } void sys_kill_by_id(int32_t pid) { if (!global_processes || global_processes->size <= (size_t)pid) { LOG("Process not exist"); INFOR(pid); return; } process_t *process = VEC_AT(process_t, global_processes, pid); process->th->status = THREAD_STATUS_ZOMBIE; LOG("Process killed"); INFOR(pid); } void sys_signal(int32_t SIGNAL, signal_handler_t handler) { thread_t *th = get_current(); th->process->sighandlers[SIGNAL] = handler; LOG(handler); LOG(SIGNAL); DEBUG_SIGNAL("registered"); } void sys_kill(int32_t pid, int32_t SIGNAL) { process_t *process = VEC_AT(process_t, global_processes, pid); process->sigstate[SIGNAL] = true; } void sys_sigreturn(void) { DEBUG_SIGNAL("sigreturn"); thread_t *th = get_current(); user_exec(th->process->regs); }