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

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

Improve the FAT32 file system to support cat, rm, cp commands.

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