POK(kernelpart)
|
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 }