/* * hal_do_syscall.c - implementation of syscall handler for TSAR-MIPS32 * * 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 extern reg_t do_syscall( reg_t arg0, reg_t arg1, reg_t arg2, reg_t arg3, reg_t service_nr ); /////////////////////////// static void sys_sigreturn() { register thread_t * this; register uint32_t uzone_src; this = CURRENT_THREAD; uzone_src = this->pws.sigstack_top; uzone_src -= sizeof(this->uzone); hal_copy_from_uspace( &this->uzone, (void*)uzone_src, sizeof(this->uzone) ); if(err) { printk(WARNING, "WARNING: %s: CPU %d, Task %d, Thread %d (%x) [ KILLED ]\n", __FUNCTION__, hal_get_id(), this->task->pid, this->info.order, this); sys_thread_exit((void*)EINTR); } if(current_cpu->fpu_owner == this) { current_cpu->fpu_owner = NULL; hal_fpu_disable(); } thread_clear_signaled(this); this->uzone.regs[V0] = this->info.retval; this->uzone.regs[V1] = this->info.errno; this->uzone.regs[EPC] += 4; } ///////////////////////////////////////////// thread_t * hal_do_syscall( reg_t * regs_tbl ) { register reg_t arg0; register reg_t arg1; register reg_t arg2; register reg_t arg3; register reg_t service_nr; register reg_t retval; register thread_t * this; service_nr = regs_tbl[V0]; if(service_nr == SYS_SIGRETURN) { sys_sigreturn(); return CURRENT_THREAD; } arg0 = regs_tbl[A0]; arg1 = regs_tbl[A1]; arg2 = regs_tbl[A2]; arg3 = regs_tbl[A3]; retval = do_syscall( arg0 , arg1 , arg2 , arg3 , service_nr ); this = CURRENT_THREAD; this->uzone.regs[V0] = retval; this->uzone.regs[V1] = this->info.errno; this->uzone.regs[EPC] += 4; return this; }