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

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

blip

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