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
RevLine 
[1]1/*
[437]2 * rpc.c - RPC operations implementation.
[1]3 *
[437]4 * Author    Alain Greiner (2016,2017,2018)
[1]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
[14]24#include <kernel_config.h>
[1]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>
[5]34#include <chdev.h>
[1]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
[433]43
[1]44/////////////////////////////////////////////////////////////////////////////////////////
[433]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",                     \
[437]54__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
[433]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",                      \
[437]60__FUNCTION__ , CURRENT_THREAD , local_cxy, CURRENT_THREAD->core->lid , cycle );
[433]61
62#else
63
64#define RPC_DEBUG_ENTER
65
66#define RPC_DEBUG_EXIT
67
68#endif
69
70/////////////////////////////////////////////////////////////////////////////////////////
[1]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
[409]77    &rpc_pmem_release_pages_server,     // 1
[433]78    &rpc_undefined,                     // 2    unused slot
[409]79    &rpc_process_make_fork_server,      // 3
[433]80    &rpc_undefined,                     // 4    unused slot
[435]81    &rpc_undefined,                     // 5    unused slot
[409]82    &rpc_thread_user_create_server,     // 6
83    &rpc_thread_kernel_create_server,   // 7
[436]84    &rpc_undefined,                     // 8    unused slot       
[409]85    &rpc_process_sigaction_server,      // 9
[1]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 
[23]91    &rpc_vfs_file_create_server,        // 14
92    &rpc_vfs_file_destroy_server,       // 15
[238]93    &rpc_vfs_inode_load_server,         // 16
94    &rpc_vfs_mapper_load_all_server,    // 17
95    &rpc_fatfs_get_cluster_server,      // 18
[433]96    &rpc_undefined,                     // 19   unused slot
[1]97
[389]98    &rpc_vmm_get_vseg_server,           // 20
[1]99    &rpc_vmm_get_pte_server,            // 21
[23]100    &rpc_kcm_alloc_server,              // 22
101    &rpc_kcm_free_server,               // 23
[265]102    &rpc_mapper_move_buffer_server,     // 24
[313]103    &rpc_mapper_get_page_server,        // 25
[407]104    &rpc_vmm_create_vseg_server,        // 26
105    &rpc_sched_display_server,          // 27
[408]106    &rpc_vmm_set_cow_server,            // 28
[428]107    &rpc_vmm_display_server,            // 29
[1]108};
109
110//////////////////////////////////////////////
111void __attribute__((noinline)) rpc_undefined()
112{
[428]113        assert( false , __FUNCTION__ , "called in cluster %x", local_cxy );
[1]114}
115
[409]116/***************************************************************************************/
117/************ Generic functions supporting RPCs : client side **************************/
118/***************************************************************************************/
119
120///////////////////////////////////////
121void rpc_send( cxy_t        server_cxy, 
[416]122               rpc_desc_t * rpc )
[409]123{
[436]124    volatile error_t   full = 0;
125    thread_t         * this = CURRENT_THREAD;
126    core_t           * core = this->core;
[409]127
[436]128#if CONFIG_DEBUG_RPC_SEND
129uint32_t cycle = (uint32_t)hal_get_cycles();
130if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]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 );
[436]133#endif
[409]134
135    // register client thread pointer and core lid in RPC descriptor
[436]136    rpc->thread = this;
137    rpc->lid    = core->lid;
[409]138
139    // build an extended pointer on the RPC descriptor
140        xptr_t   desc_xp = XPTR( local_cxy , rpc );
141
[436]142    // get local pointer on rpc_fifo in remote cluster,
[409]143    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
144
[436]145        // post RPC in remote fifo / deschedule and retry if fifo full
[409]146    do
147    { 
[436]148        full = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), (uint64_t )desc_xp );
149            if ( full ) 
[409]150        {
151            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
152            __FUNCTION__ , local_cxy , server_cxy );
153
[436]154            // deschedule without blocking
155            sched_yield("RPC fifo full");
[409]156        }
157    }
[436]158    while( full );
[409]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
[416]165    // wait RPC completion before returning if blocking RPC
[409]166    // - busy waiting policy during kernel_init, or if threads cannot yield
167    // - block and deschedule in all other cases
[416]168    if ( rpc->blocking )
[409]169    {
170        if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
171        {
172
[436]173#if CONFIG_DEBUG_RPC_SEND
174cycle = (uint32_t)hal_get_cycles();
175if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]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 );
[436]178#endif
[409]179
180            while( rpc->response ) hal_fixed_delay( 100 );
181   
[436]182#if CONFIG_DEBUG_RPC_SEND
183cycle = (uint32_t)hal_get_cycles();
184if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]185printk("\n[DBG] %s : thread % in cluster %x resume / rpc[%d] / cycle %d\n",
186__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
[436]187#endif
[409]188        } 
[436]189        else                                                         // block & deschedule
[409]190        {
191
[436]192#if CONFIG_DEBUG_RPC_SEND
193cycle = (uint32_t)hal_get_cycles();
194if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]195printk("\n[DBG] %s : thread %x in cluster %x deschedule / rpc[%d] / cycle %d\n",
196__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index , cycle );
[436]197#endif
198            thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC );
199            sched_yield("blocked on RPC");
[409]200
[436]201#if CONFIG_DEBUG_RPC_SEND
202cycle = (uint32_t)hal_get_cycles();
203if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]204printk("\n[DBG] %s : thread % in cluster %x resume / rpcr[%d] / cycle %d\n",
205__FUNCTION__, CURRENT_THREAD, local_cxy, rpc->index, cycle );
[436]206#endif
[409]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    }
[436]215    else
216    {
217
218#if CONFIG_DEBUG_RPC_SEND
219cycle = (uint32_t)hal_get_cycles();
220if( CONFIG_DEBUG_RPC_SEND < cycle ) 
[437]221printk("\n[DBG] %s : non blocking rpc[%d] => thread %x return  / cycle %d\n",
[436]222__FUNCTION__, rpc->index, CURRENT_THREAD, cycle );
223#endif
224
225    }
[409]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
[436]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
[409]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
[436]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
[409]298            }
299        }
300    }
301
[436]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
[409]308
309    // interrupted thread deschedule always           
310        sched_yield("IPI received");
311
[436]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
[409]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
[416]336    bool_t       blocking;    // blocking RPC when true
[409]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        {
[436]353
354#if CONFIG_DEBUG_RPC_SERVER
355uint32_t cycle = (uint32_t)hal_get_cycles();
356if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]357printk("\n[DBG] %s : RPC thread %x in cluster %x takes RPC fifo ownership / cycle %d\n",
[436]358__FUNCTION__, this, local_cxy, cycle );
359#endif
[409]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
[436]377                    desc_cxy = GET_CXY( desc_xp );
378                    desc_ptr = GET_PTR( desc_xp );
[409]379
[437]380                        index    = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
381                    blocking = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->blocking ) );
[409]382
[436]383#if CONFIG_DEBUG_RPC_SERVER
384cycle = (uint32_t)hal_get_cycles();
385if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]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 );
[436]388#endif
[409]389                    // call the relevant server function
390                    rpc_server[index]( desc_xp );
391
[436]392#if CONFIG_DEBUG_RPC_SERVER
393cycle = (uint32_t)hal_get_cycles();
394if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]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 );
[436]397#endif
[416]398                    // increment handled RPCs counter
[409]399                        count++;
400
[416]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);
[409]406
[416]407                        // unblock client thread
[409]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
[416]428        }  // end if RPC fifo
429
[409]430        // sucide if too many RPC threads in cluster
431        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
432            {
433
[436]434#if CONFIG_DEBUG_RPC_SERVER
435uint32_t cycle = (uint32_t)hal_get_cycles();
436if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]437printk("\n[DBG] %s : RPC thread %x in cluster %x suicides / cycle %d\n",
[436]438__FUNCTION__, this, local_cxy, cycle );
439#endif
[409]440            // update RPC threads counter
441                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
442
443            // suicide
[436]444                thread_kill( XPTR( local_cxy , this ),
445                         true,                      // is_exit
446                         true );                    // is forced
[409]447            }
448
[436]449#if CONFIG_DEBUG_RPC_SERVER
450uint32_t cycle = (uint32_t)hal_get_cycles();
451if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]452printk("\n[DBG] %s : RPC thread %x in cluster %x deschedules / cycle %d\n",
[436]453__FUNCTION__, this, local_cxy, cycle );
454#endif
[409]455
456        // deschedule without blocking
457        sched_yield("RPC fifo empty or too much work");
458
[436]459#if CONFIG_DEBUG_RPC_SERVER
460cycle = (uint32_t)hal_get_cycles();
461if( CONFIG_DEBUG_RPC_SERVER < cycle ) 
[437]462printk("\n[DBG] %s : RPC thread %x in cluster %x resumes / cycle %d\n",
[436]463__FUNCTION__, this, local_cxy, cycle );
464#endif
[409]465
466        } // end external loop
467
468} // end rpc_thread_func()
469
470
[1]471/////////////////////////////////////////////////////////////////////////////////////////
[409]472// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
[1]473/////////////////////////////////////////////////////////////////////////////////////////
474
475///////////////////////////////////////////////
476void rpc_pmem_get_pages_client( cxy_t      cxy,
477                                uint32_t   order,      // in
[313]478                                page_t  ** page )      // out
[1]479{
[296]480
[238]481    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]482
483    // initialise RPC descriptor header
484    rpc_desc_t  rpc;
485    rpc.index    = RPC_PMEM_GET_PAGES;
486    rpc.response = 1;
[416]487    rpc.blocking = true;
[1]488
489    // set input arguments in RPC descriptor
490    rpc.args[0] = (uint64_t)order;
491
[436]492    // register RPC request in remote RPC fifo
[416]493    rpc_send( cxy , &rpc );
[1]494
[313]495    // get output arguments from RPC descriptor
[407]496    *page = (page_t *)(intptr_t)rpc.args[1];
[279]497
[1]498}
499
500///////////////////////////////////////////
501void rpc_pmem_get_pages_server( xptr_t xp )
502{
[296]503
[1]504    // get client cluster identifier and pointer on RPC descriptor
[436]505    cxy_t        cxy  = GET_CXY( xp );
506    rpc_desc_t * desc = GET_PTR( xp );
[1]507
508    // get input arguments from client RPC descriptor
[409]509    uint32_t order = (uint32_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
[1]510   
511    // call local pmem allocator
512    page_t * page = ppm_alloc_pages( order ); 
513
514    // set output arguments into client RPC descriptor
[313]515    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
[296]516
[1]517}
518
519/////////////////////////////////////////////////////////////////////////////////////////
[409]520// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking)
[1]521/////////////////////////////////////////////////////////////////////////////////////////
522
[409]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;
[416]534    rpc.blocking = true;
[409]535
536    // set input arguments in RPC descriptor
537    rpc.args[0] = (uint64_t)(intptr_t)page;
538
[436]539    // register RPC request in remote RPC fifo
[416]540    rpc_send( cxy , &rpc );
[409]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
[436]549    cxy_t        cxy  = GET_CXY( xp );
550    rpc_desc_t * desc = GET_PTR( xp );
[409]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/////////////////////////////////////////////////////////////////////////////////////////
[433]564// [2]      undefined slot
[409]565/////////////////////////////////////////////////////////////////////////////////////////
566
[1]567/////////////////////////////////////////////////////////////////////////////////////////
[409]568// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking)
[1]569/////////////////////////////////////////////////////////////////////////////////////////
570
[408]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
[1]578{
[238]579    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]580
581    // initialise RPC descriptor header
582    rpc_desc_t  rpc;
[408]583    rpc.index    = RPC_PROCESS_MAKE_FORK;
[1]584    rpc.response = 1;
[416]585    rpc.blocking = true;
[1]586
587    // set input arguments in RPC descriptor 
[408]588    rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp;
589    rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp;
[1]590
[436]591    // register RPC request in remote RPC fifo
[416]592    rpc_send( cxy , &rpc );
[1]593
594    // get output arguments from RPC descriptor
[408]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];     
[279]598
[1]599}
600
[408]601//////////////////////////////////////////////
602void rpc_process_make_fork_server( xptr_t xp )
[1]603{
[409]604
[408]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
[1]610
611    // get client cluster identifier and pointer on RPC descriptor
[436]612    cxy_t        client_cxy  = GET_CXY( xp );
613    rpc_desc_t * desc        = GET_PTR( xp );
[1]614
[408]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] ) );
[1]618
619    // call local kernel function
[408]620    error = process_make_fork( ref_process_xp,
621                               parent_thread_xp,
622                               &child_pid,
623                               &child_thread_ptr ); 
[1]624
625    // set output argument into client RPC descriptor
[408]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 );
[296]629
[1]630}
631
632/////////////////////////////////////////////////////////////////////////////////////////
[433]633// [4]      undefined slot
[1]634/////////////////////////////////////////////////////////////////////////////////////////
635
[409]636/////////////////////////////////////////////////////////////////////////////////////////
[435]637// [5]      undefined slot
[409]638/////////////////////////////////////////////////////////////////////////////////////////
639
[1]640/////////////////////////////////////////////////////////////////////////////////////////
[436]641// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 
[1]642/////////////////////////////////////////////////////////////////////////////////////////
643
644/////////////////////////////////////////////////////////
645void rpc_thread_user_create_client( cxy_t            cxy, 
[23]646                                    pid_t            pid,         // in
647                                    void           * start_func,  // in
648                                    void           * start_arg,   // in
[1]649                                    pthread_attr_t * attr,        // in
650                                    xptr_t         * thread_xp,   // out
651                                    error_t        * error )      // out
652{
[238]653    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]654
655    // initialise RPC descriptor header
656    rpc_desc_t  rpc;
[436]657    rpc.index    = RPC_THREAD_USER_CREATE;
658    rpc.response = 1;
[416]659    rpc.blocking = true;
[1]660
661    // set input arguments in RPC descriptor
[23]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;
[1]666
[436]667    // register RPC request in remote RPC fifo
[416]668    rpc_send( cxy , &rpc );
[1]669
670    // get output arguments from RPC descriptor
[23]671    *thread_xp = (xptr_t)rpc.args[4];
672    *error     = (error_t)rpc.args[5];
[279]673
[1]674}
675
676///////////////////////////////////////////////
677void rpc_thread_user_create_server( xptr_t xp )
678{
[409]679
[1]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
[23]684
[1]685    pid_t            pid;        // process identifier
[23]686    void           * start_func;
687    void           * start_arg;
688    error_t          error;
[1]689
690    // get client cluster identifier and pointer on RPC descriptor
[436]691    cxy_t        client_cxy  = GET_CXY( xp );
692    rpc_desc_t * desc = GET_PTR( xp );
[1]693
694    // get pointer on attributes structure in client cluster from RPC descriptor
695
[23]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
[1]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   
[23]707    // call kernel function
708    error = thread_user_create( pid,
709                                start_func,
710                                start_arg,
711                                &attr_copy,
712                                &thread_ptr );
[1]713
714    // set output arguments
715    thread_xp = XPTR( local_cxy , thread_ptr );
[407]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 );
[296]718
[1]719}
720
721/////////////////////////////////////////////////////////////////////////////////////////
[436]722// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
[1]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{
[238]733    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]734
735    // initialise RPC descriptor header
736    rpc_desc_t  rpc;
737    rpc.index    = RPC_THREAD_KERNEL_CREATE;
738    rpc.response = 1;
[416]739    rpc.blocking = true;
[1]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   
[436]746    // register RPC request in remote RPC fifo
[416]747    rpc_send( cxy , &rpc );
[1]748
749    // get output arguments from RPC descriptor
750    *thread_xp = (xptr_t)rpc.args[3];
751    *error     = (error_t)rpc.args[4];
[279]752
[1]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
[436]764    cxy_t        client_cxy  = GET_CXY( xp );
765    rpc_desc_t * desc = GET_PTR( xp );
[1]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 );
[296]782
[1]783}
784
785/////////////////////////////////////////////////////////////////////////////////////////
[436]786// [8]   undefined slot
[1]787/////////////////////////////////////////////////////////////////////////////////////////
788
[296]789
[23]790/////////////////////////////////////////////////////////////////////////////////////////
[415]791// [9] Marshaling functions attached to RPC_PROCESS_SIGACTION (multicast / non blocking)
[23]792/////////////////////////////////////////////////////////////////////////////////////////
793
[416]794////////////////////////////////////////////////////
795void rpc_process_sigaction_client( cxy_t        cxy,
[436]796                                   rpc_desc_t * rpc )
[409]797{
798
[436]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
[409]807
[436]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" );
[409]811
[436]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
[409]824//////////////////////////////////////////////
825void rpc_process_sigaction_server( xptr_t xp )
826{
[435]827    pid_t        pid;              // target process identifier
[436]828    process_t  * process;          // pointer on local target process descriptor
[416]829    uint32_t     action;           // sigaction index
[436]830    thread_t   * client_thread;    // pointer on client thread in client cluster
[416]831    cxy_t        client_cxy;       // client cluster identifier
[436]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
[409]835
836    // get client cluster identifier and pointer on RPC descriptor
[436]837    client_cxy = GET_CXY( xp );
838    rpc        = GET_PTR( xp );
[409]839
840    // get arguments from RPC descriptor
[436]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]) );
[409]843
[436]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
[435]850
851    // get local process descriptor
[436]852    process = cluster_get_local_process_from_pid( pid );
[435]853
[409]854    // call relevant kernel function
[436]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 );
[409]858
[436]859    // build extended pointer on response counter in RPC
860    count_xp = XPTR( client_cxy , &rpc->response );
861
[416]862    // decrement the responses counter in RPC descriptor,
863    // unblock the client thread only if it is the last response.
[436]864    if( hal_remote_atomic_add( count_xp , -1 ) == 1 ) 
[416]865    {
[436]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 );
[416]872    }
873
[436]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
[409]880
[436]881} // end rpc_process_sigaction_server()
882
[409]883/////////////////////////////////////////////////////////////////////////////////////////
[436]884// [10]     Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
[409]885/////////////////////////////////////////////////////////////////////////////////////////
886
[1]887/////////////////////////////////////////////////////
888void rpc_vfs_inode_create_client( cxy_t          cxy,     
889                                  xptr_t         dentry_xp,  // in
[23]890                                  uint32_t       fs_type,    // in
891                                  uint32_t       inode_type, // in
[188]892                                  void         * extend,     // in
[1]893                                  uint32_t       attr,       // in
[23]894                                  uint32_t       rights,     // in
[1]895                                  uint32_t       uid,        // in
896                                  uint32_t       gid,        // in
897                                  xptr_t       * inode_xp,   // out
898                                  error_t      * error )     // out
899{
[238]900    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]901
902    // initialise RPC descriptor header
903    rpc_desc_t  rpc;
904    rpc.index    = RPC_VFS_INODE_CREATE;
905    rpc.response = 1;
[416]906    rpc.blocking = true;
[1]907
908    // set input arguments in RPC descriptor
909    rpc.args[0] = (uint64_t)dentry_xp;
[23]910    rpc.args[1] = (uint64_t)fs_type;
911    rpc.args[2] = (uint64_t)inode_type;
[188]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;
[1]917
[436]918    // register RPC request in remote RPC fifo
[416]919    rpc_send( cxy , &rpc );
[1]920
921    // get output values from RPC descriptor
[188]922    *inode_xp = (xptr_t)rpc.args[8];
923    *error    = (error_t)rpc.args[9];
[279]924
[1]925}
926
927/////////////////////////////////////////////
928void rpc_vfs_inode_create_server( xptr_t xp )
929{
930    xptr_t           dentry_xp;
[23]931    uint32_t         fs_type;
932    uint32_t         inode_type;
[188]933    void           * extend;
[1]934    uint32_t         attr;
[23]935    uint32_t         rights;
[1]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
[436]942    cxy_t        client_cxy  = GET_CXY( xp );
943    rpc_desc_t * desc        = GET_PTR( xp );
[1]944
945    // get input arguments from client rpc descriptor
[188]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] ) );
[1]954
955    // call local kernel function
956    error = vfs_inode_create( dentry_xp,
[23]957                              fs_type,
958                              inode_type,
[188]959                              extend,
[1]960                              attr,
[23]961                              rights,
[1]962                              uid,
963                              gid,
964                              &inode_xp );
965
966    // set output arguments
[188]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 );
[296]969
[1]970}
971
972/////////////////////////////////////////////////////////////////////////////////////////
[409]973// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
[1]974/////////////////////////////////////////////////////////////////////////////////////////
975
976/////////////////////////////////////////////////////////////
977void rpc_vfs_inode_destroy_client( cxy_t                cxy,
978                                   struct vfs_inode_s * inode )
979{
[238]980    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]981
982    // initialise RPC descriptor header
983    rpc_desc_t  rpc;
984    rpc.index    = RPC_VFS_INODE_DESTROY;
985    rpc.response = 1;
[416]986    rpc.blocking = true;
[1]987
988    // set input arguments in RPC descriptor
989    rpc.args[0] = (uint64_t)(intptr_t)inode;
990   
[436]991    // register RPC request in remote RPC fifo
[416]992    rpc_send( cxy , &rpc );
[279]993
[1]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
[436]1002    cxy_t        client_cxy  = GET_CXY( xp );
1003    rpc_desc_t * desc        = GET_PTR( xp );
[1]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 );
[296]1010
[1]1011}
1012
1013/////////////////////////////////////////////////////////////////////////////////////////
[409]1014// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
[1]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{
[437]1025    RPC_DEBUG_ENTER
[296]1026
[238]1027    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1028
1029    // initialise RPC descriptor header
1030    rpc_desc_t  rpc;
1031    rpc.index    = RPC_VFS_DENTRY_CREATE;
1032    rpc.response = 1;
[416]1033    rpc.blocking = true;
[1]1034
1035    // set input arguments in RPC descriptor
1036    rpc.args[0] = (uint64_t)type;
1037    rpc.args[1] = (uint64_t)(intptr_t)name;
[238]1038    rpc.args[2] = (uint64_t)(intptr_t)parent;
[1]1039
[436]1040    // register RPC request in remote RPC fifo
[416]1041    rpc_send( cxy , &rpc );
[1]1042
1043    // get output values from RPC descriptor
[238]1044    *dentry_xp = (xptr_t)rpc.args[3];
1045    *error     = (error_t)rpc.args[4];
[279]1046
[437]1047    RPC_DEBUG_EXIT
[1]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
[437]1059    RPC_DEBUG_ENTER
1060
[238]1061    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1062
[1]1063    // get client cluster identifier and pointer on RPC descriptor
[436]1064    cxy_t        client_cxy  = GET_CXY( xp );
1065    rpc_desc_t * desc        = GET_PTR( xp );
[1]1066
[238]1067    // get arguments "name", "type", and "parent" from client RPC descriptor
[1]1068    type   = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
[238]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] ) );
[296]1071
[238]1072    // makes a local copy of  name
1073    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1074                       XPTR( client_cxy , name ) );
1075
[1]1076    // call local kernel function
1077    error = vfs_dentry_create( type,
1078                               name_copy,
1079                               parent,
1080                               &dentry_xp );
1081    // set output arguments
[238]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 );
[296]1084
[437]1085    RPC_DEBUG_EXIT
[1]1086}
1087
1088/////////////////////////////////////////////////////////////////////////////////////////
[409]1089// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
[1]1090/////////////////////////////////////////////////////////////////////////////////////////
1091
[296]1092
[1]1093///////////////////////////////////////////////////////
1094void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1095                                    vfs_dentry_t * dentry )
1096{
[238]1097    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1098
1099    // initialise RPC descriptor header
1100    rpc_desc_t  rpc;
1101    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1102    rpc.response = 1;
[416]1103    rpc.blocking = true;
[1]1104
1105    // set input arguments in RPC descriptor
1106    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1107   
[436]1108    // register RPC request in remote RPC fifo
[416]1109    rpc_send( cxy , &rpc );
[279]1110
[1]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
[436]1119    cxy_t        client_cxy  = GET_CXY( xp );
1120    rpc_desc_t * desc        = GET_PTR( xp );
[1]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 );
[296]1127
[1]1128}
1129
1130
1131/////////////////////////////////////////////////////////////////////////////////////////
[409]1132// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
[1]1133/////////////////////////////////////////////////////////////////////////////////////////
1134
[23]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{
[238]1142    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1143
1144    // initialise RPC descriptor header
1145    rpc_desc_t  rpc;
1146    rpc.index    = RPC_VFS_FILE_CREATE;
1147    rpc.response = 1;
[416]1148    rpc.blocking = true;
[23]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
[436]1154    // register RPC request in remote RPC fifo
[416]1155    rpc_send( cxy , &rpc );
[23]1156
1157    // get output values from RPC descriptor
1158    *file_xp = (xptr_t)rpc.args[2];
1159    *error   = (error_t)rpc.args[3];
[279]1160
[23]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
[436]1172    cxy_t        client_cxy  = GET_CXY( xp );
1173    rpc_desc_t * desc        = GET_PTR( xp );
[23]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 );
[296]1187
[23]1188}
1189
1190/////////////////////////////////////////////////////////////////////////////////////////
[409]1191// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
[23]1192/////////////////////////////////////////////////////////////////////////////////////////
1193
1194///////////////////////////////////////////////////
1195void rpc_vfs_file_destroy_client( cxy_t        cxy,
1196                                  vfs_file_t * file )
1197{
[238]1198    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1199
1200    // initialise RPC descriptor header
1201    rpc_desc_t  rpc;
1202    rpc.index    = RPC_VFS_FILE_DESTROY;
1203    rpc.response = 1;
[416]1204    rpc.blocking = true;
[23]1205
1206    // set input arguments in RPC descriptor
1207    rpc.args[0] = (uint64_t)(intptr_t)file;
1208   
[436]1209    // register RPC request in remote RPC fifo
[416]1210    rpc_send( cxy , &rpc );
[279]1211
[23]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
[436]1220    cxy_t        client_cxy  = GET_CXY( xp );
1221    rpc_desc_t * desc        = GET_PTR( xp );
[23]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 );
[296]1228
[23]1229}
1230
1231/////////////////////////////////////////////////////////////////////////////////////////
[409]1232// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   (blocking)
[23]1233/////////////////////////////////////////////////////////////////////////////////////////
1234
[1]1235//////////////////////////////////////////////////
[238]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;
[416]1248    rpc.blocking = true;
[238]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
[436]1255    // register RPC request in remote RPC fifo
[416]1256    rpc_send( cxy , &rpc );
[238]1257
1258    // get output values from RPC descriptor
1259    *error   = (error_t)rpc.args[3];
[279]1260
[238]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
[436]1274    cxy_t        client_cxy  = GET_CXY( xp );
1275    rpc_desc_t * desc        = GET_PTR( xp );
[238]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 );
[296]1291
[238]1292}
1293
1294/////////////////////////////////////////////////////////////////////////////////////////
[409]1295// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL  (blocking)
[238]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;
[389]1307    rpc.index    = RPC_VFS_MAPPER_LOAD_ALL;
[238]1308    rpc.response = 1;
[416]1309    rpc.blocking = true;
[238]1310
1311    // set input arguments in RPC descriptor
1312    rpc.args[0] = (uint64_t)(intptr_t)inode;
1313
[436]1314    // register RPC request in remote RPC fifo
[416]1315    rpc_send( cxy , &rpc );
[238]1316
1317    // get output values from RPC descriptor
1318    *error   = (error_t)rpc.args[1];
[279]1319
[238]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
[436]1329    cxy_t        client_cxy  = GET_CXY( xp );
1330    rpc_desc_t * desc        = GET_PTR( xp );
[238]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
[389]1339    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
[296]1340
[238]1341}
1342
1343/////////////////////////////////////////////////////////////////////////////////////////
[409]1344// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  (blocking)
[238]1345/////////////////////////////////////////////////////////////////////////////////////////
1346
1347//////////////////////////////////////////////////
[23]1348void rpc_fatfs_get_cluster_client( cxy_t      cxy,
1349                                   mapper_t * mapper,    // in
1350                                   uint32_t   first,     // in
[407]1351                                   uint32_t   index,     // in
[23]1352                                   uint32_t * cluster,   // out
1353                                   error_t  * error )    // out
1354{
[238]1355    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1356
1357    // initialise RPC descriptor header
1358    rpc_desc_t  rpc;
1359    rpc.index    = RPC_FATFS_GET_CLUSTER;
1360    rpc.response = 1;
[416]1361    rpc.blocking = true;
[23]1362
1363    // set input arguments in RPC descriptor
1364    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1365    rpc.args[1] = (uint64_t)first;
[407]1366    rpc.args[2] = (uint64_t)index;
[23]1367
1368    // register RPC request in remote RPC fifo
[416]1369    rpc_send( cxy , &rpc );
[23]1370
1371    // get output argument from rpc descriptor
1372    *cluster = (uint32_t)rpc.args[3];
1373    *error   = (error_t)rpc.args[4];
[279]1374
[23]1375}
1376
1377//////////////////////////////////////////////
1378void rpc_fatfs_get_cluster_server( xptr_t xp )
1379{
1380    mapper_t    * mapper;
1381    uint32_t      first;
[407]1382    uint32_t      index;
[23]1383    uint32_t      cluster;
1384    error_t       error;
1385
1386    // get client cluster identifier and pointer on RPC descriptor
[436]1387    cxy_t        client_cxy  = GET_CXY( xp );
1388    rpc_desc_t * desc = GET_PTR( xp );
[23]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] ) );
[407]1393    index  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
[23]1394
1395    // call the kernel function
[407]1396    error = fatfs_get_cluster( mapper , first , index , &cluster );
[23]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 );
[296]1401
[23]1402}
1403
1404/////////////////////////////////////////////////////////////////////////////////////////
[409]1405// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
[23]1406/////////////////////////////////////////////////////////////////////////////////////////
1407
1408//////////////////////////////////////////////////
[389]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
[1]1414{
[238]1415    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1416
1417    // initialise RPC descriptor header
1418    rpc_desc_t  rpc;
[389]1419    rpc.index    = RPC_VMM_GET_VSEG;
[1]1420    rpc.response = 1;
[416]1421    rpc.blocking = true;
[1]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
[436]1427    // register RPC request in remote RPC fifo
[416]1428    rpc_send( cxy , &rpc );
[1]1429
1430    // get output argument from rpc descriptor
1431    *vseg_xp = rpc.args[2];
[389]1432    *error   = (error_t)rpc.args[3];
[279]1433
[1]1434}
1435
[389]1436/////////////////////////////////////////
1437void rpc_vmm_get_vseg_server( xptr_t xp )
[1]1438{
1439    process_t   * process;
1440    intptr_t      vaddr;
1441    vseg_t      * vseg_ptr;
1442    xptr_t        vseg_xp;
[389]1443    error_t       error;
[1]1444
1445    // get client cluster identifier and pointer on RPC descriptor
[436]1446    cxy_t        client_cxy  = GET_CXY( xp );
1447    rpc_desc_t * desc        = GET_PTR( xp );
[1]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
[389]1454    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
[1]1455
[389]1456    // set output arguments to client RPC descriptor
1457    vseg_xp = XPTR( local_cxy , vseg_ptr );
[1]1458    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
[389]1459    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1460
[1]1461}
1462
1463
1464/////////////////////////////////////////////////////////////////////////////////////////
[409]1465// [21]          Marshaling functions attached to RPC_VMM_GET_PTE  (blocking)
[1]1466/////////////////////////////////////////////////////////////////////////////////////////
1467
1468////////////////////////////////////////////
1469void rpc_vmm_get_pte_client( cxy_t       cxy,   
1470                             process_t * process,  // in
1471                             vpn_t       vpn,      // in
[407]1472                             bool_t      cow,      // in
[1]1473                             uint32_t  * attr,     // out
1474                             ppn_t     * ppn,      // out
1475                             error_t   * error )   // out
1476{
[238]1477    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1478
1479    // initialise RPC descriptor header
1480    rpc_desc_t  rpc;
1481    rpc.index    = RPC_VMM_GET_PTE;
1482    rpc.response = 1;
[416]1483    rpc.blocking = true;
[1]1484
1485    // set input arguments in RPC descriptor
1486    rpc.args[0] = (uint64_t)(intptr_t)process;
1487    rpc.args[1] = (uint64_t)vpn;
[407]1488    rpc.args[2] = (uint64_t)cow;
[1]1489
[436]1490    // register RPC request in remote RPC fifo
[416]1491    rpc_send( cxy , &rpc );
[1]1492
1493    // get output argument from rpc descriptor
[407]1494    *attr  = (uint32_t)rpc.args[3];
1495    *ppn   = (ppn_t)rpc.args[4];
1496    *error = (error_t)rpc.args[5];
[279]1497
[1]1498}
1499
1500////////////////////////////////////////
1501void rpc_vmm_get_pte_server( xptr_t xp )
1502{
1503    process_t   * process;
1504    vpn_t         vpn;
[407]1505    bool_t        cow;
[1]1506    uint32_t      attr;
1507    ppn_t         ppn;
1508    error_t       error;
1509
1510    // get client cluster identifier and pointer on RPC descriptor
[436]1511    cxy_t        client_cxy  = GET_CXY( xp );
1512    rpc_desc_t * desc        = GET_PTR( xp );
[1]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] ) );
[407]1517    cow     = (bool_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
[1]1518   
1519    // call local kernel function
[407]1520    error = vmm_get_pte( process , vpn , cow , &attr , &ppn ); 
[1]1521
1522    // set output argument "attr" & "ppn" to client RPC descriptor
[407]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 );
[296]1526
[1]1527}
1528
1529/////////////////////////////////////////////////////////////////////////////////////////
[409]1530// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
[1]1531/////////////////////////////////////////////////////////////////////////////////////////
1532
[23]1533//////////////////////////////////////////
1534void rpc_kcm_alloc_client( cxy_t      cxy,
1535                           uint32_t   kmem_type,   // in
1536                           xptr_t *   buf_xp )     // out
[1]1537{
[238]1538    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1539
1540    // initialise RPC descriptor header
1541    rpc_desc_t  rpc;
1542    rpc.index    = RPC_THREAD_USER_CREATE;
1543    rpc.response = 1;
[416]1544    rpc.blocking = true;
[1]1545
[23]1546    // set input arguments in RPC descriptor
1547    rpc.args[0] = (uint64_t)kmem_type;
1548
[436]1549    // register RPC request in remote RPC fifo
[416]1550    rpc_send( cxy , &rpc );
[1]1551
1552    // get output arguments from RPC descriptor
[23]1553    *buf_xp = (xptr_t)rpc.args[1];
[279]1554
[1]1555}
1556
[23]1557//////////////////////////////////////
1558void rpc_kcm_alloc_server( xptr_t xp )
[1]1559{
1560    // get client cluster identifier and pointer on RPC descriptor
[436]1561    cxy_t        client_cxy  = GET_CXY( xp );
1562    rpc_desc_t * desc = GET_PTR( xp );
[1]1563
[23]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
[1]1568    kmem_req_t  req;
[23]1569    req.type  = kmem_type;
[1]1570    req.flags = AF_ZERO;
[23]1571    void * buf_ptr = kmem_alloc( &req );
[1]1572
1573    // set output argument
[23]1574    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
1575    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
[296]1576
[1]1577}   
1578
1579/////////////////////////////////////////////////////////////////////////////////////////
[409]1580// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
[1]1581/////////////////////////////////////////////////////////////////////////////////////////
1582
[23]1583/////////////////////////////////////////
1584void rpc_kcm_free_client( cxy_t      cxy,
1585                          void     * buf,          // in
1586                          uint32_t   kmem_type )   // in
[1]1587{
[238]1588    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1589
1590    // initialise RPC descriptor header
1591    rpc_desc_t  rpc;
1592    rpc.index    = RPC_THREAD_USER_CREATE;
1593    rpc.response = 1;
[416]1594    rpc.blocking = true;
[1]1595
1596    // set input arguments in RPC descriptor
[23]1597    rpc.args[0] = (uint64_t)(intptr_t)buf;
1598    rpc.args[1] = (uint64_t)kmem_type;
[1]1599
[436]1600    // register RPC request in remote RPC fifo
[416]1601    rpc_send( cxy , &rpc );
[279]1602
[1]1603}
1604
[23]1605/////////////////////////////////////
1606void rpc_kcm_free_server( xptr_t xp )
[1]1607{
1608    // get client cluster identifier and pointer on RPC descriptor
[436]1609    cxy_t        client_cxy  = GET_CXY( xp );
1610    rpc_desc_t * desc = GET_PTR( xp );
[1]1611
[23]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] ) );
[1]1615
1616    // releases memory
1617    kmem_req_t  req;
[23]1618    req.type = kmem_type;
1619    req.ptr  = buf;
1620    kmem_free( &req );
[296]1621
[1]1622}   
1623
1624/////////////////////////////////////////////////////////////////////////////////////////
[265]1625// [24]          Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER
[1]1626/////////////////////////////////////////////////////////////////////////////////////////
1627
[265]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
[313]1634                                    uint64_t   buffer,        // in
[265]1635                                    uint32_t   size,          // in
1636                                    error_t  * error )        // out
[1]1637{
[238]1638    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1639
1640    // initialise RPC descriptor header
1641    rpc_desc_t  rpc;
[265]1642    rpc.index    = RPC_MAPPER_MOVE_BUFFER;
[1]1643    rpc.response = 1;
[416]1644    rpc.blocking = true;
[1]1645
1646    // set input arguments in RPC descriptor
1647    rpc.args[0] = (uint64_t)(intptr_t)mapper;
[23]1648    rpc.args[1] = (uint64_t)to_buffer;
[265]1649    rpc.args[2] = (uint64_t)is_user;
1650    rpc.args[3] = (uint64_t)file_offset;
[313]1651    rpc.args[4] = (uint64_t)buffer;
[265]1652    rpc.args[5] = (uint64_t)size;
[1]1653
[436]1654    // register RPC request in remote RPC fifo
[416]1655    rpc_send( cxy , &rpc );
[1]1656
[23]1657    // get output values from RPC descriptor
[265]1658    *error     = (error_t)rpc.args[6];
[279]1659
[1]1660}
1661
[265]1662///////////////////////////////////////////////
1663void rpc_mapper_move_buffer_server( xptr_t xp )
[1]1664{
[23]1665    mapper_t * mapper;
[265]1666    bool_t     to_buffer;
1667    bool_t     is_user;
[23]1668    uint32_t   file_offset;
[313]1669    void     * user_buffer;
1670    xptr_t     kern_buffer;
[23]1671    uint32_t   size;
1672    error_t    error;
[1]1673
1674    // get client cluster identifier and pointer on RPC descriptor
[436]1675    cxy_t        client_cxy  = GET_CXY( xp );
1676    rpc_desc_t * desc        = GET_PTR( xp );
[1]1677
[23]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] ) );
[265]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] ) );
[1]1684
[23]1685    // call local kernel function
[313]1686    if( is_user )
1687    {
1688        user_buffer = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
[1]1689
[315]1690        error = mapper_move_user( mapper,
1691                                  to_buffer,
1692                                  file_offset,
1693                                  user_buffer,
1694                                  size );
[313]1695    }
1696    else
1697    {
1698        kern_buffer = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
1699
[315]1700        error = mapper_move_kernel( mapper,
1701                                    to_buffer,
1702                                    file_offset,
1703                                    kern_buffer,
1704                                    size );
[313]1705    }
1706
[23]1707    // set output argument to client RPC descriptor
[265]1708    hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
[296]1709
[1]1710}
1711
[313]1712/////////////////////////////////////////////////////////////////////////////////////////
[409]1713// [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking)
[313]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;
[416]1728    rpc.blocking = true;
[313]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
[436]1734    // register RPC request in remote RPC fifo
[416]1735    rpc_send( cxy , &rpc );
[313]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
[436]1746    cxy_t        cxy  = GET_CXY( xp );
1747    rpc_desc_t * desc = GET_PTR( xp );
[313]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
[407]1761/////////////////////////////////////////////////////////////////////////////////////////
[409]1762// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
[407]1763/////////////////////////////////////////////////////////////////////////////////////////
[313]1764
[407]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;
[416]1783    rpc.blocking = true;
[407]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
[436]1795    // register RPC request in remote RPC fifo
[416]1796    rpc_send( cxy , &rpc );
[407]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
[436]1807    cxy_t        cxy  = GET_CXY( xp );
1808    rpc_desc_t * desc = GET_PTR( xp );
[407]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/////////////////////////////////////////////////////////////////////////////////////////
[409]1836// [27]          Marshaling functions attached to RPC_SCHED_DISPLAY (blocking)
[407]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;
[416]1849    rpc.blocking = true;
[407]1850
1851    // set input arguments in RPC descriptor
1852    rpc.args[0] = (uint64_t)lid;
1853
[436]1854    // register RPC request in remote RPC fifo
[416]1855    rpc_send( cxy , &rpc );
[407]1856
1857}
1858
1859//////////////////////////////////////////
1860void rpc_sched_display_server( xptr_t xp )
1861{
1862    // get client cluster identifier and pointer on RPC descriptor
[436]1863    cxy_t        cxy  = GET_CXY( xp );
1864    rpc_desc_t * desc = GET_PTR( xp );
[407]1865
1866    // get input arguments from client RPC descriptor
[428]1867    lid_t lid = (lid_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
[407]1868   
1869    // call local kernel function
1870    sched_display( lid );
1871
1872}
1873
[408]1874/////////////////////////////////////////////////////////////////////////////////////////
[409]1875// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
[408]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;
[416]1888    rpc.blocking = true;
[408]1889
1890    // set input arguments in RPC descriptor
1891    rpc.args[0] = (uint64_t)(intptr_t)process;
1892
[436]1893    // register RPC request in remote RPC fifo
[416]1894    rpc_send( cxy , &rpc );
[408]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
[436]1904    cxy_t        cxy  = GET_CXY( xp );
1905    rpc_desc_t * desc = GET_PTR( xp );
[408]1906
1907    // get input arguments from client RPC descriptor
[428]1908    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
[408]1909   
1910    // call local kernel function
1911    vmm_set_cow( process );
1912
1913}
1914
[428]1915/////////////////////////////////////////////////////////////////////////////////////////
1916// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
1917/////////////////////////////////////////////////////////////////////////////////////////
[1]1918
[428]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
[436]1936    // register RPC request in remote RPC fifo
[428]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
[436]1948    cxy_t        cxy  = GET_CXY( xp );
1949    rpc_desc_t * desc = GET_PTR( xp );
[428]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.