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

Last change on this file since 646 was 641, checked in by alain, 5 years ago
  • Fix several bugs.
  • Introduce the "stat" command in KSH.

This almos-mkh version sucessfully executed the FFT application
(65536 complex points) on the TSAR architecture from 1 to 64 cores.

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