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

Last change on this file since 448 was 441, checked in by alain, 7 years ago

Fix a bug in rpc_vmm_get_pte_client() function (bad RPC index).

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