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

Last change on this file since 627 was 625, checked in by alain, 5 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

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