source: trunk/kernel/kern/rpc.c

Last change on this file was 669, checked in by alain, 11 months ago

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File size: 103.1 KB
Line 
1/*
2 * rpc.c - RPC operations implementation.
3 *
4 * Author    Alain Greiner (2016,2017,2018,2019,2020)
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
24#include <kernel_config.h>
25#include <hal_kernel_types.h>
26#include <hal_vmm.h>
27#include <hal_atomic.h>
28#include <hal_remote.h>
29#include <hal_irqmask.h>
30#include <hal_special.h>
31#include <printk.h>
32#include <user_dir.h>
33#include <remote_sem.h>
34#include <core.h>
35#include <mapper.h>
36#include <chdev.h>
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
45
46/////////////////////////////////////////////////////////////////////////////////////////
47// Array of function pointers and array of printable strings.
48// These arrays must be kept consistent with enum in rpc.h file.
49/////////////////////////////////////////////////////////////////////////////////////////
50
51rpc_server_t * rpc_server[RPC_MAX_INDEX] =
52{
53    &rpc_undefined,                        // 0
54    &rpc_undefined,                        // 1
55    &rpc_undefined,                        // 2
56    &rpc_process_make_fork_server,         // 3
57    &rpc_user_dir_create_server,           // 4
58    &rpc_user_dir_destroy_server,          // 5
59    &rpc_thread_user_create_server,        // 6
60    &rpc_thread_kernel_create_server,      // 7
61    &rpc_undefined,                        // 8
62    &rpc_process_sigaction_server,         // 9
63
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
74};
75
76char * rpc_str[RPC_MAX_INDEX] =
77{
78    "undefined_0",               // 0
79    "undefined_1",               // 1
80    "undefined_2",               // 2
81    "PROCESS_MAKE_FORK",         // 3
82    "USER_DIR_CREATE",           // 4
83    "USER_DIR_DESTROY",          // 5
84    "THREAD_USER_CREATE",        // 6
85    "THREAD_KERNEL_CREATE",      // 7
86    "FBF_DISPLAY",               // 8
87    "PROCESS_SIGACTION",         // 9
88
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
99};
100
101//////////////////////////////////////////////////////////////////////////////////
102void __attribute__((noinline)) rpc_undefined( xptr_t xp __attribute__ ((unused)) )
103{
104        assert( __FUNCTION__, false , "called in cluster %x", local_cxy );
105}
106
107/***************************************************************************************/
108/************ Generic function supporting RPCs : client side ***************************/
109/***************************************************************************************/
110
111///////////////////////////////////////
112void rpc_send( cxy_t        server_cxy, 
113               rpc_desc_t * rpc )
114{
115    lid_t              server_core_lid;
116    lid_t              client_core_lid;
117    volatile error_t   full;
118    thread_t         * this;
119
120    full            = 0;
121    this            = CURRENT_THREAD;
122    client_core_lid = this->core->lid;
123
124    // check calling thread can yield when is not the IDLE thread
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__ );
127
128    // select a server_core : use client core index if possible / core 0 otherwise
129    if( client_core_lid < hal_remote_l32( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) )
130    {
131        server_core_lid = client_core_lid;
132    }
133    else
134    {   
135        server_core_lid = 0;
136    }
137
138    // register client_thread and client_core in RPC descriptor
139    rpc->thread = this;
140    rpc->lid    = client_core_lid;
141
142    // build extended pointer on the RPC descriptor
143        xptr_t   desc_xp = XPTR( local_cxy , rpc );
144
145    // get local pointer on rpc_fifo in remote cluster,
146    remote_fifo_t * rpc_fifo    = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
147    xptr_t          rpc_fifo_xp = XPTR( server_cxy , rpc_fifo );
148
149        // post RPC in remote fifo / deschedule without blocking if fifo full
150    do
151    { 
152        full = remote_fifo_put_item( rpc_fifo_xp , (uint64_t )desc_xp );
153
154            if ( full ) 
155        {
156            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
157            __FUNCTION__ , local_cxy , server_cxy );
158
159            // deschedule without blocking
160            sched_yield("RPC fifo full");
161        }
162    }
163    while( full );
164 
165#if DEBUG_RPC_CLIENT_GENERIC
166uint32_t cycle = (uint32_t)hal_get_cycles();
167uint32_t items = remote_fifo_items( rpc_fifo_xp );
168if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
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], 
171server_cxy, server_core_lid, items, cycle );
172#endif
173       
174   // send IPI to the selected server core
175   dev_pic_send_ipi( server_cxy , server_core_lid );
176
177    // wait RPC completion before returning if blocking RPC :
178    // - deschedule without blocking if thread idle (in kernel init)
179    // - block and deschedule policy for any other thread
180    if ( rpc->blocking )
181    {
182        if( this->type == THREAD_IDLE )  // deschedule without blocking policy
183        {
184 
185#if DEBUG_RPC_CLIENT_GENERIC
186cycle = (uint32_t)hal_get_cycles();
187if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
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 );
190#endif
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             }
199
200#if DEBUG_RPC_CLIENT_GENERIC
201cycle = (uint32_t)hal_get_cycles();
202if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
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 );
205#endif
206 
207        }
208        else                            // block and deschedule policy
209        {
210
211#if DEBUG_RPC_CLIENT_GENERIC
212cycle = (uint32_t)hal_get_cycles();
213if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
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 );
216#endif
217
218        // block client thread
219        thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
220
221        // deschedule
222        sched_yield("blocked on RPC");
223
224#if DEBUG_RPC_CLIENT_GENERIC
225cycle = (uint32_t)hal_get_cycles();
226if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
227printk("\n[%s] thread[%x,%x] resumes after rpc %s / cycle %d\n",
228__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
229#endif
230        }
231
232// response must be available for a blocking RPC
233assert( __FUNCTION__, (*rpc->rsp == 0) , "illegal response for RPC %s\n", rpc_str[rpc->index] );
234
235    }
236    else       // non blocking RPC
237    {
238
239#if DEBUG_RPC_CLIENT_GENERIC
240cycle = (uint32_t)hal_get_cycles();
241if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
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 );
244#endif
245
246    }
247}  // end rpc_send()
248
249
250/***************************************************************************************/
251/************ Generic functions supporting RPCs : server side **************************/
252/***************************************************************************************/
253
254////////////////////////////
255void rpc_server_func( void )
256{
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
263    xptr_t          client_xp;          // extended pointer on client thread
264    lid_t           client_lid;         // local index of client core
265        thread_t      * server_ptr;         // local pointer on server thread
266    xptr_t          server_xp;          // extended pointer on server thread
267    lid_t           server_lid;         // local index of server core
268        remote_fifo_t * rpc_fifo;           // local pointer on RPC fifo
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
273    // makes RPC thread not preemptable
274        hal_disable_irq( NULL );
275 
276        server_ptr      = CURRENT_THREAD;
277    server_xp       = XPTR( local_cxy , server_ptr );
278    server_lid      = server_ptr->core->lid;
279        rpc_fifo        = &LOCAL_CLUSTER->rpc_fifo[server_lid];
280
281    // "infinite" RPC thread loop
282        while(1)
283        {
284        // try to take RPC_FIFO ownership
285        if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) ) 
286        {
287
288#if DEBUG_RPC_SERVER_GENERIC
289uint32_t cycle = (uint32_t)hal_get_cycles();
290if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
291printk("\n[%s] RPC thread[%x,%x] on core[%d] takes RPC_FIFO ownership / cycle %d\n",
292__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, server_lid, cycle );
293#endif
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 )   
302            {
303                // get client cluster and pointer on RPC descriptor
304                desc_cxy = GET_CXY( desc_xp );
305                desc_ptr = GET_PTR( desc_xp );
306
307                // get relevant infos from RPC descriptor
308                    index      = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
309                client_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
310                rsp_ptr    = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->rsp ) );
311                client_lid = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->lid ) );
312
313                rsp_xp     = XPTR( desc_cxy , rsp_ptr );
314                client_xp  = XPTR( desc_cxy , client_ptr );
315
316#if DEBUG_RPC_SERVER_GENERIC
317cycle = (uint32_t)hal_get_cycles();
318uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) );
319if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
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 );
322#endif
323                // register client thread in RPC thread descriptor
324                server_ptr->rpc_client_xp = client_xp;
325 
326                // call the relevant server function
327                rpc_server[index]( desc_xp );
328
329                // update responses counter
330                responses = hal_remote_atomic_add( rsp_xp , -1 );
331
332#if DEBUG_RPC_SERVER_GENERIC
333cycle = (uint32_t)hal_get_cycles();
334if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
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 );
337#endif
338                // decrement expected responses counter
339                // unblock client thread if last response
340                if( responses == 1 ) 
341                {
342                    // unblock client thread
343                    thread_unblock( client_xp , THREAD_BLOCKED_RPC );
344
345                    hal_fence();
346
347#if DEBUG_RPC_SERVER_GENERIC
348cycle = (uint32_t)hal_get_cycles();
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 ) );
352if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
353printk("\n[%s] RPC thread[%x,%x] unblocked client thread[%x,%x] / cycle %d\n",
354__FUNCTION__, server_ptr->process->pid, server_ptr->trdid,
355client_pid, client_trdid, cycle );
356#endif
357                    // send IPI to client core
358                    dev_pic_send_ipi( desc_cxy , client_lid );
359                }
360            }  // end RPC handling if fifo non empty
361        }  // end if RPC_fIFO ownership successfully taken and released
362
363        // sucide if too many RPC threads
364        if( LOCAL_CLUSTER->rpc_threads[server_lid] >= CONFIG_RPC_THREADS_MAX )
365            {
366
367#if DEBUG_RPC_SERVER_GENERIC
368uint32_t cycle = (uint32_t)hal_get_cycles();
369if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
370printk("\n[%s] RPC thread[%x,%x] suicides / cycle %d\n",
371__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
372#endif
373            // update RPC threads counter
374                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[server_lid] , -1 );
375
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 );
381            }
382        // block and deschedule otherwise
383        else
384        {
385
386#if DEBUG_RPC_SERVER_GENERIC
387uint32_t cycle = (uint32_t)hal_get_cycles();
388if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
389printk("\n[%s] RPC thread[%x,%x] blocks & deschedules / cycle %d\n",
390__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
391#endif
392            // RPC thread blocks on IDLE
393            thread_block( server_xp , THREAD_BLOCKED_IDLE );
394
395            // RPC thread deschedules
396            sched_yield("RPC_FIFO empty");
397        }
398        } // end infinite loop
399
400} // end rpc_server_func()
401
402
403/***************************************************************************************/
404/************ Marshaling functions ordered by increasing index *************************/
405/***************************************************************************************/
406
407
408/////////////////////////////////////////////////////////////////////////////////////////
409// [0]           undefined                                               
410/////////////////////////////////////////////////////////////////////////////////////////
411
412/////////////////////////////////////////////////////////////////////////////////////////
413// [1]           undefined                                               
414/////////////////////////////////////////////////////////////////////////////////////////
415
416/////////////////////////////////////////////////////////////////////////////////////////
417// [2]           undefined                                               
418/////////////////////////////////////////////////////////////////////////////////////////
419
420
421/////////////////////////////////////////////////////////////////////////////////////////
422// [3]           Marshaling function attached to RPC_MAKE_FORK           
423/////////////////////////////////////////////////////////////////////////////////////////
424
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
432{
433#if DEBUG_RPC_PROCESS_MAKE_FORK
434thread_t * this = CURRENT_THREAD;
435uint32_t cycle = (uint32_t)hal_get_cycles();
436if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
437printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
438__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
439#endif
440
441    uint32_t responses = 1;
442
443    // initialise RPC descriptor header
444    rpc_desc_t  rpc;
445    rpc.index    = RPC_PROCESS_MAKE_FORK;
446    rpc.blocking = true;
447    rpc.rsp      = &responses;
448
449    // set input arguments in RPC descriptor 
450    rpc.args[0] = (uint64_t)ref_process_xp;
451    rpc.args[1] = (uint64_t)parent_thread_xp;
452
453    // register RPC request in remote RPC fifo
454    rpc_send( cxy , &rpc );
455
456    // get output arguments from RPC descriptor
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];     
460
461#if DEBUG_RPC_PROCESS_MAKE_FORK
462cycle = (uint32_t)hal_get_cycles();
463if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
464printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
465__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
466#endif
467}
468
469//////////////////////////////////////////////
470void rpc_process_make_fork_server( xptr_t xp )
471{
472#if DEBUG_RPC_PROCESS_MAKE_FORK
473thread_t * this = CURRENT_THREAD;
474uint32_t cycle = (uint32_t)hal_get_cycles();
475if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
476printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
477__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
478#endif
479
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
485
486    // get client cluster identifier and pointer on RPC descriptor
487    cxy_t        client_cxy  = GET_CXY( xp );
488    rpc_desc_t * desc        = GET_PTR( xp );
489
490    // get input arguments from cient RPC descriptor
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] ) );
493
494    // call local kernel function
495    error = process_make_fork( ref_process_xp,
496                               parent_thread_xp,
497                               &child_pid,
498                               &child_thread_ptr ); 
499
500    // set output argument into client RPC descriptor
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 );
504
505#if DEBUG_RPC_PROCESS_MAKE_FORK
506cycle = (uint32_t)hal_get_cycles();
507if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
508printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
509__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
510#endif
511}
512
513/////////////////////////////////////////////////////////////////////////////////////////
514// [4]      Marshaling functions attached to RPC_USER_DIR_CREATE 
515/////////////////////////////////////////////////////////////////////////////////////////
516
517////////////////////////////////////////////////////
518void rpc_user_dir_create_client( cxy_t          cxy,
519                                 vfs_inode_t *  inode,
520                                 xptr_t         ref_xp,
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
531    uint32_t responses = 1;
532
533    // initialise RPC descriptor header
534    rpc_desc_t  rpc;
535    rpc.index    = RPC_USER_DIR_CREATE;
536    rpc.blocking = true;
537    rpc.rsp      = &responses;
538
539    // set input arguments in RPC descriptor
540    rpc.args[0] = (uint64_t)(intptr_t)inode;
541    rpc.args[1] = (uint64_t)ref_xp;
542
543    // register RPC request in remote RPC fifo
544    rpc_send( cxy , &rpc );
545
546    // get output argument from RPC descriptor
547    *dir = (user_dir_t *)(intptr_t)rpc.args[2];
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
569    xptr_t        ref_xp;         // extended pointer on reference user process
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
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]));
579
580    // call kernel function
581    dir = user_dir_create( inode , ref_xp );
582
583    // set output argument into RPC descriptor
584    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (intptr_t)dir );
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
594/////////////////////////////////////////////////////////////////////////////////////////
595// [5]      Marshaling functions attached to RPC_USER_DIR_DESTROY
596/////////////////////////////////////////////////////////////////////////////////////////
597
598////////////////////////////////////////////////////
599void rpc_user_dir_destroy_client( cxy_t         cxy,
600                                  user_dir_t  * dir,
601                                  xptr_t        ref_xp )
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
611    uint32_t responses = 1;
612
613    // initialise RPC descriptor header
614    rpc_desc_t  rpc;
615    rpc.index    = RPC_USER_DIR_DESTROY;
616    rpc.blocking = true;
617    rpc.rsp      = &responses;
618
619    // set input arguments in RPC descriptor
620    rpc.args[0] = (uint64_t)(intptr_t)dir;
621    rpc.args[1] = (uint64_t)ref_xp;
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
646    xptr_t       ref_xp;         // extended pointer on reference process
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
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]));
655
656    // call kernel function
657    user_dir_destroy( dir , ref_xp );
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
667/////////////////////////////////////////////////////////////////////////////////////////
668// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE   
669/////////////////////////////////////////////////////////////////////////////////////////
670
671/////////////////////////////////////////////////////////
672void rpc_thread_user_create_client( cxy_t            cxy, 
673                                    pid_t            pid,         // in
674                                    void           * start_func,  // in
675                                    void           * start_arg,   // in
676                                    pthread_attr_t * attr,        // in
677                                    xptr_t         * thread_xp,   // out
678                                    error_t        * error )      // out
679{
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)
684printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
685__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
686#endif
687   
688    uint32_t responses = 1;
689
690    // initialise RPC descriptor header
691    rpc_desc_t  rpc;
692    rpc.index    = RPC_THREAD_USER_CREATE;
693    rpc.blocking = true;
694    rpc.rsp      = &responses;
695
696    // set input arguments in RPC descriptor
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;
701
702    // register RPC request in remote RPC fifo
703    rpc_send( cxy , &rpc );
704
705    // get output arguments from RPC descriptor
706    *thread_xp = (xptr_t)rpc.args[4];
707    *error     = (error_t)rpc.args[5];
708
709#if DEBUG_RPC_THREAD_USER_CREATE
710cycle = (uint32_t)hal_get_cycles();
711if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
712printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
713__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
714#endif
715}
716
717///////////////////////////////////////////////
718void rpc_thread_user_create_server( xptr_t xp )
719{
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)
724printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
725__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
726#endif
727
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
732
733    pid_t            pid;        // process identifier
734    void           * start_func;
735    void           * start_arg;
736    error_t          error;
737
738    // get client cluster identifier and pointer on RPC descriptor
739    cxy_t        client_cxy  = GET_CXY( xp );
740    rpc_desc_t * desc        = GET_PTR( xp );
741
742    // get input arguments from RPC descriptor
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]));
747
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   
753    // call kernel function
754    error = thread_user_create( pid,
755                                start_func,
756                                start_arg,
757                                &attr_copy,
758                                &thread_ptr );
759    // set output arguments
760    thread_xp = XPTR( local_cxy , thread_ptr );
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 );
763
764#if DEBUG_RPC_THREAD_USER_CREATE
765cycle = (uint32_t)hal_get_cycles();
766if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
767printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
768__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
769#endif
770}
771
772/////////////////////////////////////////////////////////////////////////////////////////
773// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
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{
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)
788printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
789__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
790#endif
791
792    uint32_t responses = 1;
793
794    // initialise RPC descriptor header
795    rpc_desc_t  rpc;
796    rpc.index    = RPC_THREAD_KERNEL_CREATE;
797    rpc.blocking = true;
798    rpc.rsp      = &responses;
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   
805    // register RPC request in remote RPC fifo
806    rpc_send( cxy , &rpc );
807
808    // get output arguments from RPC descriptor
809    *thread_xp = (xptr_t)rpc.args[3];
810    *error     = (error_t)rpc.args[4];
811
812#if DEBUG_RPC_THREAD_KERNEL_CREATE
813cycle = (uint32_t)hal_get_cycles();
814if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
815printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
816__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
817#endif
818}
819
820/////////////////////////////////////////////////
821void rpc_thread_kernel_create_server( xptr_t xp )
822{
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)
827printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
828__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
829#endif
830
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
837    cxy_t        client_cxy  = GET_CXY( xp );
838    rpc_desc_t * desc        = GET_PTR( xp );
839
840    // get attributes from RPC descriptor
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] ) );
844
845    // select one core
846    core_lid = cluster_select_local_core( local_cxy );
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 );
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 );
855
856#if DEBUG_RPC_THREAD_KERNEL_CREATE
857cycle = (uint32_t)hal_get_cycles();
858if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
859printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
860__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
861#endif
862}
863
864/////////////////////////////////////////////////////////////////////////////////////////
865// [8]      undefined
866/////////////////////////////////////////////////////////////////////////////////////////
867
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/////////////////////////////////////////////////////////////////////////////////////////
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
1540
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
1607
1608/////////////////////////////////////////////////////////////////////////////////////////
1609// [29]      RPC_VMM_DISPLAY deprecated [AG] June 2019
1610/////////////////////////////////////////////////////////////////////////////////////////
1611void rpc_hal_vmm_display_client( cxy_t       cxy,
1612                             process_t * process,
1613                             bool_t      detailed )
1614{
1615#if DEBUG_RPC_VMM_DISPLAY
1616thread_t * this = CURRENT_THREAD;
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 );
1621#endif
1622
1623    uint32_t responses = 1;
1624
1625    // initialise RPC descriptor header
1626    rpc_desc_t  rpc;
1627    rpc.index    = RPC_VMM_DISPLAY;
1628    rpc.blocking = true;
1629    rpc.rsp      = &responses;
1630
1631    // set input arguments in RPC descriptor
1632    rpc.args[0] = (uint64_t)(intptr_t)process;
1633    rpc.args[1] = (uint64_t)detailed;
1634
1635    // register RPC request in remote RPC fifo
1636    rpc_send( cxy , &rpc );
1637
1638#if DEBUG_RPC_VMM_DISPLAY
1639cycle = (uint32_t)hal_get_cycles();
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 );
1643#endif
1644}
1645
1646////////////////////////////////////////
1647void rpc_hal_vmm_display_server( xptr_t xp )
1648{
1649#if DEBUG_RPC_VMM_DISPLAY
1650thread_t * this = CURRENT_THREAD;
1651uint32_t cycle = (uint32_t)hal_get_cycles();
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 );
1655#endif
1656
1657    process_t * process;
1658    bool_t      detailed;
1659
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 );
1663
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 );
1670
1671#if DEBUG_RPC_VMM_DISPLAY
1672cycle = (uint32_t)hal_get_cycles();
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 );
1676#endif
1677}
1678
1679/////////////////////////////////////////////////////////////////////////////////////////
1680// [10]  to RPC_VFS_INODE_CREATE   deprecated [AG] dec 2019
1681/////////////////////////////////////////////////////////////////////////////////////////
1682void rpc_vfs_inode_create_client( cxy_t          cxy,     
1683                                  uint32_t       fs_type,    // in
1684                                  uint32_t       attr,       // in
1685                                  uint32_t       rights,     // in
1686                                  uint32_t       uid,        // in
1687                                  uint32_t       gid,        // in
1688                                  xptr_t       * inode_xp,   // out
1689                                  error_t      * error )     // out
1690{
1691#if DEBUG_RPC_VFS_INODE_CREATE
1692thread_t * this = CURRENT_THREAD;
1693uint32_t cycle = (uint32_t)hal_get_cycles();
1694if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1695printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1696__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1697#endif
1698
1699    uint32_t responses = 1;
1700
1701    // initialise RPC descriptor header
1702    rpc_desc_t  rpc;
1703    rpc.index    = RPC_VFS_INODE_CREATE;
1704    rpc.blocking = true;
1705    rpc.rsp      = &responses;
1706
1707    // set input arguments in RPC descriptor
1708    rpc.args[0] = (uint64_t)fs_type;
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;
1713
1714    // register RPC request in remote RPC fifo
1715    rpc_send( cxy , &rpc );
1716
1717    // get output values from RPC descriptor
1718    *inode_xp = (xptr_t)rpc.args[5];
1719    *error    = (error_t)rpc.args[6];
1720
1721#if DEBUG_RPC_VFS_INODE_CREATE
1722cycle = (uint32_t)hal_get_cycles();
1723if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1724printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1725__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1726#endif
1727}
1728
1729/////////////////////////////////////////////
1730void rpc_vfs_inode_create_server( xptr_t xp )
1731{
1732#if DEBUG_RPC_VFS_INODE_CREATE
1733thread_t * this = CURRENT_THREAD;
1734uint32_t cycle = (uint32_t)hal_get_cycles();
1735if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1736printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1737__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1738#endif
1739
1740    uint32_t         fs_type;
1741    uint32_t         attr;
1742    uint32_t         rights;
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
1749    cxy_t        client_cxy  = GET_CXY( xp );
1750    rpc_desc_t * desc        = GET_PTR( xp );
1751
1752    // get input arguments from client rpc descriptor
1753    fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
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] ) );
1758
1759    // call local kernel function
1760    error = vfs_inode_create( fs_type,
1761                              attr,
1762                              rights,
1763                              uid,
1764                              gid,
1765                              &inode_xp );
1766
1767    // set output arguments
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 );
1770
1771#if DEBUG_RPC_VFS_INODE_CREATE
1772cycle = (uint32_t)hal_get_cycles();
1773if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1774printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1775__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1776#endif
1777}
1778
1779/////////////////////////////////////////////////////////////////////////////////////////
1780// [11]  to RPC_VFS_INODE_DESTROY   deprecated [AG] dec 2019
1781/////////////////////////////////////////////////////////////////////////////////////////
1782void rpc_vfs_inode_destroy_client( cxy_t                cxy,
1783                                   struct vfs_inode_s * inode )
1784{
1785#if DEBUG_RPC_VFS_INODE_DESTROY
1786thread_t * this = CURRENT_THREAD;
1787uint32_t cycle = (uint32_t)hal_get_cycles();
1788if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1789printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1790__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1791#endif
1792
1793    uint32_t responses = 1;
1794
1795    // initialise RPC descriptor header
1796    rpc_desc_t  rpc;
1797    rpc.index    = RPC_VFS_INODE_DESTROY;
1798    rpc.blocking = true;
1799    rpc.rsp      = &responses;
1800
1801    // set input arguments in RPC descriptor
1802    rpc.args[0] = (uint64_t)(intptr_t)inode;
1803   
1804    // register RPC request in remote RPC fifo
1805    rpc_send( cxy , &rpc );
1806
1807#if DEBUG_RPC_VFS_INODE_DESTROY
1808cycle = (uint32_t)hal_get_cycles();
1809if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1810printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1811__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1812#endif
1813}
1814
1815//////////////////////////////////////////////
1816void rpc_vfs_inode_destroy_server( xptr_t xp )
1817{
1818#if DEBUG_RPC_VFS_INODE_DESTROY
1819thread_t * this = CURRENT_THREAD;
1820uint32_t cycle = (uint32_t)hal_get_cycles();
1821if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1822printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1823__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1824#endif
1825
1826    vfs_inode_t * inode;
1827
1828    // get client cluster identifier and pointer on RPC descriptor
1829    cxy_t        client_cxy  = GET_CXY( xp );
1830    rpc_desc_t * desc        = GET_PTR( xp );
1831
1832    // get argument "inode" from client RPC descriptor
1833    inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1834                       
1835    // call local kernel function
1836    vfs_inode_destroy( inode );
1837
1838#if DEBUG_RPC_VFS_INODE_DESTROY
1839cycle = (uint32_t)hal_get_cycles();
1840if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1841printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1842__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1843#endif
1844}
1845
1846/////////////////////////////////////////////////////////////////////////////////////////
1847// [12]  RPC_VFS_DENTRY_CREATE   deprecated [AG] dec 2019
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{
1855#if DEBUG_RPC_VFS_DENTRY_CREATE
1856thread_t * this = CURRENT_THREAD;
1857uint32_t cycle = (uint32_t)hal_get_cycles();
1858if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1859printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1860__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1861#endif
1862
1863    uint32_t responses = 1;
1864
1865    // initialise RPC descriptor header
1866    rpc_desc_t  rpc;
1867    rpc.index    = RPC_VFS_DENTRY_CREATE;
1868    rpc.blocking = true;
1869    rpc.rsp      = &responses;
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
1875    // register RPC request in remote RPC fifo
1876    rpc_send( cxy , &rpc );
1877
1878    // get output values from RPC descriptor
1879    *dentry_xp = (xptr_t)rpc.args[2];
1880    *error     = (error_t)rpc.args[3];
1881
1882#if DEBUG_RPC_VFS_DENTRY_CREATE
1883cycle = (uint32_t)hal_get_cycles();
1884if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1885printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1886__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1887#endif
1888}
1889
1890//////////////////////////////////////////////
1891void rpc_vfs_dentry_create_server( xptr_t xp )
1892{
1893#if DEBUG_RPC_VFS_DENTRY_CREATE
1894thread_t * this = CURRENT_THREAD;
1895uint32_t cycle = (uint32_t)hal_get_cycles();
1896if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1897printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1898__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1899#endif
1900
1901    uint32_t      type;
1902    char        * name;
1903    xptr_t        dentry_xp;
1904    error_t       error;
1905    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1906
1907    // get client cluster identifier and pointer on RPC descriptor
1908    cxy_t        client_cxy  = GET_CXY( xp );
1909    rpc_desc_t * desc        = GET_PTR( xp );
1910
1911    // get arguments "name", "type", and "parent" from client RPC descriptor
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] ) );
1914
1915    // makes a local copy of  name
1916    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1917                       XPTR( client_cxy , name ) );
1918
1919    // call local kernel function
1920    error = vfs_dentry_create( type,
1921                               name_copy,
1922                               &dentry_xp );
1923    // set output arguments
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 );
1926
1927#if DEBUG_RPC_VFS_DENTRY_CREATE
1928cycle = (uint32_t)hal_get_cycles();
1929if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1930printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1931__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1932#endif
1933}
1934
1935/////////////////////////////////////////////////////////////////////////////////////////
1936// [13]  RPC_VFS_DENTRY_DESTROY   deprecated [AG] dec 2019
1937/////////////////////////////////////////////////////////////////////////////////////////
1938void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1939                                    vfs_dentry_t * dentry )
1940{
1941#if DEBUG_RPC_VFS_DENTRY_DESTROY
1942thread_t * this = CURRENT_THREAD;
1943uint32_t cycle = (uint32_t)hal_get_cycles();
1944if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1945printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1946__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1947#endif
1948
1949    uint32_t responses = 1;
1950
1951    // initialise RPC descriptor header
1952    rpc_desc_t  rpc;
1953    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1954    rpc.blocking = true;
1955    rpc.rsp      = &responses;
1956
1957    // set input arguments in RPC descriptor
1958    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1959   
1960    // register RPC request in remote RPC fifo
1961    rpc_send( cxy , &rpc );
1962
1963#if DEBUG_RPC_VFS_DENTRY_DESTROY
1964cycle = (uint32_t)hal_get_cycles();
1965if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1966printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1967__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1968#endif
1969}
1970
1971///////////////////////////////////////////////
1972void rpc_vfs_dentry_destroy_server( xptr_t xp )
1973{
1974#if DEBUG_RPC_VFS_DENTRY_DESTROY
1975thread_t * this = CURRENT_THREAD;
1976uint32_t cycle = (uint32_t)hal_get_cycles();
1977if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1978printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1979__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1980#endif
1981
1982    vfs_dentry_t * dentry;
1983
1984    // get client cluster identifier and pointer on RPC descriptor
1985    cxy_t        client_cxy  = GET_CXY( xp );
1986    rpc_desc_t * desc        = GET_PTR( xp );
1987
1988    // get arguments "dentry" from client RPC descriptor
1989    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1990                       
1991    // call local kernel function
1992    vfs_dentry_destroy( dentry );
1993
1994#if DEBUG_RPC_VFS_DENTRY_DESTROY
1995cycle = (uint32_t)hal_get_cycles();
1996if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1997printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1998__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1999#endif
2000}
2001
2002
2003/////////////////////////////////////////////////////////////////////////////////////////
2004// [14]  RPC_VFS_FILE_CREATE  deprecated [AG] dec 2019
2005/////////////////////////////////////////////////////////////////////////////////////////
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{
2012#if DEBUG_RPC_VFS_FILE_CREATE
2013thread_t * this = CURRENT_THREAD;
2014uint32_t cycle = (uint32_t)hal_get_cycles();
2015if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
2016printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2017__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2018#endif
2019
2020    uint32_t responses = 1;
2021
2022    // initialise RPC descriptor header
2023    rpc_desc_t  rpc;
2024    rpc.index    = RPC_VFS_FILE_CREATE;
2025    rpc.blocking = true;
2026    rpc.rsp      = &responses;
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
2032    // register RPC request in remote RPC fifo
2033    rpc_send( cxy , &rpc );
2034
2035    // get output values from RPC descriptor
2036    *file_xp = (xptr_t)rpc.args[2];
2037    *error   = (error_t)rpc.args[3];
2038
2039#if DEBUG_RPC_VFS_FILE_CREATE
2040cycle = (uint32_t)hal_get_cycles();
2041if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
2042printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2043__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2044#endif
2045}
2046
2047////////////////////////////////////////////
2048void rpc_vfs_file_create_server( xptr_t xp )
2049{
2050#if DEBUG_RPC_VFS_FILE_CREATE
2051thread_t * this = CURRENT_THREAD;
2052uint32_t cycle = (uint32_t)hal_get_cycles();
2053if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
2054printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2055__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2056#endif
2057
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
2064    cxy_t        client_cxy  = GET_CXY( xp );
2065    rpc_desc_t * desc        = GET_PTR( xp );
2066
2067    // get arguments "file_attr" and "inode" from client RPC descriptor
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] ) );
2070                       
2071    // call local kernel function
2072    error = vfs_file_create( inode,
2073                             file_attr,
2074                             &file_xp );
2075 
2076    // set output arguments
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 );
2079
2080#if DEBUG_RPC_VFS_FILE_CREATE
2081cycle = (uint32_t)hal_get_cycles();
2082if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
2083printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2084__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2085#endif
2086}
2087
2088/////////////////////////////////////////////////////////////////////////////////////////
2089// [15]  RPC_VFS_FILE_DESTROY    deprecated [AG] dec 2019
2090/////////////////////////////////////////////////////////////////////////////////////////
2091void rpc_vfs_file_destroy_client( cxy_t        cxy,
2092                                  vfs_file_t * file )
2093{
2094#if DEBUG_RPC_VFS_FILE_DESTROY
2095thread_t * this = CURRENT_THREAD;
2096uint32_t cycle = (uint32_t)hal_get_cycles();
2097if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
2098printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2099__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2100#endif
2101
2102    uint32_t responses = 1;
2103
2104    // initialise RPC descriptor header
2105    rpc_desc_t  rpc;
2106    rpc.index    = RPC_VFS_FILE_DESTROY;
2107    rpc.blocking = true;
2108    rpc.rsp      = &responses;
2109
2110    // set input arguments in RPC descriptor
2111    rpc.args[0] = (uint64_t)(intptr_t)file;
2112   
2113    // register RPC request in remote RPC fifo
2114    rpc_send( cxy , &rpc );
2115
2116#if DEBUG_RPC_VFS_FILE_DESTROY
2117cycle = (uint32_t)hal_get_cycles();
2118if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
2119printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2120__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2121#endif
2122}
2123
2124/////////////////////////////////////////////
2125void rpc_vfs_file_destroy_server( xptr_t xp )
2126{
2127#if DEBUG_RPC_VFS_FILE_DESTROY
2128thread_t * this = CURRENT_THREAD;
2129uint32_t cycle = (uint32_t)hal_get_cycles();
2130if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
2131printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2132__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2133#endif
2134
2135    vfs_file_t * file;
2136
2137    // get client cluster identifier and pointer on RPC descriptor
2138    cxy_t        client_cxy  = GET_CXY( xp );
2139    rpc_desc_t * desc        = GET_PTR( xp );
2140
2141    // get arguments "dentry" from client RPC descriptor
2142    file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2143                       
2144    // call local kernel function
2145    vfs_file_destroy( file );
2146
2147#if DEBUG_RPC_VFS_FILE_DESTROY
2148cycle = (uint32_t)hal_get_cycles();
2149if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
2150printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2151__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2152#endif
2153}
2154
2155/////////////////////////////////////////////////////////////////////////////////////////
2156// [16]  RPC_VFS_FS_GET_DENTRY   deprecated [AG] dec 2019
2157/////////////////////////////////////////////////////////////////////////////////////////
2158void rpc_vfs_fs_new_dentry_client( cxy_t         cxy,
2159                                   vfs_inode_t * parent_inode,    // in
2160                                   char        * name,            // in
2161                                   xptr_t        child_inode_xp,  // in
2162                                   error_t     * error )          // out
2163{
2164#if DEBUG_RPC_VFS_FS_NEW_DENTRY
2165thread_t * this = CURRENT_THREAD;
2166uint32_t cycle = (uint32_t)hal_get_cycles();
2167if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
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
2172    uint32_t responses = 1;
2173
2174    // initialise RPC descriptor header
2175    rpc_desc_t  rpc;
2176    rpc.index    = RPC_VFS_FS_NEW_DENTRY;
2177    rpc.blocking = true;
2178    rpc.rsp      = &responses;
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
2185    // register RPC request in remote RPC fifo
2186    rpc_send( cxy , &rpc );
2187
2188    // get output values from RPC descriptor
2189    *error   = (error_t)rpc.args[3];
2190
2191#if DEBUG_RPC_VFS_FS_NEW_DENTRY
2192cycle = (uint32_t)hal_get_cycles();
2193if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
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
2197}
2198
2199//////////////////////////////////////////////
2200void rpc_vfs_fs_new_dentry_server( xptr_t xp )
2201{
2202#if DEBUG_RPC_VFS_FS_NEW_DENTRY
2203thread_t * this = CURRENT_THREAD;
2204uint32_t cycle = (uint32_t)hal_get_cycles();
2205if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
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
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
2218    cxy_t        client_cxy  = GET_CXY( xp );
2219    rpc_desc_t * desc        = GET_PTR( xp );
2220
2221    // get arguments "parent", "name", and "child_xp"
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]));
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
2231    error = vfs_fs_new_dentry( parent , name_copy , child_xp );
2232
2233    // set output argument
2234    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
2235
2236#if DEBUG_RPC_VFS_FS_NEW_DENTRY
2237cycle = (uint32_t)hal_get_cycles();
2238if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
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
2242}
2243
2244/////////////////////////////////////////////////////////////////////////////////////////
2245// [17]  RPC_VFS_FS_ADD_DENTRY  deprecated [AG] dec 2019
2246/////////////////////////////////////////////////////////////////////////////////////////
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
2251{
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
2260    uint32_t responses = 1;
2261
2262    // initialise RPC descriptor header
2263    rpc_desc_t  rpc;
2264    rpc.index    = RPC_VFS_FS_ADD_DENTRY;
2265    rpc.blocking = true;
2266    rpc.rsp      = &responses;
2267
2268    // set input arguments in RPC descriptor
2269    rpc.args[0] = (uint64_t)(intptr_t)parent;
2270    rpc.args[1] = (uint64_t)(intptr_t)dentry;
2271
2272    // register RPC request in remote RPC fifo
2273    rpc_send( cxy , &rpc );
2274
2275    // get output values from RPC descriptor
2276    *error   = (error_t)rpc.args[2];
2277
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
2284}
2285
2286//////////////////////////////////////////////
2287void rpc_vfs_fs_add_dentry_server( xptr_t xp )
2288{
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
2296
2297    error_t        error;
2298    vfs_inode_t  * parent;
2299    vfs_dentry_t * dentry;
2300
2301    // get client cluster identifier and pointer on RPC descriptor
2302    cxy_t        client_cxy  = GET_CXY( xp );
2303    rpc_desc_t * desc        = GET_PTR( xp );
2304
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]));
2308
2309    // call the kernel function
2310    error = vfs_fs_add_dentry( parent , dentry );
2311
2312    // set output argument
2313    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
2314
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
2321}
2322
2323/////////////////////////////////////////////////////////////////////////////////////////
2324// [18]   RPC_VFS_FS_REMOVE_DENTRY    deprecated [AG] dec 2019
2325/////////////////////////////////////////////////////////////////////////////////////////
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
2330{
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
2339    uint32_t responses = 1;
2340
2341    // initialise RPC descriptor header
2342    rpc_desc_t  rpc;
2343    rpc.index    = RPC_VFS_FS_REMOVE_DENTRY;
2344    rpc.blocking = true;
2345    rpc.rsp      = &responses;
2346
2347    // set input arguments in RPC descriptor
2348    rpc.args[0] = (uint64_t)(intptr_t)parent;
2349    rpc.args[1] = (uint64_t)(intptr_t)dentry;
2350
2351    // register RPC request in remote RPC fifo
2352    rpc_send( cxy , &rpc );
2353
2354    // get output values from RPC descriptor
2355    *error   = (error_t)rpc.args[2];
2356
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
2363}
2364
2365/////////////////////////////////////////////////
2366void rpc_vfs_fs_remove_dentry_server( xptr_t xp )
2367{
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
2375
2376    error_t        error;
2377    vfs_inode_t  * parent;
2378    vfs_dentry_t * dentry;
2379
2380    // get client cluster identifier and pointer on RPC descriptor
2381    cxy_t        client_cxy  = GET_CXY( xp );
2382    rpc_desc_t * desc        = GET_PTR( xp );
2383
2384    // get input arguments
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]));
2387
2388    // call the kernel function
2389    error = vfs_fs_remove_dentry( parent , dentry );
2390
2391    // set output argument
2392    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
2393
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
2400}
2401
2402/////////////////////////////////////////////////////////////////////////////////////////
2403// [19]   RPC_VFS_INODE_LOAD_ALL_PAGES deprecated [AG] dec 2019
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
2417    uint32_t responses = 1;
2418
2419    // initialise RPC descriptor header
2420    rpc_desc_t  rpc;
2421    rpc.index    = RPC_VFS_INODE_LOAD_ALL_PAGES;
2422    rpc.blocking = true;
2423    rpc.rsp      = &responses;
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/////////////////////////////////////////////////////////////////////////////////////////
2478// [20]  RPC_VMM_GET_VSEG deprecated [AG] sept 2019
2479/////////////////////////////////////////////////////////////////////////////////////////
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
2485{
2486#if DEBUG_RPC_VMM_GET_VSEG
2487thread_t * this = CURRENT_THREAD;
2488uint32_t cycle = (uint32_t)hal_get_cycles();
2489if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2490printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2491__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2492#endif
2493
2494    uint32_t responses = 1;
2495
2496    // initialise RPC descriptor header
2497    rpc_desc_t  rpc;
2498    rpc.index    = RPC_VMM_GET_VSEG;
2499    rpc.blocking = true;
2500    rpc.rsp      = &responses;
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
2506    // register RPC request in remote RPC fifo
2507    rpc_send( cxy , &rpc );
2508
2509    // get output argument from rpc descriptor
2510    *vseg_xp = rpc.args[2];
2511    *error   = (error_t)rpc.args[3];
2512
2513#if DEBUG_RPC_VMM_GET_VSEG
2514cycle = (uint32_t)hal_get_cycles();
2515if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2516printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2517__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2518#endif
2519}
2520
2521/////////////////////////////////////////
2522void rpc_vmm_get_vseg_server( xptr_t xp )
2523{
2524#if DEBUG_RPC_VMM_GET_VSEG
2525thread_t * this = CURRENT_THREAD;
2526uint32_t cycle = (uint32_t)hal_get_cycles();
2527if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2528printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2529__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2530#endif
2531
2532    process_t   * process;
2533    intptr_t      vaddr;
2534    vseg_t      * vseg_ptr;
2535    xptr_t        vseg_xp;
2536    error_t       error;
2537
2538    // get client cluster identifier and pointer on RPC descriptor
2539    cxy_t        client_cxy  = GET_CXY( xp );
2540    rpc_desc_t * desc        = GET_PTR( xp );
2541
2542    // get input argument from client RPC descriptor
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] ) );
2545   
2546    // call local kernel function
2547    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
2548
2549    // set output arguments to client RPC descriptor
2550    vseg_xp = XPTR( local_cxy , vseg_ptr );
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 );
2553
2554#if DEBUG_RPC_VMM_GET_VSEG
2555cycle = (uint32_t)hal_get_cycles();
2556if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2557printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2558__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2559#endif
2560}
2561
2562/////////////////////////////////////////////////////////////////////////////////////////
2563// [22]          RPC_KCM_ALLOC deprecated [AG] sept 2019
2564/////////////////////////////////////////////////////////////////////////////////////////
2565void rpc_kcm_alloc_client( cxy_t      cxy,
2566                           uint32_t   kmem_type,   // in
2567                           xptr_t   * buf_xp )     // out
2568{
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 )
2573printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2574__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2575#endif
2576
2577    uint32_t responses = 1;
2578
2579    // initialise RPC descriptor header
2580    rpc_desc_t  rpc;
2581    rpc.index    = RPC_KCM_ALLOC;
2582    rpc.blocking = true;
2583    rpc.rsp      = &responses;
2584
2585    // set input arguments in RPC descriptor
2586    rpc.args[0] = (uint64_t)kmem_type;
2587
2588    // register RPC request in remote RPC fifo
2589    rpc_send( cxy , &rpc );
2590
2591    // get output arguments from RPC descriptor
2592    *buf_xp = (xptr_t)rpc.args[1];
2593
2594#if DEBUG_RPC_KCM_ALLOC
2595cycle = (uint32_t)hal_get_cycles();
2596if( cycle > DEBUG_RPC_KCM_ALLOC )
2597printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2598__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2599#endif
2600}
2601
2602//////////////////////////////////////
2603void rpc_kcm_alloc_server( xptr_t xp )
2604{
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 )
2609printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2610__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2611#endif
2612
2613    // get client cluster identifier and pointer on RPC descriptor
2614    cxy_t        client_cxy  = GET_CXY( xp );
2615    rpc_desc_t * desc        = GET_PTR( xp );
2616
2617    // get input argument "kmem_type" from client RPC descriptor
2618    uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2619
2620    // allocates memory for kcm
2621    kmem_req_t  req;
2622    req.type  = kmem_type;
2623    req.flags = AF_ZERO;
2624    void * buf_ptr = kmem_alloc( &req );
2625
2626    // set output argument
2627    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
2628    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
2629
2630#if DEBUG_RPC_KCM_ALLOC
2631cycle = (uint32_t)hal_get_cycles();
2632if( cycle > DEBUG_RPC_KCM_ALLOC )
2633printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2634__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2635#endif
2636}   
2637
2638/////////////////////////////////////////////////////////////////////////////////////////
2639// [23]          RPC_KCM_FREE deprecated [AG] sept 2019
2640/////////////////////////////////////////////////////////////////////////////////////////
2641void rpc_kcm_free_client( cxy_t      cxy,
2642                          void     * buf,          // in
2643                          uint32_t   kmem_type )   // in
2644{
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 )
2649printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2650__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2651#endif
2652
2653    uint32_t responses = 1;
2654
2655    // initialise RPC descriptor header
2656    rpc_desc_t  rpc;
2657    rpc.index    = RPC_KCM_FREE;
2658    rpc.blocking = true;
2659    rpc.rsp      = &responses;
2660
2661    // set input arguments in RPC descriptor
2662    rpc.args[0] = (uint64_t)(intptr_t)buf;
2663    rpc.args[1] = (uint64_t)kmem_type;
2664
2665    // register RPC request in remote RPC fifo
2666    rpc_send( cxy , &rpc );
2667
2668#if DEBUG_RPC_KCM_FREE
2669cycle = (uint32_t)hal_get_cycles();
2670if( cycle > DEBUG_RPC_KCM_FREE )
2671printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2672__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2673#endif
2674}
2675
2676/////////////////////////////////////
2677void rpc_kcm_free_server( xptr_t xp )
2678{
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 )
2683printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2684__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2685#endif
2686
2687    // get client cluster identifier and pointer on RPC descriptor
2688    cxy_t        client_cxy  = GET_CXY( xp );
2689    rpc_desc_t * desc        = GET_PTR( xp );
2690
2691    // get input arguments "buf" and "kmem_type" from client RPC descriptor
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] ) );
2694
2695    // releases memory
2696    kmem_req_t  req;
2697    req.type = kmem_type;
2698    req.ptr  = buf;
2699    kmem_free( &req );
2700
2701#if DEBUG_RPC_KCM_FREE
2702cycle = (uint32_t)hal_get_cycles();
2703if( cycle > DEBUG_RPC_KCM_FREE )
2704printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2705__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2706#endif
2707}   
2708
2709/////////////////////////////////////////////////////////////////////////////////////////
2710// [24]          Marshaling functions attached to RPC_MAPPER_SYNC
2711/////////////////////////////////////////////////////////////////////////////////////////
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
2784*/
2785
2786
2787
2788/*
2789////////////////////////////////////////////////////
2790void rpc_fbf_display_client( cxy_t        cxy,
2791                             xptr_t       window_xp,
2792                             uint32_t     cores,
2793                             error_t    * error )
2794{
2795#if DEBUG_RPC_FBF_DISPLAY
2796uint32_t  cycle = (uint32_t)hal_get_cycles();
2797thread_t * this = CURRENT_THREAD;
2798if( DEBUG_RPC_FBF_DISPLAY < cycle )
2799printk("\n[%s] thread[%x,%x] on core %d : enter / cycle %d\n",
2800__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2801#endif
2802
2803    uint32_t    responses = 1;
2804    rpc_desc_t  rpc;
2805
2806    // initialise RPC descriptor header
2807    rpc.index    = RPC_FBF_DISPLAY;
2808    rpc.blocking = true;
2809    rpc.rsp      = &responses;
2810
2811    // set input arguments in RPC descriptor
2812    rpc.args[0] = (uint64_t)window_xp;
2813    rpc.args[1] = (uint64_t)cores;
2814
2815    // register RPC request in remote RPC fifo
2816    rpc_send( cxy , &rpc );
2817
2818    // get output argument from RPC descriptor
2819    *error     = (error_t)rpc.args[2];
2820
2821#if DEBUG_RPC_FBF_DISPLAY
2822cycle = (uint32_t)hal_get_cycles();
2823if( DEBUG_RPC_FBF_DISPLAY < cycle )
2824printk("\n[%s] thread[%x,%x] on core %d : exit / cycle %d\n",
2825__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2826#endif
2827}
2828
2829////////////////////////////////////////
2830void rpc_fbf_display_server( xptr_t xp )
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
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]) );
2839
2840#if DEBUG_RPC_FBF_DISPLAY
2841uint32_t cycle = (uint32_t)hal_get_cycles();
2842thread_t * this = CURRENT_THREAD;
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 );
2846#endif
2847
2848    // call relevant kernel function
2849    error_t error = dev_fbf_parallel_display( window_xp , ncores );
2850
2851    // WARNING : for parallel RPCs, the return error argument is shared
2852    hal_remote_atomic_or( XPTR( client_cxy , &desc->args[2] ) , error );
2853
2854#if DEBUG_RPC_FBF_DISPLAY
2855cycle = (uint32_t)hal_get_cycles();
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 );
2859#endif
2860}
2861*/
2862
2863
Note: See TracBrowser for help on using the repository browser.