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

Last change on this file since 593 was 591, checked in by alain, 6 years ago

Fix a bug in rpc_process_sigaction_server().

File size: 84.9 KB
Line 
1/*
2 * rpc.c - RPC operations implementation.
3 *
4 * Author    Alain Greiner (2016,2017,2018)
5 *
6 * Copyright (c)  UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <kernel_config.h>
25#include <hal_kernel_types.h>
26#include <hal_atomic.h>
27#include <hal_remote.h>
28#include <hal_irqmask.h>
29#include <hal_special.h>
30#include <printk.h>
31#include <remote_sem.h>
32#include <core.h>
33#include <mapper.h>
34#include <chdev.h>
35#include <bits.h>
36#include <thread.h>
37#include <cluster.h>
38#include <process.h>
39#include <vfs.h>
40#include <fatfs.h>
41#include <rpc.h>
42
43
44/////////////////////////////////////////////////////////////////////////////////////////
45// Array of function pointers and array of printable strings.
46// These arrays must be kept consistent with enum in rpc.h file.
47/////////////////////////////////////////////////////////////////////////////////////////
48
49rpc_server_t * rpc_server[RPC_MAX_INDEX] =
50{
51    &rpc_pmem_get_pages_server,         // 0
52    &rpc_pmem_release_pages_server,     // 1
53    &rpc_undefined,                     // 2    unused slot
54    &rpc_process_make_fork_server,      // 3
55    &rpc_undefined,                     // 4    unused slot
56    &rpc_undefined,                     // 5    unused slot
57    &rpc_thread_user_create_server,     // 6
58    &rpc_thread_kernel_create_server,   // 7
59    &rpc_undefined,                     // 8    unused slot       
60    &rpc_process_sigaction_server,      // 9
61
62    &rpc_vfs_inode_create_server,       // 10 
63    &rpc_vfs_inode_destroy_server,      // 11 
64    &rpc_vfs_dentry_create_server,      // 12 
65    &rpc_vfs_dentry_destroy_server,     // 13 
66    &rpc_vfs_file_create_server,        // 14
67    &rpc_vfs_file_destroy_server,       // 15
68    &rpc_vfs_inode_load_server,         // 16
69    &rpc_vfs_mapper_load_all_server,    // 17
70    &rpc_fatfs_get_cluster_server,      // 18
71    &rpc_undefined,                     // 19   unused slot
72
73    &rpc_vmm_get_vseg_server,           // 20
74    &rpc_vmm_global_update_pte_server,  // 21
75    &rpc_kcm_alloc_server,              // 22
76    &rpc_kcm_free_server,               // 23
77    &rpc_mapper_move_buffer_server,     // 24
78    &rpc_mapper_get_page_server,        // 25
79    &rpc_vmm_create_vseg_server,        // 26
80    &rpc_undefined,                     // 27   unused slot
81    &rpc_vmm_set_cow_server,            // 28
82    &rpc_vmm_display_server,            // 29
83};
84
85char * rpc_str[RPC_MAX_INDEX] =
86{
87    "PMEM_GET_PAGES",         // 0
88    "PMEM_RELEASE_PAGES",     // 1
89    "undefined",              // 2
90    "PROCESS_MAKE_FORK",      // 3
91    "undefined",              // 4
92    "undefined",              // 5
93    "THREAD_USER_CREATE",     // 6
94    "THREAD_KERNEL_CREATE",   // 7
95    "undefined",              // 8
96    "PROCESS_SIGACTION",      // 9
97
98    "VFS_INODE_CREATE",       // 10
99    "VFS_INODE_DESTROY",      // 11
100    "VFS_DENTRY_CREATE",      // 12
101    "VFS_DENTRY_DESTROY",     // 13
102    "VFS_FILE_CREATE",        // 14
103    "VFS_FILE_DESTROY",       // 15
104    "VFS_INODE_LOAD",         // 16
105    "VFS_MAPPER_LOAD_ALL",    // 17
106    "FATFS_GET_CLUSTER",      // 18
107    "undefined",              // 19
108
109    "GET_VSEG",               // 20
110    "GLOBAL_UPDATE_PTE",                // 21
111    "KCM_ALLOC",              // 22
112    "KCM_FREE",               // 23
113    "MAPPER_MOVE_BUFFER",     // 24
114    "MAPPER_GET_PAGE",        // 25
115    "VMM_CREATE_VSEG",        // 26
116    "undefined",              // 27
117    "VMM_SET_COW",            // 28
118    "VMM_DISPLAY",            // 29
119};
120
121//////////////////////////////////////////////////////////////////////////////////
122void __attribute__((noinline)) rpc_undefined( xptr_t xp __attribute__ ((unused)) )
123{
124        assert( false , "called in cluster %x", local_cxy );
125}
126
127/***************************************************************************************/
128/************ Generic function supporting RPCs : client side ***************************/
129/***************************************************************************************/
130
131///////////////////////////////////////
132void rpc_send( cxy_t        server_cxy, 
133               rpc_desc_t * rpc )
134{
135    lid_t              server_core_lid;
136    lid_t              client_core_lid;
137    volatile error_t   full;
138    thread_t         * this;
139
140    full            = 0;
141    this            = CURRENT_THREAD;
142    client_core_lid = this->core->lid;
143
144    // check calling thread can yield when client thread is not the IDLE thread
145    // RPCs executed by the IDLE thread during kernel_init do not deschedule
146    if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ );
147
148    // select a server_core : use client core index if possible / core 0 otherwise
149    if( client_core_lid < hal_remote_l32( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) )
150    {
151        server_core_lid = client_core_lid;
152    }
153    else
154    {   
155        server_core_lid = 0;
156    }
157
158    // register client_thread and client_core in RPC descriptor
159    rpc->thread = this;
160    rpc->lid    = client_core_lid;
161
162    // build extended pointer on the RPC descriptor
163        xptr_t   desc_xp = XPTR( local_cxy , rpc );
164
165    // get local pointer on rpc_fifo in remote cluster,
166    remote_fifo_t * rpc_fifo    = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
167    xptr_t          rpc_fifo_xp = XPTR( server_cxy , rpc_fifo );
168
169        // post RPC in remote fifo / deschedule without blocking if fifo full
170    do
171    { 
172        full = remote_fifo_put_item( rpc_fifo_xp , (uint64_t )desc_xp );
173
174            if ( full ) 
175        {
176            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
177            __FUNCTION__ , local_cxy , server_cxy );
178
179            // deschedule without blocking
180            sched_yield("RPC fifo full");
181        }
182    }
183    while( full );
184 
185    hal_fence();
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[DBG] %s : thread %x in process %x / rpc %s / server[%x,%d] / items %d / cycle %d\n",
192__FUNCTION__, this->trdid, this->process->pid, 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    // - descheduling 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[DBG] %s : thread %x in process %x enter waiting loop for rpc %s / cycle %d\n",
211__FUNCTION__, this->trdid, this->process->pid, rpc_str[rpc->index], cycle );
212#endif
213
214             while( rpc->responses ) sched_yield( "busy waiting on RPC");
215   
216#if DEBUG_RPC_CLIENT_GENERIC
217cycle = (uint32_t)hal_get_cycles();
218if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
219printk("\n[DBG] %s : thread %x in process %x received response for rpc %s / cycle %d\n",
220__FUNCTION__, this->trdid, this->process->pid, rpc_str[rpc->index], cycle );
221#endif
222 
223        }
224        else                            // block and deschedule policy
225        {
226
227#if DEBUG_RPC_CLIENT_GENERIC
228cycle = (uint32_t)hal_get_cycles();
229if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
230printk("\n[DBG] %s : thread %x in process %x blocks & deschedules for rpc %s / cycle %d\n",
231__FUNCTION__, this->trdid, this->process->pid, rpc_str[rpc->index], cycle );
232#endif
233
234        // block client thread
235        thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
236
237        // deschedule
238        sched_yield("blocked on RPC");
239
240#if DEBUG_RPC_CLIENT_GENERIC
241cycle = (uint32_t)hal_get_cycles();
242if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
243printk("\n[DBG] %s : thread %x in process %x resumes for rpc %s / cycle %d\n",
244__FUNCTION__, this->trdid, this->process->pid, rpc_str[rpc->index], cycle );
245#endif
246        }
247
248// response must be available for a blocking RPC
249assert( (rpc->responses == 0) , "illegal response for RPC %s\n", rpc_str[rpc->index] );
250
251    }
252    else       // non blocking RPC
253    {
254
255#if DEBUG_RPC_CLIENT_GENERIC
256cycle = (uint32_t)hal_get_cycles();
257if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
258printk("\n[DBG] %s : thread %x in process %x returns for non blocking rpc %s / cycle %d\n",
259__FUNCTION__, this->trdid, this->process->pid, rpc_str[rpc->index], cycle );
260#endif
261
262    }
263}  // end rpc_send()
264
265
266/***************************************************************************************/
267/************ Generic functions supporting RPCs : server side **************************/
268/***************************************************************************************/
269
270////////////////////////////
271void rpc_thread_func( void )
272{
273    error_t         empty;              // local RPC fifo state
274    xptr_t          desc_xp;            // extended pointer on RPC request
275    cxy_t           desc_cxy;           // RPC request cluster (client)
276    rpc_desc_t    * desc_ptr;           // RPC request local pointer
277    uint32_t        index;              // RPC request index
278    thread_t      * client_ptr;         // local pointer on client thread
279        thread_t      * server_ptr;         // local pointer on server thread
280    xptr_t          server_xp;          // extended pointer on server thread
281    lid_t           client_core_lid;    // local index of client core
282    lid_t           server_core_lid;    // local index of server core
283    bool_t          blocking;           // blocking RPC when true
284        remote_fifo_t * rpc_fifo;           // local pointer on RPC fifo
285 
286    // makes RPC thread not preemptable
287        hal_disable_irq( NULL );
288 
289        server_ptr      = CURRENT_THREAD;
290    server_xp       = XPTR( local_cxy , server_ptr );
291    server_core_lid = server_ptr->core->lid;
292        rpc_fifo        = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
293
294    // "infinite" RPC thread loop
295        while(1)
296        {
297        // try to take RPC_FIFO ownership
298        if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) ) 
299        {
300
301#if DEBUG_RPC_SERVER_GENERIC
302uint32_t cycle = (uint32_t)hal_get_cycles();
303if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
304printk("\n[DBG] %s : RPC thread %x on core[%d] takes RPC_FIFO ownership / cycle %d\n",
305__FUNCTION__, server_ptr->trdid, server_core_lid, cycle );
306#endif
307                // try to consume one RPC request 
308                empty = remote_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
309
310            // release RPC_FIFO ownership
311            rpc_fifo->owner = 0;
312
313            // handle RPC request if success
314                if ( empty == 0 )   
315            {
316                // get client cluster and pointer on RPC descriptor
317                desc_cxy = GET_CXY( desc_xp );
318                desc_ptr = GET_PTR( desc_xp );
319
320                    index    = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
321                blocking = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->blocking ) );
322
323#if DEBUG_RPC_SERVER_GENERIC
324cycle = (uint32_t)hal_get_cycles();
325uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) );
326if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
327printk("\n[DBG] %s : RPC thread %x got rpc %s / client_cxy %x / items %d / cycle %d\n",
328__FUNCTION__, server_ptr->trdid, rpc_str[index], desc_cxy, items, cycle );
329#endif
330                // call the relevant server function
331                rpc_server[index]( desc_xp );
332
333#if DEBUG_RPC_SERVER_GENERIC
334cycle = (uint32_t)hal_get_cycles();
335if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
336printk("\n[DBG] %s : RPC thread %x completes rpc %s / client_cxy %x / cycle %d\n",
337__FUNCTION__, server_ptr->trdid, rpc_str[index], desc_cxy, cycle );
338#endif
339                // decrement response counter in RPC descriptor if blocking RPC
340                if( blocking )
341                {
342                    // decrement responses counter in RPC descriptor
343                    hal_remote_atomic_add( XPTR( desc_cxy, &desc_ptr->responses ), -1 );
344
345                    // get client thread pointer and client core lid from RPC descriptor
346                    client_ptr      = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
347                    client_core_lid = hal_remote_l32 ( XPTR( desc_cxy , &desc_ptr->lid ) );
348
349                    // unblock client thread
350                    thread_unblock( XPTR( desc_cxy , client_ptr ) , THREAD_BLOCKED_RPC );
351
352                    hal_fence();
353
354#if DEBUG_RPC_SERVER_GENERIC
355cycle = (uint32_t)hal_get_cycles();
356if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
357printk("\n[DBG] %s : RPC thread %x unblocked client thread %x / cycle %d\n",
358__FUNCTION__, server_ptr->trdid, client_ptr->trdid, cycle );
359#endif
360                    // send IPI to client core
361                    dev_pic_send_ipi( desc_cxy , client_core_lid );
362
363                }  // end if blocking RPC
364            }  // end RPC handling if fifo non empty
365        }  // end if RPC_fIFO ownership successfully taken and released
366
367        // sucide if too many RPC threads
368        if( LOCAL_CLUSTER->rpc_threads[server_core_lid] >= CONFIG_RPC_THREADS_MAX )
369            {
370
371#if DEBUG_RPC_SERVER_GENERIC
372uint32_t cycle = (uint32_t)hal_get_cycles();
373if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
374printk("\n[DBG] %s : RPC thread %x suicides / cycle %d\n",
375__FUNCTION__, server_ptr->trdid, cycle );
376#endif
377            // update RPC threads counter
378                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[server_core_lid] , -1 );
379
380            // RPC thread blocks on GLOBAL
381                thread_block( server_xp , THREAD_BLOCKED_GLOBAL );
382
383            // RPC thread set the REQ_DELETE flag to suicide
384            hal_remote_atomic_or( server_xp , THREAD_FLAG_REQ_DELETE );
385            }
386        // block and deschedule otherwise
387        else
388        {
389
390#if DEBUG_RPC_SERVER_GENERIC
391uint32_t cycle = (uint32_t)hal_get_cycles();
392if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
393printk("\n[DBG] %s : RPC thread %x block IDLE & deschedules / cycle %d\n",
394__FUNCTION__, server_ptr->trdid, cycle );
395#endif
396            // RPC thread blocks on IDLE
397            thread_block( server_xp , THREAD_BLOCKED_IDLE );
398
399            // RPC thread deschedules
400            sched_yield("RPC_FIFO empty");
401        }
402        } // end infinite loop
403} // end rpc_thread_func()
404
405
406/////////////////////////////////////////////////////////////////////////////////////////
407// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
408/////////////////////////////////////////////////////////////////////////////////////////
409
410///////////////////////////////////////////////
411void rpc_pmem_get_pages_client( cxy_t      cxy,
412                                uint32_t   order,      // in
413                                page_t  ** page )      // out
414{
415#if DEBUG_RPC_PMEM_GET_PAGES
416thread_t * this = CURRENT_THREAD;
417uint32_t cycle = (uint32_t)hal_get_cycles();
418if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
419printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
420__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
421#endif
422
423    assert( (cxy != local_cxy) , "target cluster is not remote\n");
424
425    // initialise RPC descriptor header
426    rpc_desc_t  rpc;
427    rpc.index     = RPC_PMEM_GET_PAGES;
428    rpc.blocking  = true;
429    rpc.responses = 1;
430
431    // set input arguments in RPC descriptor
432    rpc.args[0] = (uint64_t)order;
433
434    // register RPC request in remote RPC fifo
435    rpc_send( cxy , &rpc );
436
437    // get output arguments from RPC descriptor
438    *page = (page_t *)(intptr_t)rpc.args[1];
439
440#if DEBUG_RPC_PMEM_GET_PAGES
441cycle = (uint32_t)hal_get_cycles();
442if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
443printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
444__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
445#endif
446}
447
448///////////////////////////////////////////
449void rpc_pmem_get_pages_server( xptr_t xp )
450{
451#if DEBUG_RPC_PMEM_GET_PAGES
452thread_t * this = CURRENT_THREAD;
453uint32_t cycle = (uint32_t)hal_get_cycles();
454if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
455printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
456__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
457#endif
458
459    // get client cluster identifier and pointer on RPC descriptor
460    cxy_t        cxy  = GET_CXY( xp );
461    rpc_desc_t * desc = GET_PTR( xp );
462
463    // get input arguments from client RPC descriptor
464    uint32_t order = (uint32_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
465   
466    // call local pmem allocator
467    page_t * page = ppm_alloc_pages( order ); 
468
469    // set output arguments into client RPC descriptor
470    hal_remote_s64( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
471
472#if DEBUG_RPC_PMEM_GET_PAGES
473cycle = (uint32_t)hal_get_cycles();
474if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
475printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
476__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
477#endif
478}
479
480/////////////////////////////////////////////////////////////////////////////////////////
481// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking)
482/////////////////////////////////////////////////////////////////////////////////////////
483
484//////////////////////////////////////////////////
485void rpc_pmem_release_pages_client( cxy_t     cxy,
486                                    page_t  * page )      // out
487{
488#if DEBUG_RPC_PMEM_RELEASE_PAGES
489thread_t * this = CURRENT_THREAD;
490uint32_t cycle = (uint32_t)hal_get_cycles();
491if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
492printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
493__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
494#endif
495
496    assert( (cxy != local_cxy) , "target cluster is not remote\n");
497
498    // initialise RPC descriptor header
499    rpc_desc_t  rpc;
500    rpc.index    = RPC_PMEM_RELEASE_PAGES;
501    rpc.blocking = true;
502    rpc.responses = 1;
503
504    // set input arguments in RPC descriptor
505    rpc.args[0] = (uint64_t)(intptr_t)page;
506
507    // register RPC request in remote RPC fifo
508    rpc_send( cxy , &rpc );
509
510#if DEBUG_RPC_PMEM_RELEASE_PAGES
511cycle = (uint32_t)hal_get_cycles();
512if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
513printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
514__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
515#endif
516}
517
518///////////////////////////////////////////////
519void rpc_pmem_release_pages_server( xptr_t xp )
520{
521#if DEBUG_RPC_PMEM_RELEASE_PAGES
522thread_t * this = CURRENT_THREAD;
523uint32_t cycle = (uint32_t)hal_get_cycles();
524if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
525printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
526__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
527#endif
528
529    // get client cluster identifier and pointer on RPC descriptor
530    cxy_t        cxy  = GET_CXY( xp );
531    rpc_desc_t * desc = GET_PTR( xp );
532
533    // get input arguments from client RPC descriptor
534    page_t * page = (page_t *)(intptr_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
535   
536    // release memory to local pmem
537    kmem_req_t req;
538    req.type = KMEM_PAGE;
539    req.ptr  = page;
540    kmem_free( &req );
541
542#if DEBUG_RPC_PMEM_RELEASE_PAGES
543cycle = (uint32_t)hal_get_cycles();
544if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
545printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
546__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
547#endif
548}
549
550/////////////////////////////////////////////////////////////////////////////////////////
551// [2]      undefined slot
552/////////////////////////////////////////////////////////////////////////////////////////
553
554/////////////////////////////////////////////////////////////////////////////////////////
555// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking)
556/////////////////////////////////////////////////////////////////////////////////////////
557
558///////////////////////////////////////////////////
559void rpc_process_make_fork_client( cxy_t       cxy,
560                                   xptr_t      ref_process_xp,      // in
561                                   xptr_t      parent_thread_xp,    // in
562                                   pid_t     * child_pid,           // out
563                                   thread_t ** child_thread_ptr,    // out     
564                                   error_t   * error )              // out
565{
566#if DEBUG_RPC_PROCESS_MAKE_FORK
567thread_t * this = CURRENT_THREAD;
568uint32_t cycle = (uint32_t)hal_get_cycles();
569if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
570printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
571__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
572#endif
573
574    assert( (cxy != local_cxy) , "target cluster is not remote\n");
575
576    // initialise RPC descriptor header
577    rpc_desc_t  rpc;
578    rpc.index    = RPC_PROCESS_MAKE_FORK;
579    rpc.blocking = true;
580    rpc.responses = 1;
581
582    // set input arguments in RPC descriptor 
583    rpc.args[0] = (uint64_t)ref_process_xp;
584    rpc.args[1] = (uint64_t)parent_thread_xp;
585
586    // register RPC request in remote RPC fifo
587    rpc_send( cxy , &rpc );
588
589    // get output arguments from RPC descriptor
590    *child_pid         = (pid_t)rpc.args[2];
591    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
592    *error             = (error_t)rpc.args[4];     
593
594#if DEBUG_RPC_PROCESS_MAKE_FORK
595cycle = (uint32_t)hal_get_cycles();
596if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
597printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
598__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
599#endif
600}
601
602//////////////////////////////////////////////
603void rpc_process_make_fork_server( xptr_t xp )
604{
605#if DEBUG_RPC_PROCESS_MAKE_FORK
606thread_t * this = CURRENT_THREAD;
607uint32_t cycle = (uint32_t)hal_get_cycles();
608if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
609printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
610__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
611#endif
612
613    xptr_t     ref_process_xp;     // extended pointer on reference parent process
614    xptr_t     parent_thread_xp;   // extended pointer on parent thread
615    pid_t      child_pid;          // child process identifier
616    thread_t * child_thread_ptr;   // local copy of exec_info structure
617    error_t    error;              // local error status
618
619    // get client cluster identifier and pointer on RPC descriptor
620    cxy_t        client_cxy  = GET_CXY( xp );
621    rpc_desc_t * desc        = GET_PTR( xp );
622
623    // get input arguments from cient RPC descriptor
624    ref_process_xp   = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
625    parent_thread_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
626
627    // call local kernel function
628    error = process_make_fork( ref_process_xp,
629                               parent_thread_xp,
630                               &child_pid,
631                               &child_thread_ptr ); 
632
633    // set output argument into client RPC descriptor
634    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
635    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
636    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
637
638#if DEBUG_RPC_PROCESS_MAKE_FORK
639cycle = (uint32_t)hal_get_cycles();
640if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
641printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
642__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
643#endif
644}
645
646/////////////////////////////////////////////////////////////////////////////////////////
647// [4]      undefined slot
648/////////////////////////////////////////////////////////////////////////////////////////
649
650/////////////////////////////////////////////////////////////////////////////////////////
651// [5]      undefined slot
652/////////////////////////////////////////////////////////////////////////////////////////
653
654/////////////////////////////////////////////////////////////////////////////////////////
655// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 
656/////////////////////////////////////////////////////////////////////////////////////////
657
658/////////////////////////////////////////////////////////
659void rpc_thread_user_create_client( cxy_t            cxy, 
660                                    pid_t            pid,         // in
661                                    void           * start_func,  // in
662                                    void           * start_arg,   // in
663                                    pthread_attr_t * attr,        // in
664                                    xptr_t         * thread_xp,   // out
665                                    error_t        * error )      // out
666{
667#if DEBUG_RPC_THREAD_USER_CREATE
668thread_t * this = CURRENT_THREAD;
669uint32_t cycle = (uint32_t)hal_get_cycles();
670if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
671printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
672__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
673#endif
674
675    assert( (cxy != local_cxy) , "target cluster is not remote\n");
676
677    // initialise RPC descriptor header
678    rpc_desc_t  rpc;
679    rpc.index    = RPC_THREAD_USER_CREATE;
680    rpc.blocking = true;
681    rpc.responses = 1;
682
683    // set input arguments in RPC descriptor
684    rpc.args[0] = (uint64_t)pid;
685    rpc.args[1] = (uint64_t)(intptr_t)start_func;
686    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
687    rpc.args[3] = (uint64_t)(intptr_t)attr;
688
689    // register RPC request in remote RPC fifo
690    rpc_send( cxy , &rpc );
691
692    // get output arguments from RPC descriptor
693    *thread_xp = (xptr_t)rpc.args[4];
694    *error     = (error_t)rpc.args[5];
695
696#if DEBUG_RPC_THREAD_USER_CREATE
697cycle = (uint32_t)hal_get_cycles();
698if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
699printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
700__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
701#endif
702}
703
704///////////////////////////////////////////////
705void rpc_thread_user_create_server( xptr_t xp )
706{
707#if DEBUG_RPC_THREAD_USER_CREATE
708thread_t * this = CURRENT_THREAD;
709uint32_t cycle = (uint32_t)hal_get_cycles();
710if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
711printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
712__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
713#endif
714
715    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
716    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
717    thread_t       * thread_ptr; // local pointer on thread descriptor
718    xptr_t           thread_xp;  // extended pointer on thread descriptor
719
720    pid_t            pid;        // process identifier
721    void           * start_func;
722    void           * start_arg;
723    error_t          error;
724
725    // get client cluster identifier and pointer on RPC descriptor
726    cxy_t        client_cxy  = GET_CXY( xp );
727    rpc_desc_t * desc        = GET_PTR( xp );
728
729    // get pointer on attributes structure in client cluster from RPC descriptor
730
731    // get input arguments from RPC descriptor
732    pid        = (pid_t)                     hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
733    start_func = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
734    start_arg  = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
735    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[3]));
736
737    // makes a local copy of attributes structure
738    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
739                       XPTR( client_cxy , attr_ptr ), 
740                       sizeof(pthread_attr_t) );
741   
742    // call kernel function
743    error = thread_user_create( pid,
744                                start_func,
745                                start_arg,
746                                &attr_copy,
747                                &thread_ptr );
748
749    // set output arguments
750    thread_xp = XPTR( local_cxy , thread_ptr );
751    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
752    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
753
754#if DEBUG_RPC_THREAD_USER_CREATE
755cycle = (uint32_t)hal_get_cycles();
756if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
757printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
758__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
759#endif
760}
761
762/////////////////////////////////////////////////////////////////////////////////////////
763// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
764/////////////////////////////////////////////////////////////////////////////////////////
765
766////////////////////////////////////////////////////
767void rpc_thread_kernel_create_client( cxy_t     cxy,
768                                      uint32_t  type,        // in
769                                      void    * func,        // in
770                                      void    * args,        // in
771                                      xptr_t  * thread_xp,   // out
772                                      error_t * error )      // out
773{
774#if DEBUG_RPC_THREAD_KERNEL_CREATE
775thread_t * this = CURRENT_THREAD;
776uint32_t cycle = (uint32_t)hal_get_cycles();
777if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
778printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
779__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
780#endif
781
782    assert( (cxy != local_cxy) , "target cluster is not remote\n");
783
784    // initialise RPC descriptor header
785    rpc_desc_t  rpc;
786    rpc.index    = RPC_THREAD_KERNEL_CREATE;
787    rpc.blocking = true;
788    rpc.responses = 1;
789
790    // set input arguments in RPC descriptor
791    rpc.args[0] = (uint64_t)type;
792    rpc.args[1] = (uint64_t)(intptr_t)func;
793    rpc.args[2] = (uint64_t)(intptr_t)args;
794   
795    // register RPC request in remote RPC fifo
796    rpc_send( cxy , &rpc );
797
798    // get output arguments from RPC descriptor
799    *thread_xp = (xptr_t)rpc.args[3];
800    *error     = (error_t)rpc.args[4];
801
802#if DEBUG_RPC_THREAD_KERNEL_CREATE
803cycle = (uint32_t)hal_get_cycles();
804if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
805printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
806__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
807#endif
808}
809
810/////////////////////////////////////////////////
811void rpc_thread_kernel_create_server( xptr_t xp )
812{
813#if DEBUG_RPC_THREAD_KERNEL_CREATE
814thread_t * this = CURRENT_THREAD;
815uint32_t cycle = (uint32_t)hal_get_cycles();
816if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
817printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
818__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
819#endif
820
821    thread_t       * thread_ptr;  // local pointer on thread descriptor
822    xptr_t           thread_xp;   // extended pointer on thread descriptor
823    lid_t            core_lid;    // core local index
824    error_t          error;   
825
826    // get client cluster identifier and pointer on RPC descriptor
827    cxy_t        client_cxy  = GET_CXY( xp );
828    rpc_desc_t * desc        = GET_PTR( xp );
829
830    // get attributes from RPC descriptor
831    uint32_t  type = (uint32_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
832    void    * func = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
833    void    * args = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
834
835    // select one core
836    core_lid = cluster_select_local_core();
837
838    // call local kernel function
839    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
840
841    // set output arguments
842    thread_xp = XPTR( local_cxy , thread_ptr );
843    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
844    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
845
846#if DEBUG_RPC_THREAD_KERNEL_CREATE
847cycle = (uint32_t)hal_get_cycles();
848if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
849printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
850__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
851#endif
852}
853
854/////////////////////////////////////////////////////////////////////////////////////////
855// [8]   undefined slot
856/////////////////////////////////////////////////////////////////////////////////////////
857
858
859/////////////////////////////////////////////////////////////////////////////////////////
860// [9] Marshaling functions attached to RPC_PROCESS_SIGACTION (multicast / non blocking)
861/////////////////////////////////////////////////////////////////////////////////////////
862
863////////////////////////////////////////////////////
864void rpc_process_sigaction_client( cxy_t        cxy,
865                                   rpc_desc_t * rpc )
866{
867
868#if DEBUG_RPC_PROCESS_SIGACTION
869uint32_t  cycle  = (uint32_t)hal_get_cycles();
870uint32_t  action = rpc->args[0];
871pid_t     pid    = rpc->args[1];
872if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
873printk("\n[DBG] %s : enter to request %s of process %x in cluster %x / cycle %d\n",
874__FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
875#endif
876
877    // check some RPC arguments
878    assert( (rpc->blocking == false) , "must be non-blocking\n");
879    assert( (rpc->index == RPC_PROCESS_SIGACTION ) , "bad RPC index\n" );
880
881    // register RPC request in remote RPC fifo and return
882    rpc_send( cxy , rpc );
883
884#if DEBUG_RPC_PROCESS_SIGACTION
885cycle = (uint32_t)hal_get_cycles();
886if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
887printk("\n[DBG] %s : exit after requesting to %s process %x in cluster %x / cycle %d\n",
888__FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
889#endif
890
891}  // end rpc_process_sigaction_client()
892
893//////////////////////////////////////////////
894void rpc_process_sigaction_server( xptr_t xp )
895{
896    pid_t        pid;             // target process identifier
897    process_t  * process;         // pointer on local target process descriptor
898    uint32_t     action;          // sigaction index
899    thread_t   * client_ptr;      // pointer on client thread in client cluster
900    xptr_t       client_xp;       // extended pointer client thread
901    cxy_t        client_cxy;      // client cluster identifier
902    rpc_desc_t * rpc;             // pointer on rpc descriptor in client cluster
903    xptr_t       count_xp;        // extended pointer on responses counter
904    uint32_t     count_value;     // responses counter value
905    lid_t        client_lid;      // client core local index
906
907    // get client cluster identifier and pointer on RPC descriptor
908    client_cxy = GET_CXY( xp );
909    rpc        = GET_PTR( xp );
910
911    // get arguments from RPC descriptor
912    action   = (uint32_t)hal_remote_l64( XPTR(client_cxy , &rpc->args[0]) );
913    pid      = (pid_t)   hal_remote_l64( XPTR(client_cxy , &rpc->args[1]) );
914
915#if DEBUG_RPC_PROCESS_SIGACTION
916uint32_t cycle = (uint32_t)hal_get_cycles();
917if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
918printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
919__FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
920#endif
921
922    // get client thread pointers
923    client_ptr = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) );
924    client_xp  = XPTR( client_cxy , client_ptr );
925
926    // get local process descriptor
927    process = cluster_get_local_process_from_pid( pid );
928
929    // call relevant kernel function
930    if      ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
931    else if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
932    else if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
933
934    // build extended pointer on response counter in RPC
935    count_xp = XPTR( client_cxy , &rpc->responses );
936
937    // decrement the responses counter in RPC descriptor,
938    count_value = hal_remote_atomic_add( count_xp , -1 );
939
940    // unblock the client thread only if it is the last response.
941    if( count_value == 1 )
942    {
943        // get client core lid
944        client_lid    = (lid_t)     hal_remote_l32 ( XPTR( client_cxy , &rpc->lid    ) );
945
946        // unblock client thread
947        thread_unblock( client_xp , THREAD_BLOCKED_RPC );
948
949        // send an IPI to client core
950        // dev_pic_send_ipi( client_cxy , client_lid );
951    }
952
953#if DEBUG_RPC_PROCESS_SIGACTION
954cycle = (uint32_t)hal_get_cycles();
955if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
956printk("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n",
957__FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
958#endif
959
960} // end rpc_process_sigaction_server()
961
962/////////////////////////////////////////////////////////////////////////////////////////
963// [10]     Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
964/////////////////////////////////////////////////////////////////////////////////////////
965
966/////////////////////////////////////////////////////
967void rpc_vfs_inode_create_client( cxy_t          cxy,     
968                                  xptr_t         dentry_xp,  // in
969                                  uint32_t       fs_type,    // in
970                                  uint32_t       inode_type, // in
971                                  void         * extend,     // in
972                                  uint32_t       attr,       // in
973                                  uint32_t       rights,     // in
974                                  uint32_t       uid,        // in
975                                  uint32_t       gid,        // in
976                                  xptr_t       * inode_xp,   // out
977                                  error_t      * error )     // out
978{
979#if DEBUG_RPC_VFS_INODE_CREATE
980thread_t * this = CURRENT_THREAD;
981uint32_t cycle = (uint32_t)hal_get_cycles();
982if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
983printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
984__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
985#endif
986
987    assert( (cxy != local_cxy) , "target cluster is not remote\n");
988
989    // initialise RPC descriptor header
990    rpc_desc_t  rpc;
991    rpc.index    = RPC_VFS_INODE_CREATE;
992    rpc.blocking = true;
993    rpc.responses = 1;
994
995    // set input arguments in RPC descriptor
996    rpc.args[0] = (uint64_t)dentry_xp;
997    rpc.args[1] = (uint64_t)fs_type;
998    rpc.args[2] = (uint64_t)inode_type;
999    rpc.args[3] = (uint64_t)(intptr_t)extend;
1000    rpc.args[4] = (uint64_t)attr;
1001    rpc.args[5] = (uint64_t)rights;
1002    rpc.args[6] = (uint64_t)uid;
1003    rpc.args[7] = (uint64_t)gid;
1004
1005    // register RPC request in remote RPC fifo
1006    rpc_send( cxy , &rpc );
1007
1008    // get output values from RPC descriptor
1009    *inode_xp = (xptr_t)rpc.args[8];
1010    *error    = (error_t)rpc.args[9];
1011
1012#if DEBUG_RPC_VFS_INODE_CREATE
1013cycle = (uint32_t)hal_get_cycles();
1014if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1015printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1016__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1017#endif
1018}
1019
1020/////////////////////////////////////////////
1021void rpc_vfs_inode_create_server( xptr_t xp )
1022{
1023#if DEBUG_RPC_VFS_INODE_CREATE
1024thread_t * this = CURRENT_THREAD;
1025uint32_t cycle = (uint32_t)hal_get_cycles();
1026if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1027printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1028__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1029#endif
1030
1031    xptr_t           dentry_xp;
1032    uint32_t         fs_type;
1033    uint32_t         inode_type;
1034    void           * extend;
1035    uint32_t         attr;
1036    uint32_t         rights;
1037    uint32_t         uid;
1038    uint32_t         gid;
1039    xptr_t           inode_xp;
1040    error_t          error;
1041
1042    // get client cluster identifier and pointer on RPC descriptor
1043    cxy_t        client_cxy  = GET_CXY( xp );
1044    rpc_desc_t * desc        = GET_PTR( xp );
1045
1046    // get input arguments from client rpc descriptor
1047    dentry_xp  = (xptr_t)          hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1048    fs_type    = (uint32_t)        hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1049    inode_type = (uint32_t)        hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1050    extend     = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1051    attr       = (uint32_t)        hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
1052    rights     = (uint32_t)        hal_remote_l64( XPTR( client_cxy , &desc->args[5] ) );
1053    uid        = (uid_t)           hal_remote_l64( XPTR( client_cxy , &desc->args[6] ) );
1054    gid        = (gid_t)           hal_remote_l64( XPTR( client_cxy , &desc->args[7] ) );
1055
1056    // call local kernel function
1057    error = vfs_inode_create( dentry_xp,
1058                              fs_type,
1059                              inode_type,
1060                              extend,
1061                              attr,
1062                              rights,
1063                              uid,
1064                              gid,
1065                              &inode_xp );
1066
1067    // set output arguments
1068    hal_remote_s64( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)inode_xp );
1069    hal_remote_s64( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
1070
1071#if DEBUG_RPC_VFS_INODE_CREATE
1072cycle = (uint32_t)hal_get_cycles();
1073if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1074printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1075__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1076#endif
1077}
1078
1079/////////////////////////////////////////////////////////////////////////////////////////
1080// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
1081/////////////////////////////////////////////////////////////////////////////////////////
1082
1083/////////////////////////////////////////////////////////////
1084void rpc_vfs_inode_destroy_client( cxy_t                cxy,
1085                                   struct vfs_inode_s * inode,
1086                                   error_t            * error )
1087{
1088#if DEBUG_RPC_VFS_INODE_DESTROY
1089thread_t * this = CURRENT_THREAD;
1090uint32_t cycle = (uint32_t)hal_get_cycles();
1091if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1092printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1093__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1094#endif
1095
1096    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1097
1098    // initialise RPC descriptor header
1099    rpc_desc_t  rpc;
1100    rpc.index    = RPC_VFS_INODE_DESTROY;
1101    rpc.blocking = true;
1102    rpc.responses = 1;
1103
1104    // set input arguments in RPC descriptor
1105    rpc.args[0] = (uint64_t)(intptr_t)inode;
1106   
1107    // register RPC request in remote RPC fifo
1108    rpc_send( cxy , &rpc );
1109
1110    // get output argument from RPC descriptor
1111    *error = (error_t)rpc.args[1];
1112
1113#if DEBUG_RPC_VFS_INODE_DESTROY
1114cycle = (uint32_t)hal_get_cycles();
1115if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1116printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1117__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1118#endif
1119}
1120
1121//////////////////////////////////////////////
1122void rpc_vfs_inode_destroy_server( xptr_t xp )
1123{
1124#if DEBUG_RPC_VFS_INODE_DESTROY
1125thread_t * this = CURRENT_THREAD;
1126uint32_t cycle = (uint32_t)hal_get_cycles();
1127if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1128printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1129__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1130#endif
1131
1132    vfs_inode_t * inode;
1133    error_t       error;
1134
1135    // get client cluster identifier and pointer on RPC descriptor
1136    cxy_t        client_cxy  = GET_CXY( xp );
1137    rpc_desc_t * desc        = GET_PTR( xp );
1138
1139    // get arguments "inode" from client RPC descriptor
1140    inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1141                       
1142    // call local kernel function
1143    error = vfs_inode_destroy( inode );
1144
1145    // set output argument
1146    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1147
1148#if DEBUG_RPC_VFS_INODE_DESTROY
1149cycle = (uint32_t)hal_get_cycles();
1150if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1151printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1152__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1153#endif
1154}
1155
1156/////////////////////////////////////////////////////////////////////////////////////////
1157// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
1158/////////////////////////////////////////////////////////////////////////////////////////
1159
1160//////////////////////////////////////////////////////////////
1161void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1162                                   uint32_t               type,         // in
1163                                   char                 * name,         // in
1164                                   struct vfs_inode_s   * parent,       // in
1165                                   xptr_t               * dentry_xp,    // out
1166                                   error_t              * error )       // out
1167{
1168#if DEBUG_RPC_VFS_DENTRY_CREATE
1169thread_t * this = CURRENT_THREAD;
1170uint32_t cycle = (uint32_t)hal_get_cycles();
1171if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1172printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1173__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1174#endif
1175
1176    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1177
1178    // initialise RPC descriptor header
1179    rpc_desc_t  rpc;
1180    rpc.index    = RPC_VFS_DENTRY_CREATE;
1181    rpc.blocking = true;
1182    rpc.responses = 1;
1183
1184    // set input arguments in RPC descriptor
1185    rpc.args[0] = (uint64_t)type;
1186    rpc.args[1] = (uint64_t)(intptr_t)name;
1187    rpc.args[2] = (uint64_t)(intptr_t)parent;
1188
1189    // register RPC request in remote RPC fifo
1190    rpc_send( cxy , &rpc );
1191
1192    // get output values from RPC descriptor
1193    *dentry_xp = (xptr_t)rpc.args[3];
1194    *error     = (error_t)rpc.args[4];
1195
1196#if DEBUG_RPC_VFS_DENTRY_CREATE
1197cycle = (uint32_t)hal_get_cycles();
1198if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1199printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1200__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1201#endif
1202}
1203
1204//////////////////////////////////////////////
1205void rpc_vfs_dentry_create_server( xptr_t xp )
1206{
1207#if DEBUG_RPC_VFS_DENTRY_CREATE
1208thread_t * this = CURRENT_THREAD;
1209uint32_t cycle = (uint32_t)hal_get_cycles();
1210if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1211printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1212__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1213#endif
1214
1215    uint32_t      type;
1216    char        * name;
1217    vfs_inode_t * parent;
1218    xptr_t        dentry_xp;
1219    error_t       error;
1220    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1221
1222    // get client cluster identifier and pointer on RPC descriptor
1223    cxy_t        client_cxy  = GET_CXY( xp );
1224    rpc_desc_t * desc        = GET_PTR( xp );
1225
1226    // get arguments "name", "type", and "parent" from client RPC descriptor
1227    type   = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1228    name   = (char *)(intptr_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1229    parent = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1230
1231    // makes a local copy of  name
1232    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1233                       XPTR( client_cxy , name ) );
1234
1235    // call local kernel function
1236    error = vfs_dentry_create( type,
1237                               name_copy,
1238                               parent,
1239                               &dentry_xp );
1240    // set output arguments
1241    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp );
1242    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
1243
1244#if DEBUG_RPC_VFS_DENTRY_CREATE
1245cycle = (uint32_t)hal_get_cycles();
1246if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1247printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1248__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1249#endif
1250}
1251
1252/////////////////////////////////////////////////////////////////////////////////////////
1253// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
1254/////////////////////////////////////////////////////////////////////////////////////////
1255
1256///////////////////////////////////////////////////////
1257void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1258                                    vfs_dentry_t * dentry,
1259                                    error_t      * error )
1260{
1261#if DEBUG_RPC_VFS_DENTRY_DESTROY
1262thread_t * this = CURRENT_THREAD;
1263uint32_t cycle = (uint32_t)hal_get_cycles();
1264if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1265printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1266__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1267#endif
1268
1269    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1270
1271    // initialise RPC descriptor header
1272    rpc_desc_t  rpc;
1273    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1274    rpc.blocking = true;
1275    rpc.responses = 1;
1276
1277    // set input arguments in RPC descriptor
1278    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1279   
1280    // register RPC request in remote RPC fifo
1281    rpc_send( cxy , &rpc );
1282
1283    // get output argument from RPC descriptor
1284    *error = (error_t)rpc.args[1];
1285
1286#if DEBUG_RPC_VFS_DENTRY_DESTROY
1287cycle = (uint32_t)hal_get_cycles();
1288if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1289printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1290__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1291#endif
1292}
1293
1294///////////////////////////////////////////////
1295void rpc_vfs_dentry_destroy_server( xptr_t xp )
1296{
1297#if DEBUG_RPC_VFS_DENTRY_DESTROY
1298thread_t * this = CURRENT_THREAD;
1299uint32_t cycle = (uint32_t)hal_get_cycles();
1300if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1301printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1302__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1303#endif
1304
1305    vfs_dentry_t * dentry;
1306    error_t        error;
1307
1308    // get client cluster identifier and pointer on RPC descriptor
1309    cxy_t        client_cxy  = GET_CXY( xp );
1310    rpc_desc_t * desc        = GET_PTR( xp );
1311
1312    // get arguments "dentry" from client RPC descriptor
1313    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1314                       
1315    // call local kernel function
1316    error = vfs_dentry_destroy( dentry );
1317
1318    // set output argument
1319    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1320
1321#if DEBUG_RPC_VFS_DENTRY_DESTROY
1322cycle = (uint32_t)hal_get_cycles();
1323if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1324printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1325__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1326#endif
1327}
1328
1329
1330/////////////////////////////////////////////////////////////////////////////////////////
1331// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
1332/////////////////////////////////////////////////////////////////////////////////////////
1333
1334//////////////////////////////////////////////////////////////
1335void rpc_vfs_file_create_client( cxy_t                  cxy,
1336                                 struct vfs_inode_s   * inode,       // in
1337                                 uint32_t               file_attr,   // in
1338                                 xptr_t               * file_xp,     // out
1339                                 error_t              * error )      // out
1340{
1341#if DEBUG_RPC_VFS_FILE_CREATE
1342thread_t * this = CURRENT_THREAD;
1343uint32_t cycle = (uint32_t)hal_get_cycles();
1344if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1345printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1346__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1347#endif
1348
1349    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1350
1351    // initialise RPC descriptor header
1352    rpc_desc_t  rpc;
1353    rpc.index    = RPC_VFS_FILE_CREATE;
1354    rpc.blocking = true;
1355    rpc.responses = 1;
1356
1357    // set input arguments in RPC descriptor
1358    rpc.args[0] = (uint64_t)(intptr_t)inode;
1359    rpc.args[1] = (uint64_t)file_attr;
1360
1361    // register RPC request in remote RPC fifo
1362    rpc_send( cxy , &rpc );
1363
1364    // get output values from RPC descriptor
1365    *file_xp = (xptr_t)rpc.args[2];
1366    *error   = (error_t)rpc.args[3];
1367
1368#if DEBUG_RPC_VFS_FILE_CREATE
1369cycle = (uint32_t)hal_get_cycles();
1370if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1371printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1372__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1373#endif
1374}
1375
1376////////////////////////////////////////////
1377void rpc_vfs_file_create_server( xptr_t xp )
1378{
1379#if DEBUG_RPC_VFS_FILE_CREATE
1380thread_t * this = CURRENT_THREAD;
1381uint32_t cycle = (uint32_t)hal_get_cycles();
1382if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1383printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1384__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1385#endif
1386
1387    uint32_t      file_attr;
1388    vfs_inode_t * inode;
1389    xptr_t        file_xp;
1390    error_t       error;
1391
1392    // get client cluster identifier and pointer on RPC descriptor
1393    cxy_t        client_cxy  = GET_CXY( xp );
1394    rpc_desc_t * desc        = GET_PTR( xp );
1395
1396    // get arguments "file_attr" and "inode" from client RPC descriptor
1397    inode     = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1398    file_attr = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1399                       
1400    // call local kernel function
1401    error = vfs_file_create( inode,
1402                             file_attr,
1403                             &file_xp );
1404 
1405    // set output arguments
1406    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
1407    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1408
1409#if DEBUG_RPC_VFS_FILE_CREATE
1410cycle = (uint32_t)hal_get_cycles();
1411if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1412printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1413__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1414#endif
1415}
1416
1417/////////////////////////////////////////////////////////////////////////////////////////
1418// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
1419/////////////////////////////////////////////////////////////////////////////////////////
1420
1421///////////////////////////////////////////////////
1422void rpc_vfs_file_destroy_client( cxy_t        cxy,
1423                                  vfs_file_t * file )
1424{
1425#if DEBUG_RPC_VFS_FILE_DESTROY
1426thread_t * this = CURRENT_THREAD;
1427uint32_t cycle = (uint32_t)hal_get_cycles();
1428if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1429printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1430__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1431#endif
1432
1433    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1434
1435    // initialise RPC descriptor header
1436    rpc_desc_t  rpc;
1437    rpc.index    = RPC_VFS_FILE_DESTROY;
1438    rpc.blocking = true;
1439    rpc.responses = 1;
1440
1441    // set input arguments in RPC descriptor
1442    rpc.args[0] = (uint64_t)(intptr_t)file;
1443   
1444    // register RPC request in remote RPC fifo
1445    rpc_send( cxy , &rpc );
1446
1447#if DEBUG_RPC_VFS_FILE_DESTROY
1448cycle = (uint32_t)hal_get_cycles();
1449if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1450printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1451__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1452#endif
1453}
1454
1455/////////////////////////////////////////////
1456void rpc_vfs_file_destroy_server( xptr_t xp )
1457{
1458#if DEBUG_RPC_VFS_FILE_DESTROY
1459thread_t * this = CURRENT_THREAD;
1460uint32_t cycle = (uint32_t)hal_get_cycles();
1461if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1462printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1463__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1464#endif
1465
1466    vfs_file_t * file;
1467
1468    // get client cluster identifier and pointer on RPC descriptor
1469    cxy_t        client_cxy  = GET_CXY( xp );
1470    rpc_desc_t * desc        = GET_PTR( xp );
1471
1472    // get arguments "dentry" from client RPC descriptor
1473    file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1474                       
1475    // call local kernel function
1476    vfs_file_destroy( file );
1477
1478#if DEBUG_RPC_VFS_FILE_DESTROY
1479cycle = (uint32_t)hal_get_cycles();
1480if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1481printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1482__FUNCTION__, this->trdid, this->process->pid, this->core->lid, cycle );
1483#endif
1484}
1485
1486/////////////////////////////////////////////////////////////////////////////////////////
1487// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   (blocking)
1488/////////////////////////////////////////////////////////////////////////////////////////
1489
1490//////////////////////////////////////////////////
1491void rpc_vfs_inode_load_client( cxy_t         cxy,
1492                                vfs_inode_t * parent_inode,    // in
1493                                char        * name,            // in
1494                                xptr_t        child_inode_xp,  // in
1495                                error_t     * error )          // out
1496{
1497    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1498
1499    // initialise RPC descriptor header
1500    rpc_desc_t  rpc;
1501    rpc.index    = RPC_VFS_INODE_LOAD;
1502    rpc.blocking = true;
1503    rpc.responses = 1;
1504
1505    // set input arguments in RPC descriptor
1506    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
1507    rpc.args[1] = (uint64_t)(intptr_t)name;
1508    rpc.args[2] = (uint64_t)child_inode_xp;
1509
1510    // register RPC request in remote RPC fifo
1511    rpc_send( cxy , &rpc );
1512
1513    // get output values from RPC descriptor
1514    *error   = (error_t)rpc.args[3];
1515
1516}
1517
1518///////////////////////////////////////////
1519void rpc_vfs_inode_load_server( xptr_t xp )
1520{
1521    error_t       error;
1522    vfs_inode_t * parent;
1523    xptr_t        child_xp;
1524    char        * name;
1525
1526    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1527
1528    // get client cluster identifier and pointer on RPC descriptor
1529    cxy_t        client_cxy  = GET_CXY( xp );
1530    rpc_desc_t * desc        = GET_PTR( xp );
1531
1532    // get arguments "parent", "name", and "child_xp"
1533    parent     = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1534    name       = (char*)(intptr_t)       hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1535    child_xp   = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
1536
1537    // get name local copy
1538    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
1539                       XPTR( client_cxy , name ) );
1540
1541    // call the kernel function
1542    error = vfs_inode_load( parent , name_copy , child_xp );
1543
1544    // set output argument
1545    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1546
1547}
1548
1549/////////////////////////////////////////////////////////////////////////////////////////
1550// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL  (blocking)
1551/////////////////////////////////////////////////////////////////////////////////////////
1552
1553///////////////////////////////////////////////////////
1554void rpc_vfs_mapper_load_all_client( cxy_t         cxy,
1555                                     vfs_inode_t * inode,      // in
1556                                     error_t     * error )     // out
1557{
1558    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1559
1560    // initialise RPC descriptor header
1561    rpc_desc_t  rpc;
1562    rpc.index    = RPC_VFS_MAPPER_LOAD_ALL;
1563    rpc.blocking = true;
1564    rpc.responses = 1;
1565
1566    // set input arguments in RPC descriptor
1567    rpc.args[0] = (uint64_t)(intptr_t)inode;
1568
1569    // register RPC request in remote RPC fifo
1570    rpc_send( cxy , &rpc );
1571
1572    // get output values from RPC descriptor
1573    *error   = (error_t)rpc.args[1];
1574
1575}
1576
1577////////////////////////////////////////////////
1578void rpc_vfs_mapper_load_all_server( xptr_t xp )
1579{
1580    error_t       error;
1581    vfs_inode_t * inode;
1582
1583    // get client cluster identifier and pointer on RPC descriptor
1584    cxy_t        client_cxy  = GET_CXY( xp );
1585    rpc_desc_t * desc        = GET_PTR( xp );
1586
1587    // get arguments "parent", "name", and "child_xp"
1588    inode = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1589
1590    // call the kernel function
1591    error = vfs_mapper_load_all( inode );
1592
1593    // set output argument
1594    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1595
1596}
1597
1598/////////////////////////////////////////////////////////////////////////////////////////
1599// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  (blocking)
1600/////////////////////////////////////////////////////////////////////////////////////////
1601
1602//////////////////////////////////////////////////
1603void rpc_fatfs_get_cluster_client( cxy_t      cxy,
1604                                   mapper_t * mapper,    // in
1605                                   uint32_t   first,     // in
1606                                   uint32_t   index,     // in
1607                                   uint32_t * cluster,   // out
1608                                   error_t  * error )    // out
1609{
1610    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1611
1612    // initialise RPC descriptor header
1613    rpc_desc_t  rpc;
1614    rpc.index    = RPC_FATFS_GET_CLUSTER;
1615    rpc.blocking = true;
1616    rpc.responses = 1;
1617
1618    // set input arguments in RPC descriptor
1619    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1620    rpc.args[1] = (uint64_t)first;
1621    rpc.args[2] = (uint64_t)index;
1622
1623    // register RPC request in remote RPC fifo
1624    rpc_send( cxy , &rpc );
1625
1626    // get output argument from rpc descriptor
1627    *cluster = (uint32_t)rpc.args[3];
1628    *error   = (error_t)rpc.args[4];
1629
1630}
1631
1632//////////////////////////////////////////////
1633void rpc_fatfs_get_cluster_server( xptr_t xp )
1634{
1635    mapper_t    * mapper;
1636    uint32_t      first;
1637    uint32_t      index;
1638    uint32_t      cluster;
1639    error_t       error;
1640
1641    // get client cluster identifier and pointer on RPC descriptor
1642    cxy_t        client_cxy  = GET_CXY( xp );
1643    rpc_desc_t * desc        = GET_PTR( xp );
1644
1645    // get input arguments
1646    mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
1647    first  = (uint32_t)            hal_remote_l32 ( XPTR( client_cxy , &desc->args[1] ) );
1648    index  = (uint32_t)            hal_remote_l32 ( XPTR( client_cxy , &desc->args[2] ) );
1649
1650    // call the kernel function
1651    error = fatfs_get_cluster( mapper , first , index , &cluster );
1652
1653    // set output argument
1654    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster );
1655    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
1656
1657}
1658
1659/////////////////////////////////////////////////////////////////////////////////////////
1660// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
1661/////////////////////////////////////////////////////////////////////////////////////////
1662
1663//////////////////////////////////////////////////
1664void rpc_vmm_get_vseg_client( cxy_t       cxy,     
1665                              process_t * process,     // in 
1666                              intptr_t    vaddr,       // in 
1667                              xptr_t    * vseg_xp,     // out
1668                              error_t   * error )      // out
1669{
1670#if DEBUG_RPC_VMM_GET_VSEG
1671thread_t * this = CURRENT_THREAD;
1672uint32_t cycle = (uint32_t)hal_get_cycles();
1673if( cycle > DEBUG_RPC_VMM_GET_VSEG )
1674printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1675__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1676#endif
1677
1678    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1679
1680    // initialise RPC descriptor header
1681    rpc_desc_t  rpc;
1682    rpc.index    = RPC_VMM_GET_VSEG;
1683    rpc.blocking = true;
1684    rpc.responses = 1;
1685
1686    // set input arguments in RPC descriptor
1687    rpc.args[0] = (uint64_t)(intptr_t)process;
1688    rpc.args[1] = (uint64_t)vaddr;
1689
1690    // register RPC request in remote RPC fifo
1691    rpc_send( cxy , &rpc );
1692
1693    // get output argument from rpc descriptor
1694    *vseg_xp = rpc.args[2];
1695    *error   = (error_t)rpc.args[3];
1696
1697#if DEBUG_RPC_VMM_GET_VSEG
1698cycle = (uint32_t)hal_get_cycles();
1699if( cycle > DEBUG_RPC_VMM_GET_VSEG )
1700printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1701__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1702#endif
1703}
1704
1705/////////////////////////////////////////
1706void rpc_vmm_get_vseg_server( xptr_t xp )
1707{
1708#if DEBUG_RPC_VMM_GET_VSEG
1709thread_t * this = CURRENT_THREAD;
1710uint32_t cycle = (uint32_t)hal_get_cycles();
1711if( cycle > DEBUG_RPC_VMM_GET_VSEG )
1712printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1713__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1714#endif
1715
1716    process_t   * process;
1717    intptr_t      vaddr;
1718    vseg_t      * vseg_ptr;
1719    xptr_t        vseg_xp;
1720    error_t       error;
1721
1722    // get client cluster identifier and pointer on RPC descriptor
1723    cxy_t        client_cxy  = GET_CXY( xp );
1724    rpc_desc_t * desc        = GET_PTR( xp );
1725
1726    // get input argument from client RPC descriptor
1727    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1728    vaddr   = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1729   
1730    // call local kernel function
1731    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
1732
1733    // set output arguments to client RPC descriptor
1734    vseg_xp = XPTR( local_cxy , vseg_ptr );
1735    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
1736    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1737
1738#if DEBUG_RPC_VMM_GET_VSEG
1739cycle = (uint32_t)hal_get_cycles();
1740if( cycle > DEBUG_RPC_VMM_GET_VSEG )
1741printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1742__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1743#endif
1744}
1745
1746
1747/////////////////////////////////////////////////////////////////////////////////////////
1748// [21]    Marshaling functions attached to RPC_VMM_GLOBAL_UPDATE_PTE  (blocking)
1749/////////////////////////////////////////////////////////////////////////////////////////
1750
1751///////////////////////////////////////////////////////
1752void rpc_vmm_global_update_pte_client( cxy_t       cxy,   
1753                                       process_t * process,  // in
1754                                       vpn_t       vpn,      // in
1755                                       uint32_t    attr,     // in
1756                                       ppn_t       ppn )     // in
1757{
1758#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
1759thread_t * this = CURRENT_THREAD;
1760uint32_t cycle = (uint32_t)hal_get_cycles();
1761if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
1762printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1763__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1764#endif
1765
1766    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1767
1768    // initialise RPC descriptor header
1769    rpc_desc_t  rpc;
1770    rpc.index    = RPC_VMM_GLOBAL_UPDATE_PTE;
1771    rpc.blocking = true;
1772    rpc.responses = 1;
1773
1774    // set input arguments in RPC descriptor
1775    rpc.args[0] = (uint64_t)(intptr_t)process;
1776    rpc.args[1] = (uint64_t)vpn;
1777    rpc.args[2] = (uint64_t)attr;
1778    rpc.args[3] = (uint64_t)ppn;
1779
1780    // register RPC request in remote RPC fifo
1781    rpc_send( cxy , &rpc );
1782
1783#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
1784cycle = (uint32_t)hal_get_cycles();
1785if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
1786printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1787__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1788#endif
1789}
1790
1791//////////////////////////////////////////////////
1792void rpc_vmm_global_update_pte_server( xptr_t xp )
1793{
1794#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
1795thread_t * this = CURRENT_THREAD;
1796uint32_t cycle = (uint32_t)hal_get_cycles();
1797if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
1798printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1799__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1800#endif
1801
1802    process_t   * process;
1803    vpn_t         vpn;
1804    uint32_t      attr;
1805    ppn_t         ppn;
1806
1807    // get client cluster identifier and pointer on RPC descriptor
1808    cxy_t        client_cxy  = GET_CXY( xp );
1809    rpc_desc_t * desc        = GET_PTR( xp );
1810
1811    // get input argument "process" & "vpn" from client RPC descriptor
1812    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1813    vpn     = (vpn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1814    attr    = (uint32_t)             hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1815    ppn     = (ppn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1816   
1817    // call local kernel function
1818    vmm_global_update_pte( process , vpn , attr , ppn ); 
1819
1820#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
1821cycle = (uint32_t)hal_get_cycles();
1822if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
1823printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1824__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1825#endif
1826}
1827
1828/////////////////////////////////////////////////////////////////////////////////////////
1829// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
1830/////////////////////////////////////////////////////////////////////////////////////////
1831
1832//////////////////////////////////////////
1833void rpc_kcm_alloc_client( cxy_t      cxy,
1834                           uint32_t   kmem_type,   // in
1835                           xptr_t *   buf_xp )     // out
1836{
1837#if DEBUG_RPC_KCM_ALLOC
1838thread_t * this = CURRENT_THREAD;
1839uint32_t cycle = (uint32_t)hal_get_cycles();
1840if( cycle > DEBUG_RPC_KCM_ALLOC )
1841printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1842__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1843#endif
1844
1845    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1846
1847    // initialise RPC descriptor header
1848    rpc_desc_t  rpc;
1849    rpc.index    = RPC_KCM_ALLOC;
1850    rpc.blocking = true;
1851    rpc.responses = 1;
1852
1853    // set input arguments in RPC descriptor
1854    rpc.args[0] = (uint64_t)kmem_type;
1855
1856    // register RPC request in remote RPC fifo
1857    rpc_send( cxy , &rpc );
1858
1859    // get output arguments from RPC descriptor
1860    *buf_xp = (xptr_t)rpc.args[1];
1861
1862#if DEBUG_RPC_KCM_ALLOC
1863cycle = (uint32_t)hal_get_cycles();
1864if( cycle > DEBUG_RPC_KCM_ALLOC )
1865printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1866__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1867#endif
1868}
1869
1870//////////////////////////////////////
1871void rpc_kcm_alloc_server( xptr_t xp )
1872{
1873#if DEBUG_RPC_KCM_ALLOC
1874thread_t * this = CURRENT_THREAD;
1875uint32_t cycle = (uint32_t)hal_get_cycles();
1876if( cycle > DEBUG_RPC_KCM_ALLOC )
1877printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1878__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1879#endif
1880
1881    // get client cluster identifier and pointer on RPC descriptor
1882    cxy_t        client_cxy  = GET_CXY( xp );
1883    rpc_desc_t * desc        = GET_PTR( xp );
1884
1885    // get input argument "kmem_type" from client RPC descriptor
1886    uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1887
1888    // allocates memory for kcm
1889    kmem_req_t  req;
1890    req.type  = kmem_type;
1891    req.flags = AF_ZERO;
1892    void * buf_ptr = kmem_alloc( &req );
1893
1894    // set output argument
1895    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
1896    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
1897
1898#if DEBUG_RPC_KCM_ALLOC
1899cycle = (uint32_t)hal_get_cycles();
1900if( cycle > DEBUG_RPC_KCM_ALLOC )
1901printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1902__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1903#endif
1904}   
1905
1906/////////////////////////////////////////////////////////////////////////////////////////
1907// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
1908/////////////////////////////////////////////////////////////////////////////////////////
1909
1910/////////////////////////////////////////
1911void rpc_kcm_free_client( cxy_t      cxy,
1912                          void     * buf,          // in
1913                          uint32_t   kmem_type )   // in
1914{
1915#if DEBUG_RPC_KCM_FREE
1916thread_t * this = CURRENT_THREAD;
1917uint32_t cycle = (uint32_t)hal_get_cycles();
1918if( cycle > DEBUG_RPC_KCM_FREE )
1919printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1920__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1921#endif
1922
1923    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1924
1925    // initialise RPC descriptor header
1926    rpc_desc_t  rpc;
1927    rpc.index    = RPC_KCM_FREE;
1928    rpc.blocking = true;
1929    rpc.responses = 1;
1930
1931    // set input arguments in RPC descriptor
1932    rpc.args[0] = (uint64_t)(intptr_t)buf;
1933    rpc.args[1] = (uint64_t)kmem_type;
1934
1935    // register RPC request in remote RPC fifo
1936    rpc_send( cxy , &rpc );
1937
1938#if DEBUG_RPC_KCM_FREE
1939cycle = (uint32_t)hal_get_cycles();
1940if( cycle > DEBUG_RPC_KCM_FREE )
1941printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1942__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1943#endif
1944}
1945
1946/////////////////////////////////////
1947void rpc_kcm_free_server( xptr_t xp )
1948{
1949#if DEBUG_RPC_KCM_FREE
1950thread_t * this = CURRENT_THREAD;
1951uint32_t cycle = (uint32_t)hal_get_cycles();
1952if( cycle > DEBUG_RPC_KCM_FREE )
1953printk("\n[DBG] %s : thread %x in process %x on core %d enter / cycle %d\n",
1954__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1955#endif
1956
1957    // get client cluster identifier and pointer on RPC descriptor
1958    cxy_t        client_cxy  = GET_CXY( xp );
1959    rpc_desc_t * desc        = GET_PTR( xp );
1960
1961    // get input arguments "buf" and "kmem_type" from client RPC descriptor
1962    void     * buf = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1963    uint32_t   kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1964
1965    // releases memory
1966    kmem_req_t  req;
1967    req.type = kmem_type;
1968    req.ptr  = buf;
1969    kmem_free( &req );
1970
1971#if DEBUG_RPC_KCM_FREE
1972cycle = (uint32_t)hal_get_cycles();
1973if( cycle > DEBUG_RPC_KCM_FREE )
1974printk("\n[DBG] %s : thread %x in process %x on core %d exit / cycle %d\n",
1975__FUNCTION__, this->trdid, this->process->pid, this->core->lid , cycle );
1976#endif
1977}   
1978
1979/////////////////////////////////////////////////////////////////////////////////////////
1980// [24]          Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER
1981/////////////////////////////////////////////////////////////////////////////////////////
1982
1983///////////////////////////////////////////////////
1984void rpc_mapper_move_buffer_client( cxy_t      cxy,
1985                                    mapper_t * mapper,        // in
1986                                    bool_t     to_buffer,     // in
1987                                    bool_t     is_user,       // in
1988                                    uint32_t   file_offset,   // in
1989                                    uint64_t   buffer,        // in
1990                                    uint32_t   size,          // in
1991                                    error_t  * error )        // out
1992{
1993    assert( (cxy != local_cxy) , "target cluster is not remote\n");
1994
1995    // initialise RPC descriptor header
1996    rpc_desc_t  rpc;
1997    rpc.index    = RPC_MAPPER_MOVE_BUFFER;
1998    rpc.blocking = true;
1999    rpc.responses = 1;
2000
2001    // set input arguments in RPC descriptor
2002    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2003    rpc.args[1] = (uint64_t)to_buffer;
2004    rpc.args[2] = (uint64_t)is_user;
2005    rpc.args[3] = (uint64_t)file_offset;
2006    rpc.args[4] = (uint64_t)buffer;
2007    rpc.args[5] = (uint64_t)size;
2008
2009    // register RPC request in remote RPC fifo
2010    rpc_send( cxy , &rpc );
2011
2012    // get output values from RPC descriptor
2013    *error     = (error_t)rpc.args[6];
2014
2015}
2016
2017///////////////////////////////////////////////
2018void rpc_mapper_move_buffer_server( xptr_t xp )
2019{
2020    mapper_t * mapper;
2021    bool_t     to_buffer;
2022    bool_t     is_user;
2023    uint32_t   file_offset;
2024    void     * user_buffer;
2025    xptr_t     kern_buffer;
2026    uint32_t   size;
2027    error_t    error;
2028
2029    // get client cluster identifier and pointer on RPC descriptor
2030    cxy_t        client_cxy  = GET_CXY( xp );
2031    rpc_desc_t * desc        = GET_PTR( xp );
2032
2033    // get arguments from client RPC descriptor
2034    mapper      = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2035    to_buffer   =                       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
2036    is_user     =                       hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
2037    file_offset =                       hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
2038    size        =                       hal_remote_l64( XPTR( client_cxy , &desc->args[5] ) );
2039
2040    // call local kernel function
2041    if( is_user )
2042    {
2043        user_buffer = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
2044
2045        error = mapper_move_user( mapper,
2046                                  to_buffer,
2047                                  file_offset,
2048                                  user_buffer,
2049                                  size );
2050    }
2051    else
2052    {
2053        kern_buffer = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
2054
2055        error = mapper_move_kernel( mapper,
2056                                    to_buffer,
2057                                    file_offset,
2058                                    kern_buffer,
2059                                    size );
2060    }
2061
2062    // set output argument to client RPC descriptor
2063    hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
2064
2065}
2066
2067/////////////////////////////////////////////////////////////////////////////////////////
2068// [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking)
2069/////////////////////////////////////////////////////////////////////////////////////////
2070
2071///////////////////////////////////////////////////////
2072void rpc_mapper_get_page_client( cxy_t             cxy,
2073                                 struct mapper_s * mapper,     // in
2074                                 uint32_t          index,      // in
2075                                 page_t         ** page )      // out
2076{
2077    assert( (cxy != local_cxy) , "target cluster is not remote\n");
2078
2079    // initialise RPC descriptor header
2080    rpc_desc_t  rpc;
2081    rpc.index    = RPC_MAPPER_GET_PAGE;
2082    rpc.blocking = true;
2083    rpc.responses = 1;
2084
2085    // set input arguments in RPC descriptor
2086    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2087    rpc.args[1] = (uint64_t)index;
2088
2089    // register RPC request in remote RPC fifo
2090    rpc_send( cxy , &rpc );
2091
2092    // get output values from RPC descriptor
2093    *page = (page_t *)(intptr_t)rpc.args[2];
2094
2095}
2096
2097////////////////////////////////////////////
2098void rpc_mapper_get_page_server( xptr_t xp )
2099{
2100    // get client cluster identifier and pointer on RPC descriptor
2101    cxy_t        cxy  = GET_CXY( xp );
2102    rpc_desc_t * desc = GET_PTR( xp );
2103
2104    // get input arguments from client RPC descriptor
2105    mapper_t * mapper = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
2106    uint32_t   index  = (uint32_t)            hal_remote_l64( XPTR( cxy , &desc->args[1] ) );
2107   
2108    // call local pmem allocator
2109    page_t * page = mapper_get_page( mapper , index ); 
2110
2111    // set output arguments into client RPC descriptor
2112    hal_remote_s64( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
2113
2114}
2115
2116/////////////////////////////////////////////////////////////////////////////////////////
2117// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
2118/////////////////////////////////////////////////////////////////////////////////////////
2119
2120////////////////////////////////////////////////////////
2121void rpc_vmm_create_vseg_client( cxy_t              cxy,
2122                                 struct process_s * process,
2123                                 vseg_type_t        type,
2124                                 intptr_t           base,
2125                                 uint32_t           size,
2126                                 uint32_t           file_offset,
2127                                 uint32_t           file_size,
2128                                 xptr_t             mapper_xp,
2129                                 cxy_t              vseg_cxy,
2130                                 struct vseg_s   ** vseg )
2131{
2132    assert( (cxy != local_cxy) , "target cluster is not remote\n");
2133
2134    // initialise RPC descriptor header
2135    rpc_desc_t  rpc;
2136    rpc.index    = RPC_VMM_CREATE_VSEG;
2137    rpc.blocking = true;
2138    rpc.responses = 1;
2139
2140    // set input arguments in RPC descriptor
2141    rpc.args[0] = (uint64_t)(intptr_t)process;
2142    rpc.args[1] = (uint64_t)type;
2143    rpc.args[2] = (uint64_t)base;
2144    rpc.args[3] = (uint64_t)size;
2145    rpc.args[4] = (uint64_t)file_offset;
2146    rpc.args[5] = (uint64_t)file_size;
2147    rpc.args[6] = (uint64_t)mapper_xp;
2148    rpc.args[7] = (uint64_t)vseg_cxy;
2149
2150    // register RPC request in remote RPC fifo
2151    rpc_send( cxy , &rpc );
2152
2153    // get output values from RPC descriptor
2154    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
2155
2156}
2157
2158////////////////////////////////////////////
2159void rpc_vmm_create_vseg_server( xptr_t xp )
2160{
2161    // get client cluster identifier and pointer on RPC descriptor
2162    cxy_t        cxy  = GET_CXY( xp );
2163    rpc_desc_t * desc = GET_PTR( xp );
2164
2165    // get input arguments from client RPC descriptor
2166    process_t * process     = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2167    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_l64( XPTR(cxy , &desc->args[1]));
2168    intptr_t    base        = (intptr_t)             hal_remote_l64( XPTR(cxy , &desc->args[2]));
2169    uint32_t    size        = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[3]));
2170    uint32_t    file_offset = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[4]));
2171    uint32_t    file_size   = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[5]));
2172    xptr_t      mapper_xp   = (xptr_t)               hal_remote_l64( XPTR(cxy , &desc->args[6]));
2173    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_l64( XPTR(cxy , &desc->args[7]));
2174   
2175    // call local kernel function
2176    vseg_t * vseg = vmm_create_vseg( process,
2177                                     type,
2178                                     base,
2179                                     size,
2180                                     file_offset,
2181                                     file_size,
2182                                     mapper_xp,
2183                                     vseg_cxy ); 
2184
2185    // set output arguments into client RPC descriptor
2186    hal_remote_s64( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
2187
2188}
2189
2190/////////////////////////////////////////////////////////////////////////////////////////
2191// [27]         undefined slot
2192/////////////////////////////////////////////////////////////////////////////////////////
2193
2194/////////////////////////////////////////////////////////////////////////////////////////
2195// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
2196/////////////////////////////////////////////////////////////////////////////////////////
2197
2198/////////////////////////////////////////////
2199void rpc_vmm_set_cow_client( cxy_t       cxy,
2200                             process_t * process )
2201{
2202    assert( (cxy != local_cxy) , "target cluster is not remote\n");
2203
2204    // initialise RPC descriptor header
2205    rpc_desc_t  rpc;
2206    rpc.index    = RPC_VMM_SET_COW;
2207    rpc.blocking = true;
2208    rpc.responses = 1;
2209
2210    // set input arguments in RPC descriptor
2211    rpc.args[0] = (uint64_t)(intptr_t)process;
2212
2213    // register RPC request in remote RPC fifo
2214    rpc_send( cxy , &rpc );
2215
2216}
2217
2218////////////////////////////////////////
2219void rpc_vmm_set_cow_server( xptr_t xp )
2220{
2221    process_t * process;
2222
2223    // get client cluster identifier and pointer on RPC descriptor
2224    cxy_t        cxy  = GET_CXY( xp );
2225    rpc_desc_t * desc = GET_PTR( xp );
2226
2227    // get input arguments from client RPC descriptor
2228    process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2229   
2230    // call local kernel function
2231    vmm_set_cow( process );
2232
2233}
2234
2235/////////////////////////////////////////////////////////////////////////////////////////
2236// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
2237/////////////////////////////////////////////////////////////////////////////////////////
2238
2239/////////////////////////////////////////////
2240void rpc_vmm_display_client( cxy_t       cxy,
2241                             process_t * process,
2242                             bool_t      detailed )
2243{
2244    assert( (cxy != local_cxy) , "target cluster is not remote\n");
2245
2246    // initialise RPC descriptor header
2247    rpc_desc_t  rpc;
2248    rpc.index    = RPC_VMM_DISPLAY;
2249    rpc.blocking = true;
2250    rpc.responses = 1;
2251
2252    // set input arguments in RPC descriptor
2253    rpc.args[0] = (uint64_t)(intptr_t)process;
2254    rpc.args[1] = (uint64_t)detailed;
2255
2256    // register RPC request in remote RPC fifo
2257    rpc_send( cxy , &rpc );
2258
2259}
2260
2261////////////////////////////////////////
2262void rpc_vmm_display_server( xptr_t xp )
2263{
2264    process_t * process;
2265    bool_t      detailed;
2266
2267    // get client cluster identifier and pointer on RPC descriptor
2268    cxy_t        cxy  = GET_CXY( xp );
2269    rpc_desc_t * desc = GET_PTR( xp );
2270
2271    // get input arguments from client RPC descriptor
2272    process  = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2273    detailed = (bool_t)               hal_remote_l64( XPTR(cxy , &desc->args[1]));
2274   
2275    // call local kernel function
2276    vmm_display( process , detailed );
2277
2278}
2279
2280
Note: See TracBrowser for help on using the repository browser.