Prex Home / Browse Source - Prex Version: 0.9.0

root/sys/kern/sysent.c

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

DEFINITIONS

This source file includes following definitions.
  1. syscall_handler
  2. strace_entry
  3. strace_return

   1 /*-
   2  * Copyright (c) 2005-2009 Kohsuke Ohtani
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * sysent.c - system call switch table.
  32  */
  33 
  34 #include <kernel.h>
  35 #include <thread.h>
  36 #include <timer.h>
  37 #include <vm.h>
  38 #include <task.h>
  39 #include <exception.h>
  40 #include <ipc.h>
  41 #include <device.h>
  42 #include <sync.h>
  43 #include <system.h>
  44 
  45 typedef register_t (*sysfn_t)(register_t, register_t, register_t, register_t);
  46 
  47 #ifdef DEBUG
  48 static void strace_entry(register_t, register_t, register_t, register_t,
  49                          register_t);
  50 static void strace_return(register_t, register_t);
  51 #endif
  52 
  53 struct sysent {
  54 #ifdef DEBUG
  55         int     sy_narg;        /* number of arguments */
  56         char    *sy_name;       /* name string */
  57 #endif
  58         sysfn_t sy_call;        /* handler */
  59 };
  60 
  61 /*
  62  * Sysent initialization macros.
  63  *
  64  * Initialization macro for system calls which take their args
  65  * in the C style. In order to reduce the memory space, we
  66  * store the syscall name and its argument count only when
  67  * DEBUG is defined.
  68  *
  69  */
  70 #ifdef DEBUG
  71 #define SYSENT(n, fn)   {n, __STRING(fn), (sysfn_t)(fn)}
  72 #else
  73 #define SYSENT(n, fn)   {(sysfn_t)(fn)}
  74 #endif
  75 
  76 /*
  77  * This table is the switch used to transfer to the
  78  * appropriate routine for processing a system call.
  79  * The first element must be exception_return because
  80  * it requires special handling in HAL code.
  81  */
  82 static const struct sysent sysent[] = {
  83         /*  0 */ SYSENT(0, exception_return),
  84         /*  1 */ SYSENT(1, exception_setup),
  85         /*  2 */ SYSENT(2, exception_raise),
  86         /*  3 */ SYSENT(1, exception_wait),
  87         /*  4 */ SYSENT(3, task_create),
  88         /*  5 */ SYSENT(1, task_terminate),
  89         /*  6 */ SYSENT(0, task_self),
  90         /*  7 */ SYSENT(1, task_suspend),
  91         /*  8 */ SYSENT(1, task_resume),
  92         /*  9 */ SYSENT(2, task_setname),
  93         /* 10 */ SYSENT(2, task_setcap),
  94         /* 11 */ SYSENT(2, task_chkcap),
  95         /* 12 */ SYSENT(2, thread_create),
  96         /* 13 */ SYSENT(1, thread_terminate),
  97         /* 14 */ SYSENT(3, thread_load),
  98         /* 15 */ SYSENT(0, thread_self),
  99         /* 16 */ SYSENT(0, thread_yield),
 100         /* 17 */ SYSENT(1, thread_suspend),
 101         /* 18 */ SYSENT(1, thread_resume),
 102         /* 19 */ SYSENT(3, thread_schedparam),
 103         /* 20 */ SYSENT(4, vm_allocate),
 104         /* 21 */ SYSENT(2, vm_free),
 105         /* 22 */ SYSENT(3, vm_attribute),
 106         /* 23 */ SYSENT(4, vm_map),
 107         /* 24 */ SYSENT(2, object_create),
 108         /* 25 */ SYSENT(1, object_destroy),
 109         /* 26 */ SYSENT(2, object_lookup),
 110         /* 27 */ SYSENT(3, msg_send),
 111         /* 28 */ SYSENT(3, msg_receive),
 112         /* 29 */ SYSENT(3, msg_reply),
 113         /* 30 */ SYSENT(2, timer_sleep),
 114         /* 31 */ SYSENT(2, timer_alarm),
 115         /* 32 */ SYSENT(3, timer_periodic),
 116         /* 33 */ SYSENT(0, timer_waitperiod),
 117         /* 34 */ SYSENT(3, device_open),
 118         /* 35 */ SYSENT(1, device_close),
 119         /* 36 */ SYSENT(4, device_read),
 120         /* 37 */ SYSENT(4, device_write),
 121         /* 38 */ SYSENT(3, device_ioctl),
 122         /* 39 */ SYSENT(1, mutex_init),
 123         /* 40 */ SYSENT(1, mutex_destroy),
 124         /* 41 */ SYSENT(1, mutex_lock),
 125         /* 42 */ SYSENT(1, mutex_trylock),
 126         /* 43 */ SYSENT(1, mutex_unlock),
 127         /* 44 */ SYSENT(1, cond_init),
 128         /* 45 */ SYSENT(1, cond_destroy),
 129         /* 46 */ SYSENT(2, cond_wait),
 130         /* 47 */ SYSENT(1, cond_signal),
 131         /* 48 */ SYSENT(1, cond_broadcast),
 132         /* 49 */ SYSENT(2, sem_init),
 133         /* 50 */ SYSENT(1, sem_destroy),
 134         /* 51 */ SYSENT(2, sem_wait),
 135         /* 52 */ SYSENT(1, sem_trywait),
 136         /* 53 */ SYSENT(1, sem_post),
 137         /* 54 */ SYSENT(2, sem_getvalue),
 138         /* 55 */ SYSENT(1, sys_log),
 139         /* 56 */ SYSENT(1, sys_panic),
 140         /* 57 */ SYSENT(2, sys_info),
 141         /* 58 */ SYSENT(1, sys_time),
 142         /* 59 */ SYSENT(2, sys_debug),
 143 };
 144 
 145 #define NSYSCALL        (int)(sizeof(sysent) / sizeof(sysent[0]))
 146 
 147 
 148 /*
 149  * System call dispatcher.
 150  */
 151 register_t
 152 syscall_handler(register_t a1, register_t a2, register_t a3, register_t a4,
 153                 register_t id)
 154 {
 155         register_t retval = EINVAL;
 156         const struct sysent *callp;
 157 
 158 #ifdef DEBUG
 159         strace_entry(a1, a2, a3, a4, id);
 160 #endif
 161 
 162         if (id < NSYSCALL) {
 163                 callp = &sysent[id];
 164                 retval = (*callp->sy_call)(a1, a2, a3, a4);
 165         }
 166 
 167 #ifdef DEBUG
 168         strace_return(retval, id);
 169 #endif
 170         return retval;
 171 }
 172 
 173 #ifdef DEBUG
 174 /*
 175  * Show syscall info if the task is being traced.
 176  */
 177 static void
 178 strace_entry(register_t a1, register_t a2, register_t a3, register_t a4,
 179              register_t id)
 180 {
 181         const struct sysent *callp;
 182 
 183         if (curtask->flags & TF_TRACE) {
 184                 if (id >= NSYSCALL) {
 185                         printf("%s: OUT OF RANGE (%d)\n",
 186                                curtask->name, id);
 187                         return;
 188                 }
 189 
 190                 callp = &sysent[id];
 191 
 192                 printf("%s: %s(", curtask->name, callp->sy_name);
 193                 switch (callp->sy_narg) {
 194                 case 0:
 195                         printf(")\n");
 196                         break;
 197                 case 1:
 198                         printf("0x%08x)\n", a1);
 199                         break;
 200                 case 2:
 201                         printf("0x%08x, 0x%08x)\n", a1, a2);
 202                         break;
 203                 case 3:
 204                         printf("0x%08x, 0x%08x, 0x%08x)\n",
 205                                a1, a2, a3);
 206                         break;
 207                 case 4:
 208                         printf("0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
 209                                a1, a2, a3, a4);
 210                         break;
 211                 }
 212         }
 213 }
 214 
 215 /*
 216  * Show status if syscall is failed.
 217  *
 218  * We ignore the return code for the function which does
 219  * not have any arguments, although timer_waitperiod()
 220  * has valid return code...
 221  */
 222 static void
 223 strace_return(register_t retval, register_t id)
 224 {
 225         const struct sysent *callp;
 226 
 227         if (curtask->flags & TF_TRACE) {
 228                 if (id >= NSYSCALL)
 229                         return;
 230                 callp = &sysent[id];
 231                 if (callp->sy_narg != 0 && retval != 0)
 232                         printf("%s: !!! %s() = 0x%08x\n",
 233                                 curtask->name, callp->sy_name, retval);
 234         }
 235 }
 236 #endif /* !DEBUG */

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