///////////////////////////////////////////////////////////////////////////////////// // File : stdio.c // Date : 01/04/2010 // Author : alain greiner & Joel Porquet // Copyright (c) UPMC-LIP6 ///////////////////////////////////////////////////////////////////////////////////// #include #include #include #include ////////////////////////////////////////////////////////////////////////////// // MIPS32 related system calls ////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////// void giet_proc_xyp( unsigned int* cluster_x, unsigned int* cluster_y, unsigned int* lpid ) { sys_call( SYSCALL_PROC_XYP, (unsigned int)cluster_x, (unsigned int)cluster_y, (unsigned int)lpid, 0 ); } //////////////////////////// unsigned int giet_proctime() { return (unsigned int)sys_call( SYSCALL_PROC_TIME, 0, 0, 0, 0 ); } //////////////////////// unsigned int giet_rand() { unsigned int x = (unsigned int)sys_call( SYSCALL_PROC_TIME, 0, 0, 0, 0); if ((x & 0xF) > 7) { return (x*x & 0xFFFF); } else { return (x*x*x & 0xFFFF); } } ////////////////////////////////////////////////////////////////////////////// // Threads related system calls ////////////////////////////////////////////////////////////////////////////// #define THREAD_CMD_PAUSE 0 #define THREAD_CMD_RESUME 1 #define THREAD_CMD_CONTEXT 2 ////////////////////////////////////////////////////////// int giet_pthread_create( pthread_t* buffer, pthread_attr_t* attr, void* function, void* arg ) { return sys_call( SYSCALL_PTHREAD_CREATE, (unsigned int)buffer, (unsigned int)attr, (unsigned int)function, (unsigned int)arg ); } ////////////////////////////////////// void giet_pthread_exit( void* string ) { sys_call( SYSCALL_PTHREAD_EXIT, (unsigned int)string, 0, 0, 0 ); } //////////////////////////////////////// int giet_pthread_join( pthread_t trdid, void** ptr ) { return sys_call( SYSCALL_PTHREAD_JOIN, trdid, (unsigned int)ptr, 0, 0 ); } /////////////////////////////////////// int giet_pthread_kill( pthread_t trdid, int signal ) { return sys_call( SYSCALL_PTHREAD_KILL, trdid, signal, 0, 0 ); } ///////////////////////// void giet_pthread_yield() { sys_call( SYSCALL_PTHREAD_YIELD, 0, 0, 0, 0 ); } ///////////////////////////////////////////////// void giet_pthread_assert( unsigned int condition, char* string ) { if ( condition == 0 ) giet_pthread_exit( string ); } //////////////////////////////////////////////// void giet_pthread_control( unsigned int command, char* vspace_name, char* thread_name ) { int ret = sys_call( SYSCALL_PTHREAD_CONTROL, command, (unsigned int) vspace_name, (unsigned int) thread_name, 0 ); if ( ret == SYSCALL_VSPACE_NOT_FOUND ) { giet_tty_printf(" ERROR in PTHREAD_CONTROL : " "vspace %s not found\n", vspace_name ); } if ( ret == SYSCALL_THREAD_NOT_FOUND ) { giet_tty_printf(" ERROR in PTHREAD_CONTROL : " "thread %s not found\n", thread_name ); } if ( ret == SYSCALL_UNCOHERENT_THREAD_CONTEXT ) { giet_tty_printf(" ERROR in PTHREAD_CONTROL : " "uncoherent context for thread %s\n", thread_name ); } if ( ret == SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE ) { giet_tty_printf(" ERROR in PTHREAD_CONTROL : " "illegal command type %d\n", command ); } } ////////////////////////////////////////////////////////////////////////////// // Applications related system calls ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////// int giet_kill_application( char* name ) { return ( sys_call( SYSCALL_KILL_APP, (unsigned int)name, 0, 0, 0 ) ); } /////////////////////////////////////// int giet_exec_application( char* name ) { return ( sys_call( SYSCALL_EXEC_APP, (unsigned int)name, 0, 0, 0 ) ); } /////////////////////////////////////////// void giet_applications_status( char* name ) { sys_call( SYSCALL_APPS_STATUS, (unsigned int)name, 0, 0, 0 ); } ////////////////////////////////////////////////////////////////////////////// // Coprocessors related system calls ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// void giet_coproc_alloc( unsigned int cluster_xy, unsigned int coproc_type, unsigned int* coproc_info ) { if ( sys_call( SYSCALL_COPROC_ALLOC, cluster_xy, coproc_type, (unsigned int)coproc_info, 0 ) ) giet_pthread_exit("error in giet_coproc_alloc()"); } ////////////////////////////////////////////////// void giet_coproc_release( unsigned int cluster_xy, unsigned int coproc_type ) { if ( sys_call( SYSCALL_COPROC_RELEASE, cluster_xy, coproc_type, 0 , 0 ) ) giet_pthread_exit("error in giet_coproc_release()"); } ////////////////////////////////////////////////////////////////// void giet_coproc_channel_init( unsigned int cluster_xy, unsigned int coproc_type, unsigned int channel, giet_coproc_channel_t* desc ) { if ( sys_call( SYSCALL_COPROC_CHANNEL_INIT, cluster_xy, coproc_type, channel, (unsigned int)desc ) ) giet_pthread_exit("error in giet_coproc_channel_init()"); } ////////////////////////////////////////////// void giet_coproc_run( unsigned int cluster_xy, unsigned int coproc_type ) { if ( sys_call( SYSCALL_COPROC_RUN, cluster_xy, coproc_type, 0 , 0 ) ) giet_pthread_exit("error in giet_coproc_run()"); } //////////////////////////////////////////////////// void giet_coproc_completed( unsigned int cluster_xy, unsigned int coproc_type ) { if ( sys_call( SYSCALL_COPROC_COMPLETED, cluster_xy, coproc_type, 0 , 0 ) ) giet_pthread_exit("error in giet_coproc_completed"); } ////////////////////////////////////////////////////////////////////////////// // TTY device related system calls ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////// void giet_tty_alloc( unsigned int shared ) { if ( sys_call( SYSCALL_TTY_ALLOC, shared, 0, 0, 0 ) ) giet_pthread_exit("error in giet_tty_alloc()"); } //////////////////////////////////////// void giet_tty_printf( char* format, ...) { va_list args; char string[4096]; unsigned int length; va_start( args, format ); length = xprintf( string , 4096 , format , &args ); va_end( args ); if ( length == 0xFFFFFFFF ) giet_pthread_exit("illegal format in giet_tty_printf()"); if ( sys_call( SYSCALL_TTY_WRITE, (unsigned int)string, // buffer address length, // number of characters 0xFFFFFFFF, // channel index from thread context 0) != length ) giet_pthread_exit("error in giet_tty_printf()"); } ///////////////////////////////// void giet_tty_getc( char * byte ) { int ret; do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int)byte, // buffer address 1, // number of characters 0xFFFFFFFF, // channel index from task context 0); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getc()"); } while (ret != 1); } ///////////////////////////////////// void giet_tty_gets( char* buf, unsigned int bufsize ) { int ret; // return value from syscalls unsigned char byte; unsigned int index = 0; unsigned int string_cancel = 0x00082008; // string containing BS/SPACE/BS while (index < (bufsize - 1)) { // get one character do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int)(&byte), 1, 0xFFFFFFFF, // channel index from task context 0); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); } while (ret != 1); // analyse character if (byte == 0x0A) // LF special character { break; } else if ( (byte == 0x7F) || // DEL special character (byte == 0x08) ) // BS special character { if ( index > 0 ) { index--; // cancel character ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&string_cancel), 3, 0XFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); } } else if ( (byte < 0x20) || (byte > 0x7F) ) // non printable characters { } else // take all other characters { buf[index] = byte; index++; // echo ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&byte), 1, 0XFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_gets()"); } } buf[index] = 0; } /////////////////////////////////////// void giet_tty_getw( unsigned int* val ) { unsigned char buf[32]; unsigned int string_byte = 0x00000000; // string containing one single byte unsigned int string_cancel = 0x00082008; // string containing BS/SPACE/BS unsigned int save = 0; unsigned int dec = 0; unsigned int done = 0; unsigned int overflow = 0; unsigned int length = 0; unsigned int i; int ret; // return value from syscalls // get characters while (done == 0) { // read one character do { ret = sys_call( SYSCALL_TTY_READ, (unsigned int)(&string_byte), 1, 0xFFFFFFFF, // channel index from task context 0); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); } while (ret != 1); // analyse character if ((string_byte > 0x2F) && (string_byte < 0x3A)) // decimal character { buf[length] = (unsigned char)string_byte; length++; // echo ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&string_byte), 1, 0xFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); } else if (string_byte == 0x0A) // LF character { done = 1; } else if ( (string_byte == 0x7F) || // DEL character (string_byte == 0x08) ) // BS character { if ( length > 0 ) { length--; // cancel the character ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&string_cancel), 3, 0xFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); } } // test buffer overflow if ( length >= 32 ) { overflow = 1; done = 1; } } // end while characters // string to int conversion with overflow detection if ( overflow == 0 ) { for (i = 0; (i < length) && (overflow == 0) ; i++) { dec = dec * 10 + (buf[i] - 0x30); if (dec < save) overflow = 1; save = dec; } } // final evaluation if ( overflow == 0 ) { // return value *val = dec; } else { // cancel all echo characters for (i = 0; i < length ; i++) { ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&string_cancel), 3, 0xFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); } // echo character '0' string_byte = 0x30; ret = sys_call( SYSCALL_TTY_WRITE, (unsigned int)(&string_byte), 1, 0xFFFFFFFF, // channel index from task context 0 ); if ( ret < 0 ) giet_pthread_exit("error in giet_tty_getw()"); // return 0 value *val = 0; } } ////////////////////////////////////////////////////////////////////////////////// // TIMER related system calls ////////////////////////////////////////////////////////////////////////////////// /////////////////////// void giet_timer_alloc() { if ( sys_call( SYSCALL_TIM_ALLOC, 0, 0, 0, 0 ) ) giet_pthread_exit("ERROR in TIMER_ALLOC"); } //////////////////////////////////////////// void giet_timer_start( unsigned int period ) { if ( sys_call( SYSCALL_TIM_START, period, 0, 0, 0 ) ) giet_pthread_exit("ERROR in TIMER_START"); } ////////////////////// void giet_timer_stop() { if ( sys_call( SYSCALL_TIM_STOP, 0, 0, 0, 0 ) ) giet_pthread_exit("ERROR in TIMER_STOP"); } ////////////////////////////////////////////////////////////////////////////////// // Frame buffer related system calls ////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// void giet_fbf_size( unsigned int* width, unsigned int* height ) { sys_call( SYSCALL_FBF_SIZE, (unsigned int)width, (unsigned int)height, 0, 0 ); } ///////////////////// void giet_fbf_alloc() { if ( sys_call( SYSCALL_FBF_ALLOC, 0, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_ALLOC"); } //////////////////////////////////////////// void giet_fbf_cma_alloc( unsigned int nbufs ) { if ( sys_call( SYSCALL_FBF_CMA_ALLOC, nbufs, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_ALLOC"); } /////////////////////////////////////////////// void giet_fbf_cma_init_buf( unsigned int index, void* buf_vaddr, void* sts_vaddr ) { if ( sys_call( SYSCALL_FBF_CMA_INIT_BUF, index, (unsigned int)buf_vaddr, (unsigned int)sts_vaddr, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_INIT_BUF"); } ///////////////////////// void giet_fbf_cma_start() { if ( sys_call( SYSCALL_FBF_CMA_START, 0, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_START"); } /////////////////////////////////////////////// void giet_fbf_cma_display( unsigned int index ) { if ( sys_call( SYSCALL_FBF_CMA_DISPLAY, index, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_DISPLAY"); } ///////////////////////////////////////////// void giet_fbf_cma_check( unsigned int index ) { if ( sys_call( SYSCALL_FBF_CMA_CHECK, index, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_CHECK"); } //////////////////////// void giet_fbf_cma_stop() { if ( sys_call( SYSCALL_FBF_CMA_STOP, 0, 0, 0, 0 ) ) giet_pthread_exit("ERROR in FBF_CMA_STOP"); } ////////////////////////////////////////////// void giet_fbf_sync_write( unsigned int offset, void * buffer, unsigned int length ) { if ( sys_call( SYSCALL_FBF_SYNC_WRITE, offset, (unsigned int)buffer, length, 0 ) ) giet_pthread_exit("ERROR in FBF_SYNC_WRITE"); } ///////////////////////////////////////////// void giet_fbf_sync_read( unsigned int offset, void * buffer, unsigned int length ) { if ( sys_call( SYSCALL_FBF_SYNC_READ, offset, (unsigned int)buffer, length, 0 ) ) giet_pthread_exit("ERROR in FBF_SYNC_READ"); } ////////////////////////////////////////////////////////////////////////////////// // NIC related system calls ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////// void giet_nic_rx_alloc( unsigned int xmax, unsigned int ymax ) { if ( sys_call( SYSCALL_NIC_ALLOC, 1, // RX xmax, ymax, 0 ) ) giet_pthread_exit("error in giet_nic_rx_alloc()"); } ////////////////////////////////////////// void giet_nic_tx_alloc( unsigned int xmax, unsigned int ymax ) { if ( sys_call( SYSCALL_NIC_ALLOC, 0, // TX xmax, ymax, 0 ) ) giet_pthread_exit("error in giet_nic_tx_alloc()"); } //////////////////////// void giet_nic_rx_start() { if ( sys_call( SYSCALL_NIC_START, 1, // RX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_start()"); } //////////////////////// void giet_nic_tx_start() { if ( sys_call( SYSCALL_NIC_START, 0, // TX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_start()"); } ///////////////////////////////////// void giet_nic_rx_move( void* buffer ) { if ( sys_call( SYSCALL_NIC_MOVE, 1, // RX (unsigned int)buffer, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_move()"); } ///////////////////////////////////// void giet_nic_tx_move( void* buffer ) { if ( sys_call( SYSCALL_NIC_MOVE, 0, // TX (unsigned int)buffer, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_move()"); } /////////////////////// void giet_nic_rx_stop() { if ( sys_call( SYSCALL_NIC_STOP, 1, // RX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stop()"); } /////////////////////// void giet_nic_tx_stop() { if ( sys_call( SYSCALL_NIC_STOP, 0, // TX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stop()"); } //////////////////////// void giet_nic_rx_stats() { if ( sys_call( SYSCALL_NIC_STATS, 1, // RX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_stats()"); } //////////////////////// void giet_nic_tx_stats() { if ( sys_call( SYSCALL_NIC_STATS, 0, // TX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_stats()"); } //////////////////////// void giet_nic_rx_clear() { if ( sys_call( SYSCALL_NIC_CLEAR, 1, // RX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_rx_clear()"); } //////////////////////// void giet_nic_tx_clear() { if ( sys_call( SYSCALL_NIC_CLEAR, 0, // TX 0, 0, 0 ) ) giet_pthread_exit("error in giet_nic_tx_clear()"); } /////////////////////////////////////////////////////////////////////////////////// // FAT related system calls /////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////// int giet_fat_open( char* pathname, unsigned int flags ) { return sys_call( SYSCALL_FAT_OPEN, (unsigned int)pathname, flags, 0, 0 ); } ///////////////////////////////////////// int giet_fat_close( unsigned int fd_id ) { return sys_call( SYSCALL_FAT_CLOSE, fd_id, 0, 0, 0 ); } ///////////////////////////////////////////// int giet_fat_file_info( unsigned int fd_id, struct fat_file_info_s* info ) { return sys_call( SYSCALL_FAT_FINFO, fd_id, (unsigned int)info, 0, 0 ); } /////////////////////////////////////// int giet_fat_read( unsigned int fd_id, void* buffer, unsigned int count ) { return sys_call( SYSCALL_FAT_READ, fd_id, (unsigned int)buffer, count, 0 ); } /////////////////////////////////////// int giet_fat_pread( unsigned int fd_id, void* buffer, unsigned int count, unsigned int offset ) { return sys_call( SYSCALL_FAT_PREAD, fd_id, (unsigned int)buffer, count, offset ); } //////////////////////////////////////// int giet_fat_write( unsigned int fd_id, void* buffer, unsigned int count ) { return sys_call( SYSCALL_FAT_WRITE, fd_id, (unsigned int)buffer, count, 0 ); } //////////////////////////////////////// int giet_fat_lseek( unsigned int fd_id, unsigned int offset, unsigned int whence ) { return sys_call( SYSCALL_FAT_LSEEK, fd_id, offset, whence, 0 ); } //////////////////////////////////////////// int giet_fat_remove( char* pathname, unsigned int should_be_dir ) { return sys_call( SYSCALL_FAT_REMOVE, (unsigned int)pathname, should_be_dir, 0, 0 ); } ///////////////////////////////////// int giet_fat_rename( char* old_path, char* new_path ) { return sys_call( SYSCALL_FAT_RENAME, (unsigned int)old_path, (unsigned int)new_path, 0, 0 ); } //////////////////////////////////// int giet_fat_mkdir( char* pathname ) { return sys_call( SYSCALL_FAT_MKDIR, (unsigned int)pathname, 0, 0, 0 ); } //////////////////////////////////// int giet_fat_opendir( char* pathname ) { return sys_call( SYSCALL_FAT_OPENDIR, (unsigned int)pathname, 0, 0, 0 ); } //////////////////////////////////// int giet_fat_closedir( unsigned int fd_id ) { return sys_call( SYSCALL_FAT_CLOSEDIR, (unsigned int)fd_id, 0, 0, 0 ); } ////////////////////////////////////////// int giet_fat_readdir( unsigned int fd_id, fat_dirent_t* entry ) { return sys_call( SYSCALL_FAT_READDIR, (unsigned int)fd_id, (unsigned int)entry, 0, 0 ); } ///////////////////////////////////////// int giet_fat_fprintf( unsigned int fd_id, char* format, ... ) { va_list args; char string[4096]; unsigned int count; va_start( args, format ); count = xprintf( string , 4096 , format , &args ); va_end( args ); if ( count == 0xFFFFFFFF ) giet_pthread_exit("error in giet_fat_fprintf()"); return sys_call( SYSCALL_FAT_WRITE, fd_id, (unsigned int)string, count, 0 ); // no physical addressing required } ///////////////////////////////////////// void* giet_fat_mmap( void* vaddr, // MAP_FIXED not supported unsigned int length, unsigned int prot, unsigned int flags, unsigned int fd_id, unsigned int offset ) { if ( flags & MAP_FIXED ) giet_pthread_exit("error in giet_fat_mmap()"); if ( flags & MAP_PRIVATE ) giet_pthread_exit("error in giet_fat_mmap()"); if ( flags & MAP_ANONYMOUS ) giet_pthread_exit("error in giet_fat_mmap()"); if ( length & 0xFFF ) giet_pthread_exit("error in giet_fat_mmap()"); if ( offset & 0xFFF ) giet_pthread_exit("error in giet_fat_mmap()"); return (void*)sys_call( SYSCALL_FAT_MMAP, fd_id, length>>12, offset>>12, prot ); } /////////////////////////////////////////// int giet_fat_munmap( void* vaddr, unsigned int length ) { if ( length & 0xFFF ) giet_pthread_exit("error in giet_fat_munmap()"); if ( (unsigned int)vaddr & 0xFFF ) giet_pthread_exit("error in giet_fat_munmap()"); return sys_call( SYSCALL_FAT_MUNMAP, (unsigned int)vaddr, length>>12, 0, 0 ); } /////////////////////////////////////// int giet_fat_dump( unsigned int type, char* pathname, unsigned int block_id ) { return sys_call( SYSCALL_FAT_DUMP, type, (unsigned int)pathname, block_id, 0 ); } ////////////////////////////////////////////////////////////////////////////////// // Miscellaneous system calls ////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////// void giet_procs_number( unsigned int* x_size, unsigned int* y_size, unsigned int* nprocs ) { if ( sys_call( SYSCALL_PROCS_NUMBER, (unsigned int)x_size, (unsigned int)y_size, (unsigned int)nprocs, 0 ) ) giet_pthread_exit("error in giet_procs_number()"); } //////////////////////////////////////////////////// void giet_vobj_get_vbase( char* vspace_name, char* vobj_name, unsigned int* vbase ) { if ( sys_call( SYSCALL_VOBJ_GET_VBASE, (unsigned int) vspace_name, (unsigned int) vobj_name, (unsigned int) vbase, 0 ) ) giet_pthread_exit("error in giet_vobj_get_vbase()"); } //////////////////////////////////////////////////// void giet_vobj_get_length( char* vspace_name, char* vobj_name, unsigned int* length ) { if ( sys_call( SYSCALL_VOBJ_GET_LENGTH, (unsigned int) vspace_name, (unsigned int) vobj_name, (unsigned int) length, 0 ) ) giet_pthread_exit("error in giet_vobj_get_length()"); } ///////////////////////////////////////// void giet_heap_info( unsigned int* vaddr, unsigned int* length, unsigned int x, unsigned int y ) { sys_call( SYSCALL_HEAP_INFO, (unsigned int)vaddr, (unsigned int)length, x, y ); } ///////////////////////////////////////// void giet_get_xy( void* ptr, unsigned int* px, unsigned int* py ) { if ( sys_call( SYSCALL_GET_XY, (unsigned int)ptr, (unsigned int)px, (unsigned int)py, 0 ) ) giet_pthread_exit("error in giet_get_xy()"); } // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4