POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/core/syscall.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  *
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team
00013  *
00014  * Created by julien on Wed Oct 21 13:12:27 2009
00015  */
00016 
00017 #include <bsp.h>
00018 #include <types.h>
00019 #include <libc.h>
00020 #include <arch/x86/ioports.h>
00021 #include <arch/x86/pci.h>
00022 
00023 #include <errno.h>
00024 #include <core/debug.h>
00025 #include <core/syscall.h>
00026 #include <core/partition.h>
00027 #include <core/thread.h>
00028 #include <core/lockobj.h>
00029 #include <core/time.h>
00030 #include <core/error.h>
00031 
00032 #include <middleware/port.h>
00033 
00040 pok_ret_t pok_core_syscall (const pok_syscall_id_t       syscall_id,
00041                             const pok_syscall_args_t*    args,
00042                             const pok_syscall_info_t*    infos)
00043 {
00044    switch (syscall_id)
00045    {
00046 #if defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_DEBUG)
00047       case POK_SYSCALL_CONSWRITE:
00048          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00049          if (pok_cons_write ((const char*)args->arg1 + infos->base_addr, args->arg2))
00050          {
00051             return POK_ERRNO_OK;
00052          }
00053          else
00054          {
00055             return POK_ERRNO_EINVAL;
00056          }
00057          break;
00058 #endif
00059 
00060 #ifdef POK_NEEDS_PORTS_VIRTUAL
00061       case POK_SYSCALL_MIDDLEWARE_VIRTUAL_CREATE:
00062          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00063          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00064          return pok_port_virtual_id ( (char*) (args->arg1 + infos->base_addr), (pok_port_id_t*) (args->arg2 + infos->base_addr));
00065          break;
00066 
00067       case POK_SYSCALL_MIDDLEWARE_VIRTUAL_NB_DESTINATIONS:
00068          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00069          return pok_port_virtual_nb_destinations ( (pok_port_id_t) (args->arg1), (uint32_t*) (args->arg2 + infos->base_addr));
00070          break;
00071 
00072       case POK_SYSCALL_MIDDLEWARE_VIRTUAL_DESTINATION:
00073          POK_CHECK_PTR_OR_RETURN(infos->partition, ((void*) args->arg3)+infos->base_addr)
00074          return pok_port_virtual_destination ( (pok_port_id_t) (args->arg1), (uint32_t) (args->arg2), (uint32_t*) (args->arg3 + infos->base_addr));
00075          break;
00076 
00077       case POK_SYSCALL_MIDDLEWARE_VIRTUAL_GET_GLOBAL:
00078          POK_CHECK_PTR_OR_RETURN(infos->partition, (void*) (args->arg2 + infos->base_addr))
00079          return pok_port_virtual_get_global ((pok_port_id_t) (args->arg1), (pok_port_id_t*) (args->arg2 + infos->base_addr));
00080          break;
00081 
00082 #endif
00083 
00084 #if defined POK_NEEDS_GETTICK
00085       case POK_SYSCALL_GETTICK:
00086          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00087          return pok_gettick_by_pointer ((uint64_t*) (args->arg1 + infos->base_addr));
00088          break;
00089 #endif
00090 
00091       case POK_SYSCALL_THREAD_CREATE:
00092          return pok_partition_thread_create  ((uint32_t*)         (args->arg1 + infos->base_addr),
00093                                              (pok_thread_attr_t*) (args->arg2 + infos->base_addr),
00094                                              (uint8_t)            infos->partition);
00095          break;
00096 
00097 #ifdef POK_NEEDS_THREAD_SLEEP
00098       case POK_SYSCALL_THREAD_SLEEP:
00099          return pok_thread_sleep (args->arg1);
00100          break;
00101 #endif
00102 
00103 #ifdef POK_NEEDS_THREAD_SLEEP_UNTIL
00104       case POK_SYSCALL_THREAD_SLEEP_UNTIL:
00105          return pok_thread_sleep_until (args->arg1);
00106          break;
00107 #endif
00108 
00109       case POK_SYSCALL_THREAD_PERIOD:
00110          return pok_sched_end_period ();
00111          break;
00112 
00113 #if defined (POK_NEEDS_THREAD_SUSPEND) || defined (POK_NEEDS_ERROR_HANDLING)
00114       case POK_SYSCALL_THREAD_SUSPEND:
00115          return pok_thread_suspend ();
00116          break;
00117 #endif
00118 
00119 #ifdef POK_NEEDS_THREAD_ID
00120       case POK_SYSCALL_THREAD_ID:
00121          return pok_sched_get_current ((uint32_t*) (args->arg1 + infos->base_addr));
00122          break;
00123 #endif
00124    case POK_SYSCALL_THREAD_STATUS:
00125               return pok_thread_get_status (args->arg1, (pok_thread_attr_t*) (args->arg2 + infos->base_addr));
00126          break;
00127 
00128    case POK_SYSCALL_THREAD_DELAYED_START:
00129      return pok_thread_delayed_start (args->arg1, args->arg2);
00130      break;
00131    case POK_SYSCALL_THREAD_SET_PRIORITY:
00132            return pok_thread_set_priority (args->arg1, args->arg2);
00133            break;
00134 
00135    case POK_SYSCALL_THREAD_RESUME:
00136            return pok_thread_resume (args->arg1);
00137            break;
00138    case POK_SYSCALL_THREAD_SUSPEND_TARGET:
00139            return pok_thread_suspend_target (args->arg1);
00140            break;
00141 
00142 #ifdef POK_NEEDS_ERROR_HANDLING
00143 
00148       case POK_SYSCALL_THREAD_RESTART:
00149          return pok_partition_restart_thread (args->arg1);
00150          break;
00151 
00152       case POK_SYSCALL_THREAD_STOP:
00153          return pok_partition_stop_thread (args->arg1);
00154          break;
00155 
00159       case POK_SYSCALL_THREAD_STOPSELF:
00160          pok_sched_stop_self ();
00161          return POK_ERRNO_OK;
00162          break;
00163 
00164 #endif
00165 
00166 #ifdef POK_NEEDS_PARTITIONS
00167       case POK_SYSCALL_PARTITION_SET_MODE:
00168          return pok_partition_set_mode_current ((pok_partition_mode_t)args->arg1);
00169          break;
00170       case POK_SYSCALL_PARTITION_GET_ID:
00171         return pok_current_partition_get_id ((uint8_t*)(args->arg1 + infos->base_addr));
00172          break;
00173       case POK_SYSCALL_PARTITION_GET_PERIOD:
00174         return pok_current_partition_get_period ((uint64_t*)(args->arg1 + infos->base_addr));
00175          break;
00176       case POK_SYSCALL_PARTITION_GET_DURATION:
00177         return pok_current_partition_get_duration ((uint64_t*)(args->arg1 + infos->base_addr));
00178          break;
00179       case POK_SYSCALL_PARTITION_GET_LOCK_LEVEL:
00180         return pok_current_partition_get_lock_level ((uint32_t*)(args->arg1 + infos->base_addr));
00181          break;
00182       case POK_SYSCALL_PARTITION_GET_OPERATING_MODE:
00183         return pok_current_partition_get_operating_mode ((pok_partition_mode_t*)(args->arg1 + infos->base_addr));
00184          break;
00185       case POK_SYSCALL_PARTITION_GET_START_CONDITION:
00186         return pok_current_partition_get_start_condition ((pok_start_condition_t*)(args->arg1 + infos->base_addr));
00187          break;
00188 #endif
00189 
00190 #ifdef POK_NEEDS_ERROR_HANDLING
00191       case POK_SYSCALL_ERROR_HANDLER_CREATE:
00192          return pok_error_thread_create (args->arg1 , (void*) (args->arg2));
00193          break;
00194 
00195       case POK_SYSCALL_ERROR_RAISE_APPLICATION_ERROR:
00196          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00197          pok_error_raise_application_error ((char*) (args->arg1 + infos->base_addr), args->arg2);
00198          return POK_ERRNO_OK;
00199          break;
00200 
00201       case POK_SYSCALL_ERROR_GET:
00202          return pok_error_get ((pok_error_status_t*) (args->arg1 + infos->base_addr));
00203          break;
00204 #endif
00205 
00206          /* Middleware syscalls */
00207 #ifdef POK_NEEDS_PORTS_SAMPLING
00208       case POK_SYSCALL_MIDDLEWARE_SAMPLING_CREATE: 
00209          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
00210          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00211          return pok_port_sampling_create  ((char*)(args->arg1 + infos->base_addr),
00212                                           (pok_port_size_t) args->arg2,
00213                                           (pok_port_direction_t) args->arg3,
00214                                           (uint64_t) args->arg4,
00215                                           (pok_port_id_t*) (args->arg5 + infos->base_addr));
00216          break;
00217 
00218       case POK_SYSCALL_MIDDLEWARE_SAMPLING_WRITE:
00219          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00220 
00221          return pok_port_sampling_write   ((const pok_port_id_t)args->arg1,
00222                                           (const void*) ((void*)args->arg2 + infos->base_addr),
00223                                           (const uint8_t) args->arg3);
00224          break;
00225 
00226       case POK_SYSCALL_MIDDLEWARE_SAMPLING_READ:
00227          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00228          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
00229          return pok_port_sampling_read ((const pok_port_id_t)args->arg1,
00230                                        (void*) args->arg2 + infos->base_addr,
00231                                        (pok_port_size_t*) (args->arg3 + infos->base_addr),
00232                                        (bool_t*) (args->arg4 + infos->base_addr));
00233          break;
00234 
00235       case POK_SYSCALL_MIDDLEWARE_SAMPLING_ID:
00236          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00237          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00238          return pok_port_sampling_id   ((char*)(args->arg1 + infos->base_addr),
00239                                        (pok_port_id_t*)(args->arg2 + infos->base_addr));
00240          break;
00241           
00242 #ifndef POK_GENERATED_CODE
00243       case POK_SYSCALL_MIDDLEWARE_SAMPLING_STATUS:
00244          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2+infos->base_addr)
00245          return pok_port_sampling_status ((const pok_port_id_t)args->arg1,
00246                                           (pok_port_sampling_status_t*) (args->arg2 + infos->base_addr));
00247          break;
00248 #endif /* POK_GENERATED_CODE */
00249 #endif /* POK_NEEDS_PORTS_SAMPLING */
00250 
00251 
00252 #ifdef POK_NEEDS_PORTS_QUEUEING
00253       case POK_SYSCALL_MIDDLEWARE_QUEUEING_CREATE: 
00254          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00255          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
00256          return pok_port_queueing_create ((char*)                          (args->arg1 + infos->base_addr), 
00257                                          (pok_port_size_t)                 args->arg2, 
00258                                          (pok_port_direction_t)            args->arg3, 
00259                                          (pok_port_queueing_discipline_t)  args->arg4, 
00260                                          (pok_port_id_t*)                  (args->arg5 + infos->base_addr));
00261          break;
00262 
00263       case POK_SYSCALL_MIDDLEWARE_QUEUEING_SEND:
00264          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00265          return pok_port_queueing_send ((const pok_port_id_t)              args->arg1,
00266                                        (const void*)                       ((void*)args->arg2 + infos->base_addr), 
00267                                        (const uint8_t)                     (args->arg3),
00268                                        (const uint64_t)                    args->arg4);
00269          break;
00270 
00271       case POK_SYSCALL_MIDDLEWARE_QUEUEING_RECEIVE:
00272          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
00273          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
00274          return pok_port_queueing_receive ((const pok_port_id_t)   args->arg1, 
00275                                           (uint64_t)              args->arg2,
00276                                           (pok_port_size_t)       args->arg3,
00277                                           (void*)                 ((void*)args->arg4 + infos->base_addr), 
00278                                           (pok_port_size_t*)      (args->arg5 + infos->base_addr));
00279          break;
00280 
00281       case POK_SYSCALL_MIDDLEWARE_QUEUEING_ID:
00282          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00283          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00284          return pok_port_queueing_id ((char*)          (args->arg1 + infos->base_addr),
00285                                     (pok_port_id_t*)  (args->arg2 + infos->base_addr));
00286          break;
00287 
00288 #ifndef POK_GENERATED_CODE
00289       case POK_SYSCALL_MIDDLEWARE_QUEUEING_STATUS:
00290          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00291          return pok_port_queueing_status     ((const pok_port_id_t)           args->arg1,
00292                                              (pok_port_queueing_status_t*)    (args->arg2 + infos->base_addr));
00293          break;
00294 #endif
00295 #endif /* POK_NEEDS_PORTS_QUEUEING */
00296 
00297 #ifdef POK_NEEDS_LOCKOBJECTS
00298       case POK_SYSCALL_LOCKOBJ_CREATE:
00299          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2+infos->base_addr)
00300          POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1+infos->base_addr)
00301          return pok_lockobj_partition_create    ((pok_lockobj_id_t*)    (args->arg1 + infos->base_addr),
00302                                                 (pok_lockobj_attr_t*)   (args->arg2 + infos->base_addr));
00303          break;
00304 
00305       case POK_SYSCALL_LOCKOBJ_OPERATION:
00306          if (args->arg2 == NULL)
00307          {
00308             return pok_lockobj_partition_wrapper ((const uint8_t) args->arg1, NULL);
00309          }
00310          else
00311          {
00312             POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
00313             return pok_lockobj_partition_wrapper   ((const uint8_t) args->arg1,
00314                                                    (pok_lockobj_lockattr_t*) (args->arg2 + infos->base_addr));
00315          }
00316          break;
00317 #endif /* POK_NEEDS_LOCKOBJECTS */
00318 
00319 #ifdef POK_NEEDS_IO
00320       case POK_SYSCALL_INB:
00321          if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
00322              (args->arg1 > pok_partitions[infos->partition].io_max))
00323          {
00324             return -POK_ERRNO_EPERM;
00325          }
00326          else
00327          {
00328             return inb((unsigned short) args->arg1);
00329          }
00330          break;
00331 
00332       case POK_SYSCALL_OUTB:
00333          if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
00334              (args->arg1 > pok_partitions[infos->partition].io_max))
00335          {
00336             return -POK_ERRNO_EPERM;
00337          }
00338          else
00339          {
00340             outb((unsigned short) args->arg1, (unsigned char) args->arg2);
00341             return POK_ERRNO_OK;
00342          }
00343        break;
00344 #endif /* POK_NEEDS_IO */
00345 
00346 #ifdef POK_NEEDS_PCI
00347      case POK_SYSCALL_PCI_REGISTER:
00348        POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
00349        return pci_register((void*)args->arg1 + infos->base_addr, infos->partition);
00350        break;
00351 #endif /* POK_NEEDS_PCI */
00352 
00353 
00360       default:
00361 #ifdef POK_NEEDS_ERROR_HANDLING
00362          pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
00363          pok_sched_activate_error_thread ();
00364 #else
00365          #ifdef POK_NEEDS_DEBUG
00366             printf ("Tried to use syscall %d\n", syscall_id);
00367          #endif
00368          POK_FATAL ("Unknown syscall");
00369 #endif
00370          break;
00371    }
00372 
00373    return POK_ERRNO_EINVAL;
00374 }