wiki:kernel_syscalls

Version 52 (modified by alain, 8 years ago) (diff)

--

GIET-VM / Syscall Handlers

The sys_handler.c and sys_handler.h files define the kernel data structure and functions that are used to handle the system calls. These functions are prefixed by _ to remind that they can only be executed by a processor in kernel mode.

  1. GIET-VM / Syscall Handlers
    1. Applications related syscall handlers
      1. 1) int _sys_exec_application( char* name )
      2. 2) int _sys_kill_application( char* name )
      3. 3) int _sys_applications_status( )
    2. Threads related syscall handlers
      1. 1) int _sys_pthread_create( pthread_t * buffer , void * attr , …
      2. 2) int _sys_pthread_join( pthread_t trdid )
      3. 3) int _sys_pthread_kill( pthread_t trdid , int signal )
      4. 4) int _sys_pthread_exit( void* string )
      5. 5) int _sys_pthread_yield( )
      6. 6) void _sys_kthread_create( unsigned int x , unsigned int y , …
    3. Coprocessors related syscall handlers
      1. 1) int _sys_coproc_alloc( unsigned int coproc_type , …
      2. 2) int _sys_coproc_release( unsigned int cluster_xy )
      3. 3) int _sys_coproc_channel_init( unsigned int cluster_xy , …
      4. 4) int _sys_coproc_channel_start( unsigned int cluster_xy , …
      5. 5) int _sys_coproc_channel_stop( unsigned int cluster_xc , …
      6. 6) int _sys_coproc_channel_completed( unsigned int cluster_xy , …
    4. TTY related syscall handlers
      1. 1) int _sys_tty_alloc( unsigned int shared )
      2. 2) int _sys_tty_release( )
      3. 3) int _sys_tty_write( const char* buffer, unsigned int …
      4. 4) int _sys_tty_read( char* buffer, unsigned int length, …
    5. TIMER retated syscall handlers
      1. 1) int _sys_tim_alloc()
      2. 2) int _sys_tim_release()
      3. 3) int _sys_tim_start( unsigned int period )
      4. 4) int _sys_tim_stop()
    6. NIC related syscall handlers
      1. 1) void _sys_nic_init( )
      2. 2) int _sys_nic_open( )
      3. 3) int _sys_nic_bind( unsigned int index , unsigned int …
      4. 4) int _sys_nic_connect( unsigned int index , unsigned int …
      5. 5) int _sys_nic_close( unsigned int index )
      6. 6) int _sys_nic_write( unsigned int index , unsigned int vaddr , …
      7. 7) int _sys_nic_read( unsigned int index , unsigned int vaddr , …
      8. 8) void _sys_nic_tx_move( unsigned int channel )
      9. 9) void _sys_nic_rx_move( unsigned int channel )
    7. FBF related syscall handlers
      1. 1) int _sys_fbf_size( unsigned int* width , unsigned int* height )
      2. 2) int _sys_fbf_alloc()
      3. 3) int _sys_fbf_release()
      4. 4) int _sys_fbf_cma_alloc( unsigned int nbufs )
      5. 5) int _sys_fbf_cma_release()
      6. 6) int _sys_fbf_cma_init_buf( unsigned int index , void* …
      7. 7) int _sys_fbf_cma_start( )
      8. 8) int _sys_fbf_cma_check( unsigned int index )
      9. 9) int _sys_fbf_cma_display( unsigned int index )
      10. 10) int _sys_fbf_cma_stop()
      11. 11) int _sys_fbf_sync_write( unsigned int offset, void* buffer, …
      12. 12) int _sys_fbf_sync_read( unsigned int offset, void* buffer, …
    8. Miscelaneous syscall handlers
      1. 1) int _sys_ukn()
      2. 2) int _sys_proc_xyp( unsigned int* x, unsigned int*, …
      3. 3) int _sys_task_exit()
      4. 4) int _sys_context_switch()
      5. 5) int _sys_local_task_id()
      6. 6) int _sys_global_task_id()
      7. 7) int _sys_thread_id()
      8. 8) int _sys_procs_number( unsigned int* x_size, unsigned int* …
      9. 9) int _sys_vseg_get_vbase( char* vspace_name, char* vobj_name, …
      10. 10) int _sys_vseg_get_length( char* vspace_name, char* …
      11. 11) int _sys_xy_from_ptr( void* ptr, unsigned int* x, …
      12. 12) int _sys_heap_info( unsigned int* vaddr, unsigned int* …

Applications related syscall handlers

These functions can be used to dynamically activate / deactivate an application.

1) int _sys_exec_application( char* name )

