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

Last change on this file since 623 was 623, checked in by alain, 3 years ago

Introduce three new types of vsegs (KCODE,KDATA,KDEV)
to map the kernel vsegs in the process VSL and GPT.
This now used by both the TSAR and the I86 architectures.

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