= GIET_VM / User-Level System Calls = The [source:soft/giet_vm/giet_libs/stdio.c stdio.c] and [source:soft/giet_vm/giet_libs/stdio.h stdio.h] files define all system calls provided to user applications by the GIET-VM. They are generally prefixed by ''giet_''. [[PageOutline]] All these functions use a ''syscall'' instruction to enter the system. In case of system call failure (illegal arguments), the syscall return value is -1 (0xFFFFFFFF), and the calling task is killed with a ''giet_exit()''. Therefore, for all these system calls, the return value has not to be tested by the calling task. == Processor related system calls == === 1) void '''giet_proc_xyp'''( unsigned int* cluster_x, unsigned int* cluster_y unsigned int* lpid )=== This function returns the processor identifiers (X,Y,P) from the wired global processor index in CP0_PROCID. * cluster_x : X cluster coordinate * cluster_y : Y cluster coordinate * lpid : local processor index No error possible, as the fixed format is gpid = ( ( cluster_x << Y_WIDTH + cluster_y ) << P_WIDTH ) + lpid === 2) unsigned int '''giet_proctime'''() === This function returns the local processor time from the CP0_TIME register (number of cycles from reset). No error possible, as the processor implements a 32 bits wrapping register. === 3) unsigned int '''giet_rand'''() === This function returns a pseudo-random value derived from both the CP0_PROCID and CP0_TIME registers. No error possible, as the return value is always between 0 & 65535. == Task related system calls == === 1) unsigned int '''giet_proc_task_id'''() === This functions returns (from the calling task context) the local task index, identifying the task amongst all task running on the same processor. No error possible. === 2) unsigned int '''giet_global_task_id'''() === This functions returns (from the calling task context) the global task id, unique in the system. No error possible. === 3) unsigned int '''giet_thread_id'''() === This functions returns (from the calling task context) the thread index, identiying the task in a given vspace. No error possible. == TTY related system calls == The GIET_VM allows an user task to use a private TTY terminal, or to display log message on a shared TTY terminal. === 1) void '''giet_tty_alloc'''() === This function allocates a private terminal to the calling task, and registers the terminal index in the task context. Task exit if no TTY terminal available. === 2) void '''giet_tty_printf'''( char* format, ... ) === This function print formated text on a private terminal that must have been allocated to the calling task in the mapping (''use_tty'' argument). Therefore, it does not take the TTY lock. Only a limited number of formats are supported: * %d : signed decimal * %u : unsigned decimal * %x : 32 bits hexadecimal * %l : 64 bits hexadecimal * %c : char * %s : string Task exit if private terminal index not defined, or in case of illegal format. === 3) void '''giet_tty_getc'''( char* byte ) === This blocking function fetches a single character from the private terminal that must have been allocated to the calling task in the application mapping. It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. Task exit if private TTY index not defined. === 4) void '''giet_tty_getw'''( unsigned int* val ) === This blocking function fetches a string of decimal characters (most significant digit first) to build a 32-bits unsigned integer from the private TTY terminal that must have been allocated to the calling task in the application mapping. It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. The non-blocking system function _tty_read is called several times, and the decimal characters are written in a 32 characters buffer until a character is read. It ignores non-decimal characters, and displays an echo for each decimal character. The character is interpreted, and previous characters can be cancelled. When the character is received, the string is converted to an unsigned int value. If the number of decimal digit is too large for the 32 bits range, the zero value is returned. Task exit if private TTY index not defined. === 5) void '''giet_tty_gets'''( char* buf, unsigned int bufsize ) === This blocking function fetches a string from the private terminal that must have been allocated to the calling task in the application mapping. It writes the string to a fixed length buffer. It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. Up to (bufsize - 1) characters (including the non printable characters) are copied into buffer, and the string is completed by a NUL character. The character is interpreted, and the function close the string with a NUL character if is read. The character is interpreted, and the corresponding character(s) are removed from the target buffer. It does not provide an echo. Task exit if private TTY index not defined. === 6) void '''giet_shr_printf'''( char* format, ... ) === This function print formated text on the kernel terminal. It takes the TTY lock for exclusive access. It supports the same formats as the giet_tty_printf() function. Task exit in case of illegal format. == Timer related system calls == The GIET_VM allows an user task to activate a private timer channel, generating periodical IRQs. This timer is allocated in the external multi-timers peripheral. === 1) void '''giet_timer_alloc'''() This function allocates a private user timer to the calling task, and registers the channel index in the task context. Task exit if no timer channel available === 2) void '''giet_timer_start'''( unsigned int period ) This function starts the private timer allocated to the calling task. Task exit if no channel allocated. === 3) void '''giet_timer_stop'''( ) === This function stops the private timer allocated to the calling task. Task exit if no channel allocated. == File system related system calls == The Giet-VM supports a FAT32 file system. === 1) int '''giet_fat_open'''( const char* pathname, unsigned int flags ) === This function open a file identified by the ''pathname'' argument. The read/write ''flags'' are not supported yet: no effect. Return -1 in case or error. === 2) void '''giet_fat_read'''( unsigned int fd, void* buffer, unsigned int count, unsigned int offset ) === Read ''count'' sectors from a file identified by the ''fd'' argument, skipping ''offset'' sectors in file, and writing into the user memory ''buffer''. The user buffer base address should be 64 bytes aligned. In case or error, it makes a giet_exit(). === 3) void '''giet_fat_write'''( unsigned int fd, void* buffer, unsigned int count, unsigned int offset ) === Write ''count'' sectors into a file identified by the ''fd'' argument, skipping ''offset'' sectors in file, and reading from the user memory ''buffer''. The user buffer base address should be 64 bytes aligned. In case or error, it makes a giet_exit(). === 4) void '''giet_fat_close'''( unsigned int fd ) === Close a file identified by the ''fd'' file descriptor. == Network related system call == The GIET_VM allows a user task to access a private NIC channel, using the CMA component (chained buffers DMA). The NIC channel and the CMA channel are registered in the task context. === 1) int '''giet_nic_tx_alloc'''( ) === This function allocates a private NIC_TX channel (coming with the associated kernel NIC_TX chbuf), and a private CMA channel to the calling task. It registers both indexes in the calling task context, and returns the NIC channel index, as this channel can be shared by severals tasks of a parallel multi-tasks application. The calling task exit if no available NIC_TX channel, or no available CMA channel. === 2) void '''giet_nic_rx_alloc'''( ) === This function allocates a private NIC_RX channel (coming with the associated kernel NIC_RX chbuf), and a private CMA channel to the calling task. It registers both indexes in the calling task context, and returns the NIC channel index, as this channel can be shared by severals tasks of a parallel multi-tasks application. The calling task exit if no available NIC_RX channel, or no available CMA channel. === 3) void '''giet_nic_tx_start'''( ) === This function activates both the NIC_TX channel, and the CMA channel allocated to the calling task. The calling task exit if no allocated NIC_TX channel or no allocated CMA channel, or if the NIC channel argument does not fit the channel allocated to the calling task. === 4) void '''giet_nic_rx_start'''( ) === This function activates both the NIC_RX channel, and the CMA channel allocated to the calling task. The calling task exit if no allocated NIC_RX channel or no allocated CMA channel. === 5) void '''giet_nic_tx_move'''( unsigned int nic_channel, void* buffer ) === This blocking function transfer one container (GIET_NIC_CHBUF_SIZE bytes) from an user buffer to the kernel chbuf defined by the nic_channel argument. * '''nic_channel''' define the NIC channel index. * '''buffer''' is the container base address in user space. Several user tasks can concurrently access the same chbuf, because the syscall handler takes the lock protecting the chbuf. It returns only when the container has been fully transfered. The calling task exit if no NIC channel allocated to the task, or in case of timeout, or if the buffer is not in user space. === 6) void '''giet_nic_rx_move'''( unsigned int nic_channel, void* buffer ) === This blocking function transfer one container (GIET_NIC_CHBUF_SIZE bytes) from the kernel chbuf defined by the nic_channel argument to an user buffer. * '''nic_channel''' define the NIC channel index. * '''buffer''' is the container base address in user space. Several user tasks can concurrently access the same chbuf, because the syscall handler takes the lock protecting the chbuf. It returns only when the container has been fully transfered. The calling task exit if no NIC channel allocated to the task, or in case of timeout, or if the buffer is not in user space. === 7) void '''giet_nic_tx_stop( ) === This function desactivates both the NIC_TX channel and the CMA channel allocated to the calling task. The calling task exit if no allocated NIC_TX channel or no allocated CMA channel. === 8) void '''giet_nic_rx_stop( ) === This function desactivates both the NIC_RX channel and the CMA channel allocated to the calling task. The calling task exit if no allocated NIC_RX channel or no allocated CMA channel. == Frame Buffer related system calls == An user task can access the frame buffer through a memcpy() or through the chained buffer DMA controller (CMA). The four first functions use a private CMA channel that is registered in the task context. The Two last functions use a memcpy(). === 1) void '''giet_fbf_cma_alloc'''() This function allocates a private CMA channel to the calling task, and registers the channel index in the task context. Task exit if no CMA channel available === 2) void '''giet_fbf_cma_start'''( void* buf0, void* buf1, unsigned int length ) === This function initializes the chained buffer DMA controller (CMA) to transfer a stream of images from two user buffers to the frame buffer. It must be used in conjunction with the giet_fbf_cma_display() function. A CMA channel should have been allocated to the calling task in the application mapping. * '''buf0('' is the first user buffer base address * '''buf1''' is the second user buffer base address, * '''length''' is the buffer size (bytes). === 3) void '''giet_fbf_cma_display'''( unsigned int buffer ) === This function enables the transfer of the buffer specified by the ''buffer'' argument (0 or 1). === 4) void '''giet_fbf_cma_stop'''( ) === This function desactivates the CMA channel allocated to the calling task. === 5) void '''giet_fb_sync_read'''( unsigned int offset, void* buffer, unsigned int length ) === This blocking function use a memcopy strategy to transfer data from the frame buffer to an user buffer: ''offset'' defines the offset (in bytes) in the frame buffer, ''buffer'' is the user buffer base address, ''length'' is the number of bytes to be transfered. === 6) void '''giet_fb_sync_write'''( unsigned int offset, void* buffer, unsigned int length ) === This blocking function use a memcopy strategy to transfer data from an user buffer to the frame buffer: ''offset'' defines the offset (in bytes) in the frame buffer, ''buffer'' is the user buffer base address, ''length'' is the number of bytes to be transfered. == Miscelaneous system calls == === 1) void '''giet_exit'''( char* string ) === This function stops execution of the calling task with a TTY message explaining the cause. The user task is descheduled and becomes not runable: it does not consume processor cycles anymore. === 2) void '''giet_assert'''( unsigned int condition, char* string ) === This function uses the giet_exit() system call to kill the calling task if the condition is false. === 3) void '''giet_context_switch'''() === The user task calling this function is descheduled and the processor is allocated to another task. === 4) void '''giet_procnumber'''( unsigned int cluster_xy, unsigned int buffer ) === This function returns in the ''buffer'' argument the number of processors in the cluster specified by the ''cluster_xy'' argument. In case or error (such as illegal cluster index), it makes a giet_exit(). === 5) void '''giet_vobj_get_vbase'''( char* vspace_name, char* vobj_name, unsigned int* vbase) === This function returns in argument ''vbase'' the virtual base address of a vobj defined in the mapping_info data structure. The vobj is identified by the two arguments ''vspace_name'' and ''vobj_name''. In case of error (such as undefined vspace or undefined vobj), it makes a giet_exit(). === 6) void '''giet_vobj_get_length'''( char* vspace_name, char* vobj_name, unsigned int* length) === This function returns in argument ''length'' the length (bytes) of a vobj defined in the mapping_info data structure. The vobj is identified by the two arguments ''vspace_name'' and ''vobj_name''. In case of error (such as undefined vspace or undefined vobj), it makes a giet_exit(). === 7) void '''giet_heap_info'''( unsigned int* vaddr, unsigned int* length, unsigned int x, unsigned int y ); This function supports access to the running task's heap or to a remote heap. If (x < X_SIZE) and (y < Y_SIZE), it returns the base address and length of the heap associated to any task running on cluster(x,y). Otherwise, it returns the base address and length of the heap associated to the calling task. In case of error (such as undefined heap segment in the selected cluster, it returns heap_size = 0). === 8) void '''giet_get_xy'''( void* ptr, unsigned int* px, unsigned int* py ) === This function takes as input a virtual address (''ptr'' argument), and returns through the ''px,py'' arguments the coordinates of the cluster containing the physical address associated to ''ptr''. In case of error (unmapped virtual address), it makes a giet_exit().