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 ||
  16       addr + sizeof(uint64) > p->sz) // both tests needed, in case of overflow
  17     return -1;
  18   if (copyin(p->pagetable, p->sz, (char *)ip, addr, sizeof(*ip)) != 0)
  19     return -1;
  20   return 0;
  21 }
  22 
  23 // Fetch the nul-terminated string at addr from the current process.
  24 // Returns length of string, not including nul, or -1 for error.
  25 int
  26 fetchstr(uint64 addr, char *buf, int max)
  27 {
  28   struct proc *p = myproc();
  29   if (copyinstr(p->pagetable, p->sz, buf, addr, max) < 0)
  30     return -1;
  31   return strlen(buf);
  32 }
  33 
  34 static uint64
  35 argraw(int n)
  36 {
  37   struct proc *p = myproc();
  38   switch (n) {
  39   case 0:
  40     return p->trapframe->a0;
  41   case 1:
  42     return p->trapframe->a1;
  43   case 2:
  44     return p->trapframe->a2;
  45   case 3:
  46     return p->trapframe->a3;
  47   case 4:
  48     return p->trapframe->a4;
  49   case 5:
  50     return p->trapframe->a5;
  51   }
  52   panic("argraw");
  53   return -1;
  54 }
  55 
  56 // Fetch the nth 32-bit system call argument.
  57 void
  58 argint(int n, int *ip)
  59 {
  60   *ip = argraw(n);
  61 }
  62 
  63 // Retrieve an argument as a pointer.
  64 // Doesn't check for legality, since
  65 // copyin/copyout will do that.
  66 void
  67 argaddr(int n, uint64 *ip)
  68 {
  69   *ip = argraw(n);
  70 }
  71 
  72 // Fetch the nth word-sized system call argument as a null-terminated string.
  73 // Copies into buf, at most max.
  74 // Returns string length if OK (not including nul), -1 if error.
  75 int
  76 argstr(int n, char *buf, int max)
  77 {
  78   uint64 addr;
  79   argaddr(n, &addr);
  80   return fetchstr(addr, buf, max);
  81 }
  82 
  83 // Prototypes for the functions that handle system calls.
  84 extern uint64 sys_fork(void);
  85 extern uint64 sys_exit(void);
  86 extern uint64 sys_wait(void);
  87 extern uint64 sys_pipe(void);
  88 extern uint64 sys_read(void);
  89 extern uint64 sys_kill(void);
  90 extern uint64 sys_exec(void);
  91 extern uint64 sys_fstat(void);
  92 extern uint64 sys_chdir(void);
  93 extern uint64 sys_dup(void);
  94 extern uint64 sys_getpid(void);
  95 extern uint64 sys_sbrk(void);
  96 extern uint64 sys_pause(void);
  97 extern uint64 sys_uptime(void);
  98 extern uint64 sys_open(void);
  99 extern uint64 sys_write(void);
 100 extern uint64 sys_mknod(void);
 101 extern uint64 sys_unlink(void);
 102 extern uint64 sys_link(void);
 103 extern uint64 sys_mkdir(void);
 104 extern uint64 sys_close(void);
 105 extern uint64 sys_sync(void);
 106 
 107 // An array mapping syscall numbers from syscall.h
 108 // to the function that handles the system call.
 109 static uint64 (*syscalls[])(void) = {
 110   // clang-format off
 111   [SYS_fork]    = sys_fork,
 112   [SYS_exit]    = sys_exit,
 113   [SYS_wait]    = sys_wait,
 114   [SYS_pipe]    = sys_pipe,
 115   [SYS_read]    = sys_read,
 116   [SYS_kill]    = sys_kill,
 117   [SYS_exec]    = sys_exec,
 118   [SYS_fstat]   = sys_fstat,
 119   [SYS_chdir]   = sys_chdir,
 120   [SYS_dup]     = sys_dup,
 121   [SYS_getpid]  = sys_getpid,
 122   [SYS_sbrk]    = sys_sbrk,
 123   [SYS_pause]   = sys_pause,
 124   [SYS_uptime]  = sys_uptime,
 125   [SYS_open]    = sys_open,
 126   [SYS_write]   = sys_write,
 127   [SYS_mknod]   = sys_mknod,
 128   [SYS_unlink]  = sys_unlink,
 129   [SYS_link]    = sys_link,
 130   [SYS_mkdir]   = sys_mkdir,
 131   [SYS_close]   = sys_close,
 132   [SYS_sync]    = sys_sync,
 133   // clang-format on
 134 };
 135 
 136 void
 137 syscall(void)
 138 {
 139   int num;
 140   struct proc *p = myproc();
 141 
 142   num = p->trapframe->a7;
 143   if (num > 0 && num < NELEM(syscalls) && syscalls[num]) {
 144     // Use num to lookup the system call function for num, call it,
 145     // and store its return value in p->trapframe->a0
 146     p->trapframe->a0 = syscalls[num]();
 147   } else {
 148     printk("%d %s: unknown sys call %d\n", p->pid, p->name, num);
 149     p->trapframe->a0 = -1;
 150   }
 151 }

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