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

Last change on this file since 624 was 624, checked in by alain, 5 years ago

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

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