kernel/syscall.c
147 lines
1#include "types.h"2#include "param.h"3#include "memlayout.h"4#include "riscv.h"5#include "spinlock.h"6#include "proc.h"7#include "syscall.h"8#include "defs.h"910// Fetch the uint64 at addr from the current process.11int12fetchaddr(uint64 addr, uint64 *ip)13{14 struct proc *p = myproc();15 if(addr >= p->sz || addr+sizeof(uint64) > p->sz) // both tests needed, in case of overflow16 return -1;17 if(copyin(p->pagetable, (char *)ip, addr, sizeof(*ip)) != 0)18 return -1;19 return 0;20}2122// Fetch the nul-terminated string at addr from the current process.23// Returns length of string, not including nul, or -1 for error.24int25fetchstr(uint64 addr, char *buf, int max)26{27 struct proc *p = myproc();28 if(copyinstr(p->pagetable, buf, addr, max) < 0)29 return -1;30 return strlen(buf);31}3233static uint6434argraw(int n)35{36 struct proc *p = myproc();37 switch (n) {38 case 0:39 return p->trapframe->a0;40 case 1:41 return p->trapframe->a1;42 case 2:43 return p->trapframe->a2;44 case 3:45 return p->trapframe->a3;46 case 4:47 return p->trapframe->a4;48 case 5:49 return p->trapframe->a5;50 }51 panic("argraw");52 return -1;53}5455// Fetch the nth 32-bit system call argument.56void57argint(int n, int *ip)58{59 *ip = argraw(n);60}6162// Retrieve an argument as a pointer.63// Doesn't check for legality, since64// copyin/copyout will do that.65void66argaddr(int n, uint64 *ip)67{68 *ip = argraw(n);69}7071// Fetch the nth word-sized system call argument as a null-terminated string.72// Copies into buf, at most max.73// Returns string length if OK (including nul), -1 if error.74int75argstr(int n, char *buf, int max)76{77 uint64 addr;78 argaddr(n, &addr);79 return fetchstr(addr, buf, max);80}8182// Prototypes for the functions that handle system calls.83extern uint64 sys_fork(void);84extern uint64 sys_exit(void);85extern uint64 sys_wait(void);86extern uint64 sys_pipe(void);87extern uint64 sys_read(void);88extern uint64 sys_kill(void);89extern uint64 sys_exec(void);90extern uint64 sys_fstat(void);91extern uint64 sys_chdir(void);92extern uint64 sys_dup(void);93extern uint64 sys_getpid(void);94extern uint64 sys_sbrk(void);95extern uint64 sys_pause(void);96extern uint64 sys_uptime(void);97extern uint64 sys_open(void);98extern uint64 sys_write(void);99extern uint64 sys_mknod(void);100extern uint64 sys_unlink(void);101extern uint64 sys_link(void);102extern uint64 sys_mkdir(void);103extern uint64 sys_close(void);104105// An array mapping syscall numbers from syscall.h106// to the function that handles the system call.107static uint64 (*syscalls[])(void) = {108[SYS_fork] sys_fork,109[SYS_exit] sys_exit,110[SYS_wait] sys_wait,111[SYS_pipe] sys_pipe,112[SYS_read] sys_read,113[SYS_kill] sys_kill,114[SYS_exec] sys_exec,115[SYS_fstat] sys_fstat,116[SYS_chdir] sys_chdir,117[SYS_dup] sys_dup,118[SYS_getpid] sys_getpid,119[SYS_sbrk] sys_sbrk,120[SYS_pause] sys_pause,121[SYS_uptime] sys_uptime,122[SYS_open] sys_open,123[SYS_write] sys_write,124[SYS_mknod] sys_mknod,125[SYS_unlink] sys_unlink,126[SYS_link] sys_link,127[SYS_mkdir] sys_mkdir,128[SYS_close] sys_close,129};130131void132syscall(void)133{134 int num;135 struct proc *p = myproc();136137 num = p->trapframe->a7;138 if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {139 // Use num to lookup the system call function for num, call it,140 // and store its return value in p->trapframe->a0141 p->trapframe->a0 = syscalls[num]();142 } else {143 printf("%d %s: unknown sys call %d\n",144 p->pid, p->name, num);145 p->trapframe->a0 = -1;146 }147}148