POK(kernelpart)
syscall.c
Go to the documentation of this file.
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Wed Oct 21 13:12:27 2009
15  */
16 
17 #include <bsp.h>
18 #include <types.h>
19 #include <libc.h>
20 #include <arch/x86/ioports.h>
21 #include <arch/x86/pci.h>
22 
23 #include <errno.h>
24 #include <core/debug.h>
25 #include <core/syscall.h>
26 #include <core/partition.h>
27 #include <core/thread.h>
28 #include <core/lockobj.h>
29 #include <core/time.h>
30 #include <core/error.h>
31 
32 #include <middleware/port.h>
33 
41  const pok_syscall_args_t* args,
42  const pok_syscall_info_t* infos)
43 {
44  switch (syscall_id)
45  {
46 #if defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_DEBUG)
48  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
49  if (pok_cons_write ((const char*)args->arg1 + infos->base_addr, args->arg2))
50  {
51  return POK_ERRNO_OK;
52  }
53  else
54  {
55  return POK_ERRNO_EINVAL;
56  }
57  break;
58 #endif
59 
60 #ifdef POK_NEEDS_PORTS_VIRTUAL
61  case POK_SYSCALL_MIDDLEWARE_VIRTUAL_CREATE:
62  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
63  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
64  return pok_port_virtual_id ( (char*) (args->arg1 + infos->base_addr), (pok_port_id_t*) (args->arg2 + infos->base_addr));
65  break;
66 
67  case POK_SYSCALL_MIDDLEWARE_VIRTUAL_NB_DESTINATIONS:
68  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
69  return pok_port_virtual_nb_destinations ( (pok_port_id_t) (args->arg1), (uint32_t*) (args->arg2 + infos->base_addr));
70  break;
71 
72  case POK_SYSCALL_MIDDLEWARE_VIRTUAL_DESTINATION:
73  POK_CHECK_PTR_OR_RETURN(infos->partition, ((void*) args->arg3)+infos->base_addr)
74  return pok_port_virtual_destination ( (pok_port_id_t) (args->arg1), (uint32_t) (args->arg2), (uint32_t*) (args->arg3 + infos->base_addr));
75  break;
76 
77  case POK_SYSCALL_MIDDLEWARE_VIRTUAL_GET_GLOBAL:
78  POK_CHECK_PTR_OR_RETURN(infos->partition, (void*) (args->arg2 + infos->base_addr))
79  return pok_port_virtual_get_global ((pok_port_id_t) (args->arg1), (pok_port_id_t*) (args->arg2 + infos->base_addr));
80  break;
81 
82 #endif
83 
84 #if defined POK_NEEDS_GETTICK
86  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
87  return pok_gettick_by_pointer ((uint64_t*) (args->arg1 + infos->base_addr));
88  break;
89 #endif
90 
92  return pok_partition_thread_create ((uint32_t*) (args->arg1 + infos->base_addr),
93  (pok_thread_attr_t*) (args->arg2 + infos->base_addr),
94  (uint8_t) infos->partition);
95  break;
96 
97 #ifdef POK_NEEDS_THREAD_SLEEP
99  return pok_thread_sleep (args->arg1);
100  break;
101 #endif
102 
103 #ifdef POK_NEEDS_THREAD_SLEEP_UNTIL
105  return pok_thread_sleep_until (args->arg1);
106  break;
107 #endif
108 
110  return pok_sched_end_period ();
111  break;
112 
113 #if defined (POK_NEEDS_THREAD_SUSPEND) || defined (POK_NEEDS_ERROR_HANDLING)
115  return pok_thread_suspend ();
116  break;
117 #endif
118 
119 #ifdef POK_NEEDS_THREAD_ID
121  return pok_sched_get_current ((uint32_t*) (args->arg1 + infos->base_addr));
122  break;
123 #endif
125  return pok_thread_get_status (args->arg1, (pok_thread_attr_t*) (args->arg2 + infos->base_addr));
126  break;
127 
128 #ifdef POK_NEEDS_ERROR_HANDLING
129 
135  return pok_partition_restart_thread (args->arg1);
136  break;
137 
139  return pok_partition_stop_thread (args->arg1);
140  break;
141 
146  pok_sched_stop_self ();
147  return POK_ERRNO_OK;
148  break;
149 
150 #endif
151 
152 #ifdef POK_NEEDS_PARTITIONS
153  case POK_SYSCALL_PARTITION_SET_MODE:
154  return pok_partition_set_mode_current ((pok_partition_mode_t)args->arg1);
155  break;
156  case POK_SYSCALL_PARTITION_GET_ID:
157  return pok_current_partition_get_id ((uint8_t*)(args->arg1 + infos->base_addr));
158  break;
159  case POK_SYSCALL_PARTITION_GET_PERIOD:
160  return pok_current_partition_get_period ((uint64_t*)(args->arg1 + infos->base_addr));
161  break;
162  case POK_SYSCALL_PARTITION_GET_DURATION:
163  return pok_current_partition_get_duration ((uint64_t*)(args->arg1 + infos->base_addr));
164  break;
165  case POK_SYSCALL_PARTITION_GET_LOCK_LEVEL:
166  return pok_current_partition_get_lock_level ((uint32_t*)(args->arg1 + infos->base_addr));
167  break;
168  case POK_SYSCALL_PARTITION_GET_OPERATING_MODE:
169  return pok_current_partition_get_operating_mode ((pok_partition_mode_t*)(args->arg1 + infos->base_addr));
170  break;
171  case POK_SYSCALL_PARTITION_GET_START_CONDITION:
172  return pok_current_partition_get_start_condition ((pok_start_condition_t*)(args->arg1 + infos->base_addr));
173  break;
174 #endif
175 
176 #ifdef POK_NEEDS_ERROR_HANDLING
177  case POK_SYSCALL_ERROR_HANDLER_CREATE:
178  return pok_error_thread_create (args->arg1 , (void*) (args->arg2));
179  break;
180 
181  case POK_SYSCALL_ERROR_RAISE_APPLICATION_ERROR:
182  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
183  pok_error_raise_application_error ((char*) (args->arg1 + infos->base_addr), args->arg2);
184  return POK_ERRNO_OK;
185  break;
186 
187  case POK_SYSCALL_ERROR_GET:
188  return pok_error_get ((pok_error_status_t*) (args->arg1 + infos->base_addr));
189  break;
190 #endif
191 
192  /* Middleware syscalls */
193 #ifdef POK_NEEDS_PORTS_SAMPLING
194  case POK_SYSCALL_MIDDLEWARE_SAMPLING_CREATE:
195  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
196  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
197  return pok_port_sampling_create ((char*)(args->arg1 + infos->base_addr),
198  (pok_port_size_t) args->arg2,
199  (pok_port_direction_t) args->arg3,
200  (uint64_t) args->arg4,
201  (pok_port_id_t*) (args->arg5 + infos->base_addr));
202  break;
203 
204  case POK_SYSCALL_MIDDLEWARE_SAMPLING_WRITE:
205  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
206 
207  return pok_port_sampling_write ((const pok_port_id_t)args->arg1,
208  (const void*) ((void*)args->arg2 + infos->base_addr),
209  (const uint8_t) args->arg3);
210  break;
211 
212  case POK_SYSCALL_MIDDLEWARE_SAMPLING_READ:
213  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
214  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
215  return pok_port_sampling_read ((const pok_port_id_t)args->arg1,
216  (void*) args->arg2 + infos->base_addr,
217  (pok_port_size_t*) (args->arg3 + infos->base_addr),
218  (bool_t*) (args->arg4 + infos->base_addr));
219  break;
220 
221  case POK_SYSCALL_MIDDLEWARE_SAMPLING_ID:
222  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
223  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
224  return pok_port_sampling_id ((char*)(args->arg1 + infos->base_addr),
225  (pok_port_id_t*)(args->arg2 + infos->base_addr));
226  break;
227 
228 #ifndef POK_GENERATED_CODE
229  case POK_SYSCALL_MIDDLEWARE_SAMPLING_STATUS:
230  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2+infos->base_addr)
231  return pok_port_sampling_status ((const pok_port_id_t)args->arg1,
232  (pok_port_sampling_status_t*) (args->arg2 + infos->base_addr));
233  break;
234 #endif /* POK_GENERATED_CODE */
235 #endif /* POK_NEEDS_PORTS_SAMPLING */
236 
237 
238 #ifdef POK_NEEDS_PORTS_QUEUEING
239  case POK_SYSCALL_MIDDLEWARE_QUEUEING_CREATE:
240  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
241  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
242  return pok_port_queueing_create ((char*) (args->arg1 + infos->base_addr),
243  (pok_port_size_t) args->arg2,
244  (pok_port_direction_t) args->arg3,
246  (pok_port_id_t*) (args->arg5 + infos->base_addr));
247  break;
248 
249  case POK_SYSCALL_MIDDLEWARE_QUEUEING_SEND:
250  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
251  return pok_port_queueing_send ((const pok_port_id_t) args->arg1,
252  (const void*) ((void*)args->arg2 + infos->base_addr),
253  (const uint8_t) (args->arg3),
254  (const uint64_t) args->arg4);
255  break;
256 
257  case POK_SYSCALL_MIDDLEWARE_QUEUEING_RECEIVE:
258  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
259  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
260  return pok_port_queueing_receive ((const pok_port_id_t) args->arg1,
261  (uint64_t) args->arg2,
262  (pok_port_size_t) args->arg3,
263  (void*) ((void*)args->arg4 + infos->base_addr),
264  (pok_port_size_t*) (args->arg5 + infos->base_addr));
265  break;
266 
267  case POK_SYSCALL_MIDDLEWARE_QUEUEING_ID:
268  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
269  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
270  return pok_port_queueing_id ((char*) (args->arg1 + infos->base_addr),
271  (pok_port_id_t*) (args->arg2 + infos->base_addr));
272  break;
273 
274 #ifndef POK_GENERATED_CODE
275  case POK_SYSCALL_MIDDLEWARE_QUEUEING_STATUS:
276  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
277  return pok_port_queueing_status ((const pok_port_id_t) args->arg1,
278  (pok_port_queueing_status_t*) (args->arg2 + infos->base_addr));
279  break;
280 #endif
281 #endif /* POK_NEEDS_PORTS_QUEUEING */
282 
283 #ifdef POK_NEEDS_LOCKOBJECTS
284  case POK_SYSCALL_LOCKOBJ_CREATE:
285  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2+infos->base_addr)
286  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1+infos->base_addr)
287  return pok_lockobj_partition_create ((pok_lockobj_id_t*) (args->arg1 + infos->base_addr),
288  (pok_lockobj_attr_t*) (args->arg2 + infos->base_addr));
289  break;
290 
291  case POK_SYSCALL_LOCKOBJ_OPERATION:
292  if (args->arg2 == NULL)
293  {
294  return pok_lockobj_partition_wrapper ((const uint8_t) args->arg1, NULL);
295  }
296  else
297  {
298  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
299  return pok_lockobj_partition_wrapper ((const uint8_t) args->arg1,
300  (pok_lockobj_lockattr_t*) (args->arg2 + infos->base_addr));
301  }
302  break;
303 #endif /* POK_NEEDS_LOCKOBJECTS */
304 
305 #ifdef POK_NEEDS_IO
306  case POK_SYSCALL_INB:
307  if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
308  (args->arg1 > pok_partitions[infos->partition].io_max))
309  {
310  return -POK_ERRNO_EPERM;
311  }
312  else
313  {
314  return inb((unsigned short) args->arg1);
315  }
316  break;
317 
318  case POK_SYSCALL_OUTB:
319  if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
320  (args->arg1 > pok_partitions[infos->partition].io_max))
321  {
322  return -POK_ERRNO_EPERM;
323  }
324  else
325  {
326  outb((unsigned short) args->arg1, (unsigned char) args->arg2);
327  return POK_ERRNO_OK;
328  }
329  break;
330 #endif /* POK_NEEDS_IO */
331 
332 #ifdef POK_NEEDS_PCI
333  case POK_SYSCALL_PCI_REGISTER:
334  POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
335  return pci_register((void*)args->arg1 + infos->base_addr, infos->partition);
336  break;
337 #endif /* POK_NEEDS_PCI */
338 
339 
346  default:
347 #ifdef POK_NEEDS_ERROR_HANDLING
348  pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
349  pok_sched_activate_error_thread ();
350 #else
351  #ifdef POK_NEEDS_DEBUG
352  printf ("Tried to use syscall %d\n", syscall_id);
353  #endif
354  POK_FATAL ("Unknown syscall");
355 #endif
356  break;
357  }
358 
359  return POK_ERRNO_EINVAL;
360 }