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

Last change on this file since 632 was 632, checked in by alain, 16 months ago

This version replace the RPC by direct remote memory access
for physical pages allacation/release.
It is commited before being tested.

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