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

Last change on this file since 581 was 581, checked in by alain, 2 years ago

1) Improve the busylock debug infrastructure.
2) introduce a non-distributed, but portable implementation for the pthread_barrier.

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