/* * sys_display.c - display the current state of a kernel structure on TXT0 * * Author Alain Greiner (2016,2017) * * 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 ///////////////////////////// int sys_display( reg_t type, reg_t arg0, reg_t arg1 ) { // get thread, process and core thread_t * this = CURRENT_THREAD; process_t * process = this->process; core_t * core = this->core; #if CONFIG_DEBUG_SYS_DISPLAY uint64_t tm_start; uint64_t tm_end; tm_start = hal_get_cycles(); if( CONFIG_DEBUG_SYS_DISPLAY < tm_start ) printk("\n[DBG] %s : thread %d enter / process %x / cycle = %d\n", __FUNCTION__, this, process->pid, (uint32_t)tm_start ); #endif if( type == DISPLAY_STRING ) { paddr_t paddr; char kbuf[256]; uint32_t length; char * string = (char *)arg0; // check string in user space if( vmm_v2p_translate( false , string , &paddr ) ) { printk("\n[ERROR] in %s : string buffer %x unmapped\n", __FUNCTION__ , string ); return -1; } // ckeck string length length = hal_strlen_from_uspace( string ); if( length >= 256 ) { printk("\n[ERROR] in %s : string length %d too large\n", __FUNCTION__ , length ); return -1; } // copy string in kernel space hal_strcpy_from_uspace( kbuf , string , 256 ); // print message on TXT0 kernel terminal printk("\n[USER] thread %x / process %x / core[%x,%d] / cycle %d\n %s", this->trdid , process->pid , local_cxy, core->lid , (uint32_t)hal_get_cycles() , kbuf ); } else if( type == DISPLAY_VMM ) { pid_t pid = (pid_t)arg0; // get extended pointer on reference process xptr_t process_xp = cluster_get_reference_process_from_pid( pid ); if( process_xp == XPTR_NULL ) { printk("\n[ERROR] in %s : undefined PID %x\n", __FUNCTION__ , pid ); return -1; } // get cluster and local pointer on process cxy_t process_cxy = GET_CXY( process_xp ); process_t * process_ptr = (process_t *)GET_PTR( process_xp ); // call kernel function if( process_cxy == local_cxy ) { vmm_display( process_ptr , true ); } else { rpc_vmm_display_client( process_cxy , process_ptr , true ); } } else if( type == DISPLAY_SCHED ) { cxy_t cxy = (cxy_t)arg0; lid_t lid = (lid_t)arg1; // check cluster argument if( cluster_is_undefined( cxy ) ) { printk("\n[ERROR] in %s : undefined cluster identifier %x\n", __FUNCTION__ , cxy ); return -1; } // check core argument if( lid >= LOCAL_CLUSTER->cores_nr ) { printk("\n[ERROR] in %s : undefined local index %d\n", __FUNCTION__ , lid ); return -1; } if( cxy == local_cxy ) { sched_display( lid ); } else { rpc_sched_display_client( cxy , lid ); } } else if( type == DISPLAY_CLUSTER_PROCESSES ) { cxy_t cxy = (cxy_t)arg0; // check cluster argument if( cluster_is_undefined( cxy ) ) { printk("\n[ERROR] in %s : undefined cluster identifier %x\n", __FUNCTION__ , cxy ); return -1; } cluster_processes_display( cxy ); } else if( type == DISPLAY_TXT_PROCESSES ) { uint32_t txt_id = (uint32_t)arg0; // check argument if( txt_id >= LOCAL_CLUSTER->nb_txt_channels ) { printk("\n[ERROR] in %s : undefined TXT channel %x\n", __FUNCTION__ , txt_id ); return -1; } process_txt_display( txt_id ); } else if( type == DISPLAY_VFS ) { // call kernel function process_t * process = CURRENT_THREAD->process; vfs_display( process->vfs_root_xp ); } else if( type == DISPLAY_CHDEV ) { chdev_dir_display(); } else { printk("\n[ERROR] in %s : undefined display type %x\n", __FUNCTION__ , type ); return -1; } #if CONFIG_DEBUG_SYS_DISPLAY tm_end = hal_get_cycles(); if( CONFIG_DEBUG_SYS_DISPLAY < tm_end ) printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n", __FUNCTION__, this, process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end ); #endif return 0; } // end sys_display()