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

Last change on this file since 629 was 629, checked in by alain, 3 years ago

Remove the "giant" rwlock protecting the GPT, and
use the GPT_LOCKED attribute in each PTE to prevent
concurrent modifications of one GPT entry.
The version number has been incremented to 2.1.

File size: 102.5 KB
Line 
1/*
2 * rpc.c - RPC operations implementation.
3 *
4 * Author    Alain Greiner (2016,2017,2018,2019)
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_vmm.h>
27#include <hal_atomic.h>
28#include <hal_remote.h>
29#include <hal_irqmask.h>
30#include <hal_special.h>
31#include <printk.h>
32#include <user_dir.h>
33#include <remote_sem.h>
34#include <core.h>
35#include <mapper.h>
36#include <chdev.h>
37#include <bits.h>
38#include <thread.h>
39#include <cluster.h>
40#include <process.h>
41#include <vfs.h>
42#include <fatfs.h>
43#include <rpc.h>
44
45
46/////////////////////////////////////////////////////////////////////////////////////////
47// Array of function pointers and array of printable strings.
48// These arrays must be kept consistent with enum in rpc.h file.
49/////////////////////////////////////////////////////////////////////////////////////////
50
51rpc_server_t * rpc_server[RPC_MAX_INDEX] =
52{
53    &rpc_pmem_get_pages_server,            // 0
54    &rpc_pmem_release_pages_server,        // 1
55    &rpc_ppm_display_server,               // 2
56    &rpc_process_make_fork_server,         // 3
57    &rpc_user_dir_create_server,           // 4
58    &rpc_user_dir_destroy_server,          // 5
59    &rpc_thread_user_create_server,        // 6
60    &rpc_thread_kernel_create_server,      // 7
61    &rpc_vfs_fs_update_dentry_server,      // 8
62    &rpc_process_sigaction_server,         // 9
63
64    &rpc_vfs_inode_create_server,          // 10 
65    &rpc_vfs_inode_destroy_server,         // 11 
66    &rpc_vfs_dentry_create_server,         // 12 
67    &rpc_vfs_dentry_destroy_server,        // 13 
68    &rpc_vfs_file_create_server,           // 14
69    &rpc_vfs_file_destroy_server,          // 15
70    &rpc_vfs_fs_new_dentry_server,         // 16
71    &rpc_vfs_fs_add_dentry_server,         // 17
72    &rpc_vfs_fs_remove_dentry_server,      // 18
73    &rpc_vfs_inode_load_all_pages_server,  // 19
74
75    &rpc_vmm_get_vseg_server,              // 20
76    &rpc_vmm_global_update_pte_server,     // 21
77    &rpc_kcm_alloc_server,                 // 22
78    &rpc_kcm_free_server,                  // 23
79    &rpc_mapper_sync_server,               // 24
80    &rpc_mapper_handle_miss_server,        // 25
81    &rpc_vmm_delete_vseg_server,           // 26
82    &rpc_vmm_create_vseg_server,           // 27
83    &rpc_vmm_set_cow_server,               // 28
84    &rpc_hal_vmm_display_server,           // 29
85};
86
87char * rpc_str[RPC_MAX_INDEX] =
88{
89    "PMEM_GET_PAGES",            // 0
90    "PMEM_RELEASE_PAGES",        // 1
91    "PPM_DISPLAY",               // 2
92    "PROCESS_MAKE_FORK",         // 3
93    "USER_DIR_CREATE",           // 4
94    "USER_DIR_DESTROY",          // 5
95    "THREAD_USER_CREATE",        // 6
96    "THREAD_KERNEL_CREATE",      // 7
97    "VFS_FS_UPDATE_DENTRY",      // 8
98    "PROCESS_SIGACTION",         // 9
99
100    "VFS_INODE_CREATE",          // 10
101    "VFS_INODE_DESTROY",         // 11
102    "VFS_DENTRY_CREATE",         // 12
103    "VFS_DENTRY_DESTROY",        // 13
104    "VFS_FILE_CREATE",           // 14
105    "VFS_FILE_DESTROY",          // 15
106    "VFS_FS_NEW_DENTRY",         // 16
107    "VFS_FS_ADD_DENTRY",         // 17
108    "VFS_FS_REMOVE_DENTRY",      // 18
109    "VFS_INODE_LOAD_ALL_PAGES",  // 19
110
111    "GET_VSEG",                  // 20
112    "GLOBAL_UPDATE_PTE",         // 21
113    "KCM_ALLOC",                 // 22
114    "KCM_FREE",                  // 23
115    "MAPPER_SYNC",               // 24
116    "MAPPER_HANDLE_MISS",        // 25
117    "VMM_DELETE_VSEG",           // 26
118    "VMM_CREATE_VSEG",           // 27
119    "VMM_SET_COW",               // 28
120    "VMM_DISPLAY",               // 29
121};
122
123//////////////////////////////////////////////////////////////////////////////////
124void __attribute__((noinline)) rpc_undefined( xptr_t xp __attribute__ ((unused)) )
125{
126        assert( false , "called in cluster %x", local_cxy );
127}
128
129/***************************************************************************************/
130/************ Generic function supporting RPCs : client side ***************************/
131/***************************************************************************************/
132
133///////////////////////////////////////
134void rpc_send( cxy_t        server_cxy, 
135               rpc_desc_t * rpc )
136{
137    lid_t              server_core_lid;
138    lid_t              client_core_lid;
139    volatile error_t   full;
140    thread_t         * this;
141
142    full            = 0;
143    this            = CURRENT_THREAD;
144    client_core_lid = this->core->lid;
145
146    // check calling thread can yield when is not the IDLE thread
147    // RPCs executed by the IDLE thread during kernel_init do not deschedule
148    if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ );
149
150    // select a server_core : use client core index if possible / core 0 otherwise
151    if( client_core_lid < hal_remote_l32( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) )
152    {
153        server_core_lid = client_core_lid;
154    }
155    else
156    {   
157        server_core_lid = 0;
158    }
159
160    // register client_thread and client_core in RPC descriptor
161    rpc->thread = this;
162    rpc->lid    = client_core_lid;
163
164    // build extended pointer on the RPC descriptor
165        xptr_t   desc_xp = XPTR( local_cxy , rpc );
166
167    // get local pointer on rpc_fifo in remote cluster,
168    remote_fifo_t * rpc_fifo    = &LOCAL_CLUSTER->rpc_fifo[server_core_lid];
169    xptr_t          rpc_fifo_xp = XPTR( server_cxy , rpc_fifo );
170
171        // post RPC in remote fifo / deschedule without blocking if fifo full
172    do
173    { 
174        full = remote_fifo_put_item( rpc_fifo_xp , (uint64_t )desc_xp );
175
176            if ( full ) 
177        {
178            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
179            __FUNCTION__ , local_cxy , server_cxy );
180
181            // deschedule without blocking
182            sched_yield("RPC fifo full");
183        }
184    }
185    while( full );
186 
187#if DEBUG_RPC_CLIENT_GENERIC
188uint32_t cycle = (uint32_t)hal_get_cycles();
189uint32_t items = remote_fifo_items( rpc_fifo_xp );
190if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
191printk("\n[%s] thread[%x,%x] / rpc %s / server[%x,%d] / items %d / cycle %d\n",
192__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], 
193server_cxy, server_core_lid, items, cycle );
194#endif
195       
196   // send IPI to the selected server core
197   dev_pic_send_ipi( server_cxy , server_core_lid );
198
199    // wait RPC completion before returning if blocking RPC :
200    // - deschedule without blocking if thread idle (in kernel init)
201    // - block and deschedule policy for any other thread
202    if ( rpc->blocking )
203    {
204        if( this->type == THREAD_IDLE )  // deschedule without blocking policy
205        {
206 
207#if DEBUG_RPC_CLIENT_GENERIC
208cycle = (uint32_t)hal_get_cycles();
209if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
210printk("\n[%s] thread[%x,%x] enter waiting loop for rpc %s / cycle %d\n",
211__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
212#endif
213             while( 1 )
214             {
215                 // check responses counter
216                 if( hal_remote_l32( XPTR( local_cxy , rpc->rsp ) ) == 0 ) break;
217                   
218                 // deschedule
219                 sched_yield("busy_waiting RPC completion");
220             }
221
222#if DEBUG_RPC_CLIENT_GENERIC
223cycle = (uint32_t)hal_get_cycles();
224if( DEBUG_RPC_CLIENT_GENERIC < cycle ) 
225printk("\n[%s] thread[%x,%x] received response for rpc %s / cycle %d\n",
226__FUNCTION__, this->process->pid, this->trdid, 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[%s] thread[%x,%x] blocks & deschedules for rpc %s / cycle %d\n",
237__FUNCTION__, this->process->pid, this->trdid, 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[%s] thread[%x,%x] resumes after rpc %s / cycle %d\n",
250__FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle );
251#endif
252        }
253
254// response must be available for a blocking RPC
255assert( (*rpc->rsp == 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[%s] thread[%x,%x] returns for non blocking rpc %s / cycle %d\n",
265__FUNCTION__, this->process->pid, this->trdid, 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_server_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    xptr_t          client_xp;          // extended pointer on client thread
286    lid_t           client_lid;         // local index of client core
287        thread_t      * server_ptr;         // local pointer on server thread
288    xptr_t          server_xp;          // extended pointer on server thread
289    lid_t           server_lid;         // local index of server core
290        remote_fifo_t * rpc_fifo;           // local pointer on RPC fifo
291    uint32_t      * rsp_ptr;            // local pointer on responses counter
292    xptr_t          rsp_xp;             // extended pointer on responses counter
293    uint32_t        responses;          // number of expected responses
294
295    // makes RPC thread not preemptable
296        hal_disable_irq( NULL );
297 
298        server_ptr      = CURRENT_THREAD;
299    server_xp       = XPTR( local_cxy , server_ptr );
300    server_lid      = server_ptr->core->lid;
301        rpc_fifo        = &LOCAL_CLUSTER->rpc_fifo[server_lid];
302
303    // "infinite" RPC thread loop
304        while(1)
305        {
306        // try to take RPC_FIFO ownership
307        if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) ) 
308        {
309
310#if DEBUG_RPC_SERVER_GENERIC
311uint32_t cycle = (uint32_t)hal_get_cycles();
312if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
313printk("\n[%s] RPC thread[%x,%x] on core[%d] takes RPC_FIFO ownership / cycle %d\n",
314__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, server_lid, cycle );
315#endif
316                // try to consume one RPC request 
317                empty = remote_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
318
319            // release RPC_FIFO ownership
320            rpc_fifo->owner = 0;
321
322            // handle RPC request if success
323                if ( empty == 0 )   
324            {
325                // get client cluster and pointer on RPC descriptor
326                desc_cxy = GET_CXY( desc_xp );
327                desc_ptr = GET_PTR( desc_xp );
328
329                // get relevant infos from RPC descriptor
330                    index      = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) );
331                client_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) );
332                rsp_ptr    = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->rsp ) );
333                client_lid = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->lid ) );
334
335                rsp_xp     = XPTR( desc_cxy , rsp_ptr );
336                client_xp  = XPTR( desc_cxy , client_ptr );
337
338#if DEBUG_RPC_SERVER_GENERIC
339cycle = (uint32_t)hal_get_cycles();
340uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) );
341if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
342printk("\n[%s] RPC thread[%x,%x] got rpc %s / client_cxy %x / items %d / cycle %d\n",
343__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], desc_cxy, items, cycle );
344#endif
345                // register client thread in RPC thread descriptor
346                server_ptr->rpc_client_xp = client_xp;
347 
348                // call the relevant server function
349                rpc_server[index]( desc_xp );
350
351#if DEBUG_RPC_SERVER_GENERIC
352cycle = (uint32_t)hal_get_cycles();
353if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
354printk("\n[%s] RPC thread[%x,%x] completes rpc %s / client_cxy %x / cycle %d\n",
355__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], desc_cxy, cycle );
356#endif
357                // decrement expected responses counter
358                responses = hal_remote_atomic_add( rsp_xp , -1 );
359
360                // unblock client thread if last response
361                if( responses == 1 ) 
362                {
363                    // unblock client thread
364                    thread_unblock( client_xp , THREAD_BLOCKED_RPC );
365
366                    hal_fence();
367
368#if DEBUG_RPC_SERVER_GENERIC
369cycle = (uint32_t)hal_get_cycles();
370trdid_t     client_trdid = hal_remote_l32( XPTR( desc_cxy , &client_ptr->trdid ) );
371process_t * process      = hal_remote_lpt( XPTR( desc_cxy , &client_ptr->process ) );
372pid_t       client_pid   = hal_remote_l32( XPTR( desc_cxy , &process->pid ) );
373if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
374printk("\n[%s] RPC thread[%x,%x] unblocked client thread[%x,%x] / cycle %d\n",
375__FUNCTION__, server_ptr->process->pid, server_ptr->trdid,
376client_pid, client_trdid, cycle );
377#endif
378                    // send IPI to client core
379                    dev_pic_send_ipi( desc_cxy , client_lid );
380                }
381            }  // end RPC handling if fifo non empty
382        }  // end if RPC_fIFO ownership successfully taken and released
383
384        // sucide if too many RPC threads
385        if( LOCAL_CLUSTER->rpc_threads[server_lid] >= CONFIG_RPC_THREADS_MAX )
386            {
387
388#if DEBUG_RPC_SERVER_GENERIC
389uint32_t cycle = (uint32_t)hal_get_cycles();
390if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
391printk("\n[%s] RPC thread[%x,%x] suicides / cycle %d\n",
392__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
393#endif
394            // update RPC threads counter
395                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[server_lid] , -1 );
396
397            // RPC thread blocks on GLOBAL
398                thread_block( server_xp , THREAD_BLOCKED_GLOBAL );
399
400            // RPC thread set the REQ_DELETE flag to suicide
401            hal_remote_atomic_or( server_xp , THREAD_FLAG_REQ_DELETE );
402            }
403        // block and deschedule otherwise
404        else
405        {
406
407#if DEBUG_RPC_SERVER_GENERIC
408uint32_t cycle = (uint32_t)hal_get_cycles();
409if( DEBUG_RPC_SERVER_GENERIC < cycle ) 
410printk("\n[%s] RPC thread[%x,%x] blocks & deschedules / cycle %d\n",
411__FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle );
412#endif
413            // RPC thread blocks on IDLE
414            thread_block( server_xp , THREAD_BLOCKED_IDLE );
415
416            // RPC thread deschedules
417            sched_yield("RPC_FIFO empty");
418        }
419        } // end infinite loop
420
421} // end rpc_server_func()
422
423
424/////////////////////////////////////////////////////////////////////////////////////////
425// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
426/////////////////////////////////////////////////////////////////////////////////////////
427
428///////////////////////////////////////////////
429void rpc_pmem_get_pages_client( cxy_t      cxy,
430                                uint32_t   order,      // in
431                                page_t  ** page )      // out
432{
433#if DEBUG_RPC_PMEM_GET_PAGES
434thread_t * this = CURRENT_THREAD;
435uint32_t cycle = (uint32_t)hal_get_cycles();
436if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
437printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
438__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
439#endif
440
441    uint32_t responses = 1;
442
443    // initialise RPC descriptor header
444    rpc_desc_t  rpc;
445    rpc.index     = RPC_PMEM_GET_PAGES;
446    rpc.blocking  = true;
447    rpc.rsp       = &responses;
448
449    // set input arguments in RPC descriptor
450    rpc.args[0] = (uint64_t)order;
451
452    // register RPC request in remote RPC fifo
453    rpc_send( cxy , &rpc );
454
455    // get output arguments from RPC descriptor
456    *page = (page_t *)(intptr_t)rpc.args[1];
457
458#if DEBUG_RPC_PMEM_GET_PAGES
459cycle = (uint32_t)hal_get_cycles();
460if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
461printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
462__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
463#endif
464}
465
466///////////////////////////////////////////
467void rpc_pmem_get_pages_server( xptr_t xp )
468{
469#if DEBUG_RPC_PMEM_GET_PAGES
470thread_t * this = CURRENT_THREAD;
471uint32_t cycle = (uint32_t)hal_get_cycles();
472if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
473printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
474__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
475#endif
476
477    // get client cluster identifier and pointer on RPC descriptor
478    cxy_t        cxy  = GET_CXY( xp );
479    rpc_desc_t * desc = GET_PTR( xp );
480
481    // get input arguments from client RPC descriptor
482    uint32_t order = (uint32_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
483   
484    // call local pmem allocator
485    page_t * page = ppm_alloc_pages( order ); 
486
487    // set output arguments into client RPC descriptor
488    hal_remote_s64( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
489
490#if DEBUG_RPC_PMEM_GET_PAGES
491cycle = (uint32_t)hal_get_cycles();
492if( cycle > DEBUG_RPC_PMEM_GET_PAGES )
493printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
494__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
495#endif
496}
497
498/////////////////////////////////////////////////////////////////////////////////////////
499// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES
500/////////////////////////////////////////////////////////////////////////////////////////
501
502//////////////////////////////////////////////////
503void rpc_pmem_release_pages_client( cxy_t     cxy,
504                                    page_t  * page )      // out
505{
506#if DEBUG_RPC_PMEM_RELEASE_PAGES
507thread_t * this = CURRENT_THREAD;
508uint32_t cycle = (uint32_t)hal_get_cycles();
509if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
510printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
511__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
512#endif
513
514    uint32_t responses = 1;
515
516    // initialise RPC descriptor header
517    rpc_desc_t  rpc;
518    rpc.index    = RPC_PMEM_RELEASE_PAGES;
519    rpc.blocking = true;
520    rpc.rsp      = &responses;
521
522    // set input arguments in RPC descriptor
523    rpc.args[0] = (uint64_t)(intptr_t)page;
524
525    // register RPC request in remote RPC fifo
526    rpc_send( cxy , &rpc );
527
528#if DEBUG_RPC_PMEM_RELEASE_PAGES
529cycle = (uint32_t)hal_get_cycles();
530if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
531printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
532__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
533#endif
534}
535
536///////////////////////////////////////////////
537void rpc_pmem_release_pages_server( xptr_t xp )
538{
539#if DEBUG_RPC_PMEM_RELEASE_PAGES
540thread_t * this = CURRENT_THREAD;
541uint32_t cycle = (uint32_t)hal_get_cycles();
542if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
543printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
544__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
545#endif
546
547    // get client cluster identifier and pointer on RPC descriptor
548    cxy_t        cxy  = GET_CXY( xp );
549    rpc_desc_t * desc = GET_PTR( xp );
550
551    // get input arguments from client RPC descriptor
552    page_t * page = (page_t *)(intptr_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) );
553   
554    // release memory to local pmem
555    kmem_req_t req;
556    req.type = KMEM_PAGE;
557    req.ptr  = page;
558    kmem_free( &req );
559
560#if DEBUG_RPC_PMEM_RELEASE_PAGES
561cycle = (uint32_t)hal_get_cycles();
562if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES )
563printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
564__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
565#endif
566}
567
568/////////////////////////////////////////////////////////////////////////////////////////
569// [2]            Marshaling functions attached to RPC_PPM_DISPLAY   
570/////////////////////////////////////////////////////////////////////////////////////////
571
572/////////////////////////////////////////
573void rpc_ppm_display_client( cxy_t  cxy )
574{
575#if DEBUG_RPC_PPM_DISPLAY
576thread_t * this = CURRENT_THREAD;
577uint32_t cycle = (uint32_t)hal_get_cycles();
578if( cycle > DEBUG_RPC_PPM_DISPLAY )
579printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
580__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
581#endif
582
583    uint32_t responses = 1;
584
585    // initialise RPC descriptor header
586    rpc_desc_t  rpc;
587    rpc.index    = RPC_PPM_DISPLAY;
588    rpc.blocking = true;
589    rpc.rsp      = &responses;
590
591    // register RPC request in remote RPC fifo
592    rpc_send( cxy , &rpc );
593
594#if DEBUG_RPC_PPM_DISPLAY
595cycle = (uint32_t)hal_get_cycles();
596if( cycle > DEBUG_RPC_PPM_DISPLAY )
597printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
598__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
599#endif
600}
601
602////////////////////////////////////////////////////////////////////
603void rpc_ppm_display_server( xptr_t __attribute__((__unused__)) xp )
604{
605#if DEBUG_RPC_PPM_DISPLAY
606thread_t * this = CURRENT_THREAD;
607uint32_t cycle = (uint32_t)hal_get_cycles();
608if( cycle > DEBUG_RPC_PPM_DISPLAY )
609printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
610__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
611#endif
612
613    // call local kernel function
614    ppm_display();
615
616#if DEBUG_RPC_PPM_DISPLAY
617cycle = (uint32_t)hal_get_cycles();
618if( cycle > DEBUG_RPC_PPM_DISPLAY )
619printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
620__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
621#endif
622}
623
624/////////////////////////////////////////////////////////////////////////////////////////
625// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK
626/////////////////////////////////////////////////////////////////////////////////////////
627
628///////////////////////////////////////////////////
629void rpc_process_make_fork_client( cxy_t       cxy,
630                                   xptr_t      ref_process_xp,      // in
631                                   xptr_t      parent_thread_xp,    // in
632                                   pid_t     * child_pid,           // out
633                                   thread_t ** child_thread_ptr,    // out     
634                                   error_t   * error )              // out
635{
636#if DEBUG_RPC_PROCESS_MAKE_FORK
637thread_t * this = CURRENT_THREAD;
638uint32_t cycle = (uint32_t)hal_get_cycles();
639if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
640printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
641__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
642#endif
643
644    uint32_t responses = 1;
645
646    // initialise RPC descriptor header
647    rpc_desc_t  rpc;
648    rpc.index    = RPC_PROCESS_MAKE_FORK;
649    rpc.blocking = true;
650    rpc.rsp      = &responses;
651
652    // set input arguments in RPC descriptor 
653    rpc.args[0] = (uint64_t)ref_process_xp;
654    rpc.args[1] = (uint64_t)parent_thread_xp;
655
656    // register RPC request in remote RPC fifo
657    rpc_send( cxy , &rpc );
658
659    // get output arguments from RPC descriptor
660    *child_pid         = (pid_t)rpc.args[2];
661    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
662    *error             = (error_t)rpc.args[4];     
663
664#if DEBUG_RPC_PROCESS_MAKE_FORK
665cycle = (uint32_t)hal_get_cycles();
666if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
667printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
668__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
669#endif
670}
671
672//////////////////////////////////////////////
673void rpc_process_make_fork_server( xptr_t xp )
674{
675#if DEBUG_RPC_PROCESS_MAKE_FORK
676thread_t * this = CURRENT_THREAD;
677uint32_t cycle = (uint32_t)hal_get_cycles();
678if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
679printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
680__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
681#endif
682
683    xptr_t     ref_process_xp;     // extended pointer on reference parent process
684    xptr_t     parent_thread_xp;   // extended pointer on parent thread
685    pid_t      child_pid;          // child process identifier
686    thread_t * child_thread_ptr;   // local copy of exec_info structure
687    error_t    error;              // local error status
688
689    // get client cluster identifier and pointer on RPC descriptor
690    cxy_t        client_cxy  = GET_CXY( xp );
691    rpc_desc_t * desc        = GET_PTR( xp );
692
693    // get input arguments from cient RPC descriptor
694    ref_process_xp   = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
695    parent_thread_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
696
697    // call local kernel function
698    error = process_make_fork( ref_process_xp,
699                               parent_thread_xp,
700                               &child_pid,
701                               &child_thread_ptr ); 
702
703    // set output argument into client RPC descriptor
704    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
705    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
706    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
707
708#if DEBUG_RPC_PROCESS_MAKE_FORK
709cycle = (uint32_t)hal_get_cycles();
710if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK )
711printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
712__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
713#endif
714}
715
716/////////////////////////////////////////////////////////////////////////////////////////
717// [4]      Marshaling functions attached to RPC_USER_DIR_CREATE 
718/////////////////////////////////////////////////////////////////////////////////////////
719
720////////////////////////////////////////////////////
721void rpc_user_dir_create_client( cxy_t          cxy,
722                                 vfs_inode_t *  inode,
723                                 xptr_t         ref_xp,
724                                 user_dir_t  ** dir )
725{
726#if DEBUG_RPC_USER_DIR_CREATE
727thread_t * this = CURRENT_THREAD;
728uint32_t cycle = (uint32_t)hal_get_cycles();
729if( cycle > DEBUG_RPC_USER_DIR_CREATE)
730printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
731__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
732#endif
733
734    uint32_t responses = 1;
735
736    // initialise RPC descriptor header
737    rpc_desc_t  rpc;
738    rpc.index    = RPC_USER_DIR_CREATE;
739    rpc.blocking = true;
740    rpc.rsp      = &responses;
741
742    // set input arguments in RPC descriptor
743    rpc.args[0] = (uint64_t)(intptr_t)inode;
744    rpc.args[1] = (uint64_t)ref_xp;
745
746    // register RPC request in remote RPC fifo
747    rpc_send( cxy , &rpc );
748
749    // get output argument from RPC descriptor
750    *dir = (user_dir_t *)(intptr_t)rpc.args[2];
751
752#if DEBUG_RPC_USER_DIR_CREATE
753cycle = (uint32_t)hal_get_cycles();
754if( cycle > DEBUG_RPC_USER_DIR_CREATE)
755printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
756__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
757#endif
758}
759
760////////////////////////////////////////////
761void rpc_user_dir_create_server( xptr_t xp )
762{
763#if DEBUG_RPC_USER_DIR_CREATE
764thread_t * this = CURRENT_THREAD;
765uint32_t cycle = (uint32_t)hal_get_cycles();
766if( cycle > DEBUG_RPC_USER_DIR_CREATE)
767printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
768__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
769#endif
770
771    vfs_inode_t * inode;          // pointer on inode in server cluster
772    xptr_t        ref_xp;         // extended pointer on reference user process
773    user_dir_t  * dir;            // pointer on user_dir structure in server cluster
774
775    // get client cluster identifier and pointer on RPC descriptor
776    cxy_t        client_cxy  = GET_CXY( xp );
777    rpc_desc_t * desc        = GET_PTR( xp );
778
779    // get input argument from RPC descriptor
780    inode  = (vfs_inode_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
781    ref_xp = (xptr_t)                 hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
782
783    // call kernel function
784    dir = user_dir_create( inode , ref_xp );
785
786    // set output argument into RPC descriptor
787    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (intptr_t)dir );
788
789#if DEBUG_RPC_USER_DIR_CREATE
790cycle = (uint32_t)hal_get_cycles();
791if( cycle > DEBUG_RPC_USER_DIR_CREATE)
792printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
793__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
794#endif
795}
796
797/////////////////////////////////////////////////////////////////////////////////////////
798// [5]      Marshaling functions attached to RPC_USER_DIR_DESTROY
799/////////////////////////////////////////////////////////////////////////////////////////
800
801////////////////////////////////////////////////////
802void rpc_user_dir_destroy_client( cxy_t         cxy,
803                                  user_dir_t  * dir,
804                                  xptr_t        ref_xp )
805{
806#if DEBUG_RPC_USER_DIR_DESTROY
807thread_t * this = CURRENT_THREAD;
808uint32_t cycle = (uint32_t)hal_get_cycles();
809if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
810printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
811__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
812#endif
813
814    uint32_t responses = 1;
815
816    // initialise RPC descriptor header
817    rpc_desc_t  rpc;
818    rpc.index    = RPC_USER_DIR_DESTROY;
819    rpc.blocking = true;
820    rpc.rsp      = &responses;
821
822    // set input arguments in RPC descriptor
823    rpc.args[0] = (uint64_t)(intptr_t)dir;
824    rpc.args[1] = (uint64_t)ref_xp;
825
826    // register RPC request in remote RPC fifo
827    rpc_send( cxy , &rpc );
828
829#if DEBUG_RPC_USER_DIR_DESTROY
830cycle = (uint32_t)hal_get_cycles();
831if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
832printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
833__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
834#endif
835}
836
837/////////////////////////////////////////////
838void rpc_user_dir_destroy_server( xptr_t xp )
839{
840#if DEBUG_RPC_USER_DIR_DESTROY
841thread_t * this = CURRENT_THREAD;
842uint32_t cycle = (uint32_t)hal_get_cycles();
843if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
844printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
845__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
846#endif
847
848    user_dir_t * dir;            // pointer on user_dir structure in server cluster
849    xptr_t       ref_xp;         // extended pointer on reference process
850
851    // get client cluster identifier and pointer on RPC descriptor
852    cxy_t        client_cxy  = GET_CXY( xp );
853    rpc_desc_t * desc        = GET_PTR( xp );
854
855    // get input argument from RPC descriptor
856    dir    = (user_dir_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
857    ref_xp = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
858
859    // call kernel function
860    user_dir_destroy( dir , ref_xp );
861
862#if DEBUG_RPC_USER_DIR_DESTROY
863cycle = (uint32_t)hal_get_cycles();
864if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
865printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
866__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
867#endif
868}
869
870/////////////////////////////////////////////////////////////////////////////////////////
871// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE   
872/////////////////////////////////////////////////////////////////////////////////////////
873
874/////////////////////////////////////////////////////////
875void rpc_thread_user_create_client( cxy_t            cxy, 
876                                    pid_t            pid,         // in
877                                    void           * start_func,  // in
878                                    void           * start_arg,   // in
879                                    pthread_attr_t * attr,        // in
880                                    xptr_t         * thread_xp,   // out
881                                    error_t        * error )      // out
882{
883#if DEBUG_RPC_THREAD_USER_CREATE
884thread_t * this = CURRENT_THREAD;
885uint32_t cycle = (uint32_t)hal_get_cycles();
886if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
887printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
888__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
889#endif
890   
891    uint32_t responses = 1;
892
893    // initialise RPC descriptor header
894    rpc_desc_t  rpc;
895    rpc.index    = RPC_THREAD_USER_CREATE;
896    rpc.blocking = true;
897    rpc.rsp      = &responses;
898
899    // set input arguments in RPC descriptor
900    rpc.args[0] = (uint64_t)pid;
901    rpc.args[1] = (uint64_t)(intptr_t)start_func;
902    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
903    rpc.args[3] = (uint64_t)(intptr_t)attr;
904
905    // register RPC request in remote RPC fifo
906    rpc_send( cxy , &rpc );
907
908    // get output arguments from RPC descriptor
909    *thread_xp = (xptr_t)rpc.args[4];
910    *error     = (error_t)rpc.args[5];
911
912#if DEBUG_RPC_THREAD_USER_CREATE
913cycle = (uint32_t)hal_get_cycles();
914if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
915printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
916__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
917#endif
918}
919
920///////////////////////////////////////////////
921void rpc_thread_user_create_server( xptr_t xp )
922{
923#if DEBUG_RPC_THREAD_USER_CREATE
924thread_t * this = CURRENT_THREAD;
925uint32_t cycle = (uint32_t)hal_get_cycles();
926if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
927printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
928__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
929#endif
930
931    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
932    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
933    thread_t       * thread_ptr; // local pointer on thread descriptor
934    xptr_t           thread_xp;  // extended pointer on thread descriptor
935
936    pid_t            pid;        // process identifier
937    void           * start_func;
938    void           * start_arg;
939    error_t          error;
940
941    // get client cluster identifier and pointer on RPC descriptor
942    cxy_t        client_cxy  = GET_CXY( xp );
943    rpc_desc_t * desc        = GET_PTR( xp );
944
945    // get input arguments from RPC descriptor
946    pid        = (pid_t)                     hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
947    start_func = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
948    start_arg  = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
949    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[3]));
950
951    // makes a local copy of attributes structure
952    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
953                       XPTR( client_cxy , attr_ptr ), 
954                       sizeof(pthread_attr_t) );
955   
956    // call kernel function
957    error = thread_user_create( pid,
958                                start_func,
959                                start_arg,
960                                &attr_copy,
961                                &thread_ptr );
962    // set output arguments
963    thread_xp = XPTR( local_cxy , thread_ptr );
964    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
965    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
966
967#if DEBUG_RPC_THREAD_USER_CREATE
968cycle = (uint32_t)hal_get_cycles();
969if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
970printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
971__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
972#endif
973}
974
975/////////////////////////////////////////////////////////////////////////////////////////
976// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
977/////////////////////////////////////////////////////////////////////////////////////////
978
979////////////////////////////////////////////////////
980void rpc_thread_kernel_create_client( cxy_t     cxy,
981                                      uint32_t  type,        // in
982                                      void    * func,        // in
983                                      void    * args,        // in
984                                      xptr_t  * thread_xp,   // out
985                                      error_t * error )      // out
986{
987#if DEBUG_RPC_THREAD_KERNEL_CREATE
988thread_t * this = CURRENT_THREAD;
989uint32_t cycle = (uint32_t)hal_get_cycles();
990if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
991printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
992__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
993#endif
994
995    uint32_t responses = 1;
996
997    // initialise RPC descriptor header
998    rpc_desc_t  rpc;
999    rpc.index    = RPC_THREAD_KERNEL_CREATE;
1000    rpc.blocking = true;
1001    rpc.rsp      = &responses;
1002
1003    // set input arguments in RPC descriptor
1004    rpc.args[0] = (uint64_t)type;
1005    rpc.args[1] = (uint64_t)(intptr_t)func;
1006    rpc.args[2] = (uint64_t)(intptr_t)args;
1007   
1008    // register RPC request in remote RPC fifo
1009    rpc_send( cxy , &rpc );
1010
1011    // get output arguments from RPC descriptor
1012    *thread_xp = (xptr_t)rpc.args[3];
1013    *error     = (error_t)rpc.args[4];
1014
1015#if DEBUG_RPC_THREAD_KERNEL_CREATE
1016cycle = (uint32_t)hal_get_cycles();
1017if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
1018printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1019__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1020#endif
1021}
1022
1023/////////////////////////////////////////////////
1024void rpc_thread_kernel_create_server( xptr_t xp )
1025{
1026#if DEBUG_RPC_THREAD_KERNEL_CREATE
1027thread_t * this = CURRENT_THREAD;
1028uint32_t cycle = (uint32_t)hal_get_cycles();
1029if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
1030printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1031__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1032#endif
1033
1034    thread_t       * thread_ptr;  // local pointer on thread descriptor
1035    xptr_t           thread_xp;   // extended pointer on thread descriptor
1036    lid_t            core_lid;    // core local index
1037    error_t          error;   
1038
1039    // get client cluster identifier and pointer on RPC descriptor
1040    cxy_t        client_cxy  = GET_CXY( xp );
1041    rpc_desc_t * desc        = GET_PTR( xp );
1042
1043    // get attributes from RPC descriptor
1044    uint32_t  type = (uint32_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1045    void    * func = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1046    void    * args = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1047
1048    // select one core
1049    core_lid = cluster_select_local_core();
1050
1051    // call local kernel function
1052    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
1053
1054    // set output arguments
1055    thread_xp = XPTR( local_cxy , thread_ptr );
1056    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1057    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
1058
1059#if DEBUG_RPC_THREAD_KERNEL_CREATE
1060cycle = (uint32_t)hal_get_cycles();
1061if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
1062printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1063__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1064#endif
1065}
1066
1067/////////////////////////////////////////////////////////////////////////////////////////
1068// [8]   Marshaling functions attached to RPC_VRS_FS_UPDATE_DENTRY
1069/////////////////////////////////////////////////////////////////////////////////////////
1070
1071/////////////////////////////////////////////////////////
1072void rpc_vfs_fs_update_dentry_client( cxy_t          cxy,
1073                                      vfs_inode_t  * inode,
1074                                      vfs_dentry_t * dentry,
1075                                      uint32_t       size,
1076                                      error_t      * error )
1077{
1078#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1079thread_t * this = CURRENT_THREAD;
1080uint32_t cycle = (uint32_t)hal_get_cycles();
1081if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1082printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1083__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1084#endif
1085
1086    uint32_t responses = 1;
1087
1088    // initialise RPC descriptor header
1089    rpc_desc_t  rpc;
1090    rpc.index    = RPC_VFS_FS_UPDATE_DENTRY;
1091    rpc.blocking = true;
1092    rpc.rsp      = &responses;
1093
1094    // set input arguments in RPC descriptor
1095    rpc.args[0] = (uint64_t)(intptr_t)inode;
1096    rpc.args[1] = (uint64_t)(intptr_t)dentry;
1097    rpc.args[2] = (uint64_t)size;
1098
1099    // register RPC request in remote RPC fifo
1100    rpc_send( cxy , &rpc );
1101
1102    // get output values from RPC descriptor
1103    *error   = (error_t)rpc.args[3];
1104
1105#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1106cycle = (uint32_t)hal_get_cycles();
1107if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1108printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1109__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1110#endif
1111}
1112
1113/////////////////////////////////////////////////
1114void rpc_vfs_fs_update_dentry_server( xptr_t xp )
1115{
1116#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1117thread_t * this = CURRENT_THREAD;
1118uint32_t cycle = (uint32_t)hal_get_cycles();
1119if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1120printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1121__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1122#endif
1123
1124    error_t        error;
1125    vfs_inode_t  * inode;
1126    vfs_dentry_t * dentry;
1127    uint32_t       size;
1128
1129    // get client cluster identifier and pointer on RPC descriptor
1130    cxy_t        client_cxy  = GET_CXY( xp );
1131    rpc_desc_t * desc        = GET_PTR( xp );
1132
1133    // get input arguments
1134    inode  = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1135    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1136    size   = (uint32_t)               hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
1137
1138    // call the kernel function
1139    error = vfs_fs_update_dentry( inode , dentry , size );
1140
1141    // set output argument
1142    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1143
1144#if DEBUG_RPC_VFS_FS_UPDATE_DENTRY
1145cycle = (uint32_t)hal_get_cycles();
1146if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY )
1147printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1148__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1149#endif
1150}
1151
1152/////////////////////////////////////////////////////////////////////////////////////////
1153// [9]   Marshaling functions attached to RPC_PROCESS_SIGACTION
1154/////////////////////////////////////////////////////////////////////////////////////////
1155
1156////////////////////////////////////////////////////
1157void rpc_process_sigaction_client( cxy_t        cxy,
1158                                   pid_t        pid,
1159                                   uint32_t     action )
1160{
1161#if DEBUG_RPC_PROCESS_SIGACTION
1162uint32_t  cycle = (uint32_t)hal_get_cycles();
1163thread_t * this = CURRENT_THREAD;
1164if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
1165printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n",
1166__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
1167process_action_str( action ), pid, cycle );
1168#endif
1169
1170    uint32_t    responses = 1;
1171    rpc_desc_t  rpc;
1172
1173    // initialise RPC descriptor header
1174    rpc.index    = RPC_PROCESS_SIGACTION;
1175    rpc.blocking = true;
1176    rpc.rsp      = &responses;
1177
1178    // set input arguments in RPC descriptor
1179    rpc.args[0] = (uint64_t)pid;
1180    rpc.args[1] = (uint64_t)action;
1181
1182    // register RPC request in remote RPC fifo
1183    rpc_send( cxy , &rpc );
1184
1185#if DEBUG_RPC_PROCESS_SIGACTION
1186cycle = (uint32_t)hal_get_cycles();
1187if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
1188printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n",
1189__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
1190process_action_str( action ), pid, cycle );
1191#endif
1192}  // end rpc_process_sigaction_client()
1193
1194//////////////////////////////////////////////
1195void rpc_process_sigaction_server( xptr_t xp )
1196{
1197    // get client cluster identifier and pointer on RPC descriptor
1198    cxy_t        client_cxy = GET_CXY( xp );
1199    rpc_desc_t * desc       = GET_PTR( xp );
1200
1201    // get arguments from RPC descriptor
1202    pid_t    pid    = (pid_t)   hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
1203    uint32_t action = (uint32_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
1204
1205#if DEBUG_RPC_PROCESS_SIGACTION
1206uint32_t cycle = (uint32_t)hal_get_cycles();
1207thread_t * this = CURRENT_THREAD;
1208if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
1209printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n",
1210__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
1211process_action_str( action ), pid, cycle );
1212#endif
1213
1214    // get client thread pointers
1215    thread_t * client_ptr = hal_remote_lpt( XPTR( client_cxy , &desc->thread ) );
1216    xptr_t     client_xp  = XPTR( client_cxy , client_ptr );
1217
1218    // get local process descriptor
1219    process_t * process = cluster_get_local_process_from_pid( pid );
1220
1221    // call relevant kernel function if found / does nothing if not found
1222    if( process != NULL )
1223    {
1224        if ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
1225        if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
1226        if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
1227    }
1228
1229#if DEBUG_RPC_PROCESS_SIGACTION
1230cycle = (uint32_t)hal_get_cycles();
1231if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
1232printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n",
1233__FUNCTION__, this->process->pid, this->trdid, this->core->lid,
1234process_action_str( action ), pid, cycle );
1235#endif
1236} // end rpc_process_sigaction_server()
1237
1238/////////////////////////////////////////////////////////////////////////////////////////
1239// [10]     Marshaling functions attached to RPC_VFS_INODE_CREATE
1240/////////////////////////////////////////////////////////////////////////////////////////
1241
1242/////////////////////////////////////////////////////
1243void rpc_vfs_inode_create_client( cxy_t          cxy,     
1244                                  uint32_t       fs_type,    // in
1245                                  uint32_t       attr,       // in
1246                                  uint32_t       rights,     // in
1247                                  uint32_t       uid,        // in
1248                                  uint32_t       gid,        // in
1249                                  xptr_t       * inode_xp,   // out
1250                                  error_t      * error )     // out
1251{
1252#if DEBUG_RPC_VFS_INODE_CREATE
1253thread_t * this = CURRENT_THREAD;
1254uint32_t cycle = (uint32_t)hal_get_cycles();
1255if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1256printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1257__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1258#endif
1259
1260    uint32_t responses = 1;
1261
1262    // initialise RPC descriptor header
1263    rpc_desc_t  rpc;
1264    rpc.index    = RPC_VFS_INODE_CREATE;
1265    rpc.blocking = true;
1266    rpc.rsp      = &responses;
1267
1268    // set input arguments in RPC descriptor
1269    rpc.args[0] = (uint64_t)fs_type;
1270    rpc.args[1] = (uint64_t)attr;
1271    rpc.args[2] = (uint64_t)rights;
1272    rpc.args[3] = (uint64_t)uid;
1273    rpc.args[4] = (uint64_t)gid;
1274
1275    // register RPC request in remote RPC fifo
1276    rpc_send( cxy , &rpc );
1277
1278    // get output values from RPC descriptor
1279    *inode_xp = (xptr_t)rpc.args[5];
1280    *error    = (error_t)rpc.args[6];
1281
1282#if DEBUG_RPC_VFS_INODE_CREATE
1283cycle = (uint32_t)hal_get_cycles();
1284if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1285printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1286__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1287#endif
1288}
1289
1290/////////////////////////////////////////////
1291void rpc_vfs_inode_create_server( xptr_t xp )
1292{
1293#if DEBUG_RPC_VFS_INODE_CREATE
1294thread_t * this = CURRENT_THREAD;
1295uint32_t cycle = (uint32_t)hal_get_cycles();
1296if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1297printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1298__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1299#endif
1300
1301    uint32_t         fs_type;
1302    uint32_t         attr;
1303    uint32_t         rights;
1304    uint32_t         uid;
1305    uint32_t         gid;
1306    xptr_t           inode_xp;
1307    error_t          error;
1308
1309    // get client cluster identifier and pointer on RPC descriptor
1310    cxy_t        client_cxy  = GET_CXY( xp );
1311    rpc_desc_t * desc        = GET_PTR( xp );
1312
1313    // get input arguments from client rpc descriptor
1314    fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1315    attr       = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1316    rights     = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1317    uid        = (uid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1318    gid        = (gid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
1319
1320    // call local kernel function
1321    error = vfs_inode_create( fs_type,
1322                              attr,
1323                              rights,
1324                              uid,
1325                              gid,
1326                              &inode_xp );
1327
1328    // set output arguments
1329    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)inode_xp );
1330    hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
1331
1332#if DEBUG_RPC_VFS_INODE_CREATE
1333cycle = (uint32_t)hal_get_cycles();
1334if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
1335printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1336__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1337#endif
1338}
1339
1340/////////////////////////////////////////////////////////////////////////////////////////
1341// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY
1342/////////////////////////////////////////////////////////////////////////////////////////
1343
1344/////////////////////////////////////////////////////////////
1345void rpc_vfs_inode_destroy_client( cxy_t                cxy,
1346                                   struct vfs_inode_s * inode )
1347{
1348#if DEBUG_RPC_VFS_INODE_DESTROY
1349thread_t * this = CURRENT_THREAD;
1350uint32_t cycle = (uint32_t)hal_get_cycles();
1351if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1352printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1353__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1354#endif
1355
1356    uint32_t responses = 1;
1357
1358    // initialise RPC descriptor header
1359    rpc_desc_t  rpc;
1360    rpc.index    = RPC_VFS_INODE_DESTROY;
1361    rpc.blocking = true;
1362    rpc.rsp      = &responses;
1363
1364    // set input arguments in RPC descriptor
1365    rpc.args[0] = (uint64_t)(intptr_t)inode;
1366   
1367    // register RPC request in remote RPC fifo
1368    rpc_send( cxy , &rpc );
1369
1370#if DEBUG_RPC_VFS_INODE_DESTROY
1371cycle = (uint32_t)hal_get_cycles();
1372if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1373printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1374__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1375#endif
1376}
1377
1378//////////////////////////////////////////////
1379void rpc_vfs_inode_destroy_server( xptr_t xp )
1380{
1381#if DEBUG_RPC_VFS_INODE_DESTROY
1382thread_t * this = CURRENT_THREAD;
1383uint32_t cycle = (uint32_t)hal_get_cycles();
1384if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1385printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1386__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1387#endif
1388
1389    vfs_inode_t * inode;
1390
1391    // get client cluster identifier and pointer on RPC descriptor
1392    cxy_t        client_cxy  = GET_CXY( xp );
1393    rpc_desc_t * desc        = GET_PTR( xp );
1394
1395    // get argument "inode" from client RPC descriptor
1396    inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1397                       
1398    // call local kernel function
1399    vfs_inode_destroy( inode );
1400
1401#if DEBUG_RPC_VFS_INODE_DESTROY
1402cycle = (uint32_t)hal_get_cycles();
1403if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
1404printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1405__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1406#endif
1407}
1408
1409/////////////////////////////////////////////////////////////////////////////////////////
1410// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE
1411/////////////////////////////////////////////////////////////////////////////////////////
1412
1413//////////////////////////////////////////////////////////////
1414void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1415                                   uint32_t               type,         // in
1416                                   char                 * name,         // in
1417                                   xptr_t               * dentry_xp,    // out
1418                                   error_t              * error )       // out
1419{
1420#if DEBUG_RPC_VFS_DENTRY_CREATE
1421thread_t * this = CURRENT_THREAD;
1422uint32_t cycle = (uint32_t)hal_get_cycles();
1423if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1424printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1425__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1426#endif
1427
1428    uint32_t responses = 1;
1429
1430    // initialise RPC descriptor header
1431    rpc_desc_t  rpc;
1432    rpc.index    = RPC_VFS_DENTRY_CREATE;
1433    rpc.blocking = true;
1434    rpc.rsp      = &responses;
1435
1436    // set input arguments in RPC descriptor
1437    rpc.args[0] = (uint64_t)type;
1438    rpc.args[1] = (uint64_t)(intptr_t)name;
1439
1440    // register RPC request in remote RPC fifo
1441    rpc_send( cxy , &rpc );
1442
1443    // get output values from RPC descriptor
1444    *dentry_xp = (xptr_t)rpc.args[2];
1445    *error     = (error_t)rpc.args[3];
1446
1447#if DEBUG_RPC_VFS_DENTRY_CREATE
1448cycle = (uint32_t)hal_get_cycles();
1449if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1450printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1451__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1452#endif
1453}
1454
1455//////////////////////////////////////////////
1456void rpc_vfs_dentry_create_server( xptr_t xp )
1457{
1458#if DEBUG_RPC_VFS_DENTRY_CREATE
1459thread_t * this = CURRENT_THREAD;
1460uint32_t cycle = (uint32_t)hal_get_cycles();
1461if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1462printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1463__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1464#endif
1465
1466    uint32_t      type;
1467    char        * name;
1468    xptr_t        dentry_xp;
1469    error_t       error;
1470    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1471
1472    // get client cluster identifier and pointer on RPC descriptor
1473    cxy_t        client_cxy  = GET_CXY( xp );
1474    rpc_desc_t * desc        = GET_PTR( xp );
1475
1476    // get arguments "name", "type", and "parent" from client RPC descriptor
1477    type   = (uint32_t)         hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1478    name   = (char *)(intptr_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1479
1480    // makes a local copy of  name
1481    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1482                       XPTR( client_cxy , name ) );
1483
1484    // call local kernel function
1485    error = vfs_dentry_create( type,
1486                               name_copy,
1487                               &dentry_xp );
1488    // set output arguments
1489    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)dentry_xp );
1490    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1491
1492#if DEBUG_RPC_VFS_DENTRY_CREATE
1493cycle = (uint32_t)hal_get_cycles();
1494if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
1495printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1496__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1497#endif
1498}
1499
1500/////////////////////////////////////////////////////////////////////////////////////////
1501// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY
1502/////////////////////////////////////////////////////////////////////////////////////////
1503
1504///////////////////////////////////////////////////////
1505void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1506                                    vfs_dentry_t * dentry )
1507{
1508#if DEBUG_RPC_VFS_DENTRY_DESTROY
1509thread_t * this = CURRENT_THREAD;
1510uint32_t cycle = (uint32_t)hal_get_cycles();
1511if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1512printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1513__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1514#endif
1515
1516    uint32_t responses = 1;
1517
1518    // initialise RPC descriptor header
1519    rpc_desc_t  rpc;
1520    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1521    rpc.blocking = true;
1522    rpc.rsp      = &responses;
1523
1524    // set input arguments in RPC descriptor
1525    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1526   
1527    // register RPC request in remote RPC fifo
1528    rpc_send( cxy , &rpc );
1529
1530#if DEBUG_RPC_VFS_DENTRY_DESTROY
1531cycle = (uint32_t)hal_get_cycles();
1532if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1533printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1534__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1535#endif
1536}
1537
1538///////////////////////////////////////////////
1539void rpc_vfs_dentry_destroy_server( xptr_t xp )
1540{
1541#if DEBUG_RPC_VFS_DENTRY_DESTROY
1542thread_t * this = CURRENT_THREAD;
1543uint32_t cycle = (uint32_t)hal_get_cycles();
1544if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1545printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1546__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1547#endif
1548
1549    vfs_dentry_t * dentry;
1550
1551    // get client cluster identifier and pointer on RPC descriptor
1552    cxy_t        client_cxy  = GET_CXY( xp );
1553    rpc_desc_t * desc        = GET_PTR( xp );
1554
1555    // get arguments "dentry" from client RPC descriptor
1556    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1557                       
1558    // call local kernel function
1559    vfs_dentry_destroy( dentry );
1560
1561#if DEBUG_RPC_VFS_DENTRY_DESTROY
1562cycle = (uint32_t)hal_get_cycles();
1563if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
1564printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1565__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1566#endif
1567}
1568
1569
1570/////////////////////////////////////////////////////////////////////////////////////////
1571// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE 
1572/////////////////////////////////////////////////////////////////////////////////////////
1573
1574//////////////////////////////////////////////////////////////
1575void rpc_vfs_file_create_client( cxy_t                  cxy,
1576                                 struct vfs_inode_s   * inode,       // in
1577                                 uint32_t               file_attr,   // in
1578                                 xptr_t               * file_xp,     // out
1579                                 error_t              * error )      // out
1580{
1581#if DEBUG_RPC_VFS_FILE_CREATE
1582thread_t * this = CURRENT_THREAD;
1583uint32_t cycle = (uint32_t)hal_get_cycles();
1584if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1585printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1586__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1587#endif
1588
1589    uint32_t responses = 1;
1590
1591    // initialise RPC descriptor header
1592    rpc_desc_t  rpc;
1593    rpc.index    = RPC_VFS_FILE_CREATE;
1594    rpc.blocking = true;
1595    rpc.rsp      = &responses;
1596
1597    // set input arguments in RPC descriptor
1598    rpc.args[0] = (uint64_t)(intptr_t)inode;
1599    rpc.args[1] = (uint64_t)file_attr;
1600
1601    // register RPC request in remote RPC fifo
1602    rpc_send( cxy , &rpc );
1603
1604    // get output values from RPC descriptor
1605    *file_xp = (xptr_t)rpc.args[2];
1606    *error   = (error_t)rpc.args[3];
1607
1608#if DEBUG_RPC_VFS_FILE_CREATE
1609cycle = (uint32_t)hal_get_cycles();
1610if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1611printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1612__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1613#endif
1614}
1615
1616////////////////////////////////////////////
1617void rpc_vfs_file_create_server( xptr_t xp )
1618{
1619#if DEBUG_RPC_VFS_FILE_CREATE
1620thread_t * this = CURRENT_THREAD;
1621uint32_t cycle = (uint32_t)hal_get_cycles();
1622if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1623printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1624__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1625#endif
1626
1627    uint32_t      file_attr;
1628    vfs_inode_t * inode;
1629    xptr_t        file_xp;
1630    error_t       error;
1631
1632    // get client cluster identifier and pointer on RPC descriptor
1633    cxy_t        client_cxy  = GET_CXY( xp );
1634    rpc_desc_t * desc        = GET_PTR( xp );
1635
1636    // get arguments "file_attr" and "inode" from client RPC descriptor
1637    inode     = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1638    file_attr = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1639                       
1640    // call local kernel function
1641    error = vfs_file_create( inode,
1642                             file_attr,
1643                             &file_xp );
1644 
1645    // set output arguments
1646    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
1647    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1648
1649#if DEBUG_RPC_VFS_FILE_CREATE
1650cycle = (uint32_t)hal_get_cycles();
1651if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
1652printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1653__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1654#endif
1655}
1656
1657/////////////////////////////////////////////////////////////////////////////////////////
1658// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY 
1659/////////////////////////////////////////////////////////////////////////////////////////
1660
1661///////////////////////////////////////////////////
1662void rpc_vfs_file_destroy_client( cxy_t        cxy,
1663                                  vfs_file_t * file )
1664{
1665#if DEBUG_RPC_VFS_FILE_DESTROY
1666thread_t * this = CURRENT_THREAD;
1667uint32_t cycle = (uint32_t)hal_get_cycles();
1668if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1669printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1670__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1671#endif
1672
1673    uint32_t responses = 1;
1674
1675    // initialise RPC descriptor header
1676    rpc_desc_t  rpc;
1677    rpc.index    = RPC_VFS_FILE_DESTROY;
1678    rpc.blocking = true;
1679    rpc.rsp      = &responses;
1680
1681    // set input arguments in RPC descriptor
1682    rpc.args[0] = (uint64_t)(intptr_t)file;
1683   
1684    // register RPC request in remote RPC fifo
1685    rpc_send( cxy , &rpc );
1686
1687#if DEBUG_RPC_VFS_FILE_DESTROY
1688cycle = (uint32_t)hal_get_cycles();
1689if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1690printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1691__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1692#endif
1693}
1694
1695/////////////////////////////////////////////
1696void rpc_vfs_file_destroy_server( xptr_t xp )
1697{
1698#if DEBUG_RPC_VFS_FILE_DESTROY
1699thread_t * this = CURRENT_THREAD;
1700uint32_t cycle = (uint32_t)hal_get_cycles();
1701if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1702printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1703__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1704#endif
1705
1706    vfs_file_t * file;
1707
1708    // get client cluster identifier and pointer on RPC descriptor
1709    cxy_t        client_cxy  = GET_CXY( xp );
1710    rpc_desc_t * desc        = GET_PTR( xp );
1711
1712    // get arguments "dentry" from client RPC descriptor
1713    file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1714                       
1715    // call local kernel function
1716    vfs_file_destroy( file );
1717
1718#if DEBUG_RPC_VFS_FILE_DESTROY
1719cycle = (uint32_t)hal_get_cycles();
1720if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
1721printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1722__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
1723#endif
1724}
1725
1726/////////////////////////////////////////////////////////////////////////////////////////
1727// [16]      Marshaling functions attached to RPC_VFS_FS_GET_DENTRY
1728/////////////////////////////////////////////////////////////////////////////////////////
1729
1730/////////////////////////////////////////////////////////
1731void rpc_vfs_fs_new_dentry_client( cxy_t         cxy,
1732                                   vfs_inode_t * parent_inode,    // in
1733                                   char        * name,            // in
1734                                   xptr_t        child_inode_xp,  // in
1735                                   error_t     * error )          // out
1736{
1737#if DEBUG_RPC_VFS_FS_NEW_DENTRY
1738thread_t * this = CURRENT_THREAD;
1739uint32_t cycle = (uint32_t)hal_get_cycles();
1740if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
1741printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1742__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1743#endif
1744
1745    uint32_t responses = 1;
1746
1747    // initialise RPC descriptor header
1748    rpc_desc_t  rpc;
1749    rpc.index    = RPC_VFS_FS_NEW_DENTRY;
1750    rpc.blocking = true;
1751    rpc.rsp      = &responses;
1752
1753    // set input arguments in RPC descriptor
1754    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
1755    rpc.args[1] = (uint64_t)(intptr_t)name;
1756    rpc.args[2] = (uint64_t)child_inode_xp;
1757
1758    // register RPC request in remote RPC fifo
1759    rpc_send( cxy , &rpc );
1760
1761    // get output values from RPC descriptor
1762    *error   = (error_t)rpc.args[3];
1763
1764#if DEBUG_RPC_VFS_FS_NEW_DENTRY
1765cycle = (uint32_t)hal_get_cycles();
1766if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
1767printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1768__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1769#endif
1770}
1771
1772//////////////////////////////////////////////
1773void rpc_vfs_fs_new_dentry_server( xptr_t xp )
1774{
1775#if DEBUG_RPC_VFS_FS_NEW_DENTRY
1776thread_t * this = CURRENT_THREAD;
1777uint32_t cycle = (uint32_t)hal_get_cycles();
1778if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
1779printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1780__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1781#endif
1782
1783    error_t       error;
1784    vfs_inode_t * parent;
1785    xptr_t        child_xp;
1786    char        * name;
1787
1788    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1789
1790    // get client cluster identifier and pointer on RPC descriptor
1791    cxy_t        client_cxy  = GET_CXY( xp );
1792    rpc_desc_t * desc        = GET_PTR( xp );
1793
1794    // get arguments "parent", "name", and "child_xp"
1795    parent     = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1796    name       = (char*)(intptr_t)       hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1797    child_xp   = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
1798
1799    // get name local copy
1800    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
1801                       XPTR( client_cxy , name ) );
1802
1803    // call the kernel function
1804    error = vfs_fs_new_dentry( parent , name_copy , child_xp );
1805
1806    // set output argument
1807    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
1808
1809#if DEBUG_RPC_VFS_FS_NEW_DENTRY
1810cycle = (uint32_t)hal_get_cycles();
1811if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY )
1812printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1813__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1814#endif
1815}
1816
1817/////////////////////////////////////////////////////////////////////////////////////////
1818// [17]      Marshaling function attached to RPC_VFS_FS_ADD_DENTRY 
1819/////////////////////////////////////////////////////////////////////////////////////////
1820
1821void rpc_vfs_fs_add_dentry_client( cxy_t          cxy,
1822                                   vfs_inode_t  * parent,     // in
1823                                   vfs_dentry_t * dentry,     // in
1824                                   error_t      * error )     // out
1825{
1826#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1827thread_t * this = CURRENT_THREAD;
1828uint32_t cycle = (uint32_t)hal_get_cycles();
1829if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1830printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1831__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1832#endif
1833
1834    uint32_t responses = 1;
1835
1836    // initialise RPC descriptor header
1837    rpc_desc_t  rpc;
1838    rpc.index    = RPC_VFS_FS_ADD_DENTRY;
1839    rpc.blocking = true;
1840    rpc.rsp      = &responses;
1841
1842    // set input arguments in RPC descriptor
1843    rpc.args[0] = (uint64_t)(intptr_t)parent;
1844    rpc.args[1] = (uint64_t)(intptr_t)dentry;
1845
1846    // register RPC request in remote RPC fifo
1847    rpc_send( cxy , &rpc );
1848
1849    // get output values from RPC descriptor
1850    *error   = (error_t)rpc.args[2];
1851
1852#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1853cycle = (uint32_t)hal_get_cycles();
1854if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1855printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1856__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1857#endif
1858}
1859
1860//////////////////////////////////////////////
1861void rpc_vfs_fs_add_dentry_server( xptr_t xp )
1862{
1863#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1864thread_t * this = CURRENT_THREAD;
1865uint32_t cycle = (uint32_t)hal_get_cycles();
1866if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1867printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1868__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1869#endif
1870
1871    error_t        error;
1872    vfs_inode_t  * parent;
1873    vfs_dentry_t * dentry;
1874
1875    // get client cluster identifier and pointer on RPC descriptor
1876    cxy_t        client_cxy  = GET_CXY( xp );
1877    rpc_desc_t * desc        = GET_PTR( xp );
1878
1879    // get input arguments
1880    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1881    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1882
1883    // call the kernel function
1884    error = vfs_fs_add_dentry( parent , dentry );
1885
1886    // set output argument
1887    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
1888
1889#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1890cycle = (uint32_t)hal_get_cycles();
1891if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1892printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1893__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1894#endif
1895}
1896
1897/////////////////////////////////////////////////////////////////////////////////////////
1898// [18]      Marshaling function attached to RPC_VFS_FS_REMOVE_DENTRY
1899/////////////////////////////////////////////////////////////////////////////////////////
1900
1901void rpc_vfs_fs_remove_dentry_client( cxy_t          cxy,
1902                                      vfs_inode_t  * parent,     // in
1903                                      vfs_dentry_t * dentry,     // in
1904                                      error_t      * error )     // out
1905{
1906#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1907thread_t * this = CURRENT_THREAD;
1908uint32_t cycle = (uint32_t)hal_get_cycles();
1909if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1910printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1911__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1912#endif
1913
1914    uint32_t responses = 1;
1915
1916    // initialise RPC descriptor header
1917    rpc_desc_t  rpc;
1918    rpc.index    = RPC_VFS_FS_REMOVE_DENTRY;
1919    rpc.blocking = true;
1920    rpc.rsp      = &responses;
1921
1922    // set input arguments in RPC descriptor
1923    rpc.args[0] = (uint64_t)(intptr_t)parent;
1924    rpc.args[1] = (uint64_t)(intptr_t)dentry;
1925
1926    // register RPC request in remote RPC fifo
1927    rpc_send( cxy , &rpc );
1928
1929    // get output values from RPC descriptor
1930    *error   = (error_t)rpc.args[2];
1931
1932#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1933cycle = (uint32_t)hal_get_cycles();
1934if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1935printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1936__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1937#endif
1938}
1939
1940/////////////////////////////////////////////////
1941void rpc_vfs_fs_remove_dentry_server( xptr_t xp )
1942{
1943#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1944thread_t * this = CURRENT_THREAD;
1945uint32_t cycle = (uint32_t)hal_get_cycles();
1946if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1947printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1948__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1949#endif
1950
1951    error_t        error;
1952    vfs_inode_t  * parent;
1953    vfs_dentry_t * dentry;
1954
1955    // get client cluster identifier and pointer on RPC descriptor
1956    cxy_t        client_cxy  = GET_CXY( xp );
1957    rpc_desc_t * desc        = GET_PTR( xp );
1958
1959    // get input arguments
1960    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1961    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1962
1963    // call the kernel function
1964    error = vfs_fs_remove_dentry( parent , dentry );
1965
1966    // set output argument
1967    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
1968
1969#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1970cycle = (uint32_t)hal_get_cycles();
1971if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1972printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1973__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1974#endif
1975}
1976
1977/////////////////////////////////////////////////////////////////////////////////////////
1978// [19]     Marshaling functions attached to RPC_VFS_INODE_LOAD_ALL_PAGES
1979/////////////////////////////////////////////////////////////////////////////////////////
1980
1981////////////////////////////////////////////////////////////
1982void rpc_vfs_inode_load_all_pages_client( cxy_t         cxy,
1983                                          vfs_inode_t * inode,      // in
1984                                          error_t     * error )     // out
1985{
1986#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
1987thread_t * this = CURRENT_THREAD;
1988uint32_t cycle = (uint32_t)hal_get_cycles();
1989if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
1990printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1991__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1992#endif
1993
1994    uint32_t responses = 1;
1995
1996    // initialise RPC descriptor header
1997    rpc_desc_t  rpc;
1998    rpc.index    = RPC_VFS_INODE_LOAD_ALL_PAGES;
1999    rpc.blocking = true;
2000    rpc.rsp      = &responses;
2001
2002    // set input arguments in RPC descriptor
2003    rpc.args[0] = (uint64_t)(intptr_t)inode;
2004
2005    // register RPC request in remote RPC fifo
2006    rpc_send( cxy , &rpc );
2007
2008    // get output values from RPC descriptor
2009    *error   = (error_t)rpc.args[1];
2010
2011#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2012cycle = (uint32_t)hal_get_cycles();
2013if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2014printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2015__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2016#endif
2017}
2018
2019/////////////////////////////////////////////////////
2020void rpc_vfs_inode_load_all_pages_server( xptr_t xp )
2021{
2022#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2023thread_t * this = CURRENT_THREAD;
2024uint32_t cycle = (uint32_t)hal_get_cycles();
2025if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2026printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2027__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2028#endif
2029
2030    error_t       error;
2031    vfs_inode_t * inode;
2032
2033    // get client cluster identifier and pointer on RPC descriptor
2034    cxy_t        client_cxy  = GET_CXY( xp );
2035    rpc_desc_t * desc        = GET_PTR( xp );
2036
2037    // get input argument
2038    inode = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
2039
2040    // call the kernel function
2041    error = vfs_inode_load_all_pages( inode );
2042
2043    // set output argument
2044    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
2045
2046#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
2047cycle = (uint32_t)hal_get_cycles();
2048if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
2049printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2050__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2051#endif
2052}
2053
2054/////////////////////////////////////////////////////////////////////////////////////////
2055// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG
2056/////////////////////////////////////////////////////////////////////////////////////////
2057
2058//////////////////////////////////////////////////
2059void rpc_vmm_get_vseg_client( cxy_t       cxy,     
2060                              process_t * process,     // in 
2061                              intptr_t    vaddr,       // in 
2062                              xptr_t    * vseg_xp,     // out
2063                              error_t   * error )      // out
2064{
2065#if DEBUG_RPC_VMM_GET_VSEG
2066thread_t * this = CURRENT_THREAD;
2067uint32_t cycle = (uint32_t)hal_get_cycles();
2068if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2069printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2070__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2071#endif
2072
2073    uint32_t responses = 1;
2074
2075    // initialise RPC descriptor header
2076    rpc_desc_t  rpc;
2077    rpc.index    = RPC_VMM_GET_VSEG;
2078    rpc.blocking = true;
2079    rpc.rsp      = &responses;
2080
2081    // set input arguments in RPC descriptor
2082    rpc.args[0] = (uint64_t)(intptr_t)process;
2083    rpc.args[1] = (uint64_t)vaddr;
2084
2085    // register RPC request in remote RPC fifo
2086    rpc_send( cxy , &rpc );
2087
2088    // get output argument from rpc descriptor
2089    *vseg_xp = rpc.args[2];
2090    *error   = (error_t)rpc.args[3];
2091
2092#if DEBUG_RPC_VMM_GET_VSEG
2093cycle = (uint32_t)hal_get_cycles();
2094if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2095printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2096__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2097#endif
2098}
2099
2100/////////////////////////////////////////
2101void rpc_vmm_get_vseg_server( xptr_t xp )
2102{
2103#if DEBUG_RPC_VMM_GET_VSEG
2104thread_t * this = CURRENT_THREAD;
2105uint32_t cycle = (uint32_t)hal_get_cycles();
2106if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2107printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2108__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2109#endif
2110
2111    process_t   * process;
2112    intptr_t      vaddr;
2113    vseg_t      * vseg_ptr;
2114    xptr_t        vseg_xp;
2115    error_t       error;
2116
2117    // get client cluster identifier and pointer on RPC descriptor
2118    cxy_t        client_cxy  = GET_CXY( xp );
2119    rpc_desc_t * desc        = GET_PTR( xp );
2120
2121    // get input argument from client RPC descriptor
2122    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2123    vaddr   = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
2124   
2125    // call local kernel function
2126    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
2127
2128    // set output arguments to client RPC descriptor
2129    vseg_xp = XPTR( local_cxy , vseg_ptr );
2130    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
2131    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
2132
2133#if DEBUG_RPC_VMM_GET_VSEG
2134cycle = (uint32_t)hal_get_cycles();
2135if( cycle > DEBUG_RPC_VMM_GET_VSEG )
2136printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2137__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2138#endif
2139}
2140
2141
2142/////////////////////////////////////////////////////////////////////////////////////////
2143// [21]    Marshaling functions attached to RPC_VMM_GLOBAL_UPDATE_PTE
2144/////////////////////////////////////////////////////////////////////////////////////////
2145
2146///////////////////////////////////////////////////////
2147void rpc_vmm_global_update_pte_client( cxy_t       cxy,   
2148                                       process_t * process,  // in
2149                                       vpn_t       vpn,      // in
2150                                       uint32_t    attr,     // in
2151                                       ppn_t       ppn )     // in
2152{
2153#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
2154thread_t * this = CURRENT_THREAD;
2155uint32_t cycle = (uint32_t)hal_get_cycles();
2156if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
2157printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2158__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2159#endif
2160
2161    uint32_t responses = 1;
2162
2163    // initialise RPC descriptor header
2164    rpc_desc_t  rpc;
2165    rpc.index    = RPC_VMM_GLOBAL_UPDATE_PTE;
2166    rpc.blocking = true;
2167    rpc.rsp      = &responses;
2168
2169    // set input arguments in RPC descriptor
2170    rpc.args[0] = (uint64_t)(intptr_t)process;
2171    rpc.args[1] = (uint64_t)vpn;
2172    rpc.args[2] = (uint64_t)attr;
2173    rpc.args[3] = (uint64_t)ppn;
2174
2175    // register RPC request in remote RPC fifo
2176    rpc_send( cxy , &rpc );
2177
2178#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
2179cycle = (uint32_t)hal_get_cycles();
2180if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
2181printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2182__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2183#endif
2184}
2185
2186//////////////////////////////////////////////////
2187void rpc_vmm_global_update_pte_server( xptr_t xp )
2188{
2189#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
2190thread_t * this = CURRENT_THREAD;
2191uint32_t cycle = (uint32_t)hal_get_cycles();
2192if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
2193printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2194__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2195#endif
2196
2197    process_t   * process;
2198    vpn_t         vpn;
2199    uint32_t      attr;
2200    ppn_t         ppn;
2201
2202    // get client cluster identifier and pointer on RPC descriptor
2203    cxy_t        client_cxy  = GET_CXY( xp );
2204    rpc_desc_t * desc        = GET_PTR( xp );
2205
2206    // get input argument "process" & "vpn" from client RPC descriptor
2207    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2208    vpn     = (vpn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
2209    attr    = (uint32_t)             hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
2210    ppn     = (ppn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
2211   
2212    // call local kernel function
2213    vmm_global_update_pte( process , vpn , attr , ppn ); 
2214
2215#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
2216cycle = (uint32_t)hal_get_cycles();
2217if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
2218printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2219__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2220#endif
2221}
2222
2223/////////////////////////////////////////////////////////////////////////////////////////
2224// [22]          Marshaling functions attached to RPC_KCM_ALLOC
2225/////////////////////////////////////////////////////////////////////////////////////////
2226
2227//////////////////////////////////////////
2228void rpc_kcm_alloc_client( cxy_t      cxy,
2229                           uint32_t   kmem_type,   // in
2230                           xptr_t   * buf_xp )     // out
2231{
2232#if DEBUG_RPC_KCM_ALLOC
2233thread_t * this = CURRENT_THREAD;
2234uint32_t cycle = (uint32_t)hal_get_cycles();
2235if( cycle > DEBUG_RPC_KCM_ALLOC )
2236printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2237__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2238#endif
2239
2240    uint32_t responses = 1;
2241
2242    // initialise RPC descriptor header
2243    rpc_desc_t  rpc;
2244    rpc.index    = RPC_KCM_ALLOC;
2245    rpc.blocking = true;
2246    rpc.rsp      = &responses;
2247
2248    // set input arguments in RPC descriptor
2249    rpc.args[0] = (uint64_t)kmem_type;
2250
2251    // register RPC request in remote RPC fifo
2252    rpc_send( cxy , &rpc );
2253
2254    // get output arguments from RPC descriptor
2255    *buf_xp = (xptr_t)rpc.args[1];
2256
2257#if DEBUG_RPC_KCM_ALLOC
2258cycle = (uint32_t)hal_get_cycles();
2259if( cycle > DEBUG_RPC_KCM_ALLOC )
2260printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2261__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2262#endif
2263}
2264
2265//////////////////////////////////////
2266void rpc_kcm_alloc_server( xptr_t xp )
2267{
2268#if DEBUG_RPC_KCM_ALLOC
2269thread_t * this = CURRENT_THREAD;
2270uint32_t cycle = (uint32_t)hal_get_cycles();
2271if( cycle > DEBUG_RPC_KCM_ALLOC )
2272printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2273__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2274#endif
2275
2276    // get client cluster identifier and pointer on RPC descriptor
2277    cxy_t        client_cxy  = GET_CXY( xp );
2278    rpc_desc_t * desc        = GET_PTR( xp );
2279
2280    // get input argument "kmem_type" from client RPC descriptor
2281    uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2282
2283    // allocates memory for kcm
2284    kmem_req_t  req;
2285    req.type  = kmem_type;
2286    req.flags = AF_ZERO;
2287    void * buf_ptr = kmem_alloc( &req );
2288
2289    // set output argument
2290    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
2291    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
2292
2293#if DEBUG_RPC_KCM_ALLOC
2294cycle = (uint32_t)hal_get_cycles();
2295if( cycle > DEBUG_RPC_KCM_ALLOC )
2296printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2297__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2298#endif
2299}   
2300
2301/////////////////////////////////////////////////////////////////////////////////////////
2302// [23]          Marshaling functions attached to RPC_KCM_FREE
2303/////////////////////////////////////////////////////////////////////////////////////////
2304
2305/////////////////////////////////////////
2306void rpc_kcm_free_client( cxy_t      cxy,
2307                          void     * buf,          // in
2308                          uint32_t   kmem_type )   // in
2309{
2310#if DEBUG_RPC_KCM_FREE
2311thread_t * this = CURRENT_THREAD;
2312uint32_t cycle = (uint32_t)hal_get_cycles();
2313if( cycle > DEBUG_RPC_KCM_FREE )
2314printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2315__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2316#endif
2317
2318    uint32_t responses = 1;
2319
2320    // initialise RPC descriptor header
2321    rpc_desc_t  rpc;
2322    rpc.index    = RPC_KCM_FREE;
2323    rpc.blocking = true;
2324    rpc.rsp      = &responses;
2325
2326    // set input arguments in RPC descriptor
2327    rpc.args[0] = (uint64_t)(intptr_t)buf;
2328    rpc.args[1] = (uint64_t)kmem_type;
2329
2330    // register RPC request in remote RPC fifo
2331    rpc_send( cxy , &rpc );
2332
2333#if DEBUG_RPC_KCM_FREE
2334cycle = (uint32_t)hal_get_cycles();
2335if( cycle > DEBUG_RPC_KCM_FREE )
2336printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2337__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2338#endif
2339}
2340
2341/////////////////////////////////////
2342void rpc_kcm_free_server( xptr_t xp )
2343{
2344#if DEBUG_RPC_KCM_FREE
2345thread_t * this = CURRENT_THREAD;
2346uint32_t cycle = (uint32_t)hal_get_cycles();
2347if( cycle > DEBUG_RPC_KCM_FREE )
2348printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2349__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2350#endif
2351
2352    // get client cluster identifier and pointer on RPC descriptor
2353    cxy_t        client_cxy  = GET_CXY( xp );
2354    rpc_desc_t * desc        = GET_PTR( xp );
2355
2356    // get input arguments "buf" and "kmem_type" from client RPC descriptor
2357    void     * buf = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2358    uint32_t   kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
2359
2360    // releases memory
2361    kmem_req_t  req;
2362    req.type = kmem_type;
2363    req.ptr  = buf;
2364    kmem_free( &req );
2365
2366#if DEBUG_RPC_KCM_FREE
2367cycle = (uint32_t)hal_get_cycles();
2368if( cycle > DEBUG_RPC_KCM_FREE )
2369printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2370__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2371#endif
2372}   
2373
2374/////////////////////////////////////////////////////////////////////////////////////////
2375// [25]          Marshaling functions attached to RPC_MAPPER_SYNC
2376/////////////////////////////////////////////////////////////////////////////////////////
2377
2378///////////////////////////////////////////////////
2379void rpc_mapper_sync_client( cxy_t             cxy,
2380                             struct mapper_s * mapper,
2381                             error_t         * error )
2382{
2383#if DEBUG_RPC_MAPPER_SYNC
2384thread_t * this = CURRENT_THREAD;
2385uint32_t cycle = (uint32_t)hal_get_cycles();
2386if( cycle > DEBUG_RPC_MAPPER_SYNC )
2387printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2388__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2389#endif
2390
2391    uint32_t responses = 1;
2392
2393    // initialise RPC descriptor header
2394    rpc_desc_t  rpc;
2395    rpc.index    = RPC_MAPPER_SYNC;
2396    rpc.blocking = true;
2397    rpc.rsp      = &responses;
2398
2399    // set input arguments in RPC descriptor
2400    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2401
2402    // register RPC request in remote RPC fifo
2403    rpc_send( cxy , &rpc );
2404
2405    // get output values from RPC descriptor
2406    *error   = (error_t)rpc.args[1];
2407
2408#if DEBUG_RPC_MAPPER_SYNC
2409cycle = (uint32_t)hal_get_cycles();
2410if( cycle > DEBUG_RPC_MAPPER_SYNC )
2411printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2412__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2413#endif
2414}
2415
2416////////////////////////////////////////
2417void rpc_mapper_sync_server( xptr_t xp )
2418{
2419#if DEBUG_RPC_MAPPER_SYNC
2420thread_t * this = CURRENT_THREAD;
2421uint32_t cycle = (uint32_t)hal_get_cycles();
2422if( cycle > DEBUG_RPC_MAPPER_SYNC )
2423printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2424__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2425#endif
2426
2427    mapper_t * mapper;
2428    error_t    error;
2429
2430    // get client cluster identifier and pointer on RPC descriptor
2431    cxy_t        client_cxy  = GET_CXY( xp );
2432    rpc_desc_t * desc        = GET_PTR( xp );
2433
2434    // get arguments from client RPC descriptor
2435    mapper  = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2436
2437    // call local kernel function
2438    error = mapper_sync( mapper );
2439
2440    // set output argument to client RPC descriptor
2441    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
2442
2443#if DEBUG_RPC_MAPPER_SYNC
2444cycle = (uint32_t)hal_get_cycles();
2445if( cycle > DEBUG_RPC_MAPPER_SYNC )
2446printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2447__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2448#endif
2449}
2450
2451/////////////////////////////////////////////////////////////////////////////////////////
2452// [25]          Marshaling functions attached to RPC_MAPPER_HANDLE_MISS
2453/////////////////////////////////////////////////////////////////////////////////////////
2454
2455//////////////////////////////////////////////////////////
2456void rpc_mapper_handle_miss_client( cxy_t             cxy,
2457                                    struct mapper_s * mapper,
2458                                    uint32_t          page_id,
2459                                    xptr_t          * page_xp,
2460                                    error_t         * error )
2461{
2462#if DEBUG_RPC_MAPPER_HANDLE_MISS
2463thread_t * this = CURRENT_THREAD;
2464uint32_t cycle = (uint32_t)hal_get_cycles();
2465if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2466printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2467__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2468#endif
2469
2470    uint32_t responses = 1;
2471
2472    // initialise RPC descriptor header
2473    rpc_desc_t  rpc;
2474    rpc.index    = RPC_MAPPER_HANDLE_MISS;
2475    rpc.blocking = true;
2476    rpc.rsp      = &responses;
2477
2478    // set input arguments in RPC descriptor
2479    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2480    rpc.args[1] = (uint64_t)page_id;
2481
2482    // register RPC request in remote RPC fifo
2483    rpc_send( cxy , &rpc );
2484
2485    // get output values from RPC descriptor
2486    *page_xp = (xptr_t)rpc.args[2];
2487    *error   = (error_t)rpc.args[3];
2488
2489#if DEBUG_RPC_MAPPER_HANDLE_MISS
2490cycle = (uint32_t)hal_get_cycles();
2491if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2492printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2493__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2494#endif
2495}
2496
2497///////////////////////////////////////////////
2498void rpc_mapper_handle_miss_server( xptr_t xp )
2499{
2500#if DEBUG_RPC_MAPPER_HANDLE_MISS
2501thread_t * this = CURRENT_THREAD;
2502uint32_t cycle = (uint32_t)hal_get_cycles();
2503if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2504printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2505__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2506#endif
2507
2508    mapper_t * mapper;
2509    uint32_t   page_id;
2510    xptr_t     page_xp;
2511    error_t    error;
2512
2513    // get client cluster identifier and pointer on RPC descriptor
2514    cxy_t        client_cxy  = GET_CXY( xp );
2515    rpc_desc_t * desc        = GET_PTR( xp );
2516
2517    // get arguments from client RPC descriptor
2518    mapper  = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2519    page_id =                       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
2520
2521    // call local kernel function
2522    error = mapper_handle_miss( mapper,
2523                                page_id,
2524                                &page_xp );
2525
2526    // set output argument to client RPC descriptor
2527    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)page_xp );
2528    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
2529
2530#if DEBUG_RPC_MAPPER_HANDLE_MISS
2531cycle = (uint32_t)hal_get_cycles();
2532if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2533printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2534__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2535#endif
2536}
2537
2538/////////////////////////////////////////////////////////////////////////////////////////
2539// [26]  Marshaling functions attached to RPC_VMM_DELETE_VSEG
2540/////////////////////////////////////////////////////////////////////////////////////////
2541
2542//////////////////////////////////////////////////
2543void rpc_vmm_delete_vseg_client( cxy_t        cxy,
2544                                 pid_t        pid,
2545                                 intptr_t     vaddr )
2546{
2547#if DEBUG_RPC_VMM_DELETE_VSEG
2548thread_t * this  = CURRENT_THREAD;
2549uint32_t   cycle = (uint32_t)hal_get_cycles();
2550if( cycle > DEBUG_RPC_VMM_DELETE_VSEG )
2551printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2552__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2553#endif
2554
2555    uint32_t    responses = 1;
2556    rpc_desc_t  rpc;
2557
2558    // initialise RPC descriptor header
2559    rpc.index    = RPC_VMM_DELETE_VSEG;
2560    rpc.blocking = true;
2561    rpc.rsp      = &responses;
2562
2563    // set input arguments in RPC descriptor
2564    rpc.args[0] = (uint64_t)pid;
2565    rpc.args[1] = (uint64_t)vaddr;
2566
2567    // register RPC request in remote RPC fifo
2568    rpc_send( cxy , &rpc );
2569
2570#if DEBUG_RPC_VMM_DELETE_VSEG
2571cycle = (uint32_t)hal_get_cycles();
2572if( cycle > DEBUG_RPC_VMM_DELETE_VSEG )
2573printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2574__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2575#endif
2576}
2577
2578////////////////////////////////////////////
2579void rpc_vmm_delete_vseg_server( xptr_t xp )
2580{
2581#if DEBUG_RPC_VMM_DELETE_VSEG
2582uint32_t cycle = (uint32_t)hal_get_cycles();
2583thread_t * this = CURRENT_THREAD;
2584if( DEBUG_RPC_VMM_DELETE_VSEG < cycle )
2585printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2586__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2587#endif
2588
2589    // get client cluster identifier and pointer on RPC descriptor
2590    cxy_t        client_cxy = GET_CXY( xp );
2591    rpc_desc_t * desc       = GET_PTR( xp );
2592
2593    // get arguments from RPC descriptor
2594    pid_t    pid   = (pid_t)   hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
2595    intptr_t vaddr = (intptr_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
2596
2597    // call relevant kernel function
2598    vmm_delete_vseg( pid , vaddr );
2599
2600#if DEBUG_RPC_VMM_DELETE_VSEG
2601cycle = (uint32_t)hal_get_cycles();
2602if( DEBUG_RPC_VMM_DELETE_VSEG < cycle )
2603printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2604__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2605#endif
2606} 
2607
2608/////////////////////////////////////////////////////////////////////////////////////////
2609// [27]          Marshaling functions attached to RPC_VMM_CREATE_VSEG
2610/////////////////////////////////////////////////////////////////////////////////////////
2611
2612////////////////////////////////////////////////////////
2613void rpc_vmm_create_vseg_client( cxy_t              cxy,
2614                                 struct process_s * process,
2615                                 vseg_type_t        type,
2616                                 intptr_t           base,
2617                                 uint32_t           size,
2618                                 uint32_t           file_offset,
2619                                 uint32_t           file_size,
2620                                 xptr_t             mapper_xp,
2621                                 cxy_t              vseg_cxy,
2622                                 struct vseg_s   ** vseg )
2623{
2624#if DEBUG_RPC_VMM_CREATE_VSEG
2625thread_t * this = CURRENT_THREAD;
2626uint32_t cycle = (uint32_t)hal_get_cycles();
2627if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2628printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2629__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2630#endif
2631
2632    uint32_t responses = 1;
2633
2634    // initialise RPC descriptor header
2635    rpc_desc_t  rpc;
2636    rpc.index    = RPC_VMM_CREATE_VSEG;
2637    rpc.blocking = true;
2638    rpc.rsp      = &responses;
2639
2640    // set input arguments in RPC descriptor
2641    rpc.args[0] = (uint64_t)(intptr_t)process;
2642    rpc.args[1] = (uint64_t)type;
2643    rpc.args[2] = (uint64_t)base;
2644    rpc.args[3] = (uint64_t)size;
2645    rpc.args[4] = (uint64_t)file_offset;
2646    rpc.args[5] = (uint64_t)file_size;
2647    rpc.args[6] = (uint64_t)mapper_xp;
2648    rpc.args[7] = (uint64_t)vseg_cxy;
2649
2650    // register RPC request in remote RPC fifo
2651    rpc_send( cxy , &rpc );
2652
2653    // get output values from RPC descriptor
2654    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
2655
2656#if DEBUG_RPC_VMM_CREATE_VSEG
2657cycle = (uint32_t)hal_get_cycles();
2658if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2659printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2660__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2661#endif
2662}
2663
2664////////////////////////////////////////////
2665void rpc_vmm_create_vseg_server( xptr_t xp )
2666{
2667#if DEBUG_RPC_VMM_CREATE_VSEG
2668thread_t * this = CURRENT_THREAD;
2669uint32_t cycle = (uint32_t)hal_get_cycles();
2670if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2671printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2672__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2673#endif
2674
2675    // get client cluster identifier and pointer on RPC descriptor
2676    cxy_t        cxy  = GET_CXY( xp );
2677    rpc_desc_t * desc = GET_PTR( xp );
2678
2679    // get input arguments from client RPC descriptor
2680    process_t * process     = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2681    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_l64( XPTR(cxy , &desc->args[1]));
2682    intptr_t    base        = (intptr_t)             hal_remote_l64( XPTR(cxy , &desc->args[2]));
2683    uint32_t    size        = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[3]));
2684    uint32_t    file_offset = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[4]));
2685    uint32_t    file_size   = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[5]));
2686    xptr_t      mapper_xp   = (xptr_t)               hal_remote_l64( XPTR(cxy , &desc->args[6]));
2687    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_l64( XPTR(cxy , &desc->args[7]));
2688   
2689    // call local kernel function
2690    vseg_t * vseg = vmm_create_vseg( process,
2691                                     type,
2692                                     base,
2693                                     size,
2694                                     file_offset,
2695                                     file_size,
2696                                     mapper_xp,
2697                                     vseg_cxy ); 
2698
2699    // set output arguments into client RPC descriptor
2700    hal_remote_s64( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
2701
2702#if DEBUG_RPC_VMM_CREATE_VSEG
2703cycle = (uint32_t)hal_get_cycles();
2704if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2705printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2706__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2707#endif
2708}
2709
2710/////////////////////////////////////////////////////////////////////////////////////////
2711// [28]          Marshaling functions attached to RPC_VMM_SET_COW
2712/////////////////////////////////////////////////////////////////////////////////////////
2713
2714/////////////////////////////////////////////
2715void rpc_vmm_set_cow_client( cxy_t       cxy,
2716                             process_t * process )
2717{
2718#if DEBUG_RPC_VMM_SET_COW
2719thread_t * this = CURRENT_THREAD;
2720uint32_t cycle = (uint32_t)hal_get_cycles();
2721if( cycle > DEBUG_RPC_VMM_SET_COW )
2722printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2723__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2724#endif
2725
2726    uint32_t responses = 1;
2727
2728    // initialise RPC descriptor header
2729    rpc_desc_t  rpc;
2730    rpc.index    = RPC_VMM_SET_COW;
2731    rpc.blocking = true;
2732    rpc.rsp      = &responses;
2733
2734    // set input arguments in RPC descriptor
2735    rpc.args[0] = (uint64_t)(intptr_t)process;
2736
2737    // register RPC request in remote RPC fifo
2738    rpc_send( cxy , &rpc );
2739
2740#if DEBUG_RPC_VMM_SET_COW
2741cycle = (uint32_t)hal_get_cycles();
2742if( cycle > DEBUG_RPC_VMM_SET_COW )
2743printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2744__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2745#endif
2746}
2747
2748////////////////////////////////////////
2749void rpc_vmm_set_cow_server( xptr_t xp )
2750{
2751#if DEBUG_RPC_VMM_SET_COW
2752thread_t * this = CURRENT_THREAD;
2753uint32_t cycle = (uint32_t)hal_get_cycles();
2754if( cycle > DEBUG_RPC_VMM_SET_COW )
2755printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2756__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2757#endif
2758
2759    process_t * process;
2760
2761    // get client cluster identifier and pointer on RPC descriptor
2762    cxy_t        cxy  = GET_CXY( xp );
2763    rpc_desc_t * desc = GET_PTR( xp );
2764
2765    // get input arguments from client RPC descriptor
2766    process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2767   
2768    // call local kernel function
2769    vmm_set_cow( process );
2770
2771#if DEBUG_RPC_VMM_SET_COW
2772cycle = (uint32_t)hal_get_cycles();
2773if( cycle > DEBUG_RPC_VMM_SET_COW )
2774printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2775__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2776#endif
2777}
2778
2779/////////////////////////////////////////////////////////////////////////////////////////
2780// [29]          Marshaling functions attached to RPC_VMM_DISPLAY
2781/////////////////////////////////////////////////////////////////////////////////////////
2782
2783/////////////////////////////////////////////
2784void rpc_hal_vmm_display_client( cxy_t       cxy,
2785                             process_t * process,
2786                             bool_t      detailed )
2787{
2788#if DEBUG_RPC_VMM_DISPLAY
2789thread_t * this = CURRENT_THREAD;
2790uint32_t cycle = (uint32_t)hal_get_cycles();
2791if( cycle > DEBUG_RPC_VMM_DISPLAY )
2792printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2793__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2794#endif
2795
2796    uint32_t responses = 1;
2797
2798    // initialise RPC descriptor header
2799    rpc_desc_t  rpc;
2800    rpc.index    = RPC_VMM_DISPLAY;
2801    rpc.blocking = true;
2802    rpc.rsp      = &responses;
2803
2804    // set input arguments in RPC descriptor
2805    rpc.args[0] = (uint64_t)(intptr_t)process;
2806    rpc.args[1] = (uint64_t)detailed;
2807
2808    // register RPC request in remote RPC fifo
2809    rpc_send( cxy , &rpc );
2810
2811#if DEBUG_RPC_VMM_DISPLAY
2812cycle = (uint32_t)hal_get_cycles();
2813if( cycle > DEBUG_RPC_VMM_DISPLAY )
2814printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2815__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2816#endif
2817}
2818
2819////////////////////////////////////////
2820void rpc_hal_vmm_display_server( xptr_t xp )
2821{
2822#if DEBUG_RPC_VMM_DISPLAY
2823thread_t * this = CURRENT_THREAD;
2824uint32_t cycle = (uint32_t)hal_get_cycles();
2825if( cycle > DEBUG_RPC_VMM_DISPLAY )
2826printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2827__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2828#endif
2829
2830    process_t * process;
2831    bool_t      detailed;
2832
2833    // get client cluster identifier and pointer on RPC descriptor
2834    cxy_t        cxy  = GET_CXY( xp );
2835    rpc_desc_t * desc = GET_PTR( xp );
2836
2837    // get input arguments from client RPC descriptor
2838    process  = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2839    detailed = (bool_t)               hal_remote_l64( XPTR(cxy , &desc->args[1]));
2840   
2841    // call local kernel function
2842    hal_vmm_display( process , detailed );
2843
2844#if DEBUG_RPC_VMM_DISPLAY
2845cycle = (uint32_t)hal_get_cycles();
2846if( cycle > DEBUG_RPC_VMM_DISPLAY )
2847printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2848__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2849#endif
2850}
2851
2852
Note: See TracBrowser for help on using the repository browser.