2) int _sys_kill_application( char* name )

3) int _sys_applications_status( )

These functions implement a subset of the POSIX threads API.

Threads related syscall handlers

1) int _sys_pthread_create( pthread_t * buffer , void * attr , void * function , void * arg )

This function search in the mapping a thread that is declared in the same space as the calling (parent) thread, and has the entry point defined by the function <argument>. If it found a matching thread in the mapping, this thread is activated.

  • buffer : pointer on buffer to store the activated thread TRDID.
  • attr : the attribute argument is not supported : must be NULL.
  • function : pointer on the thread entry function.
  • arg : pointer on function argument.

Returns 0 if success / returns -1 if matching thread not found.

2) int _sys_pthread_join( pthread_t trdid )

3) int _sys_pthread_kill( pthread_t trdid , int signal )

4) int _sys_pthread_exit( void* string )

5) int _sys_pthread_yield( )

6) void _sys_kthread_create( unsigned int x , unsigned int y , unsigned int p , void * function , void * arg )

This function initializes a kernel thread context, for a core identified by the <x,y,p> arguments, in a given scheduler. It allocate a new "ltid" and update the threads field in the scheduler. It is used in kernel-init to create the NIC_TX and NIC_RX kernel threads.

  • x : X cluster coordinate.
  • y : Y cluster coordinate.
  • p : local processor index in cluster.
  • function : pointer on the thread entry function.
  • arg : pointer on function argument.

Coprocessors related syscall handlers

These functions are used to access coprocessors connected to the VCI network with a vci_mwmr_dma controller. They make the assumption that there is only one hardware coprocessor per cluster, and a coprocessor can be identified by the cluster coordinates.

The following structure (defined in the stdio.h file) is used to define a specific TO_COPROC / FROM_COPROC channel.

typedef struct giet_coproc_channel
{
    unsigned int  channel_mode;    // MWMR / DMA_IRQ / DMA_NO_IRQ
    unsigned int  buffer_size;     // memory buffer size
    unsigned int  buffer_vaddr;    // memory buffer virtual address
    unsigned int  mwmr_vaddr;      // MWMR descriptor virtual address
    unsigned int  lock_vaddr;      // lock for MWMR virtual address
} giet_coproc_channel_t;

1) int _sys_coproc_alloc( unsigned int coproc_type , unsigned int* coproc_info , unsigned int* cluster_xy )

This function allocates an hardware coprocessor to the calling task.

  • coproc_type : requested processor type.
  • coproc_info : returns the number of ports (TO_COPROC / FROM_COPROC / CONFIG )
  • cluster_xy : returns the cluster coordinates.

In this implementation, the the requested coprocessor must be in the same cluster as the processor running the calling task.

2) int _sys_coproc_release( unsigned int cluster_xy )

This function des-allocates a previously allocated coprocessor.

  • cluster_xy : cluster coordinates.

3) int _sys_coproc_channel_init( unsigned int cluster_xy , unsigned int channel , giet_coproc_channel_t* desc )

This function initializes specific TO_COPROC or FROM_COPROC communication channel.

  • cluster_xy : cluster coordinates.
  • channel : channel index.
  • desc : pointer on the channel descriptor.

4) int _sys_coproc_channel_start( unsigned int cluster_xy , unsigned int channel )

This function starts a specific TO_COPROC / FROM_COPROC communication channel.

  • cluster_xy : cluster coordinates.
  • channel : channel index.

5) int _sys_coproc_channel_stop( unsigned int cluster_xc , unsigned int channel )

This function stops a specific TO_COPROC / FROM_COPROC communication channel.

  • cluster_xy : cluster coordinates.
  • channel : channel index.

6) int _sys_coproc_channel_completed( unsigned int cluster_xy , unsigned int channel )

This blocking function polls the CHANNEL_STATUS register, and returns only when the transfer is completed. Returns the status value (non-zero value in case of error). It should be used when a channel is operating in MODE_DMA_NO_IRQ.

  • cluster_xy : cluster coordinates.
  • channel : channel index.

TTY related syscall handlers

