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

Last change on this file since 498 was 492, checked in by viala@…, 6 years ago

Refactoring assert calling to conform with new assert macro.

Made with this command for the general case.
find ./kernel/ hal/ -name "*.c" | xargs sed -i -e '/assert(/ s/,[ ]*FUNCTION[ ]*,/,/'

And some done by hand.

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