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