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

Last change on this file since 416 was 416, checked in by alain, 4 years ago

Improve sys_exec.

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