POK(kernelpart)
syscall.c File Reference
#include <bsp.h>
#include <types.h>
#include <libc.h>
#include <arch/x86/ioports.h>
#include <arch/x86/pci.h>
#include <errno.h>
#include <core/debug.h>
#include <core/syscall.h>
#include <core/partition.h>
#include <core/thread.h>
#include <core/lockobj.h>
#include <core/time.h>
#include <core/error.h>
#include <middleware/port.h>

Go to the source code of this file.

Functions

pok_ret_t pok_core_syscall (const pok_syscall_id_t syscall_id, const pok_syscall_args_t *args, const pok_syscall_info_t *infos)

Function Documentation

pok_ret_t pok_core_syscall ( const pok_syscall_id_t  syscall_id,
const pok_syscall_args_t args,
const pok_syscall_info_t infos 
)

Function that performs the syscall. It is called by the architecture interruption handler.

Parameters:
syscall_idThis param correspond to the syscal which should be performed. The list of available syscalls is available in the definition of the pok_syscall_id_t type
argsArguments of the syscall. It corresponds to data useful to perform the syscall.
infosInformations about the syscall: which partition/thread initiates the syscall, etc ...
Returns:
Returns an error code, which is defined in include/errno.h

Here is the default syscall handler. In this case, the syscall ID was not properly identified and thus, we should return an error. If error management is activated, we raise an error in kernel of partitions, calling the error handler.

Definition at line 40 of file syscall.c.

