source: trunk/kernel/syscalls/sys_display.c @ 598

Last change on this file since 598 was 594, checked in by alain, 5 years ago

Fix various bugs in sys_stat() and sys_mmap() functions.
Improve debug in other functions.

File size: 8.1 KB
RevLine 
[421]1/*
2 * sys_display.c - display the current state of a kernel structure on TXT0
3 *
[440]4 * Author    Alain Greiner (2016,2017,2018)
[421]5 * 
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[457]24#include <hal_kernel_types.h>
[421]25#include <hal_uspace.h>
26#include <errno.h>
[433]27#include <vmm.h>
[421]28#include <cluster.h>
29#include <thread.h>
30#include <process.h>
[433]31#include <string.h>
[443]32#include <shared_syscalls.h>
[421]33
[506]34#include <syscalls.h>
35
[443]36/////////////////////////////////////////////////////////////////////////////////
37// This static function returns a printable string for the type of display.
38/////////////////////////////////////////////////////////////////////////////////
[421]39
[443]40#if DEBUG_SYS_DISPLAY
41static char* display_type_str( uint32_t type )
42{
43    if     ( type == DISPLAY_STRING            ) return "STRING"; 
44    else if( type == DISPLAY_VMM               ) return "VMM"; 
45    else if( type == DISPLAY_SCHED             ) return "SCHED"; 
46    else if( type == DISPLAY_CLUSTER_PROCESSES ) return "CLUSTER_PROCESSES"; 
47    else if( type == DISPLAY_VFS               ) return "VFS"; 
48    else if( type == DISPLAY_CHDEV             ) return "CHDEV"; 
49    else if( type == DISPLAY_TXT_PROCESSES     ) return "TXT_PROCESSES"; 
[580]50    else if( type == DISPLAY_DQDT              ) return "DQDT";
51    else if( type == DISPLAY_BUSYLOCKS         ) return "BUSYLOCKS"; 
[443]52}
53#endif
54
[421]55/////////////////////////////
56int sys_display( reg_t  type,
57                 reg_t  arg0,
58                 reg_t  arg1 )
59{
[433]60
[440]61    error_t     error;
62    vseg_t    * vseg;
63
64    thread_t  * this    = CURRENT_THREAD;
65    process_t * process = this->process;
66
[594]67#if (DEBUG_SYS_DISPLAY || CONFIG_INSTRUMENTATION_SYSCALLS)
68uint64_t     tm_start = hal_get_cycles();
69#endif
70
[438]71#if DEBUG_SYS_DISPLAY
[433]72tm_start = hal_get_cycles();
[438]73if( DEBUG_SYS_DISPLAY < tm_start )
[594]74printk("\n[DBG] %s : thread[%x,%x] enter / type  %s / cycle = %d\n",
75__FUNCTION__, process->pid, this->trdid, display_type_str(type), (uint32_t)tm_start );
[433]76#endif
77
[440]78    ////////////////////////////
[421]79    if( type == DISPLAY_STRING )
80    {
81        char      kbuf[256];
[433]82        uint32_t  length;
[421]83
84        char    * string = (char *)arg0;
[440]85
[421]86        // check string in user space
[440]87        error = vmm_get_vseg( process , (intptr_t)arg0 , &vseg );
88
89        if( error )
[433]90        {
[440]91
92#if DEBUG_SYSCALLS_ERROR
[580]93printk("\n[ERROR] in %s for STRING : string buffer %x unmapped\n",
94__FUNCTION__ , (intptr_t)arg0 );
[440]95#endif
96            this->errno = EINVAL;
[433]97            return -1;
98        }
[421]99
100        // ckeck string length
[433]101        length = hal_strlen_from_uspace( string );
[440]102
[433]103        if( length >= 256 )
104        {
[440]105
106#if DEBUG_SYSCALLS_ERROR
[580]107printk("\n[ERROR] in %s for STRING : string length %d too large\n",
108__FUNCTION__ , length );
[440]109#endif
110            this->errno = EINVAL;
[433]111            return -1;
112        }
[421]113
[440]114        // copy string to kernel space
[421]115        hal_strcpy_from_uspace( kbuf , string , 256 );
116
117        // print message on TXT0 kernel terminal
[440]118        printk("\n%s / cycle %d\n", kbuf, (uint32_t)hal_get_cycles() );
[421]119    }
[440]120    //////////////////////////////
[421]121    else if( type == DISPLAY_VMM )
122    {
[443]123        cxy_t cxy = (cxy_t)arg0;
124        pid_t pid = (pid_t)arg1;
[421]125
[443]126        // check cxy argument
127            if( cluster_is_undefined( cxy ) ) 
128        {
[421]129
[443]130#if DEBUG_SYSCALLS_ERROR
[580]131printk("\n[ERROR] in %s for VMM : process %x in cluster %x not found\n",
132__FUNCTION__ , pid , cxy );
[443]133#endif
134            this->errno = EINVAL;
135            return -1;
136        }
137
138        // get extended pointer on process PID in cluster CXY
139        xptr_t process_xp = cluster_get_process_from_pid_in_cxy( cxy , pid );
140
[433]141            if( process_xp == XPTR_NULL )
142        {
[440]143
144#if DEBUG_SYSCALLS_ERROR
[580]145printk("\n[ERROR] in %s for VMM : process %x in cluster %x not found\n",
146__FUNCTION__ , pid , cxy );
[440]147#endif
148            this->errno = EINVAL;
[433]149            return -1;
150        }
[421]151
[443]152        // get local pointer on process
153        process_t * process = (process_t *)GET_PTR( process_xp );
[421]154
155        // call kernel function
[443]156        if( cxy == local_cxy )
[421]157        {
[443]158                vmm_display( process , true );
[421]159        }
160        else
161        {
[443]162            rpc_vmm_display_client( cxy , process , true );
[421]163        }
164    }
[440]165    ////////////////////////////////
[421]166    else if( type == DISPLAY_SCHED )
167    {
168        cxy_t cxy = (cxy_t)arg0;
169        lid_t lid = (lid_t)arg1;
170
[440]171        // check cxy argument
[433]172            if( cluster_is_undefined( cxy ) ) 
173        {
[440]174
175#if DEBUG_SYSCALLS_ERROR
[580]176printk("\n[ERROR] in %s for SCHED : illegal cxy argument %x\n",
177__FUNCTION__ , cxy );
[440]178#endif
179            this->errno = EINVAL;
[433]180            return -1;
181        }
[421]182
[440]183        // check lid argument
[433]184        if( lid >= LOCAL_CLUSTER->cores_nr )
185        {
[440]186
187#if DEBUG_SYSCALLS_ERROR
[580]188printk("\n[ERROR] in %s for SCHED : illegal lid argument %x\n",
189__FUNCTION__ , lid );
[440]190#endif
191            this->errno = EINVAL;
[433]192            return -1;
193        }
[421]194
195        if( cxy == local_cxy )
196        {
197                sched_display( lid );
198        }
199        else
200        {
[450]201            sched_remote_display( cxy , lid );
[421]202        }
203    }
[440]204    ////////////////////////////////////////////
[435]205    else if( type == DISPLAY_CLUSTER_PROCESSES )
[421]206    {
[584]207        cxy_t  cxy   = (cxy_t)arg0;
208        bool_t owned = (bool_t)arg1;
[421]209
[440]210        // check cxy argument
[433]211            if( cluster_is_undefined( cxy ) )
212        {
[440]213
214#if DEBUG_SYSCALLS_ERROR
[580]215printk("\n[ERROR] in %s for CLUSTER_PROCESSES : illegal cxy argument %x\n",
216__FUNCTION__ , cxy );
[440]217#endif
218            this->errno = EINVAL;
[433]219            return -1;
220        }
[421]221
[584]222        cluster_processes_display( cxy , owned );
[421]223    }
[580]224    //////////////////////////////
225    else if( type == DISPLAY_VFS )
226    {
227        vfs_display( process->vfs_root_xp );
228    }
229    ////////////////////////////////
230    else if( type == DISPLAY_CHDEV )
231    {
232        chdev_dir_display();
233    }
[440]234    ////////////////////////////////////////
[435]235    else if( type == DISPLAY_TXT_PROCESSES )
236    {
237        uint32_t txt_id = (uint32_t)arg0;
238
239        // check argument
240            if( txt_id >= LOCAL_CLUSTER->nb_txt_channels )
241        {
[440]242
243#if DEBUG_SYSCALLS_ERROR
[580]244printk("\n[ERROR] in %s for TXT_PROCESSES : illegal txt_id argument %d\n",
245__FUNCTION__ , txt_id );
[440]246#endif
247            this->errno = EINVAL;
[435]248            return -1;
249        }
250
251        process_txt_display( txt_id );
252    }
[580]253    ///////////////////////////////
254    else if( type == DISPLAY_DQDT )
[421]255    {
[580]256        dqdt_display();
[421]257    }
[580]258    ////////////////////////////////////
259    else if( type == DISPLAY_BUSYLOCKS )
[421]260    {
[594]261        pid_t   pid   = (pid_t)arg0;
[580]262        trdid_t trdid = (trdid_t)arg1;
263
264        // get extended pointer on target thread
265        xptr_t thread_xp = thread_get_xptr( pid , trdid );
266
267        if( thread_xp == XPTR_NULL )
268        {
269
270#if DEBUG_SYSCALLS_ERROR
[594]271printk("\n[ERROR] in %s for BUSYLOCKS : thread[%x,%x] not found\n",
272__FUNCTION__ , pid, trdid );
[580]273#endif
274            this->errno = EINVAL;
275            return -1;
276        }
277
278        thread_display_busylocks( thread_xp );
[421]279    }
[440]280    ////
[433]281    else 
282    {
[440]283
284#if DEBUG_SYSCALLS_ERROR
[580]285printk("\n[ERROR] in %s : undefined display type %d\n",
286        __FUNCTION__ , type );
[440]287#endif
288        this->errno = EINVAL;
[433]289        return -1;
290    }
[421]291
[594]292#if (DEBUG_SYS_DISPLAY || CONFIG_INSTRUMENTATION_SYSCALLS)
293uint64_t     tm_end = hal_get_cycles();
294#endif
295
[438]296#if DEBUG_SYS_DISPLAY
297if( DEBUG_SYS_DISPLAY < tm_end )
[594]298printk("\n[DBG] %s : thread[%x,%x] exit / cycle %d\n",
299__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
[433]300#endif
301
[594]302#if CONFIG_INSTRUMENTATION_SYSCALLS
303hal_atomic_add( &syscalls_cumul_cost[SYS_DISPLAY] , tm_end - tm_start );
304hal_atomic_add( &syscalls_occurences[SYS_DISPLAY] , 1 );
305#endif
306
[433]307    return 0;
308
309}  // end sys_display()
Note: See TracBrowser for help on using the repository browser.