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

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

Fix a bad bug in scheduler...

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