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

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

Few bugs.

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