1) int _sys_tty_alloc( unsigned int shared )

This function allocates a private TTY terminal to the calling thread, and registers the TTY terminal index (called channel) in the thread context. If the <shared> argument is non-zero, the same TTY channel is registered in the context of all others threads in the same vspace, resulting in one single TTY terminal shared by all threads in the vspace. The number of users is registered in the _tty_users[channel] array. An external IRQ (WTI) is dynamically allocated to the processor running the calling thread. The processor coordinates[x,y,p] and the WTI index are registered in the _tty_wti[channel] array.

Returns 0 if success. Returns -1 if no available TTY channel, or TTY already allocated.

2) int _sys_tty_release( )

This function release the TTY channel allocated to the calling thread. The corresponding thread context slot is reset (0xFFFFFFFF value), and the _tty_users[channel] entry is decremented. The corresponding channel keep busy until the value stored in _tty_users[channel] is non-zero.

Returns 0 if success. Returns -1 if TTY already released.

3) int _sys_tty_write( const char* buffer, unsigned int length, unsigned int channel )

This non-blocking function writes a character string from a fixed-length buffer to a TTY terminal identified by the channel argument. If channel argument is 0xFFFFFFFF, the TTY index is found in the task context. It is non blocking: it tests the TTY_STATUS register, and stops the transfer as soon as the TTY_STATUS[WRITE] bit is set. Returns -1 if no TTT terminal allocated to the calling task. Returns the number of characters that have been written if a terminal is allocated.

4) int _sys_tty_read( char* buffer, unsigned int length, unsigned int channel )

This non-blocking function fetches one character from the terminal identified by the channel argument. If the channel argument is 0xFFFFFFFF, the TTY index is obtained from the current task context. It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been filled by the TTY_ISR. It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id] buffer, writes this character to the target buffer, and resets the_tty_rx_full[tty_id] register. The length argument is not used. Returns -1 if no TTY terminal allocated to the calling task. Returns the number of characters that have been read if a terminal is allocated (can be 0 or 1).

TIMER retated syscall handlers

1) int _sys_tim_alloc()

This function allocates a private timer to the calling thread, and register the timer index (called channel) in the thread context. The timer is not shared: a 1 value is registered in the _tim_users[channel] array. An external IRQ (WTI) is dynamically allocated to the processor running the calling thread. The processor coordinates[x,y,p] and the WTI index are registered in the _tty_wti[channel] array.

Returns 0 if success. Return -1 if no timer available, or timer already allocated.

2) int _sys_tim_release()

This function release the TIMER channel allocated to the calling thread. The corresponding thread context slot is reset (0xFFFFFFFF value), and the _tty_users[channel] entry is reset to 0.

Returns 0 if success. Returns -1 if timer already released.

3) int _sys_tim_start( unsigned int period )

This function activates the timer allocated to the calling thread. The <period> argument defines the IRQ period.

Returns 0 if success. Returns -1 if no allocated timer.

4) int _sys_tim_stop()

This function stops the user timer channel allocated to the calling task.

Returns 0 if success. Returns -1 if no allocated timer.

NIC related syscall handlers

1) void _sys_nic_init( )

This function is called by the kernel_init() function. It allocates and initializes, for each NIC channel, the kernel NIC_TX_FIFO and the NIC_RX / NIC_TX kernel threads.

2) int _sys_nic_open( )

This function allocates a socket index to the calling thread, and allocates the socket descriptor in the same cluster as the calling thread. Then it allocates and initialize the NIC_RX_FIFO associated to the socket. Returns 0 if success. Returns -1 if no socket available.

3) int _sys_nic_bind( unsigned int index , unsigned int local_addr , unsigned int local_port )

This function register the local IP address and local port number in the socket descriptor identified by the <index> argument.

  • index : socket index.
  • local_addr : local IPV4 address.
  • local_port : local port.

Returns 0 if success, returns -1 if the socket is not allocated to calling thread.

4) int _sys_nic_connect( unsigned int index , unsigned int remote_addr , unsigned int remote_port )

This function register the local IP address and local port number in the socket descriptor identified by the <index> argument.

  • index : socket index.
  • remote_addr : local IPV4 address.
  • remote_port : local port.

Returns 0 if success. Returns -1 if the socket is not allocated to calling thread.

5) int _sys_nic_close( unsigned int index )

