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

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

1) improve the threads and process destruction mechanism.
2) introduce FIFOs in the soclib_tty driver.

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