source: trunk/kernel/kern/rpc.c @ 664

Last change on this file since 664 was 657, checked in by alain, 5 years ago

Introduce remote_buf.c/.h & socket.c/.h files.
Update dev_nic.c/.h files.

File size: 103.0 KB
RevLine 
[1]1/*
[437]2 * rpc.c - RPC operations implementation.
[1]3 *
[657]4 * Author    Alain Greiner (2016,2017,2018,2019,2020)
[1]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
[14]24#include <kernel_config.h>
[457]25#include <hal_kernel_types.h>
[625]26#include <hal_vmm.h>
[1]27#include <hal_atomic.h>
28#include <hal_remote.h>
29#include <hal_irqmask.h>
30#include <hal_special.h>
31#include <printk.h>
[612]32#include <user_dir.h>
[1]33#include <remote_sem.h>
34#include <core.h>
35#include <mapper.h>
[5]36#include <chdev.h>
[1]37#include <bits.h>
38#include <thread.h>
39#include <cluster.h>
40#include <process.h>
41#include <vfs.h>
42#include <fatfs.h>
43#include <rpc.h>
44
[433]45
[1]46/////////////////////////////////////////////////////////////////////////////////////////
[564]47// Array of function pointers and array of printable strings.
48// These arrays must be kept consistent with enum in rpc.h file.
[1]49/////////////////////////////////////////////////////////////////////////////////////////
50
51rpc_server_t * rpc_server[RPC_MAX_INDEX] =
52{
[632]53    &rpc_undefined,                        // 0
54    &rpc_undefined,                        // 1
55    &rpc_undefined,                        // 2
[601]56    &rpc_process_make_fork_server,         // 3
[614]57    &rpc_user_dir_create_server,           // 4
58    &rpc_user_dir_destroy_server,          // 5
[601]59    &rpc_thread_user_create_server,        // 6
60    &rpc_thread_kernel_create_server,      // 7
[657]61    &rpc_undefined,                        // 8
[601]62    &rpc_process_sigaction_server,         // 9
[1]63
[657]64    &rpc_undefined,                        // 10
65    &rpc_undefined,                        // 11
66    &rpc_undefined,                        // 12
67    &rpc_undefined,                        // 13
68    &rpc_undefined,                        // 14
69    &rpc_vmm_resize_vseg_server,           // 15
70    &rpc_vmm_remove_vseg_server,           // 16
71    &rpc_vmm_create_vseg_server,           // 17
72    &rpc_vmm_set_cow_server,               // 18
73    &rpc_undefined,                        // 19
[1]74};
75
[564]76char * rpc_str[RPC_MAX_INDEX] =
77{
[632]78    "undefined_0",               // 0
79    "undefined_1",               // 1
80    "undefined_2",               // 2
[601]81    "PROCESS_MAKE_FORK",         // 3
[614]82    "USER_DIR_CREATE",           // 4
83    "USER_DIR_DESTROY",          // 5
[601]84    "THREAD_USER_CREATE",        // 6
85    "THREAD_KERNEL_CREATE",      // 7
[657]86    "FBF_DISPLAY",               // 8
[601]87    "PROCESS_SIGACTION",         // 9
[564]88
[657]89    "undefined_10",              // 10
90    "undefined_11",              // 11
91    "undefined_12",              // 12
92    "undefined_13",              // 13
93    "undefined_14",              // 14
94    "VMM_RESIZE_VSEG",           // 15
95    "VMM_REMOVE_VSEG",           // 16
96    "VMM_CREATE_VSEG",           // 17
97    "VMM_SET_COW",               // 18
98    "undefined_19",              // 19
[564]99};
100
101//////////////////////////////////////////////////////////////////////////////////
[503]102void __attribute__((noinline)) rpc_undefined( xptr_t xp __attribute__ ((unused)) )
[1]103{
[492]104        assert( false , "called in cluster %x", local_cxy );
[1]105}
106
[409]107/***************************************************************************************/
[583]108/************ Generic function supporting RPCs : client side ***************************/
[409]109/***************************************************************************************/
110
111///////////////////////////////////////
112void rpc_send( cxy_t        server_cxy, 
[416]113               rpc_desc_t * rpc )
[409]114{
[438]115    lid_t              server_core_lid;
116    lid_t              client_core_lid;
117    volatile error_t   full;
118    thread_t         * this;
[409]119
[457]120    full            = 0;
121    this            = CURRENT_THREAD;
122    client_core_lid = this->core->lid;
123
[619]124    // check calling thread can yield when is not the IDLE thread
[581]125    // RPCs executed by the IDLE thread during kernel_init do not deschedule
126    if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ );
[564]127
[440]128    // select a server_core : use client core index if possible / core 0 otherwise
[564]129    if( client_core_lid < hal_remote_l32( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) )
[438]130    {
131        server_core_lid = client_core_lid;
132    }
133    else
134    {   
135        server_core_lid = 0;
136    }
137
[583]138    // register client_thread and client_core in RPC descriptor
[436]139    rpc->thread = this;
[438]140    rpc->lid    = client_core_lid;
[409]141
[438]142    // build extended pointer on the RPC descriptor
[409]143        xptr_t   desc_xp = XPTR( local_cxy , rpc );
144
[436]145    // get local pointer on rpc_fifo in remote cluster,
[564]146    remote_fifo_t * rpc_fifo    = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
147    xptr_t          rpc_fifo_xp = XPTR( server_cxy , rpc_fifo );
[409]148
[564]149        // post RPC in remote fifo / deschedule without blocking if fifo full
[409]150    do
151    { 
[564]152        full = remote_fifo_put_item( rpc_fifo_xp , (uint64_t )desc_xp );
153
[436]154            if ( full ) 
[409]155        {
156            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
157            __FUNCTION__ , local_cxy , server_cxy );
158
[436]159            // deschedule without blocking
160            sched_yield("RPC fifo full");
[409]161        }
162    }
[436]163    while( full );
[409]164 
[457]165#if DEBUG_RPC_CLIENT_GENERIC
[583]166uint32_t cycle = (uint32_t)hal_get_cycles();
[564]167uint32_t items = remote_fifo_items( rpc_fifo_xp );
[457]168if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[601]169printk("\n[%s] thread[%x,%x] / rpc %s / server[%x,%d] / items %d / cycle %d\n",
170__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], 
[583]171server_cxy, server_core_lid, items, cycle );
[457]172#endif
[409]173       
[457]174   // send IPI to the selected server core
175   dev_pic_send_ipi( server_cxy , server_core_lid );
[409]176
[564]177    // wait RPC completion before returning if blocking RPC :
[619]178    // - deschedule without blocking if thread idle (in kernel init)
[564]179    // - block and deschedule policy for any other thread
[416]180    if ( rpc->blocking )
[409]181    {
[564]182        if( this->type == THREAD_IDLE )  // deschedule without blocking policy
[409]183        {
[564]184 
[438]185#if DEBUG_RPC_CLIENT_GENERIC
[436]186cycle = (uint32_t)hal_get_cycles();
[438]187if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[601]188printk("\n[%s] thread[%x,%x] enter waiting loop for rpc %s / cycle %d\n",
189__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
[436]190#endif
[619]191             while( 1 )
192             {
193                 // check responses counter
194                 if( hal_remote_l32( XPTR( local_cxy , rpc->rsp ) ) == 0 ) break;
195                   
196                 // deschedule
197                 sched_yield("busy_waiting RPC completion");
198             }
[409]199
[438]200#if DEBUG_RPC_CLIENT_GENERIC
[436]201cycle = (uint32_t)hal_get_cycles();
[438]202if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[601]203printk("\n[%s] thread[%x,%x] received response for rpc %s / cycle %d\n",
204__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
[436]205#endif
[564]206 
207        }
208        else                            // block and deschedule policy
[409]209        {
210
[438]211#if DEBUG_RPC_CLIENT_GENERIC
[436]212cycle = (uint32_t)hal_get_cycles();
[438]213if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[601]214printk("\n[%s] thread[%x,%x] blocks & deschedules for rpc %s / cycle %d\n",
215__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
[436]216#endif
[409]217
[564]218        // block client thread
219        thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
220
221        // deschedule
222        sched_yield("blocked on RPC");
223
[438]224#if DEBUG_RPC_CLIENT_GENERIC
[436]225cycle = (uint32_t)hal_get_cycles();
[438]226if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[619]227printk("\n[%s] thread[%x,%x] resumes after rpc %s / cycle %d\n",
[601]228__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
[436]229#endif
[409]230        }
231
[564]232// response must be available for a blocking RPC
[619]233assert( (*rpc->rsp == 0) , "illegal response for RPC %s\n", rpc_str[rpc->index] );
[564]234
[409]235    }
[564]236    else       // non blocking RPC
[436]237    {
238
[438]239#if DEBUG_RPC_CLIENT_GENERIC
[436]240cycle = (uint32_t)hal_get_cycles();
[438]241if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
[601]242printk("\n[%s] thread[%x,%x] returns for non blocking rpc %s / cycle %d\n",
243__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
[436]244#endif
245
246    }
[409]247}  // end rpc_send()
248
249
250/***************************************************************************************/
251/************ Generic functions supporting RPCs : server side **************************/
252/***************************************************************************************/
253
[564]254////////////////////////////
[619]255void rpc_server_func( void )
[409]256{
[440]257    error_t         empty;              // local RPC fifo state
258    xptr_t          desc_xp;            // extended pointer on RPC request
259    cxy_t           desc_cxy;           // RPC request cluster (client)
260    rpc_desc_t    * desc_ptr;           // RPC request local pointer
261    uint32_t        index;              // RPC request index
262    thread_t      * client_ptr;         // local pointer on client thread
[619]263    xptr_t          client_xp;          // extended pointer on client thread
264    lid_t           client_lid;         // local index of client core
[440]265        thread_t      * server_ptr;         // local pointer on server thread
266    xptr_t          server_xp;          // extended pointer on server thread
[619]267    lid_t           server_lid;         // local index of server core
[440]268        remote_fifo_t * rpc_fifo;           // local pointer on RPC fifo
[619]269    uint32_t      * rsp_ptr;            // local pointer on responses counter
270    xptr_t          rsp_xp;             // extended pointer on responses counter
271    uint32_t        responses;          // number of expected responses
272
[409]273    // makes RPC thread not preemptable
274        hal_disable_irq( NULL );
275 
[440]276        server_ptr      = CURRENT_THREAD;
277    server_xp       = XPTR( local_cxy , server_ptr );
[619]278    server_lid      = server_ptr->core->lid;
279        rpc_fifo        = &LOCAL_CLUSTER->rpc_fifo[server_lid];
[409]280
[564]281    // "infinite" RPC thread loop
282        while(1)
[409]283        {
284        // try to take RPC_FIFO ownership
[564]285        if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) ) 
[409]286        {
[436]287
[438]288#if DEBUG_RPC_SERVER_GENERIC
[436]289uint32_t cycle = (uint32_t)hal_get_cycles();
[438]290if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[611]291printk("\n[%s] RPC thread[%x,%x] on core[%d] takes RPC_FIFO ownership / cycle %d\n",
[619]292__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, server_lid, cycle );
[436]293#endif
[564]294                // try to consume one RPC request 
295                empty = remote_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
296
297            // release RPC_FIFO ownership
298            rpc_fifo->owner = 0;
299
300            // handle RPC request if success
301                if ( empty == 0 )   
[409]302            {
[564]303                // get client cluster and pointer on RPC descriptor
304                desc_cxy = GET_CXY( desc_xp );
305                desc_ptr = GET_PTR( desc_xp );
[409]306
[619]307                // get relevant infos from RPC descriptor
[610]308                    index      = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
309                client_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
[619]310                rsp_ptr    = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->rsp ) );
311                client_lid = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->lid ) );
[409]312
[619]313                rsp_xp     = XPTR( desc_cxy , rsp_ptr );
314                client_xp  = XPTR( desc_cxy , client_ptr );
315
[438]316#if DEBUG_RPC_SERVER_GENERIC
[436]317cycle = (uint32_t)hal_get_cycles();
[564]318uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) );
[438]319if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[611]320printk("\n[%s] RPC thread[%x,%x] got rpc %s / client_cxy %x / items %d / cycle %d\n",
321__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], desc_cxy, items, cycle );
[436]322#endif
[610]323                // register client thread in RPC thread descriptor
[619]324                server_ptr->rpc_client_xp = client_xp;
[610]325 
[564]326                // call the relevant server function
327                rpc_server[index]( desc_xp );
[409]328
[641]329                // update responses counter
330                responses = hal_remote_atomic_add( rsp_xp , -1 );
331
[438]332#if DEBUG_RPC_SERVER_GENERIC
[436]333cycle = (uint32_t)hal_get_cycles();
[438]334if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[641]335printk("\n[%s] RPC thread[%x,%x] completes rpc %s / responses %d / cycle %d\n",
336__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], responses, cycle );
[436]337#endif
[619]338                // decrement expected responses counter
339                // unblock client thread if last response
340                if( responses == 1 ) 
[564]341                {
342                    // unblock client thread
[619]343                    thread_unblock( client_xp , THREAD_BLOCKED_RPC );
[409]344
[564]345                    hal_fence();
[409]346
[438]347#if DEBUG_RPC_SERVER_GENERIC
348cycle = (uint32_t)hal_get_cycles();
[619]349trdid_t     client_trdid = hal_remote_l32( XPTR( desc_cxy , &client_ptr->trdid ) );
350process_t * process      = hal_remote_lpt( XPTR( desc_cxy , &client_ptr->process ) );
351pid_t       client_pid   = hal_remote_l32( XPTR( desc_cxy , &process->pid ) );
[438]352if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[611]353printk("\n[%s] RPC thread[%x,%x] unblocked client thread[%x,%x] / cycle %d\n",
354__FUNCTION__, server_ptr->process->pid, server_ptr->trdid,
[619]355client_pid, client_trdid, cycle );
[438]356#endif
[564]357                    // send IPI to client core
[619]358                    dev_pic_send_ipi( desc_cxy , client_lid );
[611]359                }
[564]360            }  // end RPC handling if fifo non empty
361        }  // end if RPC_fIFO ownership successfully taken and released
[409]362
[564]363        // sucide if too many RPC threads
[619]364        if( LOCAL_CLUSTER->rpc_threads[server_lid] >= CONFIG_RPC_THREADS_MAX )
[409]365            {
366
[438]367#if DEBUG_RPC_SERVER_GENERIC
[436]368uint32_t cycle = (uint32_t)hal_get_cycles();
[438]369if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[611]370printk("\n[%s] RPC thread[%x,%x] suicides / cycle %d\n",
371__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
[436]372#endif
[409]373            // update RPC threads counter
[619]374                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[server_lid] , -1 );
[409]375
[440]376            // RPC thread blocks on GLOBAL
377                thread_block( server_xp , THREAD_BLOCKED_GLOBAL );
378
379            // RPC thread set the REQ_DELETE flag to suicide
380            hal_remote_atomic_or( server_xp , THREAD_FLAG_REQ_DELETE );
[409]381            }
[564]382        // block and deschedule otherwise
[440]383        else
384        {
[409]385
[438]386#if DEBUG_RPC_SERVER_GENERIC
[436]387uint32_t cycle = (uint32_t)hal_get_cycles();
[438]388if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
[619]389printk("\n[%s] RPC thread[%x,%x] blocks & deschedules / cycle %d\n",
[611]390__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
[436]391#endif
[564]392            // RPC thread blocks on IDLE
393            thread_block( server_xp , THREAD_BLOCKED_IDLE );
[409]394
[440]395            // RPC thread deschedules
[564]396            sched_yield("RPC_FIFO empty");
[440]397        }
[438]398        } // end infinite loop
[409]399
[619]400} // end rpc_server_func()
[409]401
[619]402
[657]403/***************************************************************************************/
404/************ Marshaling functions ordered by increasing index *************************/
405/***************************************************************************************/
406
407
[1]408/////////////////////////////////////////////////////////////////////////////////////////
[657]409// [0]           undefined                                               
[1]410/////////////////////////////////////////////////////////////////////////////////////////
411
412/////////////////////////////////////////////////////////////////////////////////////////
[657]413// [1]           undefined                                               
[1]414/////////////////////////////////////////////////////////////////////////////////////////
415
[409]416/////////////////////////////////////////////////////////////////////////////////////////
[657]417// [2]           undefined                                               
[409]418/////////////////////////////////////////////////////////////////////////////////////////
419
[625]420
[1]421/////////////////////////////////////////////////////////////////////////////////////////
[657]422// [3]           Marshaling function attached to RPC_MAKE_FORK           
[1]423/////////////////////////////////////////////////////////////////////////////////////////
424
[408]425///////////////////////////////////////////////////
426void rpc_process_make_fork_client( cxy_t       cxy,
427                                   xptr_t      ref_process_xp,      // in
428                                   xptr_t      parent_thread_xp,    // in
429                                   pid_t     * child_pid,           // out
430                                   thread_t ** child_thread_ptr,    // out     
431                                   error_t   * error )              // out
[1]432{
[438]433#if DEBUG_RPC_PROCESS_MAKE_FORK
[564]434thread_t * this = CURRENT_THREAD;
[438]435uint32_t cycle = (uint32_t)hal_get_cycles();
436if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
[601]437printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
438__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]439#endif
440
[619]441    uint32_t responses = 1;
[1]442
443    // initialise RPC descriptor header
444    rpc_desc_t  rpc;
[408]445    rpc.index    = RPC_PROCESS_MAKE_FORK;
[416]446    rpc.blocking = true;
[619]447    rpc.rsp      = &responses;
[1]448
449    // set input arguments in RPC descriptor 
[440]450    rpc.args[0] = (uint64_t)ref_process_xp;
451    rpc.args[1] = (uint64_t)parent_thread_xp;
[1]452
[436]453    // register RPC request in remote RPC fifo
[416]454    rpc_send( cxy , &rpc );
[1]455
456    // get output arguments from RPC descriptor
[408]457    *child_pid         = (pid_t)rpc.args[2];
458    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
459    *error             = (error_t)rpc.args[4];     
[279]460
[438]461#if DEBUG_RPC_PROCESS_MAKE_FORK
462cycle = (uint32_t)hal_get_cycles();
463if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
[601]464printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
465__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]466#endif
[1]467}
468
[408]469//////////////////////////////////////////////
470void rpc_process_make_fork_server( xptr_t xp )
[1]471{
[438]472#if DEBUG_RPC_PROCESS_MAKE_FORK
[564]473thread_t * this = CURRENT_THREAD;
[438]474uint32_t cycle = (uint32_t)hal_get_cycles();
475if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
[601]476printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
477__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]478#endif
[409]479
[408]480    xptr_t     ref_process_xp;     // extended pointer on reference parent process
481    xptr_t     parent_thread_xp;   // extended pointer on parent thread
482    pid_t      child_pid;          // child process identifier
483    thread_t * child_thread_ptr;   // local copy of exec_info structure
484    error_t    error;              // local error status
[1]485
486    // get client cluster identifier and pointer on RPC descriptor
[436]487    cxy_t        client_cxy  = GET_CXY( xp );
488    rpc_desc_t * desc        = GET_PTR( xp );
[1]489
[408]490    // get input arguments from cient RPC descriptor
[564]491    ref_process_xp   = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
492    parent_thread_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[1]493
494    // call local kernel function
[408]495    error = process_make_fork( ref_process_xp,
496                               parent_thread_xp,
497                               &child_pid,
498                               &child_thread_ptr ); 
[1]499
500    // set output argument into client RPC descriptor
[564]501    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
502    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
503    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
[296]504
[438]505#if DEBUG_RPC_PROCESS_MAKE_FORK
506cycle = (uint32_t)hal_get_cycles();
507if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
[601]508printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
509__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]510#endif
[1]511}
512
513/////////////////////////////////////////////////////////////////////////////////////////
[619]514// [4]      Marshaling functions attached to RPC_USER_DIR_CREATE 
[1]515/////////////////////////////////////////////////////////////////////////////////////////
516
[612]517////////////////////////////////////////////////////
518void rpc_user_dir_create_client( cxy_t          cxy,
519                                 vfs_inode_t *  inode,
[614]520                                 xptr_t         ref_xp,
[612]521                                 user_dir_t  ** dir )
522{
523#if DEBUG_RPC_USER_DIR_CREATE
524thread_t * this = CURRENT_THREAD;
525uint32_t cycle = (uint32_t)hal_get_cycles();
526if( cycle > DEBUG_RPC_USER_DIR_CREATE)
527printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
528__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
529#endif
530
[619]531    uint32_t responses = 1;
[612]532
533    // initialise RPC descriptor header
534    rpc_desc_t  rpc;
535    rpc.index    = RPC_USER_DIR_CREATE;
536    rpc.blocking = true;
[619]537    rpc.rsp      = &responses;
[612]538
539    // set input arguments in RPC descriptor
540    rpc.args[0] = (uint64_t)(intptr_t)inode;
[614]541    rpc.args[1] = (uint64_t)ref_xp;
[612]542
543    // register RPC request in remote RPC fifo
544    rpc_send( cxy , &rpc );
545
546    // get output argument from RPC descriptor
[614]547    *dir = (user_dir_t *)(intptr_t)rpc.args[2];
[612]548
549#if DEBUG_RPC_USER_DIR_CREATE
550cycle = (uint32_t)hal_get_cycles();
551if( cycle > DEBUG_RPC_USER_DIR_CREATE)
552printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
553__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
554#endif
555}
556
557////////////////////////////////////////////
558void rpc_user_dir_create_server( xptr_t xp )
559{
560#if DEBUG_RPC_USER_DIR_CREATE
561thread_t * this = CURRENT_THREAD;
562uint32_t cycle = (uint32_t)hal_get_cycles();
563if( cycle > DEBUG_RPC_USER_DIR_CREATE)
564printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
565__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
566#endif
567
568    vfs_inode_t * inode;          // pointer on inode in server cluster
[614]569    xptr_t        ref_xp;         // extended pointer on reference user process
[612]570    user_dir_t  * dir;            // pointer on user_dir structure in server cluster
571
572    // get client cluster identifier and pointer on RPC descriptor
573    cxy_t        client_cxy  = GET_CXY( xp );
574    rpc_desc_t * desc        = GET_PTR( xp );
575
576    // get input argument from RPC descriptor
[614]577    inode  = (vfs_inode_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
578    ref_xp = (xptr_t)                 hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[612]579
580    // call kernel function
[614]581    dir = user_dir_create( inode , ref_xp );
[612]582
583    // set output argument into RPC descriptor
[614]584    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (intptr_t)dir );
[612]585
586#if DEBUG_RPC_USER_DIR_CREATE
587cycle = (uint32_t)hal_get_cycles();
588if( cycle > DEBUG_RPC_USER_DIR_CREATE)
589printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
590__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
591#endif
592}
593
[409]594/////////////////////////////////////////////////////////////////////////////////////////
[619]595// [5]      Marshaling functions attached to RPC_USER_DIR_DESTROY
[409]596/////////////////////////////////////////////////////////////////////////////////////////
597
[612]598////////////////////////////////////////////////////
599void rpc_user_dir_destroy_client( cxy_t         cxy,
[614]600                                  user_dir_t  * dir,
601                                  xptr_t        ref_xp )
[612]602{
603#if DEBUG_RPC_USER_DIR_DESTROY
604thread_t * this = CURRENT_THREAD;
605uint32_t cycle = (uint32_t)hal_get_cycles();
606if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
607printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
608__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
609#endif
610
[619]611    uint32_t responses = 1;
[612]612
613    // initialise RPC descriptor header
614    rpc_desc_t  rpc;
615    rpc.index    = RPC_USER_DIR_DESTROY;
616    rpc.blocking = true;
[619]617    rpc.rsp      = &responses;
[612]618
619    // set input arguments in RPC descriptor
620    rpc.args[0] = (uint64_t)(intptr_t)dir;
[614]621    rpc.args[1] = (uint64_t)ref_xp;
[612]622
623    // register RPC request in remote RPC fifo
624    rpc_send( cxy , &rpc );
625
626#if DEBUG_RPC_USER_DIR_DESTROY
627cycle = (uint32_t)hal_get_cycles();
628if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
629printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
630__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
631#endif
632}
633
634/////////////////////////////////////////////
635void rpc_user_dir_destroy_server( xptr_t xp )
636{
637#if DEBUG_RPC_USER_DIR_DESTROY
638thread_t * this = CURRENT_THREAD;
639uint32_t cycle = (uint32_t)hal_get_cycles();
640if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
641printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
642__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
643#endif
644
645    user_dir_t * dir;            // pointer on user_dir structure in server cluster
[614]646    xptr_t       ref_xp;         // extended pointer on reference process
[612]647
648    // get client cluster identifier and pointer on RPC descriptor
649    cxy_t        client_cxy  = GET_CXY( xp );
650    rpc_desc_t * desc        = GET_PTR( xp );
651
652    // get input argument from RPC descriptor
[614]653    dir    = (user_dir_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
654    ref_xp = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[612]655
656    // call kernel function
[614]657    user_dir_destroy( dir , ref_xp );
[612]658
659#if DEBUG_RPC_USER_DIR_DESTROY
660cycle = (uint32_t)hal_get_cycles();
661if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
662printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
663__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
664#endif
665}
666
[1]667/////////////////////////////////////////////////////////////////////////////////////////
[619]668// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE   
[1]669/////////////////////////////////////////////////////////////////////////////////////////
670
671/////////////////////////////////////////////////////////
672void rpc_thread_user_create_client( cxy_t            cxy, 
[23]673                                    pid_t            pid,         // in
674                                    void           * start_func,  // in
675                                    void           * start_arg,   // in
[1]676                                    pthread_attr_t * attr,        // in
677                                    xptr_t         * thread_xp,   // out
678                                    error_t        * error )      // out
679{
[564]680#if DEBUG_RPC_THREAD_USER_CREATE
681thread_t * this = CURRENT_THREAD;
682uint32_t cycle = (uint32_t)hal_get_cycles();
683if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]684printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
685__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]686#endif
[619]687   
688    uint32_t responses = 1;
[564]689
[1]690    // initialise RPC descriptor header
691    rpc_desc_t  rpc;
[436]692    rpc.index    = RPC_THREAD_USER_CREATE;
[416]693    rpc.blocking = true;
[619]694    rpc.rsp      = &responses;
[1]695
696    // set input arguments in RPC descriptor
[23]697    rpc.args[0] = (uint64_t)pid;
698    rpc.args[1] = (uint64_t)(intptr_t)start_func;
699    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
700    rpc.args[3] = (uint64_t)(intptr_t)attr;
[1]701
[436]702    // register RPC request in remote RPC fifo
[416]703    rpc_send( cxy , &rpc );
[1]704
705    // get output arguments from RPC descriptor
[23]706    *thread_xp = (xptr_t)rpc.args[4];
707    *error     = (error_t)rpc.args[5];
[279]708
[564]709#if DEBUG_RPC_THREAD_USER_CREATE
710cycle = (uint32_t)hal_get_cycles();
711if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]712printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
713__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]714#endif
[1]715}
716
717///////////////////////////////////////////////
718void rpc_thread_user_create_server( xptr_t xp )
719{
[564]720#if DEBUG_RPC_THREAD_USER_CREATE
721thread_t * this = CURRENT_THREAD;
722uint32_t cycle = (uint32_t)hal_get_cycles();
723if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]724printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
725__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]726#endif
[409]727
[1]728    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
729    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
730    thread_t       * thread_ptr; // local pointer on thread descriptor
731    xptr_t           thread_xp;  // extended pointer on thread descriptor
[23]732
[1]733    pid_t            pid;        // process identifier
[23]734    void           * start_func;
735    void           * start_arg;
736    error_t          error;
[1]737
738    // get client cluster identifier and pointer on RPC descriptor
[436]739    cxy_t        client_cxy  = GET_CXY( xp );
[438]740    rpc_desc_t * desc        = GET_PTR( xp );
[1]741
[23]742    // get input arguments from RPC descriptor
[564]743    pid        = (pid_t)                     hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
744    start_func = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
745    start_arg  = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
746    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[3]));
[23]747
[1]748    // makes a local copy of attributes structure
749    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
750                       XPTR( client_cxy , attr_ptr ), 
751                       sizeof(pthread_attr_t) );
752   
[23]753    // call kernel function
754    error = thread_user_create( pid,
755                                start_func,
756                                start_arg,
757                                &attr_copy,
758                                &thread_ptr );
[1]759    // set output arguments
760    thread_xp = XPTR( local_cxy , thread_ptr );
[564]761    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
762    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
[296]763
[564]764#if DEBUG_RPC_THREAD_USER_CREATE
765cycle = (uint32_t)hal_get_cycles();
766if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]767printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
768__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]769#endif
[1]770}
771
772/////////////////////////////////////////////////////////////////////////////////////////
[623]773// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
[1]774/////////////////////////////////////////////////////////////////////////////////////////
775
776////////////////////////////////////////////////////
777void rpc_thread_kernel_create_client( cxy_t     cxy,
778                                      uint32_t  type,        // in
779                                      void    * func,        // in
780                                      void    * args,        // in
781                                      xptr_t  * thread_xp,   // out
782                                      error_t * error )      // out
783{
[564]784#if DEBUG_RPC_THREAD_KERNEL_CREATE
785thread_t * this = CURRENT_THREAD;
786uint32_t cycle = (uint32_t)hal_get_cycles();
787if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]788printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
789__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]790#endif
791
[619]792    uint32_t responses = 1;
[1]793
794    // initialise RPC descriptor header
795    rpc_desc_t  rpc;
796    rpc.index    = RPC_THREAD_KERNEL_CREATE;
[416]797    rpc.blocking = true;
[619]798    rpc.rsp      = &responses;
[1]799
800    // set input arguments in RPC descriptor
801    rpc.args[0] = (uint64_t)type;
802    rpc.args[1] = (uint64_t)(intptr_t)func;
803    rpc.args[2] = (uint64_t)(intptr_t)args;
804   
[436]805    // register RPC request in remote RPC fifo
[416]806    rpc_send( cxy , &rpc );
[1]807
808    // get output arguments from RPC descriptor
809    *thread_xp = (xptr_t)rpc.args[3];
810    *error     = (error_t)rpc.args[4];
[279]811
[564]812#if DEBUG_RPC_THREAD_KERNEL_CREATE
813cycle = (uint32_t)hal_get_cycles();
814if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]815printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
816__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]817#endif
[1]818}
819
820/////////////////////////////////////////////////
821void rpc_thread_kernel_create_server( xptr_t xp )
822{
[564]823#if DEBUG_RPC_THREAD_KERNEL_CREATE
824thread_t * this = CURRENT_THREAD;
825uint32_t cycle = (uint32_t)hal_get_cycles();
826if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]827printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
828__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]829#endif
830
[1]831    thread_t       * thread_ptr;  // local pointer on thread descriptor
832    xptr_t           thread_xp;   // extended pointer on thread descriptor
833    lid_t            core_lid;    // core local index
834    error_t          error;   
835
836    // get client cluster identifier and pointer on RPC descriptor
[436]837    cxy_t        client_cxy  = GET_CXY( xp );
[438]838    rpc_desc_t * desc        = GET_PTR( xp );
[1]839
840    // get attributes from RPC descriptor
[564]841    uint32_t  type = (uint32_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
842    void    * func = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
843    void    * args = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
[1]844
845    // select one core
[637]846    core_lid = cluster_select_local_core( local_cxy );
[1]847
848    // call local kernel function
849    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
850
851    // set output arguments
852    thread_xp = XPTR( local_cxy , thread_ptr );
[564]853    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
854    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
[296]855
[564]856#if DEBUG_RPC_THREAD_KERNEL_CREATE
857cycle = (uint32_t)hal_get_cycles();
858if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]859printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
860__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]861#endif
[1]862}
863
864/////////////////////////////////////////////////////////////////////////////////////////
[657]865// [8]      undefined
[1]866/////////////////////////////////////////////////////////////////////////////////////////
867
[657]868/////////////////////////////////////////////////////////////////////////////////////////
869// [9]   Marshaling functions attached to RPC_PROCESS_SIGACTION
870/////////////////////////////////////////////////////////////////////////////////////////
871
872////////////////////////////////////////////////////
873void rpc_process_sigaction_client( cxy_t        cxy,
874                                   pid_t        pid,
875                                   uint32_t     action )
876{
877#if DEBUG_RPC_PROCESS_SIGACTION
878uint32_t  cycle = (uint32_t)hal_get_cycles();
879thread_t * this = CURRENT_THREAD;
880if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
881printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n",
882__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
883process_action_str( action ), pid, cycle );
884#endif
885
886    uint32_t    responses = 1;
887    rpc_desc_t  rpc;
888
889    // initialise RPC descriptor header
890    rpc.index    = RPC_PROCESS_SIGACTION;
891    rpc.blocking = true;
892    rpc.rsp      = &responses;
893
894    // set input arguments in RPC descriptor
895    rpc.args[0] = (uint64_t)pid;
896    rpc.args[1] = (uint64_t)action;
897
898    // register RPC request in remote RPC fifo
899    rpc_send( cxy , &rpc );
900
901#if DEBUG_RPC_PROCESS_SIGACTION
902cycle = (uint32_t)hal_get_cycles();
903if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
904printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n",
905__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
906process_action_str( action ), pid, cycle );
907#endif
908}
909
910//////////////////////////////////////////////
911void rpc_process_sigaction_server( xptr_t xp )
912{
913    // get client cluster identifier and pointer on RPC descriptor
914    cxy_t        client_cxy = GET_CXY( xp );
915    rpc_desc_t * desc       = GET_PTR( xp );
916
917    // get arguments from RPC descriptor
918    pid_t    pid    = (pid_t)   hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
919    uint32_t action = (uint32_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
920
921#if DEBUG_RPC_PROCESS_SIGACTION
922uint32_t cycle = (uint32_t)hal_get_cycles();
923thread_t * this = CURRENT_THREAD;
924if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
925printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n",
926__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
927process_action_str( action ), pid, cycle );
928#endif
929
930    // get client thread pointers
931    thread_t * client_ptr = hal_remote_lpt( XPTR( client_cxy , &desc->thread ) );
932    xptr_t     client_xp  = XPTR( client_cxy , client_ptr );
933
934    // get local process descriptor
935    process_t * process = cluster_get_local_process_from_pid( pid );
936
937    // call relevant kernel function if found / does nothing if not found
938    if( process != NULL )
939    {
940        if ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
941        if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
942        if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
943    }
944
945#if DEBUG_RPC_PROCESS_SIGACTION
946cycle = (uint32_t)hal_get_cycles();
947if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
948printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n",
949__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
950process_action_str( action ), pid, cycle );
951#endif
952} 
953
954/////////////////////////////////////////////////////////////////////////////////////////
955// [10]          undefined                                         
956/////////////////////////////////////////////////////////////////////////////////////////
957
958/////////////////////////////////////////////////////////////////////////////////////////
959// [11]          undefined                                         
960/////////////////////////////////////////////////////////////////////////////////////////
961
962/////////////////////////////////////////////////////////////////////////////////////////
963// [12]          undefined                                         
964/////////////////////////////////////////////////////////////////////////////////////////
965
966/////////////////////////////////////////////////////////////////////////////////////////
967// [13]          undefined                                       
968/////////////////////////////////////////////////////////////////////////////////////////
969
970/////////////////////////////////////////////////////////////////////////////////////////
971// [14]          undefined                                       
972/////////////////////////////////////////////////////////////////////////////////////////
973
974/////////////////////////////////////////////////////////////////////////////////////////
975// [15]          Marshaling functions attached to RPC_VMM_RESIZE_VSEG
976/////////////////////////////////////////////////////////////////////////////////////////
977
978//////////////////////////////////////////////////////////
979void rpc_vmm_resize_vseg_client( cxy_t          cxy,
980                                 pid_t          pid,
981                                 intptr_t       base,
982                                 intptr_t       new_base,
983                                 intptr_t       new_size )
984{
985#if DEBUG_RPC_VMM_RESIZE_VSEG
986thread_t * this = CURRENT_THREAD;
987uint32_t cycle = (uint32_t)hal_get_cycles();
988if( cycle > DEBUG_RPC_VMM_RESIZE_VSEG )
989printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
990__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
991#endif
992
993    uint32_t responses = 1;
994
995    // initialise RPC descriptor header
996    rpc_desc_t  rpc;
997    rpc.index    = RPC_VMM_RESIZE_VSEG;
998    rpc.blocking = true;
999    rpc.rsp      = &responses;
1000
1001    // set input arguments in RPC descriptor
1002    rpc.args[0] = (uint64_t)pid;
1003    rpc.args[1] = (uint64_t)base;
1004    rpc.args[2] = (uint64_t)new_base;
1005    rpc.args[3] = (uint64_t)new_size;
1006
1007    // register RPC request in remote RPC fifo
1008    rpc_send( cxy , &rpc );
1009
1010#if DEBUG_RPC_VMM_RESIZE_VSEG
1011cycle = (uint32_t)hal_get_cycles();
1012if( cycle > DEBUG_RPC_VMM_RESIZE_VSEG )
1013printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1014__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1015#endif
1016}
1017
1018////////////////////////////////////////////
1019void rpc_vmm_resize_vseg_server( xptr_t xp )
1020{
1021#if DEBUG_RPC_VMM_RESIZE_VSEG
1022thread_t * this = CURRENT_THREAD;
1023uint32_t cycle = (uint32_t)hal_get_cycles();
1024if( cycle > DEBUG_RPC_VMM_RESIZE_VSEG )
1025printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1026__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1027#endif
1028
1029    pid_t       pid;
1030    process_t * process;
1031    intptr_t    base;
1032    vseg_t    * vseg;
1033    intptr_t    new_base;
1034    intptr_t    new_size;
1035
1036    // get client cluster identifier and pointer on RPC descriptor
1037    cxy_t        client_cxy  = GET_CXY( xp );
1038    rpc_desc_t * desc        = GET_PTR( xp );
1039
1040    // get arguments from client RPC descriptor
1041    pid      = (pid_t)   hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1042    base     = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1043    new_base = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1044    new_size = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1045
1046    // get local pointer on target process
1047    process = cluster_get_local_process_from_pid( pid );
1048
1049    // get target vseg from vaddr
1050    vmm_get_vseg( process , base , &vseg );
1051
1052    // call relevant kernel function
1053    vmm_resize_vseg( process,
1054                     vseg,
1055                     new_base,
1056                     new_size );
1057
1058#if DEBUG_RPC_VMM_RESIZE_VSEG
1059cycle = (uint32_t)hal_get_cycles();
1060if( cycle > DEBUG_RPC_VMM_RESIZE_VSEG )
1061printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1062__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1063#endif
1064}
1065
1066
1067/////////////////////////////////////////////////////////////////////////////////////////
1068// [16]  Marshaling functions attached to RPC_VMM_REMOVE_VSEG
1069/////////////////////////////////////////////////////////////////////////////////////////
1070
1071/////////////////////////////////////////////////
1072void rpc_vmm_remove_vseg_client( cxy_t       cxy,
1073                                 pid_t       pid,
1074                                 intptr_t    base )
1075{
1076#if DEBUG_RPC_VMM_REMOVE_VSEG
1077thread_t * this  = CURRENT_THREAD;
1078uint32_t   cycle = (uint32_t)hal_get_cycles();
1079if( cycle > DEBUG_RPC_VMM_REMOVE_VSEG )
1080printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1081__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1082#endif
1083
1084    uint32_t    responses = 1;
1085    rpc_desc_t  rpc;
1086
1087    // initialise RPC descriptor header
1088    rpc.index    = RPC_VMM_REMOVE_VSEG;
1089    rpc.blocking = true;
1090    rpc.rsp      = &responses;
1091
1092    // set input arguments in RPC descriptor
1093    rpc.args[0] = (uint64_t)pid;
1094    rpc.args[1] = (uint64_t)base;
1095
1096    // register RPC request in remote RPC fifo
1097    rpc_send( cxy , &rpc );
1098
1099#if DEBUG_RPC_VMM_REMOVE_VSEG
1100cycle = (uint32_t)hal_get_cycles();
1101if( cycle > DEBUG_RPC_VMM_REMOVE_VSEG )
1102printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1103__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1104#endif
1105}
1106
1107////////////////////////////////////////////
1108void rpc_vmm_remove_vseg_server( xptr_t xp )
1109{
1110#if DEBUG_RPC_VMM_REMOVE_VSEG
1111uint32_t cycle = (uint32_t)hal_get_cycles();
1112thread_t * this = CURRENT_THREAD;
1113if( DEBUG_RPC_VMM_REMOVE_VSEG < cycle )
1114printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1115__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1116#endif
1117
1118    pid_t       pid;
1119    intptr_t    vaddr;
1120    process_t * process;
1121    vseg_t    * vseg;
1122
1123    // get client cluster identifier and pointer on RPC descriptor
1124    cxy_t        client_cxy = GET_CXY( xp );
1125    rpc_desc_t * desc       = GET_PTR( xp );
1126
1127    // get arguments from RPC descriptor
1128    pid   = (pid_t)   hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1129    vaddr = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1130
1131    // get local pointer on target process
1132    process = cluster_get_local_process_from_pid( pid );
1133
1134    // get target vseg from vaddr
1135    vmm_get_vseg( process , vaddr , &vseg );
1136
1137    // call relevant kernel function
1138    vmm_remove_vseg( process,
1139                     vseg );
1140
1141#if DEBUG_RPC_VMM_REMOVE_VSEG
1142cycle = (uint32_t)hal_get_cycles();
1143if( DEBUG_RPC_VMM_REMOVE_VSEG < cycle )
1144printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1145__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1146#endif
1147} 
1148
1149/////////////////////////////////////////////////////////////////////////////////////////
1150// [17]          Marshaling functions attached to RPC_VMM_CREATE_VSEG
1151/////////////////////////////////////////////////////////////////////////////////////////
1152
1153////////////////////////////////////////////////////////
1154void rpc_vmm_create_vseg_client( cxy_t              cxy,
1155                                 struct process_s * process,
1156                                 vseg_type_t        type,
1157                                 intptr_t           base,
1158                                 uint32_t           size,
1159                                 uint32_t           file_offset,
1160                                 uint32_t           file_size,
1161                                 xptr_t             mapper_xp,
1162                                 cxy_t              vseg_cxy,
1163                                 struct vseg_s   ** vseg )
1164{
1165#if DEBUG_RPC_VMM_CREATE_VSEG
1166thread_t * this = CURRENT_THREAD;
1167uint32_t cycle = (uint32_t)hal_get_cycles();
1168if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
1169printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1170__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1171#endif
1172
1173    uint32_t responses = 1;
1174
1175    // initialise RPC descriptor header
1176    rpc_desc_t  rpc;
1177    rpc.index    = RPC_VMM_CREATE_VSEG;
1178    rpc.blocking = true;
1179    rpc.rsp      = &responses;
1180
1181    // set input arguments in RPC descriptor
1182    rpc.args[0] = (uint64_t)(intptr_t)process;
1183    rpc.args[1] = (uint64_t)type;
1184    rpc.args[2] = (uint64_t)base;
1185    rpc.args[3] = (uint64_t)size;
1186    rpc.args[4] = (uint64_t)file_offset;
1187    rpc.args[5] = (uint64_t)file_size;
1188    rpc.args[6] = (uint64_t)mapper_xp;
1189    rpc.args[7] = (uint64_t)vseg_cxy;
1190
1191    // register RPC request in remote RPC fifo
1192    rpc_send( cxy , &rpc );
1193
1194    // get output values from RPC descriptor
1195    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
1196
1197#if DEBUG_RPC_VMM_CREATE_VSEG
1198cycle = (uint32_t)hal_get_cycles();
1199if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
1200printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1201__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1202#endif
1203}
1204
1205////////////////////////////////////////////
1206void rpc_vmm_create_vseg_server( xptr_t xp )
1207{
1208#if DEBUG_RPC_VMM_CREATE_VSEG
1209thread_t * this = CURRENT_THREAD;
1210uint32_t cycle = (uint32_t)hal_get_cycles();
1211if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
1212printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1213__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1214#endif
1215
1216    // get client cluster identifier and pointer on RPC descriptor
1217    cxy_t        cxy  = GET_CXY( xp );
1218    rpc_desc_t * desc = GET_PTR( xp );
1219
1220    // get input arguments from client RPC descriptor
1221    process_t * process     = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
1222    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_l64( XPTR(cxy , &desc->args[1]));
1223    intptr_t    base        = (intptr_t)             hal_remote_l64( XPTR(cxy , &desc->args[2]));
1224    uint32_t    size        = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[3]));
1225    uint32_t    file_offset = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[4]));
1226    uint32_t    file_size   = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[5]));
1227    xptr_t      mapper_xp   = (xptr_t)               hal_remote_l64( XPTR(cxy , &desc->args[6]));
1228    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_l64( XPTR(cxy , &desc->args[7]));
1229   
1230    // call local kernel function
1231    vseg_t * vseg = vmm_create_vseg( process,
1232                                     type,
1233                                     base,
1234                                     size,
1235                                     file_offset,
1236                                     file_size,
1237                                     mapper_xp,
1238                                     vseg_cxy ); 
1239
1240    // set output arguments into client RPC descriptor
1241    hal_remote_s64( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
1242
1243#if DEBUG_RPC_VMM_CREATE_VSEG
1244cycle = (uint32_t)hal_get_cycles();
1245if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
1246printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1247__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1248#endif
1249}
1250
1251/////////////////////////////////////////////////////////////////////////////////////////
1252// [18]          Marshaling functions attached to RPC_VMM_SET_COW
1253/////////////////////////////////////////////////////////////////////////////////////////
1254
1255/////////////////////////////////////////////
1256void rpc_vmm_set_cow_client( cxy_t       cxy,
1257                             process_t * process )
1258{
1259#if DEBUG_RPC_VMM_SET_COW
1260thread_t * this = CURRENT_THREAD;
1261uint32_t cycle = (uint32_t)hal_get_cycles();
1262if( cycle > DEBUG_RPC_VMM_SET_COW )
1263printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1264__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1265#endif
1266
1267    uint32_t responses = 1;
1268
1269    // initialise RPC descriptor header
1270    rpc_desc_t  rpc;
1271    rpc.index    = RPC_VMM_SET_COW;
1272    rpc.blocking = true;
1273    rpc.rsp      = &responses;
1274
1275    // set input arguments in RPC descriptor
1276    rpc.args[0] = (uint64_t)(intptr_t)process;
1277
1278    // register RPC request in remote RPC fifo
1279    rpc_send( cxy , &rpc );
1280
1281#if DEBUG_RPC_VMM_SET_COW
1282cycle = (uint32_t)hal_get_cycles();
1283if( cycle > DEBUG_RPC_VMM_SET_COW )
1284printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1285__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1286#endif
1287}
1288
1289////////////////////////////////////////
1290void rpc_vmm_set_cow_server( xptr_t xp )
1291{
1292#if DEBUG_RPC_VMM_SET_COW
1293thread_t * this = CURRENT_THREAD;
1294uint32_t cycle = (uint32_t)hal_get_cycles();
1295if( cycle > DEBUG_RPC_VMM_SET_COW )
1296printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1297__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1298#endif
1299
1300    process_t * process;
1301
1302    // get client cluster identifier and pointer on RPC descriptor
1303    cxy_t        cxy  = GET_CXY( xp );
1304    rpc_desc_t * desc = GET_PTR( xp );
1305
1306    // get input arguments from client RPC descriptor
1307    process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
1308   
1309    // call local kernel function
1310    vmm_set_cow( process );
1311
1312#if DEBUG_RPC_VMM_SET_COW
1313cycle = (uint32_t)hal_get_cycles();
1314if( cycle > DEBUG_RPC_VMM_SET_COW )
1315printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1316__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1317#endif
1318}
1319
1320
1321
1322/////////////////////////////////////////////////////////////////////////////////////////
1323/////////////////////////////////////////////////////////////////////////////////////////
1324//                            DEPRECATED RPCs
1325/////////////////////////////////////////////////////////////////////////////////////////
1326/////////////////////////////////////////////////////////////////////////////////////////
1327
1328/*
1329
1330/////////////////////////////////////////////////////////////////////////////////////////
1331// [0]       RPC_PMEM_GET_PAGES deprecated [AG] May 2019
1332/////////////////////////////////////////////////////////////////////////////////////////
1333void rpc_pmem_get_pages_client( cxy_t      cxy,
1334                                uint32_t   order,      // in
1335                                page_t  ** page )      // out
1336{
1337#if DEBUG_RPC_PMEM_GET_PAGES
1338thread_t * this = CURRENT_THREAD;
1339uint32_t cycle = (uint32_t)hal_get_cycles();
1340if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
1341printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1342__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1343#endif
1344
1345    uint32_t responses = 1;
1346
1347    // initialise RPC descriptor header
1348    rpc_desc_t  rpc;
1349    rpc.index     = RPC_PMEM_GET_PAGES;
1350    rpc.blocking  = true;
1351    rpc.rsp       = &responses;
1352
1353    // set input arguments in RPC descriptor
1354    rpc.args[0] = (uint64_t)order;
1355
1356    // register RPC request in remote RPC fifo
1357    rpc_send( cxy , &rpc );
1358
1359    // get output arguments from RPC descriptor
1360    *page = (page_t *)(intptr_t)rpc.args[1];
1361
1362#if DEBUG_RPC_PMEM_GET_PAGES
1363cycle = (uint32_t)hal_get_cycles();
1364if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
1365printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1366__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1367#endif
1368}
1369
1370///////////////////////////////////////////
1371void rpc_pmem_get_pages_server( xptr_t xp )
1372{
1373#if DEBUG_RPC_PMEM_GET_PAGES
1374thread_t * this = CURRENT_THREAD;
1375uint32_t cycle = (uint32_t)hal_get_cycles();
1376if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
1377printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1378__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1379#endif
1380
1381    // get client cluster identifier and pointer on RPC descriptor
1382    cxy_t        cxy  = GET_CXY( xp );
1383    rpc_desc_t * desc = GET_PTR( xp );
1384
1385    // get input arguments from client RPC descriptor
1386    uint32_t order = (uint32_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
1387   
1388    // call local pmem allocator
1389    page_t * page = ppm_alloc_pages( order );
1390
1391    // set output arguments into client RPC descriptor
1392    hal_remote_s64( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
1393
1394#if DEBUG_RPC_PMEM_GET_PAGES
1395cycle = (uint32_t)hal_get_cycles();
1396if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
1397printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1398__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1399#endif
1400}
1401
1402/////////////////////////////////////////////////////////////////////////////////////////
1403// [1]       RPC_PMEM_RELEASE_PAGES deprecated [AG] may 2019
1404/////////////////////////////////////////////////////////////////////////////////////////
1405void rpc_pmem_release_pages_client( cxy_t     cxy,
1406                                    page_t  * page )      // out
1407{
1408#if DEBUG_RPC_PMEM_RELEASE_PAGES
1409thread_t * this = CURRENT_THREAD;
1410uint32_t cycle = (uint32_t)hal_get_cycles();
1411if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
1412printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1413__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1414#endif
1415
1416    uint32_t responses = 1;
1417
1418    // initialise RPC descriptor header
1419    rpc_desc_t  rpc;
1420    rpc.index    = RPC_PMEM_RELEASE_PAGES;
1421    rpc.blocking = true;
1422    rpc.rsp      = &responses;
1423
1424    // set input arguments in RPC descriptor
1425    rpc.args[0] = (uint64_t)(intptr_t)page;
1426
1427    // register RPC request in remote RPC fifo
1428    rpc_send( cxy , &rpc );
1429
1430#if DEBUG_RPC_PMEM_RELEASE_PAGES
1431cycle = (uint32_t)hal_get_cycles();
1432if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
1433printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1434__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1435#endif
1436}
1437
1438///////////////////////////////////////////////
1439void rpc_pmem_release_pages_server( xptr_t xp )
1440{
1441#if DEBUG_RPC_PMEM_RELEASE_PAGES
1442thread_t * this = CURRENT_THREAD;
1443uint32_t cycle = (uint32_t)hal_get_cycles();
1444if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
1445printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1446__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1447#endif
1448
1449    // get client cluster identifier and pointer on RPC descriptor
1450    cxy_t        cxy  = GET_CXY( xp );
1451    rpc_desc_t * desc = GET_PTR( xp );
1452
1453    // get input arguments from client RPC descriptor
1454    page_t * page = (page_t *)(intptr_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
1455   
1456    // release memory to local pmem
1457    kmem_req_t req;
1458    req.type = KMEM_PPM;
1459    req.ptr  = page;
1460    kmem_free( &req );
1461
1462#if DEBUG_RPC_PMEM_RELEASE_PAGES
1463cycle = (uint32_t)hal_get_cycles();
1464if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
1465printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1466__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1467#endif
1468}
1469
1470/////////////////////////////////////////////////////////////////////////////////////////
1471// [2]          RPC_PPM_DISPLAY deprecated [AG] May 2019   
1472/////////////////////////////////////////////////////////////////////////////////////////
1473void rpc_ppm_display_client( cxy_t  cxy )
1474{
1475#if DEBUG_RPC_PPM_DISPLAY
1476thread_t * this = CURRENT_THREAD;
1477uint32_t cycle = (uint32_t)hal_get_cycles();
1478if( cycle > DEBUG_RPC_PPM_DISPLAY )
1479printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1480__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1481#endif
1482
1483    uint32_t responses = 1;
1484
1485    // initialise RPC descriptor header
1486    rpc_desc_t  rpc;
1487    rpc.index    = RPC_PPM_DISPLAY;
1488    rpc.blocking = true;
1489    rpc.rsp      = &responses;
1490
1491    // register RPC request in remote RPC fifo
1492    rpc_send( cxy , &rpc );
1493
1494#if DEBUG_RPC_PPM_DISPLAY
1495cycle = (uint32_t)hal_get_cycles();
1496if( cycle > DEBUG_RPC_PPM_DISPLAY )
1497printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1498__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1499#endif
1500}
1501
1502////////////////////////////////////////////////////////////////////
1503void rpc_ppm_display_server( xptr_t __attribute__((__unused__)) xp )
1504{
1505#if DEBUG_RPC_PPM_DISPLAY
1506thread_t * this = CURRENT_THREAD;
1507uint32_t cycle = (uint32_t)hal_get_cycles();
1508if( cycle > DEBUG_RPC_PPM_DISPLAY )
1509printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1510__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1511#endif
1512
1513    // call local kernel function
1514    ppm_display();
1515
1516#if DEBUG_RPC_PPM_DISPLAY
1517cycle = (uint32_t)hal_get_cycles();
1518if( cycle > DEBUG_RPC_PPM_DISPLAY )
1519printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1520__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1521#endif
1522}
1523
1524/////////////////////////////////////////////////////////////////////////////////////////
1525// [8]   RPC_VFS_FS_UPDATE_DENTRY deprecated [AG] dec 2019
1526/////////////////////////////////////////////////////////////////////////////////////////
[623]1527void rpc_vfs_fs_update_dentry_client( cxy_t          cxy,
1528                                      vfs_inode_t  * inode,
1529                                      vfs_dentry_t * dentry,
1530                                      uint32_t       size,
1531                                      error_t      * error )
1532{
1533#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1534thread_t * this = CURRENT_THREAD;
1535uint32_t cycle = (uint32_t)hal_get_cycles();
1536if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1537printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1538__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1539#endif
[296]1540
[623]1541    uint32_t responses = 1;
1542
1543    // initialise RPC descriptor header
1544    rpc_desc_t  rpc;
1545    rpc.index    = RPC_VFS_FS_UPDATE_DENTRY;
1546    rpc.blocking = true;
1547    rpc.rsp      = &responses;
1548
1549    // set input arguments in RPC descriptor
1550    rpc.args[0] = (uint64_t)(intptr_t)inode;
1551    rpc.args[1] = (uint64_t)(intptr_t)dentry;
1552    rpc.args[2] = (uint64_t)size;
1553
1554    // register RPC request in remote RPC fifo
1555    rpc_send( cxy , &rpc );
1556
1557    // get output values from RPC descriptor
1558    *error   = (error_t)rpc.args[3];
1559
1560#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1561cycle = (uint32_t)hal_get_cycles();
1562if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1563printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1564__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1565#endif
1566}
1567
1568/////////////////////////////////////////////////
1569void rpc_vfs_fs_update_dentry_server( xptr_t xp )
1570{
1571#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1572thread_t * this = CURRENT_THREAD;
1573uint32_t cycle = (uint32_t)hal_get_cycles();
1574if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1575printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1576__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1577#endif
1578
1579    error_t        error;
1580    vfs_inode_t  * inode;
1581    vfs_dentry_t * dentry;
1582    uint32_t       size;
1583
1584    // get client cluster identifier and pointer on RPC descriptor
1585    cxy_t        client_cxy  = GET_CXY( xp );
1586    rpc_desc_t * desc        = GET_PTR( xp );
1587
1588    // get input arguments
1589    inode  = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1590    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1591    size   = (uint32_t)               hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
1592
1593    // call the kernel function
1594    error = vfs_fs_update_dentry( inode , dentry , size );
1595
1596    // set output argument
1597    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1598
1599#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1600cycle = (uint32_t)hal_get_cycles();
1601if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1602printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1603__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1604#endif
1605}
1606
[657]1607
[23]1608/////////////////////////////////////////////////////////////////////////////////////////
[657]1609// [29]      RPC_VMM_DISPLAY deprecated [AG] June 2019
[23]1610/////////////////////////////////////////////////////////////////////////////////////////
[657]1611void rpc_hal_vmm_display_client( cxy_t       cxy,
1612                             process_t * process,
1613                             bool_t      detailed )
[409]1614{
[657]1615#if DEBUG_RPC_VMM_DISPLAY
[610]1616thread_t * this = CURRENT_THREAD;
[657]1617uint32_t cycle = (uint32_t)hal_get_cycles();
1618if( cycle > DEBUG_RPC_VMM_DISPLAY )
1619printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1620__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[436]1621#endif
[409]1622
[657]1623    uint32_t responses = 1;
[409]1624
[619]1625    // initialise RPC descriptor header
[657]1626    rpc_desc_t  rpc;
1627    rpc.index    = RPC_VMM_DISPLAY;
[619]1628    rpc.blocking = true;
1629    rpc.rsp      = &responses;
[436]1630
[619]1631    // set input arguments in RPC descriptor
[657]1632    rpc.args[0] = (uint64_t)(intptr_t)process;
1633    rpc.args[1] = (uint64_t)detailed;
[619]1634
[657]1635    // register RPC request in remote RPC fifo
[619]1636    rpc_send( cxy , &rpc );
1637
[657]1638#if DEBUG_RPC_VMM_DISPLAY
[436]1639cycle = (uint32_t)hal_get_cycles();
[657]1640if( cycle > DEBUG_RPC_VMM_DISPLAY )
1641printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1642__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[436]1643#endif
[657]1644}
[436]1645
[657]1646////////////////////////////////////////
1647void rpc_hal_vmm_display_server( xptr_t xp )
[409]1648{
[657]1649#if DEBUG_RPC_VMM_DISPLAY
1650thread_t * this = CURRENT_THREAD;
[619]1651uint32_t cycle = (uint32_t)hal_get_cycles();
[657]1652if( cycle > DEBUG_RPC_VMM_DISPLAY )
1653printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1654__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[619]1655#endif
1656
[657]1657    process_t * process;
1658    bool_t      detailed;
[440]1659
[657]1660    // get client cluster identifier and pointer on RPC descriptor
1661    cxy_t        cxy  = GET_CXY( xp );
1662    rpc_desc_t * desc = GET_PTR( xp );
[435]1663
[657]1664    // get input arguments from client RPC descriptor
1665    process  = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
1666    detailed = (bool_t)               hal_remote_l64( XPTR(cxy , &desc->args[1]));
1667   
1668    // call local kernel function
1669    hal_vmm_display( process , detailed );
[409]1670
[657]1671#if DEBUG_RPC_VMM_DISPLAY
[436]1672cycle = (uint32_t)hal_get_cycles();
[657]1673if( cycle > DEBUG_RPC_VMM_DISPLAY )
1674printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1675__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[436]1676#endif
[657]1677}
[436]1678
[409]1679/////////////////////////////////////////////////////////////////////////////////////////
[657]1680// [10]  to RPC_VFS_INODE_CREATE   deprecated [AG] dec 2019
[409]1681/////////////////////////////////////////////////////////////////////////////////////////
[1]1682void rpc_vfs_inode_create_client( cxy_t          cxy,     
[23]1683                                  uint32_t       fs_type,    // in
[1]1684                                  uint32_t       attr,       // in
[23]1685                                  uint32_t       rights,     // in
[1]1686                                  uint32_t       uid,        // in
1687                                  uint32_t       gid,        // in
1688                                  xptr_t       * inode_xp,   // out
1689                                  error_t      * error )     // out
1690{
[459]1691#if DEBUG_RPC_VFS_INODE_CREATE
[564]1692thread_t * this = CURRENT_THREAD;
[459]1693uint32_t cycle = (uint32_t)hal_get_cycles();
1694if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1695printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1696__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[459]1697#endif
1698
[619]1699    uint32_t responses = 1;
[1]1700
1701    // initialise RPC descriptor header
1702    rpc_desc_t  rpc;
1703    rpc.index    = RPC_VFS_INODE_CREATE;
[416]1704    rpc.blocking = true;
[619]1705    rpc.rsp      = &responses;
[1]1706
1707    // set input arguments in RPC descriptor
[610]1708    rpc.args[0] = (uint64_t)fs_type;
[623]1709    rpc.args[1] = (uint64_t)attr;
1710    rpc.args[2] = (uint64_t)rights;
1711    rpc.args[3] = (uint64_t)uid;
1712    rpc.args[4] = (uint64_t)gid;
[1]1713
[436]1714    // register RPC request in remote RPC fifo
[416]1715    rpc_send( cxy , &rpc );
[1]1716
1717    // get output values from RPC descriptor
[623]1718    *inode_xp = (xptr_t)rpc.args[5];
1719    *error    = (error_t)rpc.args[6];
[279]1720
[459]1721#if DEBUG_RPC_VFS_INODE_CREATE
[564]1722cycle = (uint32_t)hal_get_cycles();
[459]1723if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1724printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1725__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1726#endif
[1]1727}
1728
1729/////////////////////////////////////////////
1730void rpc_vfs_inode_create_server( xptr_t xp )
1731{
[459]1732#if DEBUG_RPC_VFS_INODE_CREATE
[564]1733thread_t * this = CURRENT_THREAD;
[459]1734uint32_t cycle = (uint32_t)hal_get_cycles();
1735if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1736printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1737__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1738#endif
1739
[23]1740    uint32_t         fs_type;
[1]1741    uint32_t         attr;
[23]1742    uint32_t         rights;
[1]1743    uint32_t         uid;
1744    uint32_t         gid;
1745    xptr_t           inode_xp;
1746    error_t          error;
1747
1748    // get client cluster identifier and pointer on RPC descriptor
[436]1749    cxy_t        client_cxy  = GET_CXY( xp );
1750    rpc_desc_t * desc        = GET_PTR( xp );
[1]1751
1752    // get input arguments from client rpc descriptor
[610]1753    fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[623]1754    attr       = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1755    rights     = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1756    uid        = (uid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1757    gid        = (gid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
[1]1758
1759    // call local kernel function
[610]1760    error = vfs_inode_create( fs_type,
[1]1761                              attr,
[23]1762                              rights,
[1]1763                              uid,
1764                              gid,
1765                              &inode_xp );
1766
1767    // set output arguments
[623]1768    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)inode_xp );
1769    hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
[296]1770
[459]1771#if DEBUG_RPC_VFS_INODE_CREATE
[564]1772cycle = (uint32_t)hal_get_cycles();
[459]1773if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1774printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1775__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1776#endif
[1]1777}
1778
1779/////////////////////////////////////////////////////////////////////////////////////////
[657]1780// [11]  to RPC_VFS_INODE_DESTROY   deprecated [AG] dec 2019
[1]1781/////////////////////////////////////////////////////////////////////////////////////////
1782void rpc_vfs_inode_destroy_client( cxy_t                cxy,
[601]1783                                   struct vfs_inode_s * inode )
[1]1784{
[459]1785#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1786thread_t * this = CURRENT_THREAD;
[459]1787uint32_t cycle = (uint32_t)hal_get_cycles();
1788if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1789printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1790__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1791#endif
1792
[619]1793    uint32_t responses = 1;
[1]1794
1795    // initialise RPC descriptor header
1796    rpc_desc_t  rpc;
1797    rpc.index    = RPC_VFS_INODE_DESTROY;
[416]1798    rpc.blocking = true;
[619]1799    rpc.rsp      = &responses;
[1]1800
1801    // set input arguments in RPC descriptor
1802    rpc.args[0] = (uint64_t)(intptr_t)inode;
1803   
[436]1804    // register RPC request in remote RPC fifo
[416]1805    rpc_send( cxy , &rpc );
[279]1806
[459]1807#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1808cycle = (uint32_t)hal_get_cycles();
[459]1809if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1810printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1811__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1812#endif
[1]1813}
1814
1815//////////////////////////////////////////////
1816void rpc_vfs_inode_destroy_server( xptr_t xp )
1817{
[459]1818#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1819thread_t * this = CURRENT_THREAD;
[459]1820uint32_t cycle = (uint32_t)hal_get_cycles();
1821if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1822printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1823__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1824#endif
1825
[1]1826    vfs_inode_t * inode;
1827
1828    // get client cluster identifier and pointer on RPC descriptor
[436]1829    cxy_t        client_cxy  = GET_CXY( xp );
1830    rpc_desc_t * desc        = GET_PTR( xp );
[1]1831
[601]1832    // get argument "inode" from client RPC descriptor
[564]1833    inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[1]1834                       
1835    // call local kernel function
[601]1836    vfs_inode_destroy( inode );
[296]1837
[459]1838#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1839cycle = (uint32_t)hal_get_cycles();
[459]1840if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1841printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1842__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1843#endif
[1]1844}
1845
1846/////////////////////////////////////////////////////////////////////////////////////////
[657]1847// [12]  RPC_VFS_DENTRY_CREATE   deprecated [AG] dec 2019
[1]1848/////////////////////////////////////////////////////////////////////////////////////////
1849void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1850                                   uint32_t               type,         // in
1851                                   char                 * name,         // in
1852                                   xptr_t               * dentry_xp,    // out
1853                                   error_t              * error )       // out
1854{
[438]1855#if DEBUG_RPC_VFS_DENTRY_CREATE
[564]1856thread_t * this = CURRENT_THREAD;
[438]1857uint32_t cycle = (uint32_t)hal_get_cycles();
1858if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1859printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1860__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1861#endif
[296]1862
[619]1863    uint32_t responses = 1;
[1]1864
1865    // initialise RPC descriptor header
1866    rpc_desc_t  rpc;
1867    rpc.index    = RPC_VFS_DENTRY_CREATE;
[416]1868    rpc.blocking = true;
[619]1869    rpc.rsp      = &responses;
[1]1870
1871    // set input arguments in RPC descriptor
1872    rpc.args[0] = (uint64_t)type;
1873    rpc.args[1] = (uint64_t)(intptr_t)name;
1874
[436]1875    // register RPC request in remote RPC fifo
[416]1876    rpc_send( cxy , &rpc );
[1]1877
1878    // get output values from RPC descriptor
[610]1879    *dentry_xp = (xptr_t)rpc.args[2];
1880    *error     = (error_t)rpc.args[3];
[279]1881
[438]1882#if DEBUG_RPC_VFS_DENTRY_CREATE
1883cycle = (uint32_t)hal_get_cycles();
1884if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1885printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1886__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1887#endif
[1]1888}
1889
1890//////////////////////////////////////////////
1891void rpc_vfs_dentry_create_server( xptr_t xp )
1892{
[438]1893#if DEBUG_RPC_VFS_DENTRY_CREATE
[564]1894thread_t * this = CURRENT_THREAD;
[438]1895uint32_t cycle = (uint32_t)hal_get_cycles();
1896if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1897printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1898__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]1899#endif
1900
[1]1901    uint32_t      type;
1902    char        * name;
1903    xptr_t        dentry_xp;
1904    error_t       error;
[238]1905    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1906
[1]1907    // get client cluster identifier and pointer on RPC descriptor
[436]1908    cxy_t        client_cxy  = GET_CXY( xp );
1909    rpc_desc_t * desc        = GET_PTR( xp );
[1]1910
[238]1911    // get arguments "name", "type", and "parent" from client RPC descriptor
[610]1912    type   = (uint32_t)         hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1913    name   = (char *)(intptr_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[296]1914
[238]1915    // makes a local copy of  name
1916    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1917                       XPTR( client_cxy , name ) );
1918
[1]1919    // call local kernel function
1920    error = vfs_dentry_create( type,
1921                               name_copy,
1922                               &dentry_xp );
1923    // set output arguments
[610]1924    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)dentry_xp );
1925    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1926
[438]1927#if DEBUG_RPC_VFS_DENTRY_CREATE
1928cycle = (uint32_t)hal_get_cycles();
1929if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1930printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1931__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1932#endif
[1]1933}
1934
1935/////////////////////////////////////////////////////////////////////////////////////////
[657]1936// [13]  RPC_VFS_DENTRY_DESTROY   deprecated [AG] dec 2019
[1]1937/////////////////////////////////////////////////////////////////////////////////////////
1938void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
[601]1939                                    vfs_dentry_t * dentry )
[1]1940{
[440]1941#if DEBUG_RPC_VFS_DENTRY_DESTROY
[564]1942thread_t * this = CURRENT_THREAD;
[440]1943uint32_t cycle = (uint32_t)hal_get_cycles();
1944if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1945printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1946__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1947#endif
1948
[619]1949    uint32_t responses = 1;
[1]1950
1951    // initialise RPC descriptor header
1952    rpc_desc_t  rpc;
1953    rpc.index    = RPC_VFS_DENTRY_DESTROY;
[416]1954    rpc.blocking = true;
[619]1955    rpc.rsp      = &responses;
[1]1956
1957    // set input arguments in RPC descriptor
1958    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1959   
[436]1960    // register RPC request in remote RPC fifo
[416]1961    rpc_send( cxy , &rpc );
[279]1962
[440]1963#if DEBUG_RPC_VFS_DENTRY_DESTROY
1964cycle = (uint32_t)hal_get_cycles();
1965if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1966printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1967__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1968#endif
[1]1969}
1970
1971///////////////////////////////////////////////
1972void rpc_vfs_dentry_destroy_server( xptr_t xp )
1973{
[440]1974#if DEBUG_RPC_VFS_DENTRY_DESTROY
[564]1975thread_t * this = CURRENT_THREAD;
[440]1976uint32_t cycle = (uint32_t)hal_get_cycles();
1977if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1978printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1979__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1980#endif
1981
[1]1982    vfs_dentry_t * dentry;
1983
1984    // get client cluster identifier and pointer on RPC descriptor
[436]1985    cxy_t        client_cxy  = GET_CXY( xp );
1986    rpc_desc_t * desc        = GET_PTR( xp );
[1]1987
1988    // get arguments "dentry" from client RPC descriptor
[564]1989    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[1]1990                       
1991    // call local kernel function
[601]1992    vfs_dentry_destroy( dentry );
[296]1993
[440]1994#if DEBUG_RPC_VFS_DENTRY_DESTROY
1995cycle = (uint32_t)hal_get_cycles();
1996if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1997printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1998__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1999#endif
[1]2000}
2001
2002
2003/////////////////////////////////////////////////////////////////////////////////////////
[657]2004// [14]  RPC_VFS_FILE_CREATE  deprecated [AG] dec 2019
[1]2005/////////////////////////////////////////////////////////////////////////////////////////
[23]2006void rpc_vfs_file_create_client( cxy_t                  cxy,
2007                                 struct vfs_inode_s   * inode,       // in
2008                                 uint32_t               file_attr,   // in
2009                                 xptr_t               * file_xp,     // out
2010                                 error_t              * error )      // out
2011{
[438]2012#if DEBUG_RPC_VFS_FILE_CREATE
[564]2013thread_t * this = CURRENT_THREAD;
[438]2014uint32_t cycle = (uint32_t)hal_get_cycles();
2015if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]2016printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2017__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]2018#endif
2019
[619]2020    uint32_t responses = 1;
[23]2021
2022    // initialise RPC descriptor header
2023    rpc_desc_t  rpc;
2024    rpc.index    = RPC_VFS_FILE_CREATE;
[416]2025    rpc.blocking = true;
[619]2026    rpc.rsp      = &responses;
[23]2027
2028    // set input arguments in RPC descriptor
2029    rpc.args[0] = (uint64_t)(intptr_t)inode;
2030    rpc.args[1] = (uint64_t)file_attr;
2031
[436]2032    // register RPC request in remote RPC fifo
[416]2033    rpc_send( cxy , &rpc );
[23]2034
2035    // get output values from RPC descriptor
2036    *file_xp = (xptr_t)rpc.args[2];
2037    *error   = (error_t)rpc.args[3];
[279]2038
[438]2039#if DEBUG_RPC_VFS_FILE_CREATE
2040cycle = (uint32_t)hal_get_cycles();
2041if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]2042printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2043__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]2044#endif
[23]2045}
2046
2047////////////////////////////////////////////
2048void rpc_vfs_file_create_server( xptr_t xp )
2049{
[438]2050#if DEBUG_RPC_VFS_FILE_CREATE
[564]2051thread_t * this = CURRENT_THREAD;
[438]2052uint32_t cycle = (uint32_t)hal_get_cycles();
2053if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]2054printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2055__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]2056#endif
2057
[23]2058    uint32_t      file_attr;
2059    vfs_inode_t * inode;
2060    xptr_t        file_xp;
2061    error_t       error;
2062
2063    // get client cluster identifier and pointer on RPC descriptor
[436]2064    cxy_t        client_cxy  = GET_CXY( xp );
2065    rpc_desc_t * desc        = GET_PTR( xp );
[23]2066
2067    // get arguments "file_attr" and "inode" from client RPC descriptor
[564]2068    inode     = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2069    file_attr = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[23]2070                       
2071    // call local kernel function
2072    error = vfs_file_create( inode,
2073                             file_attr,
2074                             &file_xp );
2075 
2076    // set output arguments
[564]2077    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
2078    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]2079
[438]2080#if DEBUG_RPC_VFS_FILE_CREATE
2081cycle = (uint32_t)hal_get_cycles();
2082if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]2083printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2084__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]2085#endif
[23]2086}
2087
2088/////////////////////////////////////////////////////////////////////////////////////////
[657]2089// [15]  RPC_VFS_FILE_DESTROY    deprecated [AG] dec 2019
[23]2090/////////////////////////////////////////////////////////////////////////////////////////
2091void rpc_vfs_file_destroy_client( cxy_t        cxy,
2092                                  vfs_file_t * file )
2093{
[440]2094#if DEBUG_RPC_VFS_FILE_DESTROY
[564]2095thread_t * this = CURRENT_THREAD;
[440]2096uint32_t cycle = (uint32_t)hal_get_cycles();
2097if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]2098printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2099__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2100#endif
2101
[619]2102    uint32_t responses = 1;
[23]2103
2104    // initialise RPC descriptor header
2105    rpc_desc_t  rpc;
2106    rpc.index    = RPC_VFS_FILE_DESTROY;
[416]2107    rpc.blocking = true;
[619]2108    rpc.rsp      = &responses;
[23]2109
2110    // set input arguments in RPC descriptor
2111    rpc.args[0] = (uint64_t)(intptr_t)file;
2112   
[436]2113    // register RPC request in remote RPC fifo
[416]2114    rpc_send( cxy , &rpc );
[279]2115
[440]2116#if DEBUG_RPC_VFS_FILE_DESTROY
2117cycle = (uint32_t)hal_get_cycles();
2118if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]2119printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2120__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]2121#endif
[23]2122}
2123
2124/////////////////////////////////////////////
2125void rpc_vfs_file_destroy_server( xptr_t xp )
2126{
[440]2127#if DEBUG_RPC_VFS_FILE_DESTROY
[564]2128thread_t * this = CURRENT_THREAD;
[440]2129uint32_t cycle = (uint32_t)hal_get_cycles();
2130if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]2131printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2132__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2133#endif
2134
[23]2135    vfs_file_t * file;
2136
2137    // get client cluster identifier and pointer on RPC descriptor
[436]2138    cxy_t        client_cxy  = GET_CXY( xp );
2139    rpc_desc_t * desc        = GET_PTR( xp );
[23]2140
2141    // get arguments "dentry" from client RPC descriptor
[564]2142    file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[23]2143                       
2144    // call local kernel function
2145    vfs_file_destroy( file );
[296]2146
[440]2147#if DEBUG_RPC_VFS_FILE_DESTROY
2148cycle = (uint32_t)hal_get_cycles();
2149if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]2150printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2151__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]2152#endif
[23]2153}
2154
2155/////////////////////////////////////////////////////////////////////////////////////////
[657]2156// [16]  RPC_VFS_FS_GET_DENTRY   deprecated [AG] dec 2019
[23]2157/////////////////////////////////////////////////////////////////////////////////////////
[623]2158void rpc_vfs_fs_new_dentry_client( cxy_t         cxy,
[601]2159                                   vfs_inode_t * parent_inode,    // in
2160                                   char        * name,            // in
2161                                   xptr_t        child_inode_xp,  // in
2162                                   error_t     * error )          // out
[238]2163{
[628]2164#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]2165thread_t * this = CURRENT_THREAD;
2166uint32_t cycle = (uint32_t)hal_get_cycles();
[628]2167if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
[601]2168printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2169__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2170#endif
2171
[619]2172    uint32_t responses = 1;
[238]2173
2174    // initialise RPC descriptor header
2175    rpc_desc_t  rpc;
[628]2176    rpc.index    = RPC_VFS_FS_NEW_DENTRY;
[416]2177    rpc.blocking = true;
[619]2178    rpc.rsp      = &responses;
[238]2179
2180    // set input arguments in RPC descriptor
2181    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
2182    rpc.args[1] = (uint64_t)(intptr_t)name;
2183    rpc.args[2] = (uint64_t)child_inode_xp;
2184
[436]2185    // register RPC request in remote RPC fifo
[416]2186    rpc_send( cxy , &rpc );
[238]2187
2188    // get output values from RPC descriptor
2189    *error   = (error_t)rpc.args[3];
[279]2190
[628]2191#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]2192cycle = (uint32_t)hal_get_cycles();
[628]2193if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
[601]2194printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2195__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2196#endif
[238]2197}
2198
[601]2199//////////////////////////////////////////////
[623]2200void rpc_vfs_fs_new_dentry_server( xptr_t xp )
[238]2201{
[628]2202#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]2203thread_t * this = CURRENT_THREAD;
2204uint32_t cycle = (uint32_t)hal_get_cycles();
[628]2205if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
[601]2206printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2207__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2208#endif
2209
[238]2210    error_t       error;
2211    vfs_inode_t * parent;
2212    xptr_t        child_xp;
2213    char        * name;
2214
2215    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
2216
2217    // get client cluster identifier and pointer on RPC descriptor
[436]2218    cxy_t        client_cxy  = GET_CXY( xp );
2219    rpc_desc_t * desc        = GET_PTR( xp );
[238]2220
2221    // get arguments "parent", "name", and "child_xp"
[564]2222    parent     = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
2223    name       = (char*)(intptr_t)       hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
2224    child_xp   = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
[238]2225
2226    // get name local copy
2227    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
2228                       XPTR( client_cxy , name ) );
2229
2230    // call the kernel function
[623]2231    error = vfs_fs_new_dentry( parent , name_copy , child_xp );
[238]2232
2233    // set output argument
[564]2234    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]2235
[628]2236#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]2237cycle = (uint32_t)hal_get_cycles();
[628]2238if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
[601]2239printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2240__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2241#endif
[238]2242}
2243
2244/////////////////////////////////////////////////////////////////////////////////////////
[657]2245// [17]  RPC_VFS_FS_ADD_DENTRY  deprecated [AG] dec 2019
[238]2246/////////////////////////////////////////////////////////////////////////////////////////
[601]2247void rpc_vfs_fs_add_dentry_client( cxy_t          cxy,
2248                                   vfs_inode_t  * parent,     // in
2249                                   vfs_dentry_t * dentry,     // in
2250                                   error_t      * error )     // out
[238]2251{
[601]2252#if DEBUG_RPC_VFS_FS_ADD_DENTRY
2253thread_t * this = CURRENT_THREAD;
2254uint32_t cycle = (uint32_t)hal_get_cycles();
2255if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
2256printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2257__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2258#endif
2259
[619]2260    uint32_t responses = 1;
[238]2261
2262    // initialise RPC descriptor header
2263    rpc_desc_t  rpc;
[601]2264    rpc.index    = RPC_VFS_FS_ADD_DENTRY;
[416]2265    rpc.blocking = true;
[619]2266    rpc.rsp      = &responses;
[238]2267
2268    // set input arguments in RPC descriptor
[601]2269    rpc.args[0] = (uint64_t)(intptr_t)parent;
2270    rpc.args[1] = (uint64_t)(intptr_t)dentry;
[238]2271
[436]2272    // register RPC request in remote RPC fifo
[416]2273    rpc_send( cxy , &rpc );
[238]2274
2275    // get output values from RPC descriptor
[601]2276    *error   = (error_t)rpc.args[2];
[279]2277
[601]2278#if DEBUG_RPC_VFS_FS_ADD_DENTRY
2279cycle = (uint32_t)hal_get_cycles();
2280if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
2281printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2282__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2283#endif
[238]2284}
2285
[619]2286//////////////////////////////////////////////
[601]2287void rpc_vfs_fs_add_dentry_server( xptr_t xp )
[238]2288{
[601]2289#if DEBUG_RPC_VFS_FS_ADD_DENTRY
2290thread_t * this = CURRENT_THREAD;
2291uint32_t cycle = (uint32_t)hal_get_cycles();
2292if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
2293printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2294__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2295#endif
[238]2296
[601]2297    error_t        error;
2298    vfs_inode_t  * parent;
2299    vfs_dentry_t * dentry;
2300
[238]2301    // get client cluster identifier and pointer on RPC descriptor
[436]2302    cxy_t        client_cxy  = GET_CXY( xp );
2303    rpc_desc_t * desc        = GET_PTR( xp );
[238]2304
[601]2305    // get input arguments
2306    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
2307    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[238]2308
2309    // call the kernel function
[601]2310    error = vfs_fs_add_dentry( parent , dentry );
[238]2311
2312    // set output argument
[601]2313    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
[296]2314
[601]2315#if DEBUG_RPC_VFS_FS_ADD_DENTRY
2316cycle = (uint32_t)hal_get_cycles();
2317if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
2318printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2319__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2320#endif
[238]2321}
2322
2323/////////////////////////////////////////////////////////////////////////////////////////
[657]2324// [18]   RPC_VFS_FS_REMOVE_DENTRY    deprecated [AG] dec 2019
[238]2325/////////////////////////////////////////////////////////////////////////////////////////
[601]2326void rpc_vfs_fs_remove_dentry_client( cxy_t          cxy,
2327                                      vfs_inode_t  * parent,     // in
2328                                      vfs_dentry_t * dentry,     // in
2329                                      error_t      * error )     // out
[23]2330{
[601]2331#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
2332thread_t * this = CURRENT_THREAD;
2333uint32_t cycle = (uint32_t)hal_get_cycles();
2334if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
2335printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2336__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2337#endif
2338
[619]2339    uint32_t responses = 1;
[23]2340
2341    // initialise RPC descriptor header
2342    rpc_desc_t  rpc;
[601]2343    rpc.index    = RPC_VFS_FS_REMOVE_DENTRY;
[416]2344    rpc.blocking = true;
[619]2345    rpc.rsp      = &responses;
[23]2346
2347    // set input arguments in RPC descriptor
[601]2348    rpc.args[0] = (uint64_t)(intptr_t)parent;
2349    rpc.args[1] = (uint64_t)(intptr_t)dentry;
[23]2350
[601]2351    // register RPC request in remote RPC fifo
[416]2352    rpc_send( cxy , &rpc );
[23]2353
[601]2354    // get output values from RPC descriptor
2355    *error   = (error_t)rpc.args[2];
[279]2356
[601]2357#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
2358cycle = (uint32_t)hal_get_cycles();
2359if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
2360printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2361__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2362#endif
[23]2363}
2364
[601]2365/////////////////////////////////////////////////
2366void rpc_vfs_fs_remove_dentry_server( xptr_t xp )
[23]2367{
[601]2368#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
2369thread_t * this = CURRENT_THREAD;
2370uint32_t cycle = (uint32_t)hal_get_cycles();
2371if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
2372printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2373__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2374#endif
[23]2375
[601]2376    error_t        error;
2377    vfs_inode_t  * parent;
2378    vfs_dentry_t * dentry;
2379
[23]2380    // get client cluster identifier and pointer on RPC descriptor
[436]2381    cxy_t        client_cxy  = GET_CXY( xp );
[438]2382    rpc_desc_t * desc        = GET_PTR( xp );
[23]2383
2384    // get input arguments
[601]2385    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
2386    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[23]2387
2388    // call the kernel function
[601]2389    error = vfs_fs_remove_dentry( parent , dentry );
[23]2390
2391    // set output argument
[601]2392    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
[296]2393
[601]2394#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
2395cycle = (uint32_t)hal_get_cycles();
2396if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
2397printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2398__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2399#endif
[23]2400}
2401
2402/////////////////////////////////////////////////////////////////////////////////////////
[657]2403// [19]   RPC_VFS_INODE_LOAD_ALL_PAGES deprecated [AG] dec 2019
[601]2404/////////////////////////////////////////////////////////////////////////////////////////
2405void rpc_vfs_inode_load_all_pages_client( cxy_t         cxy,
2406                                          vfs_inode_t * inode,      // in
2407                                          error_t     * error )     // out
2408{
2409#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2410thread_t * this = CURRENT_THREAD;
2411uint32_t cycle = (uint32_t)hal_get_cycles();
2412if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2413printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2414__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2415#endif
2416
[619]2417    uint32_t responses = 1;
[601]2418
2419    // initialise RPC descriptor header
2420    rpc_desc_t  rpc;
2421    rpc.index    = RPC_VFS_INODE_LOAD_ALL_PAGES;
2422    rpc.blocking = true;
[619]2423    rpc.rsp      = &responses;
[601]2424
2425    // set input arguments in RPC descriptor
2426    rpc.args[0] = (uint64_t)(intptr_t)inode;
2427
2428    // register RPC request in remote RPC fifo
2429    rpc_send( cxy , &rpc );
2430
2431    // get output values from RPC descriptor
2432    *error   = (error_t)rpc.args[1];
2433
2434#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2435cycle = (uint32_t)hal_get_cycles();
2436if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2437printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2438__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2439#endif
2440}
2441
2442/////////////////////////////////////////////////////
2443void rpc_vfs_inode_load_all_pages_server( xptr_t xp )
2444{
2445#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2446thread_t * this = CURRENT_THREAD;
2447uint32_t cycle = (uint32_t)hal_get_cycles();
2448if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2449printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2450__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2451#endif
2452
2453    error_t       error;
2454    vfs_inode_t * inode;
2455
2456    // get client cluster identifier and pointer on RPC descriptor
2457    cxy_t        client_cxy  = GET_CXY( xp );
2458    rpc_desc_t * desc        = GET_PTR( xp );
2459
2460    // get input argument
2461    inode = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
2462
2463    // call the kernel function
2464    error = vfs_inode_load_all_pages( inode );
2465
2466    // set output argument
2467    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
2468
2469#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2470cycle = (uint32_t)hal_get_cycles();
2471if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2472printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2473__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2474#endif
2475}
2476
2477/////////////////////////////////////////////////////////////////////////////////////////
[657]2478// [20]  RPC_VMM_GET_VSEG deprecated [AG] sept 2019
[23]2479/////////////////////////////////////////////////////////////////////////////////////////
[389]2480void rpc_vmm_get_vseg_client( cxy_t       cxy,     
2481                              process_t * process,     // in 
2482                              intptr_t    vaddr,       // in 
2483                              xptr_t    * vseg_xp,     // out
2484                              error_t   * error )      // out
[1]2485{
[440]2486#if DEBUG_RPC_VMM_GET_VSEG
[564]2487thread_t * this = CURRENT_THREAD;
[440]2488uint32_t cycle = (uint32_t)hal_get_cycles();
2489if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]2490printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2491__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2492#endif
2493
[619]2494    uint32_t responses = 1;
[1]2495
2496    // initialise RPC descriptor header
2497    rpc_desc_t  rpc;
[389]2498    rpc.index    = RPC_VMM_GET_VSEG;
[416]2499    rpc.blocking = true;
[619]2500    rpc.rsp      = &responses;
[1]2501
2502    // set input arguments in RPC descriptor
2503    rpc.args[0] = (uint64_t)(intptr_t)process;
2504    rpc.args[1] = (uint64_t)vaddr;
2505
[436]2506    // register RPC request in remote RPC fifo
[416]2507    rpc_send( cxy , &rpc );
[1]2508
2509    // get output argument from rpc descriptor
2510    *vseg_xp = rpc.args[2];
[389]2511    *error   = (error_t)rpc.args[3];
[279]2512
[440]2513#if DEBUG_RPC_VMM_GET_VSEG
2514cycle = (uint32_t)hal_get_cycles();
2515if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]2516printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2517__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2518#endif
[1]2519}
2520
[389]2521/////////////////////////////////////////
2522void rpc_vmm_get_vseg_server( xptr_t xp )
[1]2523{
[440]2524#if DEBUG_RPC_VMM_GET_VSEG
[564]2525thread_t * this = CURRENT_THREAD;
[440]2526uint32_t cycle = (uint32_t)hal_get_cycles();
2527if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]2528printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2529__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2530#endif
2531
[1]2532    process_t   * process;
2533    intptr_t      vaddr;
2534    vseg_t      * vseg_ptr;
2535    xptr_t        vseg_xp;
[389]2536    error_t       error;
[1]2537
2538    // get client cluster identifier and pointer on RPC descriptor
[436]2539    cxy_t        client_cxy  = GET_CXY( xp );
2540    rpc_desc_t * desc        = GET_PTR( xp );
[1]2541
2542    // get input argument from client RPC descriptor
[564]2543    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2544    vaddr   = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[1]2545   
2546    // call local kernel function
[389]2547    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
[1]2548
[389]2549    // set output arguments to client RPC descriptor
2550    vseg_xp = XPTR( local_cxy , vseg_ptr );
[564]2551    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
2552    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]2553
[440]2554#if DEBUG_RPC_VMM_GET_VSEG
2555cycle = (uint32_t)hal_get_cycles();
2556if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]2557printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2558__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2559#endif
[1]2560}
2561
2562/////////////////////////////////////////////////////////////////////////////////////////
[640]2563// [22]          RPC_KCM_ALLOC deprecated [AG] sept 2019
[1]2564/////////////////////////////////////////////////////////////////////////////////////////
[23]2565void rpc_kcm_alloc_client( cxy_t      cxy,
2566                           uint32_t   kmem_type,   // in
[619]2567                           xptr_t   * buf_xp )     // out
[1]2568{
[564]2569#if DEBUG_RPC_KCM_ALLOC
2570thread_t * this = CURRENT_THREAD;
2571uint32_t cycle = (uint32_t)hal_get_cycles();
2572if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2573printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2574__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2575#endif
2576
[619]2577    uint32_t responses = 1;
[1]2578
2579    // initialise RPC descriptor header
2580    rpc_desc_t  rpc;
[441]2581    rpc.index    = RPC_KCM_ALLOC;
[416]2582    rpc.blocking = true;
[619]2583    rpc.rsp      = &responses;
[1]2584
[23]2585    // set input arguments in RPC descriptor
2586    rpc.args[0] = (uint64_t)kmem_type;
2587
[436]2588    // register RPC request in remote RPC fifo
[416]2589    rpc_send( cxy , &rpc );
[1]2590
2591    // get output arguments from RPC descriptor
[23]2592    *buf_xp = (xptr_t)rpc.args[1];
[279]2593
[564]2594#if DEBUG_RPC_KCM_ALLOC
2595cycle = (uint32_t)hal_get_cycles();
2596if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2597printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2598__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2599#endif
[1]2600}
2601
[23]2602//////////////////////////////////////
2603void rpc_kcm_alloc_server( xptr_t xp )
[1]2604{
[564]2605#if DEBUG_RPC_KCM_ALLOC
2606thread_t * this = CURRENT_THREAD;
2607uint32_t cycle = (uint32_t)hal_get_cycles();
2608if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2609printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2610__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2611#endif
2612
[1]2613    // get client cluster identifier and pointer on RPC descriptor
[436]2614    cxy_t        client_cxy  = GET_CXY( xp );
[438]2615    rpc_desc_t * desc        = GET_PTR( xp );
[1]2616
[23]2617    // get input argument "kmem_type" from client RPC descriptor
[564]2618    uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[23]2619
2620    // allocates memory for kcm
[1]2621    kmem_req_t  req;
[23]2622    req.type  = kmem_type;
[1]2623    req.flags = AF_ZERO;
[23]2624    void * buf_ptr = kmem_alloc( &req );
[1]2625
2626    // set output argument
[23]2627    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
[564]2628    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
[296]2629
[564]2630#if DEBUG_RPC_KCM_ALLOC
2631cycle = (uint32_t)hal_get_cycles();
2632if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2633printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2634__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2635#endif
[1]2636}   
2637
2638/////////////////////////////////////////////////////////////////////////////////////////
[640]2639// [23]          RPC_KCM_FREE deprecated [AG] sept 2019
[1]2640/////////////////////////////////////////////////////////////////////////////////////////
[23]2641void rpc_kcm_free_client( cxy_t      cxy,
2642                          void     * buf,          // in
2643                          uint32_t   kmem_type )   // in
[1]2644{
[564]2645#if DEBUG_RPC_KCM_FREE
2646thread_t * this = CURRENT_THREAD;
2647uint32_t cycle = (uint32_t)hal_get_cycles();
2648if( cycle > DEBUG_RPC_KCM_FREE )
[601]2649printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2650__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2651#endif
2652
[619]2653    uint32_t responses = 1;
[1]2654
2655    // initialise RPC descriptor header
2656    rpc_desc_t  rpc;
[441]2657    rpc.index    = RPC_KCM_FREE;
[416]2658    rpc.blocking = true;
[619]2659    rpc.rsp      = &responses;
[1]2660
2661    // set input arguments in RPC descriptor
[23]2662    rpc.args[0] = (uint64_t)(intptr_t)buf;
2663    rpc.args[1] = (uint64_t)kmem_type;
[1]2664
[436]2665    // register RPC request in remote RPC fifo
[416]2666    rpc_send( cxy , &rpc );
[279]2667
[564]2668#if DEBUG_RPC_KCM_FREE
2669cycle = (uint32_t)hal_get_cycles();
2670if( cycle > DEBUG_RPC_KCM_FREE )
[601]2671printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2672__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2673#endif
[1]2674}
2675
[23]2676/////////////////////////////////////
2677void rpc_kcm_free_server( xptr_t xp )
[1]2678{
[564]2679#if DEBUG_RPC_KCM_FREE
2680thread_t * this = CURRENT_THREAD;
2681uint32_t cycle = (uint32_t)hal_get_cycles();
2682if( cycle > DEBUG_RPC_KCM_FREE )
[601]2683printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2684__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2685#endif
2686
[1]2687    // get client cluster identifier and pointer on RPC descriptor
[436]2688    cxy_t        client_cxy  = GET_CXY( xp );
[438]2689    rpc_desc_t * desc        = GET_PTR( xp );
[1]2690
[23]2691    // get input arguments "buf" and "kmem_type" from client RPC descriptor
[564]2692    void     * buf = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2693    uint32_t   kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[1]2694
2695    // releases memory
2696    kmem_req_t  req;
[23]2697    req.type = kmem_type;
2698    req.ptr  = buf;
2699    kmem_free( &req );
[296]2700
[564]2701#if DEBUG_RPC_KCM_FREE
2702cycle = (uint32_t)hal_get_cycles();
2703if( cycle > DEBUG_RPC_KCM_FREE )
[601]2704printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2705__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2706#endif
[1]2707}   
2708
2709/////////////////////////////////////////////////////////////////////////////////////////
[635]2710// [24]          Marshaling functions attached to RPC_MAPPER_SYNC
[1]2711/////////////////////////////////////////////////////////////////////////////////////////
[623]2712void rpc_mapper_sync_client( cxy_t             cxy,
2713                             struct mapper_s * mapper,
2714                             error_t         * error )
2715{
2716#if DEBUG_RPC_MAPPER_SYNC
2717thread_t * this = CURRENT_THREAD;
2718uint32_t cycle = (uint32_t)hal_get_cycles();
2719if( cycle > DEBUG_RPC_MAPPER_SYNC )
2720printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2721__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2722#endif
2723
2724    uint32_t responses = 1;
2725
2726    // initialise RPC descriptor header
2727    rpc_desc_t  rpc;
2728    rpc.index    = RPC_MAPPER_SYNC;
2729    rpc.blocking = true;
2730    rpc.rsp      = &responses;
2731
2732    // set input arguments in RPC descriptor
2733    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2734
2735    // register RPC request in remote RPC fifo
2736    rpc_send( cxy , &rpc );
2737
2738    // get output values from RPC descriptor
2739    *error   = (error_t)rpc.args[1];
2740
2741#if DEBUG_RPC_MAPPER_SYNC
2742cycle = (uint32_t)hal_get_cycles();
2743if( cycle > DEBUG_RPC_MAPPER_SYNC )
2744printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2745__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2746#endif
2747}
2748
2749////////////////////////////////////////
2750void rpc_mapper_sync_server( xptr_t xp )
2751{
2752#if DEBUG_RPC_MAPPER_SYNC
2753thread_t * this = CURRENT_THREAD;
2754uint32_t cycle = (uint32_t)hal_get_cycles();
2755if( cycle > DEBUG_RPC_MAPPER_SYNC )
2756printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2757__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2758#endif
2759
2760    mapper_t * mapper;
2761    error_t    error;
2762
2763    // get client cluster identifier and pointer on RPC descriptor
2764    cxy_t        client_cxy  = GET_CXY( xp );
2765    rpc_desc_t * desc        = GET_PTR( xp );
2766
2767    // get arguments from client RPC descriptor
2768    mapper  = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2769
2770    // call local kernel function
2771    error = mapper_sync( mapper );
2772
2773    // set output argument to client RPC descriptor
2774    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
2775
2776#if DEBUG_RPC_MAPPER_SYNC
2777cycle = (uint32_t)hal_get_cycles();
2778if( cycle > DEBUG_RPC_MAPPER_SYNC )
2779printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2780__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2781#endif
2782}
2783
[657]2784*/
[313]2785
[601]2786
[313]2787
[657]2788/*
2789////////////////////////////////////////////////////
2790void rpc_fbf_display_client( cxy_t        cxy,
2791                             xptr_t       window_xp,
2792                             uint32_t     cores,
2793                             error_t    * error )
[313]2794{
[657]2795#if DEBUG_RPC_FBF_DISPLAY
2796uint32_t  cycle = (uint32_t)hal_get_cycles();
[611]2797thread_t * this = CURRENT_THREAD;
[657]2798if( DEBUG_RPC_FBF_DISPLAY < cycle )
2799printk("\n[%s] thread[%x,%x] on core %d : enter / cycle %d\n",
[611]2800__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2801#endif
2802
[619]2803    uint32_t    responses = 1;
2804    rpc_desc_t  rpc;
[611]2805
[619]2806    // initialise RPC descriptor header
[657]2807    rpc.index    = RPC_FBF_DISPLAY;
[619]2808    rpc.blocking = true;
2809    rpc.rsp      = &responses;
2810
2811    // set input arguments in RPC descriptor
[657]2812    rpc.args[0] = (uint64_t)window_xp;
2813    rpc.args[1] = (uint64_t)cores;
[619]2814
[657]2815    // register RPC request in remote RPC fifo
[619]2816    rpc_send( cxy , &rpc );
[611]2817
[657]2818    // get output argument from RPC descriptor
2819    *error     = (error_t)rpc.args[2];
2820
2821#if DEBUG_RPC_FBF_DISPLAY
[611]2822cycle = (uint32_t)hal_get_cycles();
[657]2823if( DEBUG_RPC_FBF_DISPLAY < cycle )
2824printk("\n[%s] thread[%x,%x] on core %d : exit / cycle %d\n",
[611]2825__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2826#endif
2827}
2828
[657]2829////////////////////////////////////////
2830void rpc_fbf_display_server( xptr_t xp )
[611]2831{
2832    // get client cluster identifier and pointer on RPC descriptor
2833    cxy_t        client_cxy = GET_CXY( xp );
2834    rpc_desc_t * desc       = GET_PTR( xp );
2835
2836    // get arguments from RPC descriptor
[657]2837    xptr_t   window_xp = (xptr_t  )hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
2838    uint32_t ncores    = (uint32_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
[611]2839
[657]2840#if DEBUG_RPC_FBF_DISPLAY
[611]2841uint32_t cycle = (uint32_t)hal_get_cycles();
2842thread_t * this = CURRENT_THREAD;
[657]2843if( DEBUG_RPC_FBF_DISPLAY < cycle )
2844printk("\n[%s] thread[%x,%x] on core %d : enter / cycle %d\n",
2845__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[611]2846#endif
2847
[657]2848    // call relevant kernel function
2849    error_t error = dev_fbf_parallel_display( window_xp , ncores );
[407]2850
[657]2851    // WARNING : for parallel RPCs, the return error argument is shared
2852    hal_remote_atomic_or( XPTR( client_cxy , &desc->args[2] ) , error );
[407]2853
[657]2854#if DEBUG_RPC_FBF_DISPLAY
[611]2855cycle = (uint32_t)hal_get_cycles();
[657]2856if( DEBUG_RPC_FBF_DISPLAY < cycle )
2857printk("\n[%s] thread[%x,%x] on core %d : exit / cycle %d\n",
2858__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[611]2859#endif
[657]2860}
2861*/
[407]2862
[408]2863
Note: See TracBrowser for help on using the repository browser.