This function release the memory allocated for a socket identified by the <index> argument.

  • index : socket index.

Returns 0 if success, returns -1 if the socket is not allocated to calling thread.

6) int _sys_nic_write( unsigned int index , unsigned int vaddr , unsigned int count )

This blocking function moves a RAW packet from the user buffer to the kernel NIC_TX_FIFO, after building the ETH/IP/UDP headers. In this first implementation, we use a polling strategy in case of FIFO full.

  • index : socket index.
  • vaddr : virtual base address of source user buffer.
  • count : number of bytes.

Returns number of bytes written if success / returns -1 if error

7) int _sys_nic_read( unsigned int index , unsigned int vaddr , unsigned int count )

This blocking function moves a RAW packet from the kernel NIC_RX_FIFO, to the user buffer, after removing the ETH/IP/UDP headers. In this first implementation, we use a polling strategy in case of FIFO empty.

  • index : socket index.
  • vaddr : virtual base address of destination user buffer.
  • count : max number of bytes in user buffer.

Returns number of bytes read if success / returns -1 if error

8) void _sys_nic_tx_move( unsigned int channel )

This function is executed by the NIC_TX kernel thread. It continuously move a stream of ETH paquets from the NIC_TX_FIFO (associated to a given NIC channel) to the NIC_TX_QUEUE (associated to the same channel). The NIC_TX_QUEUE implementation depends on the available NIC hardware (it is implemented as a CHBUF for the VciMasterNic? component). It blocks if the source TX_FIFO is empty or if the dest TX_QUEUE is full.In this first implementation, the blocking uses a busy-waiting policy, but this should be replaced by a descheduling policy.

  • channel : NIC channel index.

9) void _sys_nic_rx_move( unsigned int channel )

This function is executed by the NIC_RX kernel thread. It continuously move a stream of ETH paquets from the NIC_RX_QUEUE (associated to a given NIC channel) to several NIC_RX_FIFOs (one per socket). The NIC_RX_QUEUE implementation depends on the available NIC hardware (it is implemented as a CHBUF for the VciMasterNic? component). It blocks if the source RX_QUEUE is empty or if the dest TX_FIFO is full. In this first implementation, the blocking uses a busy-waiting policy, but this should be replaced by a descheduling policy.

  • channel : NIC channel index.

FBF related syscall handlers

1) int _sys_fbf_size( unsigned int* width , unsigned int* height )

This function returns in the <width> and <height> buffers the Frame Buffer size. It returns always SYSCALL_OK.

2) int _sys_fbf_alloc()

This function takes the exclusive ownership of the frame buffer for the calling thread application. It must be called by a single thread. It register the number of potential users : all threads in the same space as the calling thread. It returns SYSCALL_OK in case of success. It returns SYSCALL_SHARED_PERIPHERAL_BUSY if the frame buffer is already allocated.

3) int _sys_fbf_release()

This function decrement the number of registered users for the frame buffer. It must be called by all the threads of a given application to completely release the frame buffer. It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the frame buffer was not allocated.

4) int _sys_fbf_cma_alloc( unsigned int nbufs )

This function allocates a private CMA channel, that can be used by all threads in the same space as the calling thread. It must be called by a single thread, but the channel index is registered in all threads contexts in the same vspace. The <nbufs> argument define the CMA length (number of chained buffers). Ir returns SYSCALL_OK in case of success. It returns SYSCALL_NO_CHANNEL_AVAILABLE if no CMA channel available. It returns SYSCALL_CHANNEL_ALREADY_ALLOCATED if CMA already allocated. It returns SYSCALL_ILLEGAL_ARGUMENT if <nbufs> is larger than 256.

5) int _sys_fbf_cma_release()

This function decrement the number of registered users for the allocated CMA channel. It must be called by all the threads of a given application to completely release the CMA channel. It stops the CMA transfer, when the last thread in the space releases the CMA channel. It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated.

6) int _sys_fbf_cma_init_buf( unsigned int index , void* buf_vaddr , void* sts_vaddr )

This function register an user buffer and a buffer status in the the CHBUF descriptor associated to the frame buffer. The <index> argument is the buffer index in the CHBUF. The <buf_vaddr> and <sts_vaddr> arguments are the pointers on the user buffer and status. Both the user buffer and the user status must be 64 bytes aligned. It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated. It returns SYSCALL_ADDRESS_NON_ALIGNED if the buffer or status are not 64 bytes aligned. It returns SYSCALL_ADDRESS_NON_USER_ACCESSIBLE if addresses are protected.