{
switch (syscall_id)
{
#if defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_DEBUG)
if (pok_cons_write ((const char*)args->arg1 + infos->base_addr, args->arg2))
{
return POK_ERRNO_OK;
}
else
{
}
break;
#endif
#ifdef POK_NEEDS_PORTS_VIRTUAL
case POK_SYSCALL_MIDDLEWARE_VIRTUAL_CREATE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_virtual_id ( (char*) (args->arg1 + infos->base_addr), (pok_port_id_t*) (args->arg2 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_VIRTUAL_NB_DESTINATIONS:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_virtual_nb_destinations ( (pok_port_id_t) (args->arg1), (uint32_t*) (args->arg2 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_VIRTUAL_DESTINATION:
POK_CHECK_PTR_OR_RETURN(infos->partition, ((void*) args->arg3)+infos->base_addr)
return pok_port_virtual_destination ( (pok_port_id_t) (args->arg1), (uint32_t) (args->arg2), (uint32_t*) (args->arg3 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_VIRTUAL_GET_GLOBAL:
POK_CHECK_PTR_OR_RETURN(infos->partition, (void*) (args->arg2 + infos->base_addr))
return pok_port_virtual_get_global ((pok_port_id_t) (args->arg1), (pok_port_id_t*) (args->arg2 + infos->base_addr));
break;
#endif
#if defined POK_NEEDS_GETTICK
return pok_gettick_by_pointer ((uint64_t*) (args->arg1 + infos->base_addr));
break;
#endif
return pok_partition_thread_create ((uint32_t*) (args->arg1 + infos->base_addr),
(pok_thread_attr_t*) (args->arg2 + infos->base_addr),
(uint8_t) infos->partition);
break;
#ifdef POK_NEEDS_THREAD_SLEEP
return pok_thread_sleep (args->arg1);
break;
#endif
#ifdef POK_NEEDS_THREAD_SLEEP_UNTIL
return pok_thread_sleep_until (args->arg1);
break;
#endif
return pok_sched_end_period ();
break;
#if defined (POK_NEEDS_THREAD_SUSPEND) || defined (POK_NEEDS_ERROR_HANDLING)
return pok_thread_suspend ();
break;
#endif
#ifdef POK_NEEDS_THREAD_ID
return pok_sched_get_current ((uint32_t*) (args->arg1 + infos->base_addr));
break;
#endif
return pok_thread_get_status (args->arg1, (pok_thread_attr_t*) (args->arg2 + infos->base_addr));
break;
#ifdef POK_NEEDS_ERROR_HANDLING
return pok_partition_restart_thread (args->arg1);
break;
return pok_partition_stop_thread (args->arg1);
break;
pok_sched_stop_self ();
return POK_ERRNO_OK;
break;
#endif
#ifdef POK_NEEDS_PARTITIONS
case POK_SYSCALL_PARTITION_SET_MODE:
return pok_partition_set_mode_current ((pok_partition_mode_t)args->arg1);
break;
case POK_SYSCALL_PARTITION_GET_ID:
return pok_current_partition_get_id ((uint8_t*)(args->arg1 + infos->base_addr));
break;
case POK_SYSCALL_PARTITION_GET_PERIOD:
return pok_current_partition_get_period ((uint64_t*)(args->arg1 + infos->base_addr));
break;
case POK_SYSCALL_PARTITION_GET_DURATION:
return pok_current_partition_get_duration ((uint64_t*)(args->arg1 + infos->base_addr));
break;
case POK_SYSCALL_PARTITION_GET_LOCK_LEVEL:
return pok_current_partition_get_lock_level ((uint32_t*)(args->arg1 + infos->base_addr));
break;
case POK_SYSCALL_PARTITION_GET_OPERATING_MODE:
return pok_current_partition_get_operating_mode ((pok_partition_mode_t*)(args->arg1 + infos->base_addr));
break;
case POK_SYSCALL_PARTITION_GET_START_CONDITION:
return pok_current_partition_get_start_condition ((pok_start_condition_t*)(args->arg1 + infos->base_addr));
break;
#endif
#ifdef POK_NEEDS_ERROR_HANDLING
case POK_SYSCALL_ERROR_HANDLER_CREATE:
return pok_error_thread_create (args->arg1 , (void*) (args->arg2));
break;
case POK_SYSCALL_ERROR_RAISE_APPLICATION_ERROR:
pok_error_raise_application_error ((char*) (args->arg1 + infos->base_addr), args->arg2);
return POK_ERRNO_OK;
break;
case POK_SYSCALL_ERROR_GET:
return pok_error_get ((pok_error_status_t*) (args->arg1 + infos->base_addr));
break;
#endif
/* Middleware syscalls */
#ifdef POK_NEEDS_PORTS_SAMPLING
case POK_SYSCALL_MIDDLEWARE_SAMPLING_CREATE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
return pok_port_sampling_create ((char*)(args->arg1 + infos->base_addr),
(pok_port_size_t) args->arg2,
(pok_port_direction_t) args->arg3,
(uint64_t) args->arg4,
(pok_port_id_t*) (args->arg5 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_SAMPLING_WRITE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_sampling_write ((const pok_port_id_t)args->arg1,
(const void*) ((void*)args->arg2 + infos->base_addr),
(const uint8_t) args->arg3);
break;
case POK_SYSCALL_MIDDLEWARE_SAMPLING_READ:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
return pok_port_sampling_read ((const pok_port_id_t)args->arg1,
(void*) args->arg2 + infos->base_addr,
(pok_port_size_t*) (args->arg3 + infos->base_addr),
(bool_t*) (args->arg4 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_SAMPLING_ID:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_sampling_id ((char*)(args->arg1 + infos->base_addr),
(pok_port_id_t*)(args->arg2 + infos->base_addr));
break;
#ifndef POK_GENERATED_CODE
case POK_SYSCALL_MIDDLEWARE_SAMPLING_STATUS:
return pok_port_sampling_status ((const pok_port_id_t)args->arg1,
(pok_port_sampling_status_t*) (args->arg2 + infos->base_addr));
break;
#endif /* POK_GENERATED_CODE */
#endif /* POK_NEEDS_PORTS_SAMPLING */
#ifdef POK_NEEDS_PORTS_QUEUEING
case POK_SYSCALL_MIDDLEWARE_QUEUEING_CREATE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
return pok_port_queueing_create ((char*) (args->arg1 + infos->base_addr),
(pok_port_size_t) args->arg2,
(pok_port_direction_t) args->arg3,
(pok_port_id_t*) (args->arg5 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_QUEUEING_SEND:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_queueing_send ((const pok_port_id_t) args->arg1,
(const void*) ((void*)args->arg2 + infos->base_addr),
(const uint8_t) (args->arg3),
(const uint64_t) args->arg4);
break;
case POK_SYSCALL_MIDDLEWARE_QUEUEING_RECEIVE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg4 + infos->base_addr)
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg5 + infos->base_addr)
return pok_port_queueing_receive ((const pok_port_id_t) args->arg1,
(uint64_t) args->arg2,
(pok_port_size_t) args->arg3,
(void*) ((void*)args->arg4 + infos->base_addr),
(pok_port_size_t*) (args->arg5 + infos->base_addr));
break;
case POK_SYSCALL_MIDDLEWARE_QUEUEING_ID:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr)
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr)
return pok_port_queueing_id ((char*) (args->arg1 + infos->base_addr),
(pok_port_id_t*) (args->arg2 + infos->base_addr));
break;
#ifndef POK_GENERATED_CODE
case POK_SYSCALL_MIDDLEWARE_QUEUEING_STATUS:
return pok_port_queueing_status ((const pok_port_id_t) args->arg1,
(pok_port_queueing_status_t*) (args->arg2 + infos->base_addr));
break;
#endif
#endif /* POK_NEEDS_PORTS_QUEUEING */
#ifdef POK_NEEDS_LOCKOBJECTS
case POK_SYSCALL_LOCKOBJ_CREATE:
POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1+infos->base_addr)
return pok_lockobj_partition_create ((pok_lockobj_id_t*) (args->arg1 + infos->base_addr),
(pok_lockobj_attr_t*) (args->arg2 + infos->base_addr));
break;
case POK_SYSCALL_LOCKOBJ_OPERATION:
if (args->arg2 == NULL)
{
return pok_lockobj_partition_wrapper ((const uint8_t) args->arg1, NULL);
}
else
{
return pok_lockobj_partition_wrapper ((const uint8_t) args->arg1,
(pok_lockobj_lockattr_t*) (args->arg2 + infos->base_addr));
}
break;
#endif /* POK_NEEDS_LOCKOBJECTS */
#ifdef POK_NEEDS_IO
case POK_SYSCALL_INB:
if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
(args->arg1 > pok_partitions[infos->partition].io_max))
{
return -POK_ERRNO_EPERM;
}
else
{
return inb((unsigned short) args->arg1);
}
break;
case POK_SYSCALL_OUTB:
if ((args->arg1 < pok_partitions[infos->partition].io_min) ||
(args->arg1 > pok_partitions[infos->partition].io_max))
{
return -POK_ERRNO_EPERM;
}
else
{
outb((unsigned short) args->arg1, (unsigned char) args->arg2);
return POK_ERRNO_OK;
}
break;
#endif /* POK_NEEDS_IO */
#ifdef POK_NEEDS_PCI
case POK_SYSCALL_PCI_REGISTER:
return pci_register((void*)args->arg1 + infos->base_addr, infos->partition);
break;
#endif /* POK_NEEDS_PCI */
default:
#ifdef POK_NEEDS_ERROR_HANDLING
pok_error_declare (POK_ERROR_KIND_ILLEGAL_REQUEST);
pok_sched_activate_error_thread ();
#else
#ifdef POK_NEEDS_DEBUG
printf ("Tried to use syscall %d\n", syscall_id);
#endif
POK_FATAL ("Unknown syscall");
#endif
break;
}
}