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

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

Fix various bugs

File size: 70.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_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//        Debug macros for marshalling functions
46/////////////////////////////////////////////////////////////////////////////////////////
47
48#if CONFIG_DEBUG_RPC_MARSHALING
49
50#define RPC_DEBUG_ENTER                                                                \
51uint32_t cycle = (uint32_t)hal_get_cycles();                                           \
52if( cycle > CONFIG_DEBUG_RPC_MARSHALING )                                              \
53printk("\n[DBG] %s : enter thread %x on core[%x,%d] / cycle %d\n",                     \
54__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
55
56#define RPC_DEBUG_EXIT                                                                 \
57cycle = (uint32_t)hal_get_cycles();                                                    \
58if( cycle > CONFIG_DEBUG_RPC_MARSHALING )                                              \
59printk("\n[DBG] %s : exit thread %x on core[%x,%d] / cycle %d\n",                      \
60__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
61
62#else
63
64#define RPC_DEBUG_ENTER
65
66#define RPC_DEBUG_EXIT
67
68#endif
69
70/////////////////////////////////////////////////////////////////////////////////////////
71//      array of function pointers  (must be consistent with enum in rpc.h)
72/////////////////////////////////////////////////////////////////////////////////////////
73
74rpc_server_t * rpc_server[RPC_MAX_INDEX] =
75{
76    &rpc_pmem_get_pages_server,         // 0
77    &rpc_pmem_release_pages_server,     // 1
78    &rpc_undefined,                     // 2    unused slot
79    &rpc_process_make_fork_server,      // 3
80    &rpc_undefined,                     // 4    unused slot
81    &rpc_undefined,                     // 5    unused slot
82    &rpc_thread_user_create_server,     // 6
83    &rpc_thread_kernel_create_server,   // 7
84    &rpc_undefined,                     // 8    unused slot       
85    &rpc_process_sigaction_server,      // 9
86
87    &rpc_vfs_inode_create_server,       // 10 
88    &rpc_vfs_inode_destroy_server,      // 11 
89    &rpc_vfs_dentry_create_server,      // 12 
90    &rpc_vfs_dentry_destroy_server,     // 13 
91    &rpc_vfs_file_create_server,        // 14
92    &rpc_vfs_file_destroy_server,       // 15
93    &rpc_vfs_inode_load_server,         // 16
94    &rpc_vfs_mapper_load_all_server,    // 17
95    &rpc_fatfs_get_cluster_server,      // 18
96    &rpc_undefined,                     // 19   unused slot
97
98    &rpc_vmm_get_vseg_server,           // 20
99    &rpc_vmm_get_pte_server,            // 21
100    &rpc_kcm_alloc_server,              // 22
101    &rpc_kcm_free_server,               // 23
102    &rpc_mapper_move_buffer_server,     // 24
103    &rpc_mapper_get_page_server,        // 25
104    &rpc_vmm_create_vseg_server,        // 26
105    &rpc_sched_display_server,          // 27
106    &rpc_vmm_set_cow_server,            // 28
107    &rpc_vmm_display_server,            // 29
108};
109
110//////////////////////////////////////////////
111void __attribute__((noinline)) rpc_undefined()
112{
113        assert( false , __FUNCTION__ , "called in cluster %x", local_cxy );
114}
115
116/***************************************************************************************/
117/************ Generic functions supporting RPCs : client side **************************/
118/***************************************************************************************/
119
120///////////////////////////////////////
121void rpc_send( cxy_t        server_cxy, 
122               rpc_desc_t * rpc )
123{
124    volatile error_t   full = 0;
125    thread_t         * this = CURRENT_THREAD;
126    core_t           * core = this->core;
127
128#if CONFIG_DEBUG_RPC_SEND
129uint32_t cycle = (uint32_t)hal_get_cycles();
130if( CONFIG_DEBUG_RPC_SEND < cycle ) 
131printk("\n[DBG] %s : thread %x in cluster %x enter for rpc[%d] / rpc_ptr %x / cycle %d\n",
132__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, rpc, cycle );
133#endif
134
135    // register client thread pointer and core lid in RPC descriptor
136    rpc->thread = this;
137    rpc->lid    = core->lid;
138
139    // build an extended pointer on the RPC descriptor
140        xptr_t   desc_xp = XPTR( local_cxy , rpc );
141
142    // get local pointer on rpc_fifo in remote cluster,
143    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
144
145        // post RPC in remote fifo / deschedule and retry if fifo full
146    do
147    { 
148        full = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), (uint64_t )desc_xp );
149            if ( full ) 
150        {
151            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
152            __FUNCTION__ , local_cxy , server_cxy );
153
154            // deschedule without blocking
155            sched_yield("RPC fifo full");
156        }
157    }
158    while( full );
159 
160    hal_fence();
161       
162    // send IPI to the remote core corresponding to the client core
163        dev_pic_send_ipi( server_cxy , core->lid );
164
165    // wait RPC completion before returning if blocking RPC
166    // - busy waiting policy during kernel_init, or if threads cannot yield
167    // - block and deschedule in all other cases
168    if ( rpc->blocking )
169    {
170        if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
171        {
172
173#if CONFIG_DEBUG_RPC_SEND
174cycle = (uint32_t)hal_get_cycles();
175if( CONFIG_DEBUG_RPC_SEND < cycle ) 
176printk("\n[DBG] %s : thread %x in cluster %x busy waiting / rpc[%d] / cycle %d\n",
177__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index , cycle );
178#endif
179
180            while( rpc->response ) hal_fixed_delay( 100 );
181   
182#if CONFIG_DEBUG_RPC_SEND
183cycle = (uint32_t)hal_get_cycles();
184if( CONFIG_DEBUG_RPC_SEND < cycle ) 
185printk("\n[DBG] %s : thread % in cluster %x resume / rpc[%d] / cycle %d\n",
186__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
187#endif
188        } 
189        else                                                         // block & deschedule
190        {
191
192#if CONFIG_DEBUG_RPC_SEND
193cycle = (uint32_t)hal_get_cycles();
194if( CONFIG_DEBUG_RPC_SEND < cycle ) 
195printk("\n[DBG] %s : thread %x in cluster %x deschedule / rpc[%d] / cycle %d\n",
196__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index , cycle );
197#endif
198            thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
199            sched_yield("blocked on RPC");
200
201#if CONFIG_DEBUG_RPC_SEND
202cycle = (uint32_t)hal_get_cycles();
203if( CONFIG_DEBUG_RPC_SEND < cycle ) 
204printk("\n[DBG] %s : thread % in cluster %x resume / rpcr[%d] / cycle %d\n",
205__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
206#endif
207        }
208
209        // check response available
210        assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" );
211
212        // acknowledge the IPI sent by the server
213        dev_pic_ack_ipi();
214    }
215    else
216    {
217
218#if CONFIG_DEBUG_RPC_SEND
219cycle = (uint32_t)hal_get_cycles();
220if( CONFIG_DEBUG_RPC_SEND < cycle ) 
221printk("\n[DBG] %s : non blocking rpc[%d] => thread %x return  / cycle %d\n",
222__FUNCTION__, rpc->index, CURRENT_THREAD, cycle );
223#endif
224
225    }
226}  // end rpc_send()
227
228
229/***************************************************************************************/
230/************ Generic functions supporting RPCs : server side **************************/
231/***************************************************************************************/
232
233////////////////
234void rpc_check()
235{
236    error_t         error;
237    thread_t      * thread; 
238    uint32_t        sr_save;
239
240    bool_t          found    = false;
241        thread_t      * this     = CURRENT_THREAD;
242    core_t        * core     = this->core;
243    scheduler_t   * sched    = &core->scheduler;
244        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
245
246#if CONFIG_DEBUG_RPC_SERVER
247uint32_t cycle = (uint32_t)hal_get_cycles();
248if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
249printk("\n[DBG] %s : thread %x interrupted in cluster %x / cycle %d\n",
250__FUNCTION__, this, local_cxy, cycle );
251#endif
252
253    // interrupted thread not preemptable during RPC chek
254        hal_disable_irq( &sr_save );
255
256    // check RPC FIFO not empty and no RPC thread handling it 
257        if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
258    {
259        // search one non blocked RPC thread   
260        list_entry_t * iter;
261        LIST_FOREACH( &sched->k_root , iter )
262        {
263            thread = LIST_ELEMENT( iter , thread_t , sched_list );
264            if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 
265            {
266                found = true;
267                break;
268            }
269        }
270
271        // create new RPC thread if not found   
272        if( found == false )                   
273        {
274            error = thread_kernel_create( &thread,
275                                          THREAD_RPC, 
276                                                      &rpc_thread_func, 
277                                          NULL,
278                                                      this->core->lid );
279                if( error ) 
280            {
281                printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n",
282                __FUNCTION__ , local_cxy );
283            }
284            else
285            {
286                // unblock created RPC thread
287                thread->blocked = 0;
288
289                // update core descriptor counter 
290                    hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
291
292#if CONFIG_DEBUG_RPC_SERVER
293cycle = (uint32_t)hal_get_cycles();
294if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
295printk("\n[DBG] %s : create a new RPC thread %x in cluster %x / cycle %d\n",
296__FUNCTION__, thread, local_cxy, cycle );
297#endif
298            }
299        }
300    }
301
302#if CONFIG_DEBUG_RPC_SERVER
303cycle = (uint32_t)hal_get_cycles();
304if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
305printk("\n[DBG] %s : interrupted thread %x deschedules in cluster %x / cycle %d\n",
306__FUNCTION__, this, local_cxy, cycle );
307#endif
308
309    // interrupted thread deschedule always           
310        sched_yield("IPI received");
311
312#if CONFIG_DEBUG_RPC_SERVER
313cycle = (uint32_t)hal_get_cycles();
314if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
315printk("\n[DBG] %s : interrupted thread %x resumes in cluster %x / cycle %d\n",
316__FUNCTION__, this, local_cxy, cycle );
317#endif
318
319    // interrupted thread restore IRQs after resume
320        hal_restore_irq( sr_save );
321
322} // end rpc_check()
323
324
325//////////////////////
326void rpc_thread_func()
327{
328    uint32_t     count;       // handled RPC requests counter
329    error_t      empty;       // local RPC fifo state
330    xptr_t       desc_xp;     // extended pointer on RPC request
331    cxy_t        desc_cxy;    // RPC request cluster (client)
332    rpc_desc_t * desc_ptr;    // RPC request local pointer
333    uint32_t     index;       // RPC request index
334    thread_t   * thread_ptr;  // local pointer on client thread
335    lid_t        core_lid;    // local index of client core
336    bool_t       blocking;    // blocking RPC when true
337 
338    // makes RPC thread not preemptable
339        hal_disable_irq( NULL );
340 
341        thread_t      * this     = CURRENT_THREAD;
342        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
343
344    // two embedded loops:
345    // - external loop : "infinite" RPC thread
346    // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
347 
348        while(1)  // external loop
349        {
350        // try to take RPC_FIFO ownership
351        if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
352        {
353
354#if CONFIG_DEBUG_RPC_SERVER
355uint32_t cycle = (uint32_t)hal_get_cycles();
356if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
357printk("\n[DBG] %s : RPC thread %x in cluster %x takes RPC fifo ownership / cycle %d\n",
358__FUNCTION__, this, local_cxy, cycle );
359#endif
360            // initializes RPC requests counter
361            count = 0;
362
363            // acknowledge local IPI
364            dev_pic_ack_ipi();
365
366                    // exit internal loop in three cases:
367            // - RPC fifo is empty
368            // - ownership has been lost (because descheduling)
369            // - max number of RPCs is reached
370                while( 1 )  // internal loop
371            {
372                    empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
373
374                    if ( empty == 0 ) // one RPC request found
375                {
376                    // get client cluster and pointer on RPC descriptor
377                    desc_cxy = GET_CXY( desc_xp );
378                    desc_ptr = GET_PTR( desc_xp );
379
380                        index    = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
381                    blocking = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->blocking ) );
382
383#if CONFIG_DEBUG_RPC_SERVER
384cycle = (uint32_t)hal_get_cycles();
385if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
386printk("\n[DBG] %s : RPC thread %x in cluster %x got rpc[%d] / rpc_ptr %x / cycle %d\n",
387__FUNCTION__, this, local_cxy, index, desc_ptr, cycle );
388#endif
389                    // call the relevant server function
390                    rpc_server[index]( desc_xp );
391
392#if CONFIG_DEBUG_RPC_SERVER
393cycle = (uint32_t)hal_get_cycles();
394if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
395printk("\n[DBG] %s : RPC thread %x in cluster %x completes rpc[%d] / rpc_ptr %x / cycle %d\n",
396__FUNCTION__, this, local_cxy, index, cycle );
397#endif
398                    // increment handled RPCs counter
399                        count++;
400
401                    // decrement response counter in RPC descriptor if blocking
402                    if( blocking )
403                    {
404                        // decrement responses counter in RPC descriptor
405                        hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
406
407                        // unblock client thread
408                        thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread));
409                        thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC );
410
411                        hal_fence();
412
413                        // get client core lid and send IPI
414                        core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid));
415                            dev_pic_send_ipi( desc_cxy , core_lid );
416                    }
417                        }
418       
419                // chek exit condition
420                        if( local_fifo_is_empty( rpc_fifo )  || 
421                    (rpc_fifo->owner != this->trdid) || 
422                    (count >= CONFIG_RPC_PENDING_MAX) ) break;
423                } // end internal loop
424
425            // release rpc_fifo ownership if not lost
426            if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
427
428        }  // end if RPC fifo
429
430        // sucide if too many RPC threads in cluster
431        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
432            {
433
434#if CONFIG_DEBUG_RPC_SERVER
435uint32_t cycle = (uint32_t)hal_get_cycles();
436if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
437printk("\n[DBG] %s : RPC thread %x in cluster %x suicides / cycle %d\n",
438__FUNCTION__, this, local_cxy, cycle );
439#endif
440            // update RPC threads counter
441                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
442
443            // suicide
444                thread_kill( XPTR( local_cxy , this ),
445                         true,                      // is_exit
446                         true );                    // is forced
447            }
448
449#if CONFIG_DEBUG_RPC_SERVER
450uint32_t cycle = (uint32_t)hal_get_cycles();
451if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
452printk("\n[DBG] %s : RPC thread %x in cluster %x deschedules / cycle %d\n",
453__FUNCTION__, this, local_cxy, cycle );
454#endif
455
456        // deschedule without blocking
457        sched_yield("RPC fifo empty or too much work");
458
459#if CONFIG_DEBUG_RPC_SERVER
460cycle = (uint32_t)hal_get_cycles();
461if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
462printk("\n[DBG] %s : RPC thread %x in cluster %x resumes / cycle %d\n",
463__FUNCTION__, this, local_cxy, cycle );
464#endif
465
466        } // end external loop
467
468} // end rpc_thread_func()
469
470
471/////////////////////////////////////////////////////////////////////////////////////////
472// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
473/////////////////////////////////////////////////////////////////////////////////////////
474
475///////////////////////////////////////////////
476void rpc_pmem_get_pages_client( cxy_t      cxy,
477                                uint32_t   order,      // in
478                                page_t  ** page )      // out
479{
480
481    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
482
483    // initialise RPC descriptor header
484    rpc_desc_t  rpc;
485    rpc.index    = RPC_PMEM_GET_PAGES;
486    rpc.response = 1;
487    rpc.blocking = true;
488
489    // set input arguments in RPC descriptor
490    rpc.args[0] = (uint64_t)order;
491
492    // register RPC request in remote RPC fifo
493    rpc_send( cxy , &rpc );
494
495    // get output arguments from RPC descriptor
496    *page = (page_t *)(intptr_t)rpc.args[1];
497
498}
499
500///////////////////////////////////////////
501void rpc_pmem_get_pages_server( xptr_t xp )
502{
503
504    // get client cluster identifier and pointer on RPC descriptor
505    cxy_t        cxy  = GET_CXY( xp );
506    rpc_desc_t * desc = GET_PTR( xp );
507
508    // get input arguments from client RPC descriptor
509    uint32_t order = (uint32_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
510   
511    // call local pmem allocator
512    page_t * page = ppm_alloc_pages( order ); 
513
514    // set output arguments into client RPC descriptor
515    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
516
517}
518
519/////////////////////////////////////////////////////////////////////////////////////////
520// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking)
521/////////////////////////////////////////////////////////////////////////////////////////
522
523//////////////////////////////////////////////////
524void rpc_pmem_release_pages_client( cxy_t     cxy,
525                                    page_t  * page )      // out
526{
527
528    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
529
530    // initialise RPC descriptor header
531    rpc_desc_t  rpc;
532    rpc.index    = RPC_PMEM_RELEASE_PAGES;
533    rpc.response = 1;
534    rpc.blocking = true;
535
536    // set input arguments in RPC descriptor
537    rpc.args[0] = (uint64_t)(intptr_t)page;
538
539    // register RPC request in remote RPC fifo
540    rpc_send( cxy , &rpc );
541
542}
543
544///////////////////////////////////////////////
545void rpc_pmem_release_pages_server( xptr_t xp )
546{
547
548    // get client cluster identifier and pointer on RPC descriptor
549    cxy_t        cxy  = GET_CXY( xp );
550    rpc_desc_t * desc = GET_PTR( xp );
551
552    // get input arguments from client RPC descriptor
553    page_t * page = (page_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
554   
555    // release memory to local pmem
556    kmem_req_t req;
557    req.type = KMEM_PAGE;
558    req.ptr  = page;
559    kmem_free( &req );
560
561}
562
563/////////////////////////////////////////////////////////////////////////////////////////
564// [2]      undefined slot
565/////////////////////////////////////////////////////////////////////////////////////////
566
567/////////////////////////////////////////////////////////////////////////////////////////
568// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking)
569/////////////////////////////////////////////////////////////////////////////////////////
570
571///////////////////////////////////////////////////
572void rpc_process_make_fork_client( cxy_t       cxy,
573                                   xptr_t      ref_process_xp,      // in
574                                   xptr_t      parent_thread_xp,    // in
575                                   pid_t     * child_pid,           // out
576                                   thread_t ** child_thread_ptr,    // out     
577                                   error_t   * error )              // out
578{
579    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
580
581    // initialise RPC descriptor header
582    rpc_desc_t  rpc;
583    rpc.index    = RPC_PROCESS_MAKE_FORK;
584    rpc.response = 1;
585    rpc.blocking = true;
586
587    // set input arguments in RPC descriptor 
588    rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp;
589    rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp;
590
591    // register RPC request in remote RPC fifo
592    rpc_send( cxy , &rpc );
593
594    // get output arguments from RPC descriptor
595    *child_pid         = (pid_t)rpc.args[2];
596    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
597    *error             = (error_t)rpc.args[4];     
598
599}
600
601//////////////////////////////////////////////
602void rpc_process_make_fork_server( xptr_t xp )
603{
604
605    xptr_t     ref_process_xp;     // extended pointer on reference parent process
606    xptr_t     parent_thread_xp;   // extended pointer on parent thread
607    pid_t      child_pid;          // child process identifier
608    thread_t * child_thread_ptr;   // local copy of exec_info structure
609    error_t    error;              // local error status
610
611    // get client cluster identifier and pointer on RPC descriptor
612    cxy_t        client_cxy  = GET_CXY( xp );
613    rpc_desc_t * desc        = GET_PTR( xp );
614
615    // get input arguments from cient RPC descriptor
616    ref_process_xp   = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
617    parent_thread_xp = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
618
619    // call local kernel function
620    error = process_make_fork( ref_process_xp,
621                               parent_thread_xp,
622                               &child_pid,
623                               &child_thread_ptr ); 
624
625    // set output argument into client RPC descriptor
626    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
627    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
628    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
629
630}
631
632/////////////////////////////////////////////////////////////////////////////////////////
633// [4]      undefined slot
634/////////////////////////////////////////////////////////////////////////////////////////
635
636/////////////////////////////////////////////////////////////////////////////////////////
637// [5]      undefined slot
638/////////////////////////////////////////////////////////////////////////////////////////
639
640/////////////////////////////////////////////////////////////////////////////////////////
641// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 
642/////////////////////////////////////////////////////////////////////////////////////////
643
644/////////////////////////////////////////////////////////
645void rpc_thread_user_create_client( cxy_t            cxy, 
646                                    pid_t            pid,         // in
647                                    void           * start_func,  // in
648                                    void           * start_arg,   // in
649                                    pthread_attr_t * attr,        // in
650                                    xptr_t         * thread_xp,   // out
651                                    error_t        * error )      // out
652{
653    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
654
655    // initialise RPC descriptor header
656    rpc_desc_t  rpc;
657    rpc.index    = RPC_THREAD_USER_CREATE;
658    rpc.response = 1;
659    rpc.blocking = true;
660
661    // set input arguments in RPC descriptor
662    rpc.args[0] = (uint64_t)pid;
663    rpc.args[1] = (uint64_t)(intptr_t)start_func;
664    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
665    rpc.args[3] = (uint64_t)(intptr_t)attr;
666
667    // register RPC request in remote RPC fifo
668    rpc_send( cxy , &rpc );
669
670    // get output arguments from RPC descriptor
671    *thread_xp = (xptr_t)rpc.args[4];
672    *error     = (error_t)rpc.args[5];
673
674}
675
676///////////////////////////////////////////////
677void rpc_thread_user_create_server( xptr_t xp )
678{
679
680    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
681    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
682    thread_t       * thread_ptr; // local pointer on thread descriptor
683    xptr_t           thread_xp;  // extended pointer on thread descriptor
684
685    pid_t            pid;        // process identifier
686    void           * start_func;
687    void           * start_arg;
688    error_t          error;
689
690    // get client cluster identifier and pointer on RPC descriptor
691    cxy_t        client_cxy  = GET_CXY( xp );
692    rpc_desc_t * desc = GET_PTR( xp );
693
694    // get pointer on attributes structure in client cluster from RPC descriptor
695
696    // get input arguments from RPC descriptor
697    pid        = (pid_t)                     hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
698    start_func = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
699    start_arg  = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
700    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[3]));
701
702    // makes a local copy of attributes structure
703    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
704                       XPTR( client_cxy , attr_ptr ), 
705                       sizeof(pthread_attr_t) );
706   
707    // call kernel function
708    error = thread_user_create( pid,
709                                start_func,
710                                start_arg,
711                                &attr_copy,
712                                &thread_ptr );
713
714    // set output arguments
715    thread_xp = XPTR( local_cxy , thread_ptr );
716    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
717    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
718
719}
720
721/////////////////////////////////////////////////////////////////////////////////////////
722// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
723/////////////////////////////////////////////////////////////////////////////////////////
724
725////////////////////////////////////////////////////
726void rpc_thread_kernel_create_client( cxy_t     cxy,
727                                      uint32_t  type,        // in
728                                      void    * func,        // in
729                                      void    * args,        // in
730                                      xptr_t  * thread_xp,   // out
731                                      error_t * error )      // out
732{
733    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
734
735    // initialise RPC descriptor header
736    rpc_desc_t  rpc;
737    rpc.index    = RPC_THREAD_KERNEL_CREATE;
738    rpc.response = 1;
739    rpc.blocking = true;
740
741    // set input arguments in RPC descriptor
742    rpc.args[0] = (uint64_t)type;
743    rpc.args[1] = (uint64_t)(intptr_t)func;
744    rpc.args[2] = (uint64_t)(intptr_t)args;
745   
746    // register RPC request in remote RPC fifo
747    rpc_send( cxy , &rpc );
748
749    // get output arguments from RPC descriptor
750    *thread_xp = (xptr_t)rpc.args[3];
751    *error     = (error_t)rpc.args[4];
752
753}
754
755/////////////////////////////////////////////////
756void rpc_thread_kernel_create_server( xptr_t xp )
757{
758    thread_t       * thread_ptr;  // local pointer on thread descriptor
759    xptr_t           thread_xp;   // extended pointer on thread descriptor
760    lid_t            core_lid;    // core local index
761    error_t          error;   
762
763    // get client cluster identifier and pointer on RPC descriptor
764    cxy_t        client_cxy  = GET_CXY( xp );
765    rpc_desc_t * desc = GET_PTR( xp );
766
767    // get attributes from RPC descriptor
768    uint32_t  type = (uint32_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
769    void    * func = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
770    void    * args = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
771
772    // select one core
773    core_lid = cluster_select_local_core();
774
775    // call local kernel function
776    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
777
778    // set output arguments
779    thread_xp = XPTR( local_cxy , thread_ptr );
780    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
781    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
782
783}
784
785/////////////////////////////////////////////////////////////////////////////////////////
786// [8]   undefined slot
787/////////////////////////////////////////////////////////////////////////////////////////
788
789
790/////////////////////////////////////////////////////////////////////////////////////////
791// [9] Marshaling functions attached to RPC_PROCESS_SIGACTION (multicast / non blocking)
792/////////////////////////////////////////////////////////////////////////////////////////
793
794////////////////////////////////////////////////////
795void rpc_process_sigaction_client( cxy_t        cxy,
796                                   rpc_desc_t * rpc )
797{
798
799#if (CONFIG_DEBUG_PROCESS_SIGACTION & 1)
800uint32_t  cycle  = (uint32_t)hal_get_cycles();
801uint32_t  action = rpc->args[0];
802pid_t     pid    = rpc->args[1];
803if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
804printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
805__FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
806#endif
807
808    // check some RPC arguments
809    assert( (rpc->blocking == false) , __FUNCTION__ , "must be non-blocking\n");
810    assert( (rpc->index == RPC_PROCESS_SIGACTION ) , __FUNCTION__ , "bad RPC index\n" );
811
812    // register RPC request in remote RPC fifo and return
813    rpc_send( cxy , rpc );
814
815#if (CONFIG_DEBUG_PROCESS_SIGACTION & 1)
816cycle = (uint32_t)hal_get_cycles();
817if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
818printk("\n[DBG] %s : exit after requesting to %s process %x in cluster %x / cycle %d\n",
819__FUNCTION__ , process_action_str( action ) , pid , cxy , cycle );
820#endif
821
822}  // end rpc_process_sigaction_client()
823
824//////////////////////////////////////////////
825void rpc_process_sigaction_server( xptr_t xp )
826{
827    pid_t        pid;              // target process identifier
828    process_t  * process;          // pointer on local target process descriptor
829    uint32_t     action;           // sigaction index
830    thread_t   * client_thread;    // pointer on client thread in client cluster
831    cxy_t        client_cxy;       // client cluster identifier
832    rpc_desc_t * rpc;              // pointer on rpc descriptor in client cluster
833    xptr_t       count_xp;         // extended pointer on response counter
834    lid_t        client_lid;       // client core local index
835
836    // get client cluster identifier and pointer on RPC descriptor
837    client_cxy = GET_CXY( xp );
838    rpc        = GET_PTR( xp );
839
840    // get arguments from RPC descriptor
841    action   = (uint32_t)hal_remote_lwd( XPTR(client_cxy , &rpc->args[0]) );
842    pid      = (pid_t)   hal_remote_lwd( XPTR(client_cxy , &rpc->args[1]) );
843
844#if (CONFIG_DEBUG_PROCESS_SIGACTION & 1)
845uint32_t cycle = (uint32_t)hal_get_cycles();
846if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
847printk("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
848__FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
849#endif
850
851    // get local process descriptor
852    process = cluster_get_local_process_from_pid( pid );
853
854    // call relevant kernel function
855    if      ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process ); 
856    else if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
857    else if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
858
859    // build extended pointer on response counter in RPC
860    count_xp = XPTR( client_cxy , &rpc->response );
861
862    // decrement the responses counter in RPC descriptor,
863    // unblock the client thread only if it is the last response.
864    if( hal_remote_atomic_add( count_xp , -1 ) == 1 ) 
865    {
866        // get client thread pointer and client core lid
867        client_thread = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) );
868        client_lid    = (lid_t)     hal_remote_lw ( XPTR( client_cxy , &rpc->lid    ) );
869
870        thread_unblock( XPTR( client_cxy , client_thread ) , THREAD_BLOCKED_RPC );
871        dev_pic_send_ipi( client_cxy , client_lid );
872    }
873
874#if (CONFIG_DEBUG_PROCESS_SIGACTION & 1)
875cycle = (uint32_t)hal_get_cycles();
876if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle )
877printk("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n",
878__FUNCTION__ , process_action_str( action ) , pid , local_cxy , cycle );
879#endif
880
881} // end rpc_process_sigaction_server()
882
883/////////////////////////////////////////////////////////////////////////////////////////
884// [10]     Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
885/////////////////////////////////////////////////////////////////////////////////////////
886
887/////////////////////////////////////////////////////
888void rpc_vfs_inode_create_client( cxy_t          cxy,     
889                                  xptr_t         dentry_xp,  // in
890                                  uint32_t       fs_type,    // in
891                                  uint32_t       inode_type, // in
892                                  void         * extend,     // in
893                                  uint32_t       attr,       // in
894                                  uint32_t       rights,     // in
895                                  uint32_t       uid,        // in
896                                  uint32_t       gid,        // in
897                                  xptr_t       * inode_xp,   // out
898                                  error_t      * error )     // out
899{
900    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
901
902    // initialise RPC descriptor header
903    rpc_desc_t  rpc;
904    rpc.index    = RPC_VFS_INODE_CREATE;
905    rpc.response = 1;
906    rpc.blocking = true;
907
908    // set input arguments in RPC descriptor
909    rpc.args[0] = (uint64_t)dentry_xp;
910    rpc.args[1] = (uint64_t)fs_type;
911    rpc.args[2] = (uint64_t)inode_type;
912    rpc.args[3] = (uint64_t)(intptr_t)extend;
913    rpc.args[4] = (uint64_t)attr;
914    rpc.args[5] = (uint64_t)rights;
915    rpc.args[6] = (uint64_t)uid;
916    rpc.args[7] = (uint64_t)gid;
917
918    // register RPC request in remote RPC fifo
919    rpc_send( cxy , &rpc );
920
921    // get output values from RPC descriptor
922    *inode_xp = (xptr_t)rpc.args[8];
923    *error    = (error_t)rpc.args[9];
924
925}
926
927/////////////////////////////////////////////
928void rpc_vfs_inode_create_server( xptr_t xp )
929{
930    xptr_t           dentry_xp;
931    uint32_t         fs_type;
932    uint32_t         inode_type;
933    void           * extend;
934    uint32_t         attr;
935    uint32_t         rights;
936    uint32_t         uid;
937    uint32_t         gid;
938    xptr_t           inode_xp;
939    error_t          error;
940
941    // get client cluster identifier and pointer on RPC descriptor
942    cxy_t        client_cxy  = GET_CXY( xp );
943    rpc_desc_t * desc        = GET_PTR( xp );
944
945    // get input arguments from client rpc descriptor
946    dentry_xp  = (xptr_t)          hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
947    fs_type    = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
948    inode_type = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
949    extend     = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
950    attr       = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
951    rights     = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
952    uid        = (uid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) );
953    gid        = (gid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[7] ) );
954
955    // call local kernel function
956    error = vfs_inode_create( dentry_xp,
957                              fs_type,
958                              inode_type,
959                              extend,
960                              attr,
961                              rights,
962                              uid,
963                              gid,
964                              &inode_xp );
965
966    // set output arguments
967    hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)inode_xp );
968    hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
969
970}
971
972/////////////////////////////////////////////////////////////////////////////////////////
973// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
974/////////////////////////////////////////////////////////////////////////////////////////
975
976/////////////////////////////////////////////////////////////
977void rpc_vfs_inode_destroy_client( cxy_t                cxy,
978                                   struct vfs_inode_s * inode )
979{
980    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
981
982    // initialise RPC descriptor header
983    rpc_desc_t  rpc;
984    rpc.index    = RPC_VFS_INODE_DESTROY;
985    rpc.response = 1;
986    rpc.blocking = true;
987
988    // set input arguments in RPC descriptor
989    rpc.args[0] = (uint64_t)(intptr_t)inode;
990   
991    // register RPC request in remote RPC fifo
992    rpc_send( cxy , &rpc );
993
994}
995
996//////////////////////////////////////////////
997void rpc_vfs_inode_destroy_server( xptr_t xp )
998{
999    vfs_inode_t * inode;
1000
1001    // get client cluster identifier and pointer on RPC descriptor
1002    cxy_t        client_cxy  = GET_CXY( xp );
1003    rpc_desc_t * desc        = GET_PTR( xp );
1004
1005    // get arguments "inode" from client RPC descriptor
1006    inode = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1007                       
1008    // call local kernel function
1009    vfs_inode_destroy( inode );
1010
1011}
1012
1013/////////////////////////////////////////////////////////////////////////////////////////
1014// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
1015/////////////////////////////////////////////////////////////////////////////////////////
1016
1017//////////////////////////////////////////////////////////////
1018void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1019                                   uint32_t               type,         // in
1020                                   char                 * name,         // in
1021                                   struct vfs_inode_s   * parent,       // in
1022                                   xptr_t               * dentry_xp,    // out
1023                                   error_t              * error )       // out
1024{
1025    RPC_DEBUG_ENTER
1026
1027    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1028
1029    // initialise RPC descriptor header
1030    rpc_desc_t  rpc;
1031    rpc.index    = RPC_VFS_DENTRY_CREATE;
1032    rpc.response = 1;
1033    rpc.blocking = true;
1034
1035    // set input arguments in RPC descriptor
1036    rpc.args[0] = (uint64_t)type;
1037    rpc.args[1] = (uint64_t)(intptr_t)name;
1038    rpc.args[2] = (uint64_t)(intptr_t)parent;
1039
1040    // register RPC request in remote RPC fifo
1041    rpc_send( cxy , &rpc );
1042
1043    // get output values from RPC descriptor
1044    *dentry_xp = (xptr_t)rpc.args[3];
1045    *error     = (error_t)rpc.args[4];
1046
1047    RPC_DEBUG_EXIT
1048}
1049
1050//////////////////////////////////////////////
1051void rpc_vfs_dentry_create_server( xptr_t xp )
1052{
1053    uint32_t      type;
1054    char        * name;
1055    vfs_inode_t * parent;
1056    xptr_t        dentry_xp;
1057    error_t       error;
1058
1059    RPC_DEBUG_ENTER
1060
1061    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1062
1063    // get client cluster identifier and pointer on RPC descriptor
1064    cxy_t        client_cxy  = GET_CXY( xp );
1065    rpc_desc_t * desc        = GET_PTR( xp );
1066
1067    // get arguments "name", "type", and "parent" from client RPC descriptor
1068    type   = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1069    name   = (char *)(intptr_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1070    parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
1071
1072    // makes a local copy of  name
1073    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1074                       XPTR( client_cxy , name ) );
1075
1076    // call local kernel function
1077    error = vfs_dentry_create( type,
1078                               name_copy,
1079                               parent,
1080                               &dentry_xp );
1081    // set output arguments
1082    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp );
1083    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
1084
1085    RPC_DEBUG_EXIT
1086}
1087
1088/////////////////////////////////////////////////////////////////////////////////////////
1089// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
1090/////////////////////////////////////////////////////////////////////////////////////////
1091
1092
1093///////////////////////////////////////////////////////
1094void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1095                                    vfs_dentry_t * dentry )
1096{
1097    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1098
1099    // initialise RPC descriptor header
1100    rpc_desc_t  rpc;
1101    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1102    rpc.response = 1;
1103    rpc.blocking = true;
1104
1105    // set input arguments in RPC descriptor
1106    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1107   
1108    // register RPC request in remote RPC fifo
1109    rpc_send( cxy , &rpc );
1110
1111}
1112
1113///////////////////////////////////////////////
1114void rpc_vfs_dentry_destroy_server( xptr_t xp )
1115{
1116    vfs_dentry_t * dentry;
1117
1118    // get client cluster identifier and pointer on RPC descriptor
1119    cxy_t        client_cxy  = GET_CXY( xp );
1120    rpc_desc_t * desc        = GET_PTR( xp );
1121
1122    // get arguments "dentry" from client RPC descriptor
1123    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1124                       
1125    // call local kernel function
1126    vfs_dentry_destroy( dentry );
1127
1128}
1129
1130
1131/////////////////////////////////////////////////////////////////////////////////////////
1132// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
1133/////////////////////////////////////////////////////////////////////////////////////////
1134
1135//////////////////////////////////////////////////////////////
1136void rpc_vfs_file_create_client( cxy_t                  cxy,
1137                                 struct vfs_inode_s   * inode,       // in
1138                                 uint32_t               file_attr,   // in
1139                                 xptr_t               * file_xp,     // out
1140                                 error_t              * error )      // out
1141{
1142    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1143
1144    // initialise RPC descriptor header
1145    rpc_desc_t  rpc;
1146    rpc.index    = RPC_VFS_FILE_CREATE;
1147    rpc.response = 1;
1148    rpc.blocking = true;
1149
1150    // set input arguments in RPC descriptor
1151    rpc.args[0] = (uint64_t)(intptr_t)inode;
1152    rpc.args[1] = (uint64_t)file_attr;
1153
1154    // register RPC request in remote RPC fifo
1155    rpc_send( cxy , &rpc );
1156
1157    // get output values from RPC descriptor
1158    *file_xp = (xptr_t)rpc.args[2];
1159    *error   = (error_t)rpc.args[3];
1160
1161}
1162
1163////////////////////////////////////////////
1164void rpc_vfs_file_create_server( xptr_t xp )
1165{
1166    uint32_t      file_attr;
1167    vfs_inode_t * inode;
1168    xptr_t        file_xp;
1169    error_t       error;
1170
1171    // get client cluster identifier and pointer on RPC descriptor
1172    cxy_t        client_cxy  = GET_CXY( xp );
1173    rpc_desc_t * desc        = GET_PTR( xp );
1174
1175    // get arguments "file_attr" and "inode" from client RPC descriptor
1176    inode     = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1177    file_attr = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1178                       
1179    // call local kernel function
1180    error = vfs_file_create( inode,
1181                             file_attr,
1182                             &file_xp );
1183 
1184    // set output arguments
1185    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
1186    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1187
1188}
1189
1190/////////////////////////////////////////////////////////////////////////////////////////
1191// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
1192/////////////////////////////////////////////////////////////////////////////////////////
1193
1194///////////////////////////////////////////////////
1195void rpc_vfs_file_destroy_client( cxy_t        cxy,
1196                                  vfs_file_t * file )
1197{
1198    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1199
1200    // initialise RPC descriptor header
1201    rpc_desc_t  rpc;
1202    rpc.index    = RPC_VFS_FILE_DESTROY;
1203    rpc.response = 1;
1204    rpc.blocking = true;
1205
1206    // set input arguments in RPC descriptor
1207    rpc.args[0] = (uint64_t)(intptr_t)file;
1208   
1209    // register RPC request in remote RPC fifo
1210    rpc_send( cxy , &rpc );
1211
1212}
1213
1214/////////////////////////////////////////////
1215void rpc_vfs_file_destroy_server( xptr_t xp )
1216{
1217    vfs_file_t * file;
1218
1219    // get client cluster identifier and pointer on RPC descriptor
1220    cxy_t        client_cxy  = GET_CXY( xp );
1221    rpc_desc_t * desc        = GET_PTR( xp );
1222
1223    // get arguments "dentry" from client RPC descriptor
1224    file = (vfs_file_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1225                       
1226    // call local kernel function
1227    vfs_file_destroy( file );
1228
1229}
1230
1231/////////////////////////////////////////////////////////////////////////////////////////
1232// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   (blocking)
1233/////////////////////////////////////////////////////////////////////////////////////////
1234
1235//////////////////////////////////////////////////
1236void rpc_vfs_inode_load_client( cxy_t         cxy,
1237                                vfs_inode_t * parent_inode,    // in
1238                                char        * name,            // in
1239                                xptr_t        child_inode_xp,  // in
1240                                error_t     * error )          // out
1241{
1242    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1243
1244    // initialise RPC descriptor header
1245    rpc_desc_t  rpc;
1246    rpc.index    = RPC_VFS_INODE_LOAD;
1247    rpc.response = 1;
1248    rpc.blocking = true;
1249
1250    // set input arguments in RPC descriptor
1251    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
1252    rpc.args[1] = (uint64_t)(intptr_t)name;
1253    rpc.args[2] = (uint64_t)child_inode_xp;
1254
1255    // register RPC request in remote RPC fifo
1256    rpc_send( cxy , &rpc );
1257
1258    // get output values from RPC descriptor
1259    *error   = (error_t)rpc.args[3];
1260
1261}
1262
1263///////////////////////////////////////////
1264void rpc_vfs_inode_load_server( xptr_t xp )
1265{
1266    error_t       error;
1267    vfs_inode_t * parent;
1268    xptr_t        child_xp;
1269    char        * name;
1270
1271    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1272
1273    // get client cluster identifier and pointer on RPC descriptor
1274    cxy_t        client_cxy  = GET_CXY( xp );
1275    rpc_desc_t * desc        = GET_PTR( xp );
1276
1277    // get arguments "parent", "name", and "child_xp"
1278    parent     = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
1279    name       = (char*)(intptr_t)       hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
1280    child_xp   = (xptr_t)                hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
1281
1282    // get name local copy
1283    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
1284                       XPTR( client_cxy , name ) );
1285
1286    // call the kernel function
1287    error = vfs_inode_load( parent , name_copy , child_xp );
1288
1289    // set output argument
1290    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1291
1292}
1293
1294/////////////////////////////////////////////////////////////////////////////////////////
1295// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL  (blocking)
1296/////////////////////////////////////////////////////////////////////////////////////////
1297
1298///////////////////////////////////////////////////////
1299void rpc_vfs_mapper_load_all_client( cxy_t         cxy,
1300                                     vfs_inode_t * inode,      // in
1301                                     error_t     * error )     // out
1302{
1303    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1304
1305    // initialise RPC descriptor header
1306    rpc_desc_t  rpc;
1307    rpc.index    = RPC_VFS_MAPPER_LOAD_ALL;
1308    rpc.response = 1;
1309    rpc.blocking = true;
1310
1311    // set input arguments in RPC descriptor
1312    rpc.args[0] = (uint64_t)(intptr_t)inode;
1313
1314    // register RPC request in remote RPC fifo
1315    rpc_send( cxy , &rpc );
1316
1317    // get output values from RPC descriptor
1318    *error   = (error_t)rpc.args[1];
1319
1320}
1321
1322////////////////////////////////////////////////
1323void rpc_vfs_mapper_load_all_server( xptr_t xp )
1324{
1325    error_t       error;
1326    vfs_inode_t * inode;
1327
1328    // get client cluster identifier and pointer on RPC descriptor
1329    cxy_t        client_cxy  = GET_CXY( xp );
1330    rpc_desc_t * desc        = GET_PTR( xp );
1331
1332    // get arguments "parent", "name", and "child_xp"
1333    inode = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
1334
1335    // call the kernel function
1336    error = vfs_mapper_load_all( inode );
1337
1338    // set output argument
1339    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1340
1341}
1342
1343/////////////////////////////////////////////////////////////////////////////////////////
1344// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  (blocking)
1345/////////////////////////////////////////////////////////////////////////////////////////
1346
1347//////////////////////////////////////////////////
1348void rpc_fatfs_get_cluster_client( cxy_t      cxy,
1349                                   mapper_t * mapper,    // in
1350                                   uint32_t   first,     // in
1351                                   uint32_t   index,     // in
1352                                   uint32_t * cluster,   // out
1353                                   error_t  * error )    // out
1354{
1355    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1356
1357    // initialise RPC descriptor header
1358    rpc_desc_t  rpc;
1359    rpc.index    = RPC_FATFS_GET_CLUSTER;
1360    rpc.response = 1;
1361    rpc.blocking = true;
1362
1363    // set input arguments in RPC descriptor
1364    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1365    rpc.args[1] = (uint64_t)first;
1366    rpc.args[2] = (uint64_t)index;
1367
1368    // register RPC request in remote RPC fifo
1369    rpc_send( cxy , &rpc );
1370
1371    // get output argument from rpc descriptor
1372    *cluster = (uint32_t)rpc.args[3];
1373    *error   = (error_t)rpc.args[4];
1374
1375}
1376
1377//////////////////////////////////////////////
1378void rpc_fatfs_get_cluster_server( xptr_t xp )
1379{
1380    mapper_t    * mapper;
1381    uint32_t      first;
1382    uint32_t      index;
1383    uint32_t      cluster;
1384    error_t       error;
1385
1386    // get client cluster identifier and pointer on RPC descriptor
1387    cxy_t        client_cxy  = GET_CXY( xp );
1388    rpc_desc_t * desc = GET_PTR( xp );
1389
1390    // get input arguments
1391    mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
1392    first  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
1393    index  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
1394
1395    // call the kernel function
1396    error = fatfs_get_cluster( mapper , first , index , &cluster );
1397
1398    // set output argument
1399    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster );
1400    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
1401
1402}
1403
1404/////////////////////////////////////////////////////////////////////////////////////////
1405// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
1406/////////////////////////////////////////////////////////////////////////////////////////
1407
1408//////////////////////////////////////////////////
1409void rpc_vmm_get_vseg_client( cxy_t       cxy,     
1410                              process_t * process,     // in 
1411                              intptr_t    vaddr,       // in 
1412                              xptr_t    * vseg_xp,     // out
1413                              error_t   * error )      // out
1414{
1415    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1416
1417    // initialise RPC descriptor header
1418    rpc_desc_t  rpc;
1419    rpc.index    = RPC_VMM_GET_VSEG;
1420    rpc.response = 1;
1421    rpc.blocking = true;
1422
1423    // set input arguments in RPC descriptor
1424    rpc.args[0] = (uint64_t)(intptr_t)process;
1425    rpc.args[1] = (uint64_t)vaddr;
1426
1427    // register RPC request in remote RPC fifo
1428    rpc_send( cxy , &rpc );
1429
1430    // get output argument from rpc descriptor
1431    *vseg_xp = rpc.args[2];
1432    *error   = (error_t)rpc.args[3];
1433
1434}
1435
1436/////////////////////////////////////////
1437void rpc_vmm_get_vseg_server( xptr_t xp )
1438{
1439    process_t   * process;
1440    intptr_t      vaddr;
1441    vseg_t      * vseg_ptr;
1442    xptr_t        vseg_xp;
1443    error_t       error;
1444
1445    // get client cluster identifier and pointer on RPC descriptor
1446    cxy_t        client_cxy  = GET_CXY( xp );
1447    rpc_desc_t * desc        = GET_PTR( xp );
1448
1449    // get input argument from client RPC descriptor
1450    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1451    vaddr   = (intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1452   
1453    // call local kernel function
1454    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
1455
1456    // set output arguments to client RPC descriptor
1457    vseg_xp = XPTR( local_cxy , vseg_ptr );
1458    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
1459    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1460
1461}
1462
1463
1464/////////////////////////////////////////////////////////////////////////////////////////
1465// [21]          Marshaling functions attached to RPC_VMM_GET_PTE  (blocking)
1466/////////////////////////////////////////////////////////////////////////////////////////
1467
1468////////////////////////////////////////////
1469void rpc_vmm_get_pte_client( cxy_t       cxy,   
1470                             process_t * process,  // in
1471                             vpn_t       vpn,      // in
1472                             bool_t      cow,      // in
1473                             uint32_t  * attr,     // out
1474                             ppn_t     * ppn,      // out
1475                             error_t   * error )   // out
1476{
1477    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1478
1479    // initialise RPC descriptor header
1480    rpc_desc_t  rpc;
1481    rpc.index    = RPC_VMM_GET_PTE;
1482    rpc.response = 1;
1483    rpc.blocking = true;
1484
1485    // set input arguments in RPC descriptor
1486    rpc.args[0] = (uint64_t)(intptr_t)process;
1487    rpc.args[1] = (uint64_t)vpn;
1488    rpc.args[2] = (uint64_t)cow;
1489
1490    // register RPC request in remote RPC fifo
1491    rpc_send( cxy , &rpc );
1492
1493    // get output argument from rpc descriptor
1494    *attr  = (uint32_t)rpc.args[3];
1495    *ppn   = (ppn_t)rpc.args[4];
1496    *error = (error_t)rpc.args[5];
1497
1498}
1499
1500////////////////////////////////////////
1501void rpc_vmm_get_pte_server( xptr_t xp )
1502{
1503    process_t   * process;
1504    vpn_t         vpn;
1505    bool_t        cow;
1506    uint32_t      attr;
1507    ppn_t         ppn;
1508    error_t       error;
1509
1510    // get client cluster identifier and pointer on RPC descriptor
1511    cxy_t        client_cxy  = GET_CXY( xp );
1512    rpc_desc_t * desc        = GET_PTR( xp );
1513
1514    // get input argument "process" & "vpn" from client RPC descriptor
1515    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1516    vpn     = (vpn_t)                hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1517    cow     = (bool_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
1518   
1519    // call local kernel function
1520    error = vmm_get_pte( process , vpn , cow , &attr , &ppn ); 
1521
1522    // set output argument "attr" & "ppn" to client RPC descriptor
1523    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)attr );
1524    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)ppn );
1525    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
1526
1527}
1528
1529/////////////////////////////////////////////////////////////////////////////////////////
1530// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
1531/////////////////////////////////////////////////////////////////////////////////////////
1532
1533//////////////////////////////////////////
1534void rpc_kcm_alloc_client( cxy_t      cxy,
1535                           uint32_t   kmem_type,   // in
1536                           xptr_t *   buf_xp )     // out
1537{
1538    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1539
1540    // initialise RPC descriptor header
1541    rpc_desc_t  rpc;
1542    rpc.index    = RPC_THREAD_USER_CREATE;
1543    rpc.response = 1;
1544    rpc.blocking = true;
1545
1546    // set input arguments in RPC descriptor
1547    rpc.args[0] = (uint64_t)kmem_type;
1548
1549    // register RPC request in remote RPC fifo
1550    rpc_send( cxy , &rpc );
1551
1552    // get output arguments from RPC descriptor
1553    *buf_xp = (xptr_t)rpc.args[1];
1554
1555}
1556
1557//////////////////////////////////////
1558void rpc_kcm_alloc_server( xptr_t xp )
1559{
1560    // get client cluster identifier and pointer on RPC descriptor
1561    cxy_t        client_cxy  = GET_CXY( xp );
1562    rpc_desc_t * desc = GET_PTR( xp );
1563
1564    // get input argument "kmem_type" from client RPC descriptor
1565    uint32_t kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1566
1567    // allocates memory for kcm
1568    kmem_req_t  req;
1569    req.type  = kmem_type;
1570    req.flags = AF_ZERO;
1571    void * buf_ptr = kmem_alloc( &req );
1572
1573    // set output argument
1574    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
1575    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
1576
1577}   
1578
1579/////////////////////////////////////////////////////////////////////////////////////////
1580// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
1581/////////////////////////////////////////////////////////////////////////////////////////
1582
1583/////////////////////////////////////////
1584void rpc_kcm_free_client( cxy_t      cxy,
1585                          void     * buf,          // in
1586                          uint32_t   kmem_type )   // in
1587{
1588    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1589
1590    // initialise RPC descriptor header
1591    rpc_desc_t  rpc;
1592    rpc.index    = RPC_THREAD_USER_CREATE;
1593    rpc.response = 1;
1594    rpc.blocking = true;
1595
1596    // set input arguments in RPC descriptor
1597    rpc.args[0] = (uint64_t)(intptr_t)buf;
1598    rpc.args[1] = (uint64_t)kmem_type;
1599
1600    // register RPC request in remote RPC fifo
1601    rpc_send( cxy , &rpc );
1602
1603}
1604
1605/////////////////////////////////////
1606void rpc_kcm_free_server( xptr_t xp )
1607{
1608    // get client cluster identifier and pointer on RPC descriptor
1609    cxy_t        client_cxy  = GET_CXY( xp );
1610    rpc_desc_t * desc = GET_PTR( xp );
1611
1612    // get input arguments "buf" and "kmem_type" from client RPC descriptor
1613    void     * buf = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1614    uint32_t   kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1615
1616    // releases memory
1617    kmem_req_t  req;
1618    req.type = kmem_type;
1619    req.ptr  = buf;
1620    kmem_free( &req );
1621
1622}   
1623
1624/////////////////////////////////////////////////////////////////////////////////////////
1625// [24]          Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER
1626/////////////////////////////////////////////////////////////////////////////////////////
1627
1628///////////////////////////////////////////////////
1629void rpc_mapper_move_buffer_client( cxy_t      cxy,
1630                                    mapper_t * mapper,        // in
1631                                    bool_t     to_buffer,     // in
1632                                    bool_t     is_user,       // in
1633                                    uint32_t   file_offset,   // in
1634                                    uint64_t   buffer,        // in
1635                                    uint32_t   size,          // in
1636                                    error_t  * error )        // out
1637{
1638    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1639
1640    // initialise RPC descriptor header
1641    rpc_desc_t  rpc;
1642    rpc.index    = RPC_MAPPER_MOVE_BUFFER;
1643    rpc.response = 1;
1644    rpc.blocking = true;
1645
1646    // set input arguments in RPC descriptor
1647    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1648    rpc.args[1] = (uint64_t)to_buffer;
1649    rpc.args[2] = (uint64_t)is_user;
1650    rpc.args[3] = (uint64_t)file_offset;
1651    rpc.args[4] = (uint64_t)buffer;
1652    rpc.args[5] = (uint64_t)size;
1653
1654    // register RPC request in remote RPC fifo
1655    rpc_send( cxy , &rpc );
1656
1657    // get output values from RPC descriptor
1658    *error     = (error_t)rpc.args[6];
1659
1660}
1661
1662///////////////////////////////////////////////
1663void rpc_mapper_move_buffer_server( xptr_t xp )
1664{
1665    mapper_t * mapper;
1666    bool_t     to_buffer;
1667    bool_t     is_user;
1668    uint32_t   file_offset;
1669    void     * user_buffer;
1670    xptr_t     kern_buffer;
1671    uint32_t   size;
1672    error_t    error;
1673
1674    // get client cluster identifier and pointer on RPC descriptor
1675    cxy_t        client_cxy  = GET_CXY( xp );
1676    rpc_desc_t * desc        = GET_PTR( xp );
1677
1678    // get arguments from client RPC descriptor
1679    mapper      = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1680    to_buffer   =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1681    is_user     =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
1682    file_offset =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
1683    size        =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
1684
1685    // call local kernel function
1686    if( is_user )
1687    {
1688        user_buffer = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
1689
1690        error = mapper_move_user( mapper,
1691                                  to_buffer,
1692                                  file_offset,
1693                                  user_buffer,
1694                                  size );
1695    }
1696    else
1697    {
1698        kern_buffer = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
1699
1700        error = mapper_move_kernel( mapper,
1701                                    to_buffer,
1702                                    file_offset,
1703                                    kern_buffer,
1704                                    size );
1705    }
1706
1707    // set output argument to client RPC descriptor
1708    hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
1709
1710}
1711
1712/////////////////////////////////////////////////////////////////////////////////////////
1713// [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking)
1714/////////////////////////////////////////////////////////////////////////////////////////
1715
1716///////////////////////////////////////////////////////
1717void rpc_mapper_get_page_client( cxy_t             cxy,
1718                                 struct mapper_s * mapper,     // in
1719                                 uint32_t          index,      // in
1720                                 page_t         ** page )      // out
1721{
1722    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1723
1724    // initialise RPC descriptor header
1725    rpc_desc_t  rpc;
1726    rpc.index    = RPC_MAPPER_GET_PAGE;
1727    rpc.response = 1;
1728    rpc.blocking = true;
1729
1730    // set input arguments in RPC descriptor
1731    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1732    rpc.args[1] = (uint64_t)index;
1733
1734    // register RPC request in remote RPC fifo
1735    rpc_send( cxy , &rpc );
1736
1737    // get output values from RPC descriptor
1738    *page = (page_t *)(intptr_t)rpc.args[2];
1739
1740}
1741
1742////////////////////////////////////////////
1743void rpc_mapper_get_page_server( xptr_t xp )
1744{
1745    // get client cluster identifier and pointer on RPC descriptor
1746    cxy_t        cxy  = GET_CXY( xp );
1747    rpc_desc_t * desc = GET_PTR( xp );
1748
1749    // get input arguments from client RPC descriptor
1750    mapper_t * mapper = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
1751    uint32_t   index  = (uint32_t)            hal_remote_lwd( XPTR( cxy , &desc->args[1] ) );
1752   
1753    // call local pmem allocator
1754    page_t * page = mapper_get_page( mapper , index ); 
1755
1756    // set output arguments into client RPC descriptor
1757    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
1758
1759}
1760
1761/////////////////////////////////////////////////////////////////////////////////////////
1762// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
1763/////////////////////////////////////////////////////////////////////////////////////////
1764
1765////////////////////////////////////////////////////////
1766void rpc_vmm_create_vseg_client( cxy_t              cxy,
1767                                 struct process_s * process,
1768                                 vseg_type_t        type,
1769                                 intptr_t           base,
1770                                 uint32_t           size,
1771                                 uint32_t           file_offset,
1772                                 uint32_t           file_size,
1773                                 xptr_t             mapper_xp,
1774                                 cxy_t              vseg_cxy,
1775                                 struct vseg_s   ** vseg )
1776{
1777    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1778
1779    // initialise RPC descriptor header
1780    rpc_desc_t  rpc;
1781    rpc.index    = RPC_VMM_CREATE_VSEG;
1782    rpc.response = 1;
1783    rpc.blocking = true;
1784
1785    // set input arguments in RPC descriptor
1786    rpc.args[0] = (uint64_t)(intptr_t)process;
1787    rpc.args[1] = (uint64_t)type;
1788    rpc.args[2] = (uint64_t)base;
1789    rpc.args[3] = (uint64_t)size;
1790    rpc.args[4] = (uint64_t)file_offset;
1791    rpc.args[5] = (uint64_t)file_size;
1792    rpc.args[6] = (uint64_t)mapper_xp;
1793    rpc.args[7] = (uint64_t)vseg_cxy;
1794
1795    // register RPC request in remote RPC fifo
1796    rpc_send( cxy , &rpc );
1797
1798    // get output values from RPC descriptor
1799    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
1800
1801}
1802
1803////////////////////////////////////////////
1804void rpc_vmm_create_vseg_server( xptr_t xp )
1805{
1806    // get client cluster identifier and pointer on RPC descriptor
1807    cxy_t        cxy  = GET_CXY( xp );
1808    rpc_desc_t * desc = GET_PTR( xp );
1809
1810    // get input arguments from client RPC descriptor
1811    process_t * process     = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
1812    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_lwd( XPTR(cxy , &desc->args[1]));
1813    intptr_t    base        = (intptr_t)             hal_remote_lwd( XPTR(cxy , &desc->args[2]));
1814    uint32_t    size        = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[3]));
1815    uint32_t    file_offset = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[4]));
1816    uint32_t    file_size   = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[5]));
1817    xptr_t      mapper_xp   = (xptr_t)               hal_remote_lwd( XPTR(cxy , &desc->args[6]));
1818    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_lwd( XPTR(cxy , &desc->args[7]));
1819   
1820    // call local kernel function
1821    vseg_t * vseg = vmm_create_vseg( process,
1822                                     type,
1823                                     base,
1824                                     size,
1825                                     file_offset,
1826                                     file_size,
1827                                     mapper_xp,
1828                                     vseg_cxy ); 
1829
1830    // set output arguments into client RPC descriptor
1831    hal_remote_swd( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
1832
1833}
1834
1835/////////////////////////////////////////////////////////////////////////////////////////
1836// [27]          Marshaling functions attached to RPC_SCHED_DISPLAY (blocking)
1837/////////////////////////////////////////////////////////////////////////////////////////
1838
1839////////////////////////////////////////////////////////
1840void rpc_sched_display_client( cxy_t              cxy,
1841                               lid_t              lid)
1842{
1843    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1844
1845    // initialise RPC descriptor header
1846    rpc_desc_t  rpc;
1847    rpc.index    = RPC_SCHED_DISPLAY;
1848    rpc.response = 1;
1849    rpc.blocking = true;
1850
1851    // set input arguments in RPC descriptor
1852    rpc.args[0] = (uint64_t)lid;
1853
1854    // register RPC request in remote RPC fifo
1855    rpc_send( cxy , &rpc );
1856
1857}
1858
1859//////////////////////////////////////////
1860void rpc_sched_display_server( xptr_t xp )
1861{
1862    // get client cluster identifier and pointer on RPC descriptor
1863    cxy_t        cxy  = GET_CXY( xp );
1864    rpc_desc_t * desc = GET_PTR( xp );
1865
1866    // get input arguments from client RPC descriptor
1867    lid_t lid = (lid_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
1868   
1869    // call local kernel function
1870    sched_display( lid );
1871
1872}
1873
1874/////////////////////////////////////////////////////////////////////////////////////////
1875// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
1876/////////////////////////////////////////////////////////////////////////////////////////
1877
1878/////////////////////////////////////////////
1879void rpc_vmm_set_cow_client( cxy_t       cxy,
1880                             process_t * process )
1881{
1882    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1883
1884    // initialise RPC descriptor header
1885    rpc_desc_t  rpc;
1886    rpc.index    = RPC_VMM_SET_COW;
1887    rpc.response = 1;
1888    rpc.blocking = true;
1889
1890    // set input arguments in RPC descriptor
1891    rpc.args[0] = (uint64_t)(intptr_t)process;
1892
1893    // register RPC request in remote RPC fifo
1894    rpc_send( cxy , &rpc );
1895
1896}
1897
1898////////////////////////////////////////
1899void rpc_vmm_set_cow_server( xptr_t xp )
1900{
1901    process_t * process;
1902
1903    // get client cluster identifier and pointer on RPC descriptor
1904    cxy_t        cxy  = GET_CXY( xp );
1905    rpc_desc_t * desc = GET_PTR( xp );
1906
1907    // get input arguments from client RPC descriptor
1908    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
1909   
1910    // call local kernel function
1911    vmm_set_cow( process );
1912
1913}
1914
1915/////////////////////////////////////////////////////////////////////////////////////////
1916// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
1917/////////////////////////////////////////////////////////////////////////////////////////
1918
1919/////////////////////////////////////////////
1920void rpc_vmm_display_client( cxy_t       cxy,
1921                             process_t * process,
1922                             bool_t      detailed )
1923{
1924    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1925
1926    // initialise RPC descriptor header
1927    rpc_desc_t  rpc;
1928    rpc.index    = RPC_VMM_DISPLAY;
1929    rpc.response = 1;
1930    rpc.blocking = true;
1931
1932    // set input arguments in RPC descriptor
1933    rpc.args[0] = (uint64_t)(intptr_t)process;
1934    rpc.args[1] = (uint64_t)detailed;
1935
1936    // register RPC request in remote RPC fifo
1937    rpc_send( cxy , &rpc );
1938
1939}
1940
1941////////////////////////////////////////
1942void rpc_vmm_display_server( xptr_t xp )
1943{
1944    process_t * process;
1945    bool_t      detailed;
1946
1947    // get client cluster identifier and pointer on RPC descriptor
1948    cxy_t        cxy  = GET_CXY( xp );
1949    rpc_desc_t * desc = GET_PTR( xp );
1950
1951    // get input arguments from client RPC descriptor
1952    process  = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
1953    detailed = (bool_t)               hal_remote_lwd( XPTR(cxy , &desc->args[1]));
1954   
1955    // call local kernel function
1956    vmm_display( process , detailed );
1957
1958}
1959
1960
Note: See TracBrowser for help on using the repository browser.