root/kernel/syscall.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fetchaddr
  2. fetchstr
  3. argraw
  4. argint
  5. argaddr
  6. argstr
  7. syscall

   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"
   9 
  10 // Fetch the uint64 at addr from the current process.
  11 int
  12 fetchaddr(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 overflow
  16     return -1;
  17   if(copyin(p->pagetable, (char *)ip, addr, sizeof(*ip)) != 0)
  18     return -1;
  19   return 0;
  20 }
  21 
  22 // Fetch the nul-terminated string at addr from the current process.
  23 // Returns length of string, not including nul, or -1 for error.
  24 int
  25 fetchstr(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 }
  32 
  33 static uint64
  34 argraw(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 }
  54 
  55 // Fetch the nth 32-bit system call argument.
  56 void
  57 argint(int n, int *ip)
  58 {
  59   *ip = argraw(n);
  60 }
  61 
  62 // Retrieve an argument as a pointer.
  63 // Doesn't check for legality, since
  64 // copyin/copyout will do that.
  65 void
  66 argaddr(int n, uint64 *ip)
  67 {
  68   *ip = argraw(n);
  69 }
  70 
  71 // 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.
  74 int
  75 argstr(int n, char *buf, int max)
  76 {
  77   uint64 addr;
  78   argaddr(n, &addr);
  79   return fetchstr(addr, buf, max);
  80 }
  81 
  82 // Prototypes for the functions that handle system calls.
  83 extern uint64 sys_fork(void);
  84 extern uint64 sys_exit(void);
  85 extern uint64 sys_wait(void);
  86 extern uint64 sys_pipe(void);
  87 extern uint64 sys_read(void);
  88 extern uint64 sys_kill(void);
  89 extern uint64 sys_exec(void);
  90 extern uint64 sys_fstat(void);
  91 extern uint64 sys_chdir(void);
  92 extern uint64 sys_dup(void);
  93 extern uint64 sys_getpid(void);
  94 extern uint64 sys_sbrk(void);
  95 extern uint64 sys_sleep(void);
  96 extern uint64 sys_uptime(void);
  97 extern uint64 sys_open(void);
  98 extern uint64 sys_write(void);
  99 extern uint64 sys_mknod(void);
 100 extern uint64 sys_unlink(void);
 101 extern uint64 sys_link(void);
 102 extern uint64 sys_mkdir(void);
 103 extern uint64 sys_close(void);
 104 
 105 // An array mapping syscall numbers from syscall.h
 106 // to the function that handles the system call.
 107 static 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_sleep]   sys_sleep,
 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 };
 130 
 131 void
 132 syscall(void)
 133 {
 134   int num;
 135   struct proc *p = myproc();
 136 
 137   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->a0
 141     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 }

/* [<][>][^][v][top][bottom][index][help] */