7) int _sys_fbf_cma_start( )

This function activates the CMA channel to transfer of a stream of images from the user buffers to the frame buffer. The user buffers musThe CMA component is configured in IN_ORDER transfer mode (blocking when the expected source buffer is not available). It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated. It returns SYSCALL_MISSING_INITIALISATION if the CHBUF was not initialized.

8) int _sys_fbf_cma_check( unsigned int index )

This blocking function checks that the user buffer identified by the <index> argument is empty, and can be reused by the application. It makes an INVAL request to the L2 cache, before testing the source buffer status, because it is modified in XRAM by the CMA component. It returns SYSCALL_OK when the buffer is empty. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated.

9) int _sys_fbf_cma_display( unsigned int index )

This function must be used to signal that the user buffer identified by the <index> argument is full and can be transferred to the frame buffer. It makes a SYNC request to the L2 cache, for both the source user buffer the status, because these data will be read from XRAM by the CMA component. It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated.

10) int _sys_fbf_cma_stop()

This function desactivares the CMA channel allocated to the calling task. It returns SYSCALL_OK in case of success. It returns SYCALL_CHANNEL_NON_ALLOCATED if the CMA channel was not allocated.

11) int _sys_fbf_sync_write( unsigned int offset, void* buffer, unsigned int length )

This function transfer data from an user buffer to the frame_buffer device using a memcpy.

  • offset : offset (in bytes) in the frame buffer.
  • buffer : base address of the memory buffer.
  • length : number of bytes to be transfered.

12) int _sys_fbf_sync_read( unsigned int offset, void* buffer, unsigned int length )

This function transfer data from the frame_buffer device to anuser buffer using a memcpy.

  • offset : offset (in bytes) in the frame buffer.
  • buffer : base address of the memory buffer.
  • length : number of bytes to be transfered.

Miscelaneous syscall handlers

1) int _sys_ukn()

This function executed in case of undefined syscall. It just display an error message on TTY0.

2) int _sys_proc_xyp( unsigned int* x, unsigned int*, unsigned int* p )

This function returns the processor (x,y,p) identifiers.

3) int _sys_task_exit()

The calling task goes to sleeping state, after printing an exit message. It is descheduled and enters the "not runable" mode.

4) int _sys_context_switch()

This function deschedules the calling task. It mask interrupts before calling the _ctx_switch, and restore it when the task is rescheduled.

5) int _sys_local_task_id()

This function returns the current task local index (amongst tasks running on a given processor).

6) int _sys_global_task_id()

This function returns the current task global index (amongst all tasks running on all processors).

7) int _sys_thread_id()

This function returns the current task thread index (amongst all tasks in a given multi-tasks application).

8) int _sys_procs_number( unsigned int* x_size, unsigned int* y_size, unsigned int* nprocs )

Returns in the arguments the 2D mesh size (only clusters containing processors), and the number of processors per cluster.

9) int _sys_vseg_get_vbase( char* vspace_name, char* vobj_name, unsigned int* vbase )

This function returns in the vbase argument the virtual base address of the private vseg identified by the (vspace_name / vseg_name ) couple. Returns 0 if success, -1 if vobj not found.

10) int _sys_vseg_get_length( char* vspace_name, char* vseg_name, unsigned int* length )

This function returns in the length argument the length of the private vseg identified by the (vspace_name / vseg_name ) couple. Returns 0 if success, -1 if vobj not found

11) int _sys_xy_from_ptr( void* ptr, unsigned int* x, unsigned int* y )

This function returns in the (x,y) arguments the coordinates of the cluster where is mapped the ptr virtual address. It use the _get_context_slot() function to get the calling task page table, and uses the _v2p_translate() function to obtain the physical address. Returns 0 if success, -1 if ptr not mapped in the calling task vspace.

12) int _sys_heap_info( unsigned int* vaddr, unsigned int* length, unsigned int x, unsigned int y )

This function returns the information associated to a user heap vseg : vaddr and length.

  • If (x < X_SIZE) and (y < Y_SIZE), it return the heap associated to any task running in cluster(x,y).
  • else, it return the heap associated to the calling task.

Returns 0 if success, returns -1 if not found.