/* * syscall.c - kernel unified syscall entry-point * * Author Ghassan Almaless (2008,2009,2010,2011,2012) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH.is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH.is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH.; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ///////////////////////////////// static error_t sys_notAvailable() { printk(WARNING, "WARNING: Undefined system call\n"); return ENOSYS; } ////////////////////////////////////////////////////////////////////////// // Syscall vector definition ////////////////////////////////////////////////////////////////////////// typedef int (*sys_func_t) (); static const sys_func_t sys_call_tbl[SYSCALLS_NR] = { sys_thread_exit, // 0 sys_mmap, // 1 sys_thread_create, // 2 sys_thread_join, // 3 sys_thread_detach, // 4 sys_thread_yield, // 5 sys_sem, // 6 sys_cond_var, // 7 sys_barrier, // 8 sys_rwlock, // 9 sys_thread_sleep, // 10 sys_thread_wakeup, // 11 sys_open, // 12 sys_creat, // 13 sys_read, // 14 sys_write, // 15 sys_lseek, // 16 sys_close, // 17 sys_unlink, // 18 sys_pipe, // 19 sys_chdir, // 20 sys_mkdir, // 21 sys_mkfifo, // 22 sys_opendir, // 23 sys_readdir, // 24 sys_closedir, // 25 sys_getcwd, // 26 sys_clock, // 27 sys_alarm, // 28 sys_dma_memcpy, // 29 sys_utls, // 30 sys_notAvailable, // 31 reserved for sigreturn TODO ??? [AG] sys_signal, // 32 sys_sigreturn_setup, // 33 sys_kill, // 34 sys_getpid, // 35 sys_fork, // 36 sys_exec, // 37 sys_thread_getattr, // 38 sys_ps, // 39 sys_madvise, // 40 sys_mcntl, // 41 sys_stat, // 42 sys_thread_migrate, // 43 sys_sbrk, // 44 sys_rmdir, // 45 sys_ftime, // 46 sys_chmod, // 47 sys_fsync, // 48 sys_gettimeofday, // 49 sys_times // 50 }; ///////////////////////////// reg_t do_syscall ( reg_t arg0, reg_t arg1, reg_t arg2, reg_t arg3, reg_t service_num ) { int32_t return_val = 0; // default value thread_t * this = CURRENT_THREAD; cpu_t * cpu = thread_current_cpu( this ); // change thread state this->state = S_KERNEL; // prepare kernel time computation tm_usr_compute( this ); /* TODO Pourqoi cette sauvegarde ? [AG] return_val = cpu_context_save( &this->info.pss ); if(return_val != 0) { // Reload these pointers as the process may be forked this = CURRENT_THREAD; cpu = current_cpu; cpu_wbflush(); return_val = this->info.retval; goto END_DO_SYSCALL; } */ // check syscall index if( service_num >= SYSCALLS_NR ) { printk(INFO, "INFO %s : Undefined sysccall %d / thread = %x in cluster %x\n", __FUNCTION__, service_num, this, cluster_cxy ); this->info.errno = ENOSYS; goto END_DO_SYSCALL; } // debug message before syscall execution if( this->info.isTraced == true ) { printk(DEBUG, "DEBUG %s : Pid %d / Tid %d / CPU %d in cluster %x\n" " Service %d / Arg0 %x / Arg1 %x / Arg2 %x / Arg3 %x\n", __FUNCTION__, this->process->pid, this->info.order, cpu->lid, cluster_cxy, service_num, arg0, arg1, arg2, arg3); } // reset errno this->info.errno = 0; // enable interrupts cpu_enable_all_irq( NULL ); // call the proper kernel function return_val = sys_call_tbl[service_num] (arg0,arg1,arg2,arg3); // disable interrupts cpu_disable_all_irq(NULL); // debug message after syscall execution if(this->info.isTraced == true) { printk(DEBUG, "DEBUG %s : Pid %d / Tid %d / CPU %d in cluster %x\n" " Service %d / Return = %x / Error = %d\n", __FUNCTION__, this->process->pid, this->info.order, cpu->lid, cluster_cxy, service_num, return_val, this->info.errno ); } END_DO_SYSCALL: // compute kernel time tm_sys_compute(this); // update thread state this->info.retval = return_val; this->state = S_USER; // notify syscall completion signal_notify( this ); return return_val; } // end do_syscall()