| [1] | 1 | /* | 
|---|
 | 2 |  * rpc.c - RPC related operations implementation. | 
|---|
 | 3 |  *  | 
|---|
| [23] | 4 |  * Author    Alain Greiner (2016,2017) | 
|---|
| [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> | 
|---|
| [1] | 25 | #include <hal_types.h> | 
|---|
 | 26 | #include <hal_atomic.h> | 
|---|
 | 27 | #include <hal_remote.h> | 
|---|
 | 28 | #include <hal_irqmask.h> | 
|---|
 | 29 | #include <hal_special.h> | 
|---|
 | 30 | #include <printk.h> | 
|---|
 | 31 | #include <remote_sem.h> | 
|---|
 | 32 | #include <core.h> | 
|---|
 | 33 | #include <mapper.h> | 
|---|
| [5] | 34 | #include <chdev.h> | 
|---|
| [1] | 35 | #include <bits.h> | 
|---|
 | 36 | #include <thread.h> | 
|---|
 | 37 | #include <cluster.h> | 
|---|
 | 38 | #include <process.h> | 
|---|
 | 39 | #include <vfs.h> | 
|---|
 | 40 | #include <fatfs.h> | 
|---|
| [23] | 41 | #include <signal.h> | 
|---|
| [1] | 42 | #include <rpc.h> | 
|---|
 | 43 |  | 
|---|
 | 44 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 45 | //      array of function pointers  (must be consistent with enum in rpc.h)  | 
|---|
 | 46 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 47 |  | 
|---|
 | 48 | rpc_server_t * rpc_server[RPC_MAX_INDEX] = | 
|---|
 | 49 | { | 
|---|
 | 50 |     &rpc_pmem_get_pages_server,         // 0 | 
|---|
 | 51 |     &rpc_process_pid_alloc_server,      // 1 | 
|---|
 | 52 |     &rpc_process_exec_server,           // 2 | 
|---|
 | 53 |     &rpc_process_kill_server,           // 3 | 
|---|
 | 54 |     &rpc_thread_user_create_server,     // 4 | 
|---|
 | 55 |     &rpc_thread_kernel_create_server,   // 5 | 
|---|
| [23] | 56 |     &rpc_signal_rise_server,            // 6                        | 
|---|
| [5] | 57 |     &rpc_undefined,                     // 7 | 
|---|
| [1] | 58 |     &rpc_undefined,                     // 8 | 
|---|
 | 59 |     &rpc_undefined,                     // 9 | 
|---|
 | 60 |  | 
|---|
 | 61 |     &rpc_vfs_inode_create_server,       // 10   | 
|---|
 | 62 |     &rpc_vfs_inode_destroy_server,      // 11   | 
|---|
 | 63 |     &rpc_vfs_dentry_create_server,      // 12   | 
|---|
 | 64 |     &rpc_vfs_dentry_destroy_server,     // 13   | 
|---|
| [23] | 65 |     &rpc_vfs_file_create_server,        // 14 | 
|---|
 | 66 |     &rpc_vfs_file_destroy_server,       // 15 | 
|---|
| [238] | 67 |     &rpc_vfs_inode_load_server,         // 16 | 
|---|
 | 68 |     &rpc_vfs_mapper_load_all_server,    // 17 | 
|---|
 | 69 |     &rpc_fatfs_get_cluster_server,      // 18 | 
|---|
| [1] | 70 |     &rpc_undefined,                     // 19 | 
|---|
 | 71 |  | 
|---|
 | 72 |     &rpc_vmm_get_ref_vseg_server,       // 20 | 
|---|
 | 73 |     &rpc_vmm_get_pte_server,            // 21 | 
|---|
| [23] | 74 |     &rpc_kcm_alloc_server,              // 22 | 
|---|
 | 75 |     &rpc_kcm_free_server,               // 23 | 
|---|
| [265] | 76 |     &rpc_mapper_move_buffer_server,     // 24 | 
|---|
| [1] | 77 |     &rpc_undefined,                     // 25 | 
|---|
 | 78 |     &rpc_undefined,                     // 26 | 
|---|
 | 79 |     &rpc_undefined,                     // 27 | 
|---|
 | 80 |     &rpc_undefined,                     // 28 | 
|---|
 | 81 |     &rpc_undefined,                     // 29 | 
|---|
 | 82 | }; | 
|---|
 | 83 |  | 
|---|
 | 84 | ////////////////////////////////////////////// | 
|---|
 | 85 | void __attribute__((noinline)) rpc_undefined() | 
|---|
 | 86 | { | 
|---|
 | 87 |     printk("\n[PANIC] ‰s called in cluster %x\n", __FUNCTION__ , local_cxy ); | 
|---|
 | 88 |     hal_core_sleep(); | 
|---|
 | 89 | } | 
|---|
 | 90 |  | 
|---|
 | 91 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 92 | // [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES  | 
|---|
| [1] | 93 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 94 |  | 
|---|
 | 95 | /////////////////////////////////////////////// | 
|---|
 | 96 | void rpc_pmem_get_pages_client( cxy_t      cxy, | 
|---|
 | 97 |                                 uint32_t   order,      // in  | 
|---|
 | 98 |                                 error_t  * error,      // out  | 
|---|
 | 99 |                                 uint32_t * ppn )       // out  | 
|---|
 | 100 | { | 
|---|
| [238] | 101 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 102 |  | 
|---|
 | 103 |     // initialise RPC descriptor header  | 
|---|
 | 104 |     rpc_desc_t  rpc; | 
|---|
 | 105 |     rpc.index    = RPC_PMEM_GET_PAGES; | 
|---|
 | 106 |     rpc.response = 1; | 
|---|
 | 107 |  | 
|---|
 | 108 |     // set input arguments in RPC descriptor  | 
|---|
 | 109 |     rpc.args[0] = (uint64_t)order; | 
|---|
 | 110 |  | 
|---|
 | 111 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 112 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 113 |  | 
|---|
 | 114 |     // get output arguments RPC descriptor | 
|---|
 | 115 |     *error  = (error_t)rpc.args[0];      | 
|---|
 | 116 |     *ppn    = (uint32_t)rpc.args[1]; | 
|---|
 | 117 | } | 
|---|
 | 118 |  | 
|---|
 | 119 | /////////////////////////////////////////// | 
|---|
 | 120 | void rpc_pmem_get_pages_server( xptr_t xp ) | 
|---|
 | 121 | { | 
|---|
 | 122 |     uint32_t order;  // input | 
|---|
 | 123 |     error_t  error;  // output | 
|---|
 | 124 |     uint32_t ppn;    // output | 
|---|
 | 125 |  | 
|---|
 | 126 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 127 |     cxy_t        cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 128 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 129 |  | 
|---|
 | 130 |     // get input arguments from client RPC descriptor | 
|---|
 | 131 |     order = hal_remote_lw( XPTR( cxy , &desc->args[0] ) ); | 
|---|
 | 132 |      | 
|---|
 | 133 |     // call local pmem allocator | 
|---|
 | 134 |     page_t * page = ppm_alloc_pages( order );  | 
|---|
 | 135 |     error = ( page == NULL ) ? ENOMEM : 0; | 
|---|
 | 136 |     ppn   = ppm_page2ppn( page ); | 
|---|
 | 137 |  | 
|---|
 | 138 |     // set output arguments into client RPC descriptor | 
|---|
 | 139 |     hal_remote_sw( XPTR( cxy , &desc->args[0] ) , error ); | 
|---|
 | 140 |     hal_remote_sw( XPTR( cxy , &desc->args[1] ) , ppn ); | 
|---|
 | 141 | } | 
|---|
 | 142 |  | 
|---|
 | 143 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 144 | // [1]           Marshaling functions attached to RPC_PROCESS_PID_ALLOC | 
|---|
| [1] | 145 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 146 |  | 
|---|
 | 147 | ////////////////////////////////////////////////// | 
|---|
 | 148 | void rpc_process_pid_alloc_client( cxy_t       cxy,  | 
|---|
 | 149 |                                    process_t * process,  // in | 
|---|
 | 150 |                                    error_t   * error,    // out | 
|---|
 | 151 |                                    pid_t     * pid )     // out | 
|---|
 | 152 | { | 
|---|
| [238] | 153 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 154 |  | 
|---|
 | 155 |     // initialise RPC descriptor header  | 
|---|
 | 156 |     rpc_desc_t  rpc; | 
|---|
 | 157 |     rpc.index    = RPC_PROCESS_PID_ALLOC; | 
|---|
 | 158 |     rpc.response = 1; | 
|---|
 | 159 |  | 
|---|
 | 160 |     // set input arguments in RPC descriptor  | 
|---|
 | 161 |     rpc.args[0] = (uint64_t)(intptr_t)process; | 
|---|
 | 162 |  | 
|---|
 | 163 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 164 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 165 |  | 
|---|
 | 166 |     // get output arguments RPC descriptor | 
|---|
 | 167 |     *pid    = (pid_t)rpc.args[1]; | 
|---|
 | 168 |     *error  = (error_t)rpc.args[2];      | 
|---|
 | 169 | } | 
|---|
 | 170 |  | 
|---|
 | 171 | ////////////////////////////////////////////// | 
|---|
 | 172 | void rpc_process_pid_alloc_server( xptr_t xp ) | 
|---|
 | 173 | { | 
|---|
 | 174 |     process_t * process;   // input  : client process descriptor | 
|---|
 | 175 |     error_t     error;     // output : error status | 
|---|
 | 176 |     pid_t       pid;       // output : process identifier | 
|---|
 | 177 |  | 
|---|
 | 178 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 179 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 180 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 181 |  | 
|---|
 | 182 |     // get input argument from client RPC descriptor | 
|---|
 | 183 |     process = (process_t*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 184 |      | 
|---|
 | 185 |     // call local pid allocator  | 
|---|
 | 186 |     xptr_t xp_process = XPTR( client_cxy , process ); | 
|---|
 | 187 |     error = cluster_pid_alloc( xp_process , &pid );  | 
|---|
 | 188 |  | 
|---|
 | 189 |     // set output arguments into client RPC descriptor | 
|---|
 | 190 |     hal_remote_sw( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)error ); | 
|---|
 | 191 |     hal_remote_sw( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)pid ); | 
|---|
 | 192 | } | 
|---|
 | 193 |  | 
|---|
 | 194 |  | 
|---|
 | 195 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 196 | // [2]           Marshaling functions attached to RPC_PROCESS_EXEC  | 
|---|
| [1] | 197 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 198 |  | 
|---|
 | 199 | //////////////////////////////////////////////// | 
|---|
 | 200 | void rpc_process_exec_client( cxy_t         cxy, | 
|---|
 | 201 |                               exec_info_t * info,     // in | 
|---|
 | 202 |                               error_t     * error )   // out | 
|---|
 | 203 | { | 
|---|
| [238] | 204 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 205 |  | 
|---|
 | 206 |     // initialise RPC descriptor header  | 
|---|
 | 207 |     rpc_desc_t  rpc; | 
|---|
 | 208 |     rpc.index    = RPC_PROCESS_EXEC; | 
|---|
 | 209 |     rpc.response = 1; | 
|---|
 | 210 |  | 
|---|
 | 211 |     // set input arguments in RPC descriptor   | 
|---|
 | 212 |     rpc.args[0] = (uint64_t)(intptr_t)info; | 
|---|
 | 213 |  | 
|---|
 | 214 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 215 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 216 |  | 
|---|
 | 217 |     // get output arguments from RPC descriptor | 
|---|
 | 218 |     *error  = (error_t)rpc.args[1];      | 
|---|
 | 219 | } | 
|---|
 | 220 |  | 
|---|
 | 221 | ///////////////////////////////////////// | 
|---|
 | 222 | void rpc_process_exec_server( xptr_t xp ) | 
|---|
 | 223 | { | 
|---|
 | 224 |     exec_info_t * ptr;       // local pointer on remote exec_info structure | 
|---|
 | 225 |     exec_info_t   info;      // local copy of exec_info structure | 
|---|
 | 226 |     error_t       error;     // local error error status | 
|---|
 | 227 |  | 
|---|
 | 228 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 229 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 230 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 231 |  | 
|---|
 | 232 |     // get pointer on exec_info structure in client cluster from RPC descriptor | 
|---|
 | 233 |     ptr = (exec_info_t*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 234 |  | 
|---|
 | 235 |     // copy exec_info structure from client buffer to server buffer | 
|---|
 | 236 |     hal_remote_memcpy( XPTR( client_cxy , ptr ), | 
|---|
 | 237 |                        XPTR( local_cxy , &info ), | 
|---|
 | 238 |                        sizeof(exec_info_t) ); | 
|---|
 | 239 |  | 
|---|
 | 240 |     // call local kernel function | 
|---|
 | 241 |     error = process_make_exec( &info );  | 
|---|
 | 242 |  | 
|---|
 | 243 |     // set output argument into client RPC descriptor | 
|---|
 | 244 |     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); | 
|---|
 | 245 | } | 
|---|
 | 246 |  | 
|---|
 | 247 |  | 
|---|
 | 248 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 249 | // [3]           Marshaling functions attached to RPC_PROCESS_KILL  | 
|---|
| [1] | 250 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 251 |  | 
|---|
 | 252 | /////////////////////////////////////////////////// | 
|---|
 | 253 | void rpc_process_kill_client( process_t * process )  | 
|---|
 | 254 | { | 
|---|
 | 255 |     // only reference cluster can send this RPC | 
|---|
| [238] | 256 |     assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ , | 
|---|
 | 257 |             "caller must be reference process cluster\n"); | 
|---|
| [1] | 258 |  | 
|---|
 | 259 |     // get local process index in reference cluster | 
|---|
 | 260 |     lpid_t lpid = LPID_FROM_PID( process->pid ); | 
|---|
 | 261 |  | 
|---|
 | 262 |     // get local process manager pointer | 
|---|
 | 263 |     pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; | 
|---|
 | 264 |  | 
|---|
 | 265 |     // get number of copies | 
|---|
 | 266 |     uint32_t copies = pmgr->copies_nr[lpid]; | 
|---|
 | 267 |  | 
|---|
 | 268 |     // initialise RPC descriptor  | 
|---|
 | 269 |     rpc_desc_t  rpc; | 
|---|
 | 270 |     rpc.index    = RPC_PROCESS_KILL; | 
|---|
 | 271 |     rpc.response = copies; | 
|---|
 | 272 |     rpc.args[0]  = (uint64_t)process->pid; | 
|---|
 | 273 |  | 
|---|
 | 274 |     // loop on list of copies to send RPC | 
|---|
 | 275 |     xptr_t  iter; | 
|---|
 | 276 |     XLIST_FOREACH( XPTR( local_cxy , &pmgr->copies_root[lpid] ) , iter ) | 
|---|
 | 277 |     { | 
|---|
 | 278 |         // get cluster_identifier for current copy | 
|---|
 | 279 |         cxy_t  target_cxy = GET_CXY( iter ); | 
|---|
 | 280 |  | 
|---|
 | 281 |         // register RPC request in remote RPC fifo ... but the reference | 
|---|
 | 282 |         if( target_cxy != local_cxy ) rpc_send_sync( target_cxy , &rpc ); | 
|---|
 | 283 |     } | 
|---|
 | 284 | }   | 
|---|
 | 285 |  | 
|---|
 | 286 | ///////////////////////////////////////// | 
|---|
 | 287 | void rpc_process_kill_server( xptr_t xp ) | 
|---|
 | 288 | { | 
|---|
 | 289 |     pid_t       pid; | 
|---|
 | 290 |     process_t * process;   | 
|---|
 | 291 |  | 
|---|
 | 292 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 293 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 294 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 295 |  | 
|---|
 | 296 |     // get pid argument from RPC descriptor | 
|---|
 | 297 |     pid = (pid_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 298 |  | 
|---|
 | 299 |     // get process pointer to call local kernel function | 
|---|
 | 300 |     process = cluster_get_local_process_from_pid( pid ); | 
|---|
 | 301 |  | 
|---|
 | 302 |     if( process == NULL )  // process not found => do nothing | 
|---|
 | 303 |     { | 
|---|
 | 304 |         printk("\n[WARNING] in %s : process %x not found in cluster %x\n", | 
|---|
 | 305 |                __FUNCTION__ , pid , local_cxy ); | 
|---|
 | 306 |     } | 
|---|
 | 307 |     else                   // destroy process  | 
|---|
 | 308 |     { | 
|---|
 | 309 |         process_kill( process );  | 
|---|
 | 310 |     } | 
|---|
 | 311 | }  | 
|---|
 | 312 |  | 
|---|
 | 313 |  | 
|---|
 | 314 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 315 | // [4]           Marshaling functions attached to RPC_THREAD_USER_CREATE                | 
|---|
| [1] | 316 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 317 |  | 
|---|
 | 318 | ///////////////////////////////////////////////////////// | 
|---|
 | 319 | void rpc_thread_user_create_client( cxy_t            cxy,   | 
|---|
| [23] | 320 |                                     pid_t            pid,         // in | 
|---|
 | 321 |                                     void           * start_func,  // in | 
|---|
 | 322 |                                     void           * start_arg,   // in | 
|---|
| [1] | 323 |                                     pthread_attr_t * attr,        // in | 
|---|
 | 324 |                                     xptr_t         * thread_xp,   // out  | 
|---|
 | 325 |                                     error_t        * error )      // out  | 
|---|
 | 326 | { | 
|---|
| [238] | 327 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 328 |  | 
|---|
 | 329 |     // initialise RPC descriptor header  | 
|---|
 | 330 |     rpc_desc_t  rpc; | 
|---|
 | 331 |     rpc.index    = RPC_THREAD_USER_CREATE; | 
|---|
 | 332 |     rpc.response = 1; | 
|---|
 | 333 |  | 
|---|
 | 334 |     // set input arguments in RPC descriptor  | 
|---|
| [23] | 335 |     rpc.args[0] = (uint64_t)pid; | 
|---|
 | 336 |     rpc.args[1] = (uint64_t)(intptr_t)start_func; | 
|---|
 | 337 |     rpc.args[2] = (uint64_t)(intptr_t)start_arg; | 
|---|
 | 338 |     rpc.args[3] = (uint64_t)(intptr_t)attr; | 
|---|
| [1] | 339 |  | 
|---|
 | 340 |     // register RPC request in remote RPC fifo  | 
|---|
 | 341 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 342 |  | 
|---|
 | 343 |     // get output arguments from RPC descriptor | 
|---|
| [23] | 344 |     *thread_xp = (xptr_t)rpc.args[4]; | 
|---|
 | 345 |     *error     = (error_t)rpc.args[5]; | 
|---|
| [1] | 346 | } | 
|---|
 | 347 |  | 
|---|
 | 348 | /////////////////////////////////////////////// | 
|---|
 | 349 | void rpc_thread_user_create_server( xptr_t xp ) | 
|---|
 | 350 | { | 
|---|
 | 351 |     pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster  | 
|---|
 | 352 |     pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster | 
|---|
 | 353 |     thread_t       * thread_ptr; // local pointer on thread descriptor | 
|---|
 | 354 |     xptr_t           thread_xp;  // extended pointer on thread descriptor | 
|---|
| [23] | 355 |  | 
|---|
| [1] | 356 |     pid_t            pid;        // process identifier | 
|---|
| [23] | 357 |     void           * start_func; | 
|---|
 | 358 |     void           * start_arg; | 
|---|
 | 359 |     error_t          error; | 
|---|
| [1] | 360 |  | 
|---|
 | 361 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 362 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 363 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 364 |  | 
|---|
 | 365 |     // get pointer on attributes structure in client cluster from RPC descriptor | 
|---|
 | 366 |  | 
|---|
| [23] | 367 |     // get input arguments from RPC descriptor | 
|---|
 | 368 |     pid        = (pid_t)                     hal_remote_lwd(XPTR(client_cxy , &desc->args[0])); | 
|---|
 | 369 |     start_func = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[1])); | 
|---|
 | 370 |     start_arg  = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[2])); | 
|---|
 | 371 |     attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[3])); | 
|---|
 | 372 |  | 
|---|
| [1] | 373 |     // makes a local copy of attributes structure | 
|---|
 | 374 |     hal_remote_memcpy( XPTR( local_cxy , &attr_copy ), | 
|---|
 | 375 |                        XPTR( client_cxy , attr_ptr ),  | 
|---|
 | 376 |                        sizeof(pthread_attr_t) ); | 
|---|
 | 377 |      | 
|---|
| [23] | 378 |     assert( (attr_copy.cxy == local_cxy) , __FUNCTION__ , "bad target cluster\n" ); | 
|---|
| [1] | 379 |  | 
|---|
| [23] | 380 |     // call kernel function | 
|---|
 | 381 |     error = thread_user_create( pid, | 
|---|
 | 382 |                                 start_func, | 
|---|
 | 383 |                                 start_arg, | 
|---|
 | 384 |                                 &attr_copy, | 
|---|
 | 385 |                                 &thread_ptr ); | 
|---|
| [1] | 386 |  | 
|---|
 | 387 |     // set output arguments | 
|---|
 | 388 |     thread_xp = XPTR( local_cxy , thread_ptr ); | 
|---|
 | 389 |     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); | 
|---|
 | 390 |     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp ); | 
|---|
 | 391 | } | 
|---|
 | 392 |  | 
|---|
 | 393 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 394 | // [5]           Marshaling functions attached to RPC_THREAD_KERNEL_CREATE | 
|---|
| [1] | 395 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 396 |  | 
|---|
 | 397 | //////////////////////////////////////////////////// | 
|---|
 | 398 | void rpc_thread_kernel_create_client( cxy_t     cxy, | 
|---|
 | 399 |                                       uint32_t  type,        // in | 
|---|
 | 400 |                                       void    * func,        // in | 
|---|
 | 401 |                                       void    * args,        // in | 
|---|
 | 402 |                                       xptr_t  * thread_xp,   // out | 
|---|
 | 403 |                                       error_t * error )      // out | 
|---|
 | 404 | { | 
|---|
| [238] | 405 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 406 |  | 
|---|
 | 407 |     // initialise RPC descriptor header  | 
|---|
 | 408 |     rpc_desc_t  rpc; | 
|---|
 | 409 |     rpc.index    = RPC_THREAD_KERNEL_CREATE; | 
|---|
 | 410 |     rpc.response = 1; | 
|---|
 | 411 |  | 
|---|
 | 412 |     // set input arguments in RPC descriptor  | 
|---|
 | 413 |     rpc.args[0] = (uint64_t)type; | 
|---|
 | 414 |     rpc.args[1] = (uint64_t)(intptr_t)func; | 
|---|
 | 415 |     rpc.args[2] = (uint64_t)(intptr_t)args; | 
|---|
 | 416 |      | 
|---|
 | 417 |     // register RPC request in remote RPC fifo  | 
|---|
 | 418 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 419 |  | 
|---|
 | 420 |     // get output arguments from RPC descriptor | 
|---|
 | 421 |     *thread_xp = (xptr_t)rpc.args[3]; | 
|---|
 | 422 |     *error     = (error_t)rpc.args[4]; | 
|---|
 | 423 | } | 
|---|
 | 424 |  | 
|---|
 | 425 | ///////////////////////////////////////////////// | 
|---|
 | 426 | void rpc_thread_kernel_create_server( xptr_t xp ) | 
|---|
 | 427 | { | 
|---|
 | 428 |     thread_t       * thread_ptr;  // local pointer on thread descriptor | 
|---|
 | 429 |     xptr_t           thread_xp;   // extended pointer on thread descriptor | 
|---|
 | 430 |     lid_t            core_lid;    // core local index | 
|---|
 | 431 |     error_t          error;     | 
|---|
 | 432 |  | 
|---|
 | 433 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 434 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 435 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 436 |  | 
|---|
 | 437 |     // get attributes from RPC descriptor | 
|---|
 | 438 |     uint32_t  type = (uint32_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 439 |     void    * func = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 440 |     void    * args = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); | 
|---|
 | 441 |  | 
|---|
 | 442 |     // select one core | 
|---|
 | 443 |     core_lid = cluster_select_local_core(); | 
|---|
 | 444 |  | 
|---|
 | 445 |     // call local kernel function | 
|---|
 | 446 |     error = thread_kernel_create( &thread_ptr , type , func , args , core_lid ); | 
|---|
 | 447 |  | 
|---|
 | 448 |     // set output arguments | 
|---|
 | 449 |     thread_xp = XPTR( local_cxy , thread_ptr ); | 
|---|
 | 450 |     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); | 
|---|
 | 451 |     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp ); | 
|---|
 | 452 | } | 
|---|
 | 453 |  | 
|---|
 | 454 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 455 | // [6]           Marshaling functions attached to RPC_SIGNAL_RISE | 
|---|
| [1] | 456 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 457 |  | 
|---|
| [23] | 458 | ///////////////////////////////////////////// | 
|---|
 | 459 | void rpc_signal_rise_client( cxy_t       cxy, | 
|---|
 | 460 |                              process_t * process,    // in | 
|---|
 | 461 |                              uint32_t    sig_id )    // in | 
|---|
 | 462 | { | 
|---|
| [238] | 463 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [23] | 464 |  | 
|---|
 | 465 |     // initialise RPC descriptor header  | 
|---|
 | 466 |     rpc_desc_t  rpc; | 
|---|
 | 467 |     rpc.index    = RPC_SIGNAL_RISE; | 
|---|
 | 468 |     rpc.response = 1; | 
|---|
 | 469 |  | 
|---|
 | 470 |     // set input arguments in RPC descriptor  | 
|---|
 | 471 |     rpc.args[0] = (uint64_t)(intptr_t)process; | 
|---|
 | 472 |     rpc.args[1] = (uint64_t)sig_id; | 
|---|
 | 473 |      | 
|---|
 | 474 |     // register RPC request in remote RPC fifo  | 
|---|
 | 475 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 476 | } | 
|---|
 | 477 |  | 
|---|
 | 478 | ////////////////////////////////////////                              | 
|---|
 | 479 | void rpc_signal_rise_server( xptr_t xp ) | 
|---|
 | 480 | { | 
|---|
 | 481 |     process_t  * process;  // local pointer on process descriptor | 
|---|
 | 482 |     uint32_t     sig_id;   // signal index | 
|---|
 | 483 |  | 
|---|
 | 484 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 485 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 486 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 487 |  | 
|---|
 | 488 |     // get attributes from RPC descriptor | 
|---|
 | 489 |     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 490 |     sig_id  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 491 |  | 
|---|
 | 492 |     // call local kernel function | 
|---|
 | 493 |     signal_rise( process , sig_id ); | 
|---|
 | 494 | } | 
|---|
 | 495 |  | 
|---|
 | 496 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 497 | // [10]          Marshaling functions attached to RPC_VFS_INODE_CREATE  | 
|---|
 | 498 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 499 |  | 
|---|
| [1] | 500 | ///////////////////////////////////////////////////// | 
|---|
 | 501 | void rpc_vfs_inode_create_client( cxy_t          cxy,      | 
|---|
 | 502 |                                   xptr_t         dentry_xp,  // in | 
|---|
| [23] | 503 |                                   uint32_t       fs_type,    // in | 
|---|
 | 504 |                                   uint32_t       inode_type, // in | 
|---|
| [188] | 505 |                                   void         * extend,     // in | 
|---|
| [1] | 506 |                                   uint32_t       attr,       // in | 
|---|
| [23] | 507 |                                   uint32_t       rights,     // in | 
|---|
| [1] | 508 |                                   uint32_t       uid,        // in | 
|---|
 | 509 |                                   uint32_t       gid,        // in | 
|---|
 | 510 |                                   xptr_t       * inode_xp,   // out | 
|---|
 | 511 |                                   error_t      * error )     // out | 
|---|
 | 512 | { | 
|---|
| [238] | 513 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 514 |  | 
|---|
 | 515 |     // initialise RPC descriptor header  | 
|---|
 | 516 |     rpc_desc_t  rpc; | 
|---|
 | 517 |     rpc.index    = RPC_VFS_INODE_CREATE; | 
|---|
 | 518 |     rpc.response = 1; | 
|---|
 | 519 |  | 
|---|
 | 520 |     // set input arguments in RPC descriptor  | 
|---|
 | 521 |     rpc.args[0] = (uint64_t)dentry_xp; | 
|---|
| [23] | 522 |     rpc.args[1] = (uint64_t)fs_type; | 
|---|
 | 523 |     rpc.args[2] = (uint64_t)inode_type; | 
|---|
| [188] | 524 |     rpc.args[3] = (uint64_t)(intptr_t)extend; | 
|---|
 | 525 |     rpc.args[4] = (uint64_t)attr; | 
|---|
 | 526 |     rpc.args[5] = (uint64_t)rights; | 
|---|
 | 527 |     rpc.args[6] = (uint64_t)uid; | 
|---|
 | 528 |     rpc.args[7] = (uint64_t)gid; | 
|---|
| [1] | 529 |  | 
|---|
 | 530 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 531 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 532 |  | 
|---|
 | 533 |     // get output values from RPC descriptor | 
|---|
| [188] | 534 |     *inode_xp = (xptr_t)rpc.args[8]; | 
|---|
 | 535 |     *error    = (error_t)rpc.args[9]; | 
|---|
| [1] | 536 | } | 
|---|
 | 537 |  | 
|---|
 | 538 | ///////////////////////////////////////////// | 
|---|
 | 539 | void rpc_vfs_inode_create_server( xptr_t xp ) | 
|---|
 | 540 | { | 
|---|
 | 541 |     xptr_t           dentry_xp; | 
|---|
| [23] | 542 |     uint32_t         fs_type; | 
|---|
 | 543 |     uint32_t         inode_type; | 
|---|
| [188] | 544 |     void           * extend; | 
|---|
| [1] | 545 |     uint32_t         attr; | 
|---|
| [23] | 546 |     uint32_t         rights; | 
|---|
| [1] | 547 |     uint32_t         uid; | 
|---|
 | 548 |     uint32_t         gid; | 
|---|
 | 549 |     xptr_t           inode_xp; | 
|---|
 | 550 |     error_t          error; | 
|---|
 | 551 |  | 
|---|
 | 552 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 553 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 554 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 555 |  | 
|---|
 | 556 |     // get input arguments from client rpc descriptor | 
|---|
| [188] | 557 |     dentry_xp  = (xptr_t)          hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 558 |     fs_type    = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 559 |     inode_type = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); | 
|---|
 | 560 |     extend     = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); | 
|---|
 | 561 |     attr       = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) ); | 
|---|
 | 562 |     rights     = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) ); | 
|---|
 | 563 |     uid        = (uid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) ); | 
|---|
 | 564 |     gid        = (gid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[7] ) ); | 
|---|
| [1] | 565 |  | 
|---|
 | 566 |     // call local kernel function | 
|---|
 | 567 |     error = vfs_inode_create( dentry_xp, | 
|---|
| [23] | 568 |                               fs_type, | 
|---|
 | 569 |                               inode_type, | 
|---|
| [188] | 570 |                               extend, | 
|---|
| [1] | 571 |                               attr, | 
|---|
| [23] | 572 |                               rights, | 
|---|
| [1] | 573 |                               uid, | 
|---|
 | 574 |                               gid, | 
|---|
 | 575 |                               &inode_xp ); | 
|---|
 | 576 |  | 
|---|
 | 577 |     // set output arguments | 
|---|
| [188] | 578 |     hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)inode_xp ); | 
|---|
 | 579 |     hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error ); | 
|---|
| [1] | 580 | } | 
|---|
 | 581 |  | 
|---|
 | 582 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 583 | // [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  | 
|---|
| [1] | 584 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 585 |  | 
|---|
 | 586 | ///////////////////////////////////////////////////////////// | 
|---|
 | 587 | void rpc_vfs_inode_destroy_client( cxy_t                cxy, | 
|---|
 | 588 |                                    struct vfs_inode_s * inode ) | 
|---|
 | 589 | { | 
|---|
| [238] | 590 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 591 |  | 
|---|
 | 592 |     // initialise RPC descriptor header  | 
|---|
 | 593 |     rpc_desc_t  rpc; | 
|---|
 | 594 |     rpc.index    = RPC_VFS_INODE_DESTROY; | 
|---|
 | 595 |     rpc.response = 1; | 
|---|
 | 596 |  | 
|---|
 | 597 |     // set input arguments in RPC descriptor  | 
|---|
 | 598 |     rpc.args[0] = (uint64_t)(intptr_t)inode; | 
|---|
 | 599 |      | 
|---|
 | 600 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 601 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 602 | } | 
|---|
 | 603 |  | 
|---|
 | 604 | ////////////////////////////////////////////// | 
|---|
 | 605 | void rpc_vfs_inode_destroy_server( xptr_t xp ) | 
|---|
 | 606 | { | 
|---|
 | 607 |     vfs_inode_t * inode; | 
|---|
 | 608 |  | 
|---|
 | 609 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 610 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 611 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 612 |  | 
|---|
 | 613 |     // get arguments "inode" from client RPC descriptor | 
|---|
 | 614 |     inode = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 615 |                         | 
|---|
 | 616 |     // call local kernel function | 
|---|
 | 617 |     vfs_inode_destroy( inode ); | 
|---|
 | 618 | } | 
|---|
 | 619 |  | 
|---|
 | 620 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 621 | // [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE | 
|---|
| [1] | 622 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 623 |  | 
|---|
 | 624 | ////////////////////////////////////////////////////////////// | 
|---|
 | 625 | void rpc_vfs_dentry_create_client( cxy_t                  cxy, | 
|---|
 | 626 |                                    uint32_t               type,         // in | 
|---|
 | 627 |                                    char                 * name,         // in | 
|---|
 | 628 |                                    struct vfs_inode_s   * parent,       // in | 
|---|
 | 629 |                                    xptr_t               * dentry_xp,    // out | 
|---|
 | 630 |                                    error_t              * error )       // out | 
|---|
 | 631 | { | 
|---|
| [238] | 632 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 633 |  | 
|---|
 | 634 |     // initialise RPC descriptor header  | 
|---|
 | 635 |     rpc_desc_t  rpc; | 
|---|
 | 636 |     rpc.index    = RPC_VFS_DENTRY_CREATE; | 
|---|
 | 637 |     rpc.response = 1; | 
|---|
 | 638 |  | 
|---|
 | 639 |     // set input arguments in RPC descriptor  | 
|---|
 | 640 |     rpc.args[0] = (uint64_t)type; | 
|---|
 | 641 |     rpc.args[1] = (uint64_t)(intptr_t)name; | 
|---|
| [238] | 642 |     rpc.args[2] = (uint64_t)(intptr_t)parent; | 
|---|
| [1] | 643 |  | 
|---|
 | 644 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 645 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 646 |  | 
|---|
 | 647 |     // get output values from RPC descriptor | 
|---|
| [238] | 648 |     *dentry_xp = (xptr_t)rpc.args[3]; | 
|---|
 | 649 |     *error     = (error_t)rpc.args[4]; | 
|---|
| [1] | 650 | } | 
|---|
 | 651 |  | 
|---|
 | 652 | ////////////////////////////////////////////// | 
|---|
 | 653 | void rpc_vfs_dentry_create_server( xptr_t xp ) | 
|---|
 | 654 | { | 
|---|
 | 655 |     uint32_t      type; | 
|---|
 | 656 |     char        * name; | 
|---|
 | 657 |     vfs_inode_t * parent; | 
|---|
 | 658 |     xptr_t        dentry_xp; | 
|---|
 | 659 |     error_t       error; | 
|---|
 | 660 |  | 
|---|
| [238] | 661 |     char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; | 
|---|
 | 662 |  | 
|---|
| [1] | 663 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 664 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 665 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 666 |  | 
|---|
| [238] | 667 |     // get arguments "name", "type", and "parent" from client RPC descriptor | 
|---|
| [1] | 668 |     type   = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
| [238] | 669 |     name   = (char *)(intptr_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 670 |     parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); | 
|---|
| [1] | 671 |                         | 
|---|
| [238] | 672 |     // makes a local copy of  name | 
|---|
 | 673 |     hal_remote_strcpy( XPTR( local_cxy , name_copy ), | 
|---|
 | 674 |                        XPTR( client_cxy , name ) ); | 
|---|
 | 675 |  | 
|---|
| [1] | 676 |     // call local kernel function | 
|---|
 | 677 |     error = vfs_dentry_create( type, | 
|---|
 | 678 |                                name_copy, | 
|---|
 | 679 |                                parent, | 
|---|
 | 680 |                                &dentry_xp ); | 
|---|
 | 681 |   | 
|---|
 | 682 |     // set output arguments | 
|---|
| [238] | 683 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp ); | 
|---|
 | 684 |     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); | 
|---|
| [1] | 685 | } | 
|---|
 | 686 |  | 
|---|
 | 687 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 688 | // [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  | 
|---|
| [1] | 689 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 690 |  | 
|---|
 | 691 | /////////////////////////////////////////////////////// | 
|---|
 | 692 | void rpc_vfs_dentry_destroy_client( cxy_t          cxy, | 
|---|
 | 693 |                                     vfs_dentry_t * dentry ) | 
|---|
 | 694 | { | 
|---|
| [238] | 695 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 696 |  | 
|---|
 | 697 |     // initialise RPC descriptor header  | 
|---|
 | 698 |     rpc_desc_t  rpc; | 
|---|
 | 699 |     rpc.index    = RPC_VFS_DENTRY_DESTROY; | 
|---|
 | 700 |     rpc.response = 1; | 
|---|
 | 701 |  | 
|---|
 | 702 |     // set input arguments in RPC descriptor  | 
|---|
 | 703 |     rpc.args[0] = (uint64_t)(intptr_t)dentry; | 
|---|
 | 704 |      | 
|---|
 | 705 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 706 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 707 | } | 
|---|
 | 708 |  | 
|---|
 | 709 | /////////////////////////////////////////////// | 
|---|
 | 710 | void rpc_vfs_dentry_destroy_server( xptr_t xp ) | 
|---|
 | 711 | { | 
|---|
 | 712 |     vfs_dentry_t * dentry; | 
|---|
 | 713 |  | 
|---|
 | 714 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 715 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 716 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 717 |  | 
|---|
 | 718 |     // get arguments "dentry" from client RPC descriptor | 
|---|
 | 719 |     dentry = (vfs_dentry_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 720 |                         | 
|---|
 | 721 |     // call local kernel function | 
|---|
 | 722 |     vfs_dentry_destroy( dentry ); | 
|---|
 | 723 | } | 
|---|
 | 724 |  | 
|---|
 | 725 |  | 
|---|
 | 726 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 727 | // [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE | 
|---|
| [1] | 728 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 729 |  | 
|---|
| [23] | 730 | ////////////////////////////////////////////////////////////// | 
|---|
 | 731 | void rpc_vfs_file_create_client( cxy_t                  cxy, | 
|---|
 | 732 |                                  struct vfs_inode_s   * inode,       // in | 
|---|
 | 733 |                                  uint32_t               file_attr,   // in | 
|---|
 | 734 |                                  xptr_t               * file_xp,     // out | 
|---|
 | 735 |                                  error_t              * error )      // out | 
|---|
 | 736 | { | 
|---|
| [238] | 737 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [23] | 738 |  | 
|---|
 | 739 |     // initialise RPC descriptor header  | 
|---|
 | 740 |     rpc_desc_t  rpc; | 
|---|
 | 741 |     rpc.index    = RPC_VFS_FILE_CREATE; | 
|---|
 | 742 |     rpc.response = 1; | 
|---|
 | 743 |  | 
|---|
 | 744 |     // set input arguments in RPC descriptor  | 
|---|
 | 745 |     rpc.args[0] = (uint64_t)(intptr_t)inode; | 
|---|
 | 746 |     rpc.args[1] = (uint64_t)file_attr; | 
|---|
 | 747 |  | 
|---|
 | 748 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 749 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 750 |  | 
|---|
 | 751 |     // get output values from RPC descriptor | 
|---|
 | 752 |     *file_xp = (xptr_t)rpc.args[2]; | 
|---|
 | 753 |     *error   = (error_t)rpc.args[3]; | 
|---|
 | 754 | } | 
|---|
 | 755 |  | 
|---|
 | 756 | //////////////////////////////////////////// | 
|---|
 | 757 | void rpc_vfs_file_create_server( xptr_t xp ) | 
|---|
 | 758 | { | 
|---|
 | 759 |     uint32_t      file_attr; | 
|---|
 | 760 |     vfs_inode_t * inode; | 
|---|
 | 761 |     xptr_t        file_xp; | 
|---|
 | 762 |     error_t       error; | 
|---|
 | 763 |  | 
|---|
 | 764 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 765 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 766 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 767 |  | 
|---|
 | 768 |     // get arguments "file_attr" and "inode" from client RPC descriptor | 
|---|
 | 769 |     inode     = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 770 |     file_attr = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 771 |                         | 
|---|
 | 772 |     // call local kernel function | 
|---|
 | 773 |     error = vfs_file_create( inode, | 
|---|
 | 774 |                              file_attr, | 
|---|
 | 775 |                              &file_xp ); | 
|---|
 | 776 |   | 
|---|
 | 777 |     // set output arguments | 
|---|
 | 778 |     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp ); | 
|---|
 | 779 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); | 
|---|
 | 780 | } | 
|---|
 | 781 |  | 
|---|
 | 782 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 783 | // [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  | 
|---|
 | 784 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 785 |  | 
|---|
 | 786 | /////////////////////////////////////////////////// | 
|---|
 | 787 | void rpc_vfs_file_destroy_client( cxy_t        cxy, | 
|---|
 | 788 |                                   vfs_file_t * file ) | 
|---|
 | 789 | { | 
|---|
| [238] | 790 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [23] | 791 |  | 
|---|
 | 792 |     // initialise RPC descriptor header  | 
|---|
 | 793 |     rpc_desc_t  rpc; | 
|---|
 | 794 |     rpc.index    = RPC_VFS_FILE_DESTROY; | 
|---|
 | 795 |     rpc.response = 1; | 
|---|
 | 796 |  | 
|---|
 | 797 |     // set input arguments in RPC descriptor  | 
|---|
 | 798 |     rpc.args[0] = (uint64_t)(intptr_t)file; | 
|---|
 | 799 |      | 
|---|
 | 800 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 801 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 802 | } | 
|---|
 | 803 |  | 
|---|
 | 804 | ///////////////////////////////////////////// | 
|---|
 | 805 | void rpc_vfs_file_destroy_server( xptr_t xp ) | 
|---|
 | 806 | { | 
|---|
 | 807 |     vfs_file_t * file; | 
|---|
 | 808 |  | 
|---|
 | 809 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 810 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 811 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 812 |  | 
|---|
 | 813 |     // get arguments "dentry" from client RPC descriptor | 
|---|
 | 814 |     file = (vfs_file_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 815 |                         | 
|---|
 | 816 |     // call local kernel function | 
|---|
 | 817 |     vfs_file_destroy( file ); | 
|---|
 | 818 | } | 
|---|
 | 819 |  | 
|---|
 | 820 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [238] | 821 | // [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   | 
|---|
| [23] | 822 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 823 |  | 
|---|
| [1] | 824 | ////////////////////////////////////////////////// | 
|---|
| [238] | 825 | void rpc_vfs_inode_load_client( cxy_t         cxy, | 
|---|
 | 826 |                                 vfs_inode_t * parent_inode,    // in | 
|---|
 | 827 |                                 char        * name,            // in | 
|---|
 | 828 |                                 xptr_t        child_inode_xp,  // in | 
|---|
 | 829 |                                 error_t     * error )          // out | 
|---|
 | 830 | { | 
|---|
 | 831 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
 | 832 |  | 
|---|
 | 833 |     // initialise RPC descriptor header  | 
|---|
 | 834 |     rpc_desc_t  rpc; | 
|---|
 | 835 |     rpc.index    = RPC_VFS_INODE_LOAD; | 
|---|
 | 836 |     rpc.response = 1; | 
|---|
 | 837 |  | 
|---|
 | 838 |     // set input arguments in RPC descriptor  | 
|---|
 | 839 |     rpc.args[0] = (uint64_t)(intptr_t)parent_inode; | 
|---|
 | 840 |     rpc.args[1] = (uint64_t)(intptr_t)name; | 
|---|
 | 841 |     rpc.args[2] = (uint64_t)child_inode_xp; | 
|---|
 | 842 |  | 
|---|
 | 843 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 844 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 845 |  | 
|---|
 | 846 |     // get output values from RPC descriptor | 
|---|
 | 847 |     *error   = (error_t)rpc.args[3]; | 
|---|
 | 848 | } | 
|---|
 | 849 |  | 
|---|
 | 850 | /////////////////////////////////////////// | 
|---|
 | 851 | void rpc_vfs_inode_load_server( xptr_t xp ) | 
|---|
 | 852 | { | 
|---|
 | 853 |     error_t       error; | 
|---|
 | 854 |     vfs_inode_t * parent; | 
|---|
 | 855 |     xptr_t        child_xp; | 
|---|
 | 856 |     char        * name; | 
|---|
 | 857 |  | 
|---|
 | 858 |     char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; | 
|---|
 | 859 |  | 
|---|
 | 860 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 861 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 862 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 863 |  | 
|---|
 | 864 |     // get arguments "parent", "name", and "child_xp" | 
|---|
 | 865 |     parent     = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0])); | 
|---|
 | 866 |     name       = (char*)(intptr_t)       hal_remote_lwd(XPTR(client_cxy , &desc->args[1])); | 
|---|
 | 867 |     child_xp   = (xptr_t)                hal_remote_lwd(XPTR(client_cxy , &desc->args[2])); | 
|---|
 | 868 |  | 
|---|
 | 869 |     // get name local copy | 
|---|
 | 870 |     hal_remote_strcpy( XPTR( local_cxy , name_copy ) , | 
|---|
 | 871 |                        XPTR( client_cxy , name ) ); | 
|---|
 | 872 |  | 
|---|
 | 873 |     // call the kernel function | 
|---|
 | 874 |     error = vfs_inode_load( parent , name_copy , child_xp ); | 
|---|
 | 875 |  | 
|---|
 | 876 |     // set output argument | 
|---|
 | 877 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); | 
|---|
 | 878 | } | 
|---|
 | 879 |  | 
|---|
 | 880 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 881 | // [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL | 
|---|
 | 882 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 883 |  | 
|---|
 | 884 | /////////////////////////////////////////////////////// | 
|---|
 | 885 | void rpc_vfs_mapper_load_all_client( cxy_t         cxy, | 
|---|
 | 886 |                                      vfs_inode_t * inode,      // in | 
|---|
 | 887 |                                      error_t     * error )     // out | 
|---|
 | 888 | { | 
|---|
 | 889 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
 | 890 |  | 
|---|
 | 891 |     // initialise RPC descriptor header  | 
|---|
 | 892 |     rpc_desc_t  rpc; | 
|---|
 | 893 |     rpc.index    = RPC_VFS_INODE_LOAD; | 
|---|
 | 894 |     rpc.response = 1; | 
|---|
 | 895 |  | 
|---|
 | 896 |     // set input arguments in RPC descriptor  | 
|---|
 | 897 |     rpc.args[0] = (uint64_t)(intptr_t)inode; | 
|---|
 | 898 |  | 
|---|
 | 899 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 900 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 901 |  | 
|---|
 | 902 |     // get output values from RPC descriptor | 
|---|
 | 903 |     *error   = (error_t)rpc.args[1]; | 
|---|
 | 904 | } | 
|---|
 | 905 |  | 
|---|
 | 906 | //////////////////////////////////////////////// | 
|---|
 | 907 | void rpc_vfs_mapper_load_all_server( xptr_t xp ) | 
|---|
 | 908 | { | 
|---|
 | 909 |     error_t       error; | 
|---|
 | 910 |     vfs_inode_t * inode; | 
|---|
 | 911 |  | 
|---|
 | 912 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 913 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 914 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 915 |  | 
|---|
 | 916 |     // get arguments "parent", "name", and "child_xp" | 
|---|
 | 917 |     inode = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0])); | 
|---|
 | 918 |  | 
|---|
 | 919 |     // call the kernel function | 
|---|
 | 920 |     error = vfs_mapper_load_all( inode ); | 
|---|
 | 921 |  | 
|---|
 | 922 |     // set output argument | 
|---|
 | 923 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); | 
|---|
 | 924 | } | 
|---|
 | 925 |  | 
|---|
 | 926 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 927 | // [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  | 
|---|
 | 928 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 929 |  | 
|---|
 | 930 | ////////////////////////////////////////////////// | 
|---|
| [23] | 931 | void rpc_fatfs_get_cluster_client( cxy_t      cxy, | 
|---|
 | 932 |                                    mapper_t * mapper,    // in | 
|---|
 | 933 |                                    uint32_t   first,     // in | 
|---|
 | 934 |                                    uint32_t   page,      // in | 
|---|
 | 935 |                                    uint32_t * cluster,   // out | 
|---|
 | 936 |                                    error_t  * error )    // out | 
|---|
 | 937 | { | 
|---|
| [238] | 938 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [23] | 939 |  | 
|---|
 | 940 |     // initialise RPC descriptor header  | 
|---|
 | 941 |     rpc_desc_t  rpc; | 
|---|
 | 942 |     rpc.index    = RPC_FATFS_GET_CLUSTER; | 
|---|
 | 943 |     rpc.response = 1; | 
|---|
 | 944 |  | 
|---|
 | 945 |     // set input arguments in RPC descriptor  | 
|---|
 | 946 |     rpc.args[0] = (uint64_t)(intptr_t)mapper; | 
|---|
 | 947 |     rpc.args[1] = (uint64_t)first; | 
|---|
 | 948 |     rpc.args[2] = (uint64_t)page; | 
|---|
 | 949 |  | 
|---|
 | 950 |     // register RPC request in remote RPC fifo  | 
|---|
 | 951 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 952 |  | 
|---|
 | 953 |     // get output argument from rpc descriptor | 
|---|
 | 954 |     *cluster = (uint32_t)rpc.args[3]; | 
|---|
 | 955 |     *error   = (error_t)rpc.args[4]; | 
|---|
 | 956 | } | 
|---|
 | 957 |  | 
|---|
 | 958 | ////////////////////////////////////////////// | 
|---|
 | 959 | void rpc_fatfs_get_cluster_server( xptr_t xp ) | 
|---|
 | 960 | { | 
|---|
 | 961 |     mapper_t    * mapper; | 
|---|
 | 962 |     uint32_t      first; | 
|---|
 | 963 |     uint32_t      page; | 
|---|
 | 964 |     uint32_t      cluster; | 
|---|
 | 965 |     error_t       error; | 
|---|
 | 966 |  | 
|---|
 | 967 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 968 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 969 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 970 |  | 
|---|
 | 971 |     // get input arguments | 
|---|
 | 972 |     mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 973 |     first  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 974 |     page   = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) ); | 
|---|
 | 975 |  | 
|---|
 | 976 |     // call the kernel function | 
|---|
 | 977 |     error = fatfs_get_cluster( mapper , first , page , &cluster ); | 
|---|
 | 978 |  | 
|---|
 | 979 |     // set output argument | 
|---|
 | 980 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster ); | 
|---|
 | 981 |     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); | 
|---|
 | 982 | } | 
|---|
 | 983 |  | 
|---|
 | 984 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 985 | // [20]          Marshaling functions attached to RPC_VMM_GET_REF_VSEG | 
|---|
 | 986 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 987 |  | 
|---|
 | 988 | ////////////////////////////////////////////////// | 
|---|
| [1] | 989 | void rpc_vmm_get_ref_vseg_client( cxy_t       cxy,       | 
|---|
 | 990 |                                   process_t * process,     // in   | 
|---|
 | 991 |                                   intptr_t    vaddr,       // in   | 
|---|
 | 992 |                                   xptr_t    * vseg_xp )    // out | 
|---|
 | 993 | { | 
|---|
| [238] | 994 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 995 |  | 
|---|
 | 996 |     // initialise RPC descriptor header  | 
|---|
 | 997 |     rpc_desc_t  rpc; | 
|---|
 | 998 |     rpc.index    = RPC_VMM_GET_REF_VSEG; | 
|---|
 | 999 |     rpc.response = 1; | 
|---|
 | 1000 |  | 
|---|
 | 1001 |     // set input arguments in RPC descriptor  | 
|---|
 | 1002 |     rpc.args[0] = (uint64_t)(intptr_t)process; | 
|---|
 | 1003 |     rpc.args[1] = (uint64_t)vaddr; | 
|---|
 | 1004 |  | 
|---|
 | 1005 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 1006 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 1007 |  | 
|---|
 | 1008 |     // get output argument from rpc descriptor | 
|---|
 | 1009 |     *vseg_xp = rpc.args[2]; | 
|---|
 | 1010 | } | 
|---|
 | 1011 |  | 
|---|
 | 1012 | ///////////////////////////////////////////// | 
|---|
 | 1013 | void rpc_vmm_get_ref_vseg_server( xptr_t xp ) | 
|---|
 | 1014 | { | 
|---|
 | 1015 |     process_t   * process; | 
|---|
 | 1016 |     intptr_t      vaddr; | 
|---|
 | 1017 |     vseg_t      * vseg_ptr; | 
|---|
 | 1018 |     xptr_t        vseg_xp; | 
|---|
 | 1019 |  | 
|---|
 | 1020 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1021 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 1022 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 1023 |  | 
|---|
 | 1024 |     // get input argument from client RPC descriptor | 
|---|
 | 1025 |     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 1026 |     vaddr   = (intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 1027 |      | 
|---|
 | 1028 |     // call local kernel function | 
|---|
 | 1029 |     vseg_ptr = vmm_get_vseg( process , vaddr ); | 
|---|
 | 1030 |  | 
|---|
 | 1031 |     // set output argument to client RPC descriptor | 
|---|
| [16] | 1032 |     if( vseg_ptr == NULL ) vseg_xp = XPTR_NULL; | 
|---|
 | 1033 |     else                   vseg_xp = XPTR( local_cxy , vseg_ptr ); | 
|---|
| [1] | 1034 |     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp ); | 
|---|
 | 1035 | } | 
|---|
 | 1036 |  | 
|---|
 | 1037 |  | 
|---|
 | 1038 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 1039 | // [21]          Marshaling functions attached to RPC_VMM_GET_PTE  | 
|---|
| [1] | 1040 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1041 |  | 
|---|
 | 1042 | //////////////////////////////////////////// | 
|---|
 | 1043 | void rpc_vmm_get_pte_client( cxy_t       cxy,    | 
|---|
 | 1044 |                              process_t * process,  // in  | 
|---|
 | 1045 |                              vpn_t       vpn,      // in  | 
|---|
 | 1046 |                              uint32_t  * attr,     // out | 
|---|
 | 1047 |                              ppn_t     * ppn,      // out | 
|---|
 | 1048 |                              error_t   * error )   // out  | 
|---|
 | 1049 | { | 
|---|
| [238] | 1050 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 1051 |  | 
|---|
 | 1052 |     // initialise RPC descriptor header  | 
|---|
 | 1053 |     rpc_desc_t  rpc; | 
|---|
 | 1054 |     rpc.index    = RPC_VMM_GET_PTE; | 
|---|
 | 1055 |     rpc.response = 1; | 
|---|
 | 1056 |  | 
|---|
 | 1057 |     // set input arguments in RPC descriptor  | 
|---|
 | 1058 |     rpc.args[0] = (uint64_t)(intptr_t)process; | 
|---|
 | 1059 |     rpc.args[1] = (uint64_t)vpn; | 
|---|
 | 1060 |  | 
|---|
 | 1061 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
 | 1062 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 1063 |  | 
|---|
 | 1064 |     // get output argument from rpc descriptor | 
|---|
 | 1065 |     *attr  = (uint32_t)rpc.args[2]; | 
|---|
 | 1066 |     *ppn   = (ppn_t)rpc.args[3]; | 
|---|
 | 1067 |     *error = (error_t)rpc.args[4]; | 
|---|
 | 1068 | } | 
|---|
 | 1069 |  | 
|---|
 | 1070 | //////////////////////////////////////// | 
|---|
 | 1071 | void rpc_vmm_get_pte_server( xptr_t xp ) | 
|---|
 | 1072 | { | 
|---|
 | 1073 |     process_t   * process; | 
|---|
 | 1074 |     vpn_t         vpn; | 
|---|
 | 1075 |     uint32_t      attr; | 
|---|
 | 1076 |     ppn_t         ppn; | 
|---|
 | 1077 |     error_t       error; | 
|---|
 | 1078 |  | 
|---|
 | 1079 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1080 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 1081 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 1082 |  | 
|---|
 | 1083 |     // get input argument "process" & "vpn" from client RPC descriptor | 
|---|
 | 1084 |     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 1085 |     vpn     = (vpn_t)                hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
 | 1086 |      | 
|---|
 | 1087 |     // call local kernel function | 
|---|
 | 1088 |     error = vmm_get_pte( process , vpn , &attr , &ppn );  | 
|---|
 | 1089 |  | 
|---|
 | 1090 |     // set output argument "attr" & "ppn" to client RPC descriptor | 
|---|
 | 1091 |     hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)attr ); | 
|---|
 | 1092 |     hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)ppn ); | 
|---|
 | 1093 |     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); | 
|---|
 | 1094 | } | 
|---|
 | 1095 |  | 
|---|
 | 1096 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 1097 | // [22]          Marshaling functions attached to RPC_KCM_ALLOC  | 
|---|
| [1] | 1098 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1099 |  | 
|---|
| [23] | 1100 | ////////////////////////////////////////// | 
|---|
 | 1101 | void rpc_kcm_alloc_client( cxy_t      cxy, | 
|---|
 | 1102 |                            uint32_t   kmem_type,   // in | 
|---|
 | 1103 |                            xptr_t *   buf_xp )     // out | 
|---|
| [1] | 1104 | { | 
|---|
| [238] | 1105 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 1106 |  | 
|---|
 | 1107 |     // initialise RPC descriptor header  | 
|---|
 | 1108 |     rpc_desc_t  rpc; | 
|---|
 | 1109 |     rpc.index    = RPC_THREAD_USER_CREATE; | 
|---|
 | 1110 |     rpc.response = 1; | 
|---|
 | 1111 |  | 
|---|
| [23] | 1112 |     // set input arguments in RPC descriptor  | 
|---|
 | 1113 |     rpc.args[0] = (uint64_t)kmem_type; | 
|---|
 | 1114 |  | 
|---|
| [1] | 1115 |     // register RPC request in remote RPC fifo  | 
|---|
 | 1116 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 1117 |  | 
|---|
 | 1118 |     // get output arguments from RPC descriptor | 
|---|
| [23] | 1119 |     *buf_xp = (xptr_t)rpc.args[1]; | 
|---|
| [1] | 1120 | } | 
|---|
 | 1121 |  | 
|---|
| [23] | 1122 | ////////////////////////////////////// | 
|---|
 | 1123 | void rpc_kcm_alloc_server( xptr_t xp ) | 
|---|
| [1] | 1124 | { | 
|---|
 | 1125 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1126 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 1127 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 1128 |  | 
|---|
| [23] | 1129 |     // get input argument "kmem_type" from client RPC descriptor | 
|---|
 | 1130 |     uint32_t kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 1131 |  | 
|---|
 | 1132 |     // allocates memory for kcm | 
|---|
| [1] | 1133 |     kmem_req_t  req; | 
|---|
| [23] | 1134 |     req.type  = kmem_type; | 
|---|
| [1] | 1135 |     req.flags = AF_ZERO; | 
|---|
| [23] | 1136 |     void * buf_ptr = kmem_alloc( &req ); | 
|---|
| [1] | 1137 |  | 
|---|
 | 1138 |     // set output argument | 
|---|
| [23] | 1139 |     xptr_t buf_xp = XPTR( local_cxy , buf_ptr ); | 
|---|
 | 1140 |     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp ); | 
|---|
| [1] | 1141 | }    | 
|---|
 | 1142 |  | 
|---|
 | 1143 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [23] | 1144 | // [23]          Marshaling functions attached to RPC_KCM_FREE  | 
|---|
| [1] | 1145 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1146 |  | 
|---|
| [23] | 1147 | ///////////////////////////////////////// | 
|---|
 | 1148 | void rpc_kcm_free_client( cxy_t      cxy, | 
|---|
 | 1149 |                           void     * buf,          // in | 
|---|
 | 1150 |                           uint32_t   kmem_type )   // in | 
|---|
| [1] | 1151 | { | 
|---|
| [238] | 1152 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 1153 |  | 
|---|
 | 1154 |     // initialise RPC descriptor header  | 
|---|
 | 1155 |     rpc_desc_t  rpc; | 
|---|
 | 1156 |     rpc.index    = RPC_THREAD_USER_CREATE; | 
|---|
 | 1157 |     rpc.response = 1; | 
|---|
 | 1158 |  | 
|---|
 | 1159 |     // set input arguments in RPC descriptor  | 
|---|
| [23] | 1160 |     rpc.args[0] = (uint64_t)(intptr_t)buf; | 
|---|
 | 1161 |     rpc.args[1] = (uint64_t)kmem_type; | 
|---|
| [1] | 1162 |  | 
|---|
 | 1163 |     // register RPC request in remote RPC fifo  | 
|---|
 | 1164 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 1165 | } | 
|---|
 | 1166 |  | 
|---|
| [23] | 1167 | ///////////////////////////////////// | 
|---|
 | 1168 | void rpc_kcm_free_server( xptr_t xp ) | 
|---|
| [1] | 1169 | { | 
|---|
 | 1170 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1171 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
 | 1172 |     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 1173 |  | 
|---|
| [23] | 1174 |     // get input arguments "buf" and "kmem_type" from client RPC descriptor | 
|---|
 | 1175 |     void     * buf = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 1176 |     uint32_t   kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
| [1] | 1177 |  | 
|---|
 | 1178 |     // releases memory | 
|---|
 | 1179 |     kmem_req_t  req; | 
|---|
| [23] | 1180 |     req.type = kmem_type; | 
|---|
 | 1181 |     req.ptr  = buf; | 
|---|
 | 1182 |     kmem_free( &req ); | 
|---|
| [1] | 1183 | }    | 
|---|
 | 1184 |  | 
|---|
 | 1185 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [265] | 1186 | // [24]          Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER | 
|---|
| [1] | 1187 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1188 |  | 
|---|
| [265] | 1189 | /////////////////////////////////////////////////// | 
|---|
 | 1190 | void rpc_mapper_move_buffer_client( cxy_t      cxy, | 
|---|
 | 1191 |                                     mapper_t * mapper,        // in | 
|---|
 | 1192 |                                     bool_t     to_buffer,     // in | 
|---|
 | 1193 |                                     bool_t     is_user,       // in | 
|---|
 | 1194 |                                     uint32_t   file_offset,   // in | 
|---|
 | 1195 |                                     void     * buffer,        // in | 
|---|
 | 1196 |                                     uint32_t   size,          // in | 
|---|
 | 1197 |                                     error_t  * error )        // out | 
|---|
| [1] | 1198 | { | 
|---|
| [238] | 1199 |     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); | 
|---|
| [1] | 1200 |  | 
|---|
 | 1201 |     // initialise RPC descriptor header  | 
|---|
 | 1202 |     rpc_desc_t  rpc; | 
|---|
| [265] | 1203 |     rpc.index    = RPC_MAPPER_MOVE_BUFFER; | 
|---|
| [1] | 1204 |     rpc.response = 1; | 
|---|
 | 1205 |  | 
|---|
 | 1206 |     // set input arguments in RPC descriptor  | 
|---|
 | 1207 |     rpc.args[0] = (uint64_t)(intptr_t)mapper; | 
|---|
| [23] | 1208 |     rpc.args[1] = (uint64_t)to_buffer; | 
|---|
| [265] | 1209 |     rpc.args[2] = (uint64_t)is_user; | 
|---|
 | 1210 |     rpc.args[3] = (uint64_t)file_offset; | 
|---|
 | 1211 |     rpc.args[4] = (uint64_t)(intptr_t)buffer; | 
|---|
 | 1212 |     rpc.args[5] = (uint64_t)size; | 
|---|
| [1] | 1213 |  | 
|---|
| [23] | 1214 |     // register RPC request in remote RPC fifo (blocking function) | 
|---|
| [1] | 1215 |     rpc_send_sync( cxy , &rpc ); | 
|---|
 | 1216 |  | 
|---|
| [23] | 1217 |     // get output values from RPC descriptor | 
|---|
| [265] | 1218 |     *error     = (error_t)rpc.args[6]; | 
|---|
| [1] | 1219 | } | 
|---|
 | 1220 |  | 
|---|
| [265] | 1221 | /////////////////////////////////////////////// | 
|---|
 | 1222 | void rpc_mapper_move_buffer_server( xptr_t xp ) | 
|---|
| [1] | 1223 | { | 
|---|
| [23] | 1224 |     mapper_t * mapper; | 
|---|
| [265] | 1225 |     bool_t     to_buffer; | 
|---|
 | 1226 |     bool_t     is_user; | 
|---|
| [23] | 1227 |     uint32_t   file_offset; | 
|---|
 | 1228 |     void     * buffer; | 
|---|
 | 1229 |     uint32_t   size; | 
|---|
 | 1230 |     error_t    error; | 
|---|
| [1] | 1231 |  | 
|---|
 | 1232 |     // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1233 |     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp ); | 
|---|
| [23] | 1234 |     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
| [1] | 1235 |  | 
|---|
| [23] | 1236 |     // get arguments from client RPC descriptor | 
|---|
 | 1237 |     mapper      = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); | 
|---|
 | 1238 |     to_buffer   =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); | 
|---|
| [265] | 1239 |     is_user     =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); | 
|---|
 | 1240 |     file_offset =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); | 
|---|
 | 1241 |     buffer      = (void     *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) ); | 
|---|
 | 1242 |     size        =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) ); | 
|---|
| [1] | 1243 |  | 
|---|
| [23] | 1244 |     // call local kernel function | 
|---|
| [265] | 1245 |     error = mapper_move_buffer( mapper, | 
|---|
 | 1246 |                                 to_buffer, | 
|---|
 | 1247 |                                 is_user, | 
|---|
 | 1248 |                                 file_offset, | 
|---|
 | 1249 |                                 buffer, | 
|---|
 | 1250 |                                 size ); | 
|---|
| [1] | 1251 |  | 
|---|
| [23] | 1252 |     // set output argument to client RPC descriptor | 
|---|
| [265] | 1253 |     hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error ); | 
|---|
| [1] | 1254 | } | 
|---|
 | 1255 |  | 
|---|
 | 1256 | /***************************************************************************************/ | 
|---|
 | 1257 | /************ Generic functions supporting RPCs : client side **************************/ | 
|---|
 | 1258 | /***************************************************************************************/ | 
|---|
 | 1259 |  | 
|---|
 | 1260 | //////////////////////////////////////////// | 
|---|
 | 1261 | void rpc_send_sync( cxy_t        server_cxy,  | 
|---|
 | 1262 |                     rpc_desc_t * rpc ) | 
|---|
 | 1263 | { | 
|---|
 | 1264 |         thread_t * this = CURRENT_THREAD; | 
|---|
 | 1265 |     uint32_t   cores; | 
|---|
 | 1266 |     error_t    error; | 
|---|
 | 1267 |     bool_t     first; | 
|---|
 | 1268 |     reg_t      sr_save; | 
|---|
 | 1269 |  | 
|---|
 | 1270 |     // get client CPU and cluster coordinates | 
|---|
 | 1271 |     cxy_t      client_cxy = local_cxy;    | 
|---|
 | 1272 |     lid_t      client_lid = CURRENT_CORE->lid; | 
|---|
 | 1273 |  | 
|---|
 | 1274 |     // allocate and initialise an extended pointer on the RPC descriptor | 
|---|
 | 1275 |         xptr_t   xp = XPTR( client_cxy , rpc ); | 
|---|
 | 1276 |  | 
|---|
 | 1277 |     // get local pointer on rpc_fifo in remote cluster with the  | 
|---|
 | 1278 |     // assumption that addresses are identical in all clusters | 
|---|
 | 1279 |     rpc_fifo_t * rf = &LOCAL_CLUSTER->rpc_fifo; | 
|---|
 | 1280 |  | 
|---|
 | 1281 |         // try to post an item in remote fifo | 
|---|
 | 1282 |     // deschedule and retry if remote fifo full | 
|---|
 | 1283 |     do | 
|---|
 | 1284 |     {  | 
|---|
 | 1285 |         error = remote_fifo_put_item( XPTR( server_cxy , &rf->fifo ), | 
|---|
| [68] | 1286 |                                       (uint64_t *)&xp, | 
|---|
| [1] | 1287 |                                       &first ); | 
|---|
 | 1288 |  | 
|---|
 | 1289 |             if ( error )  | 
|---|
 | 1290 |         { | 
|---|
 | 1291 |             printk("\n[WARNING] %s : core %d in cluster %x cannot post RPC to cluster %x\n", | 
|---|
 | 1292 |                    __FUNCTION__ , client_lid , client_cxy , server_cxy ); | 
|---|
 | 1293 |             if( thread_can_yield() ) sched_yield(); | 
|---|
 | 1294 |         } | 
|---|
 | 1295 |     } | 
|---|
 | 1296 |     while( error ); | 
|---|
 | 1297 |   | 
|---|
 | 1298 |     rpc_dmsg("\n[INFO] %s on core %d in cluster %x sent RPC %p to cluster %x\n",  | 
|---|
 | 1299 |               __FUNCTION__ , client_lid , client_cxy , rpc , server_cxy ); | 
|---|
 | 1300 |          | 
|---|
 | 1301 |     // send IPI if this is the first RPC in remote FIFO | 
|---|
 | 1302 |     // and no CPU is in kernel mode in server cluster. | 
|---|
 | 1303 |     // the selected CPU in server has the same lid as the client CPU. | 
|---|
 | 1304 |         if( first ) | 
|---|
 | 1305 |         { | 
|---|
 | 1306 |         // get number of cores in kernel mode in server cluster | 
|---|
 | 1307 |         cores = hal_remote_lw( XPTR( server_cxy , &LOCAL_CLUSTER->cores_in_kernel ) ); | 
|---|
 | 1308 |  | 
|---|
 | 1309 |                 if( cores == 0 ) // no core in kernel mode in server | 
|---|
 | 1310 |                 { | 
|---|
| [188] | 1311 |                     dev_pic_send_ipi( server_cxy , client_lid ); | 
|---|
| [1] | 1312 |  | 
|---|
 | 1313 |                     rpc_dmsg("\n[INFO] %s : core %d in cluster %x send IPI to core %d in cluster %x\n", | 
|---|
 | 1314 |                       __FUNCTION__, client_lid , client_cxy , client_lid , server_cxy ); | 
|---|
 | 1315 |         } | 
|---|
 | 1316 |         } | 
|---|
 | 1317 |  | 
|---|
 | 1318 |         // activate preemption to allow incoming RPC and avoid deadlock | 
|---|
 | 1319 |         if( this->type == THREAD_RPC ) hal_enable_irq( &sr_save ); | 
|---|
 | 1320 |  | 
|---|
 | 1321 |     // the sending thread poll the response slot until RPC completed | 
|---|
 | 1322 |         while( 1 ) | 
|---|
 | 1323 |     { | 
|---|
 | 1324 |         if( rpc->response == 0 ) break; | 
|---|
 | 1325 |     } | 
|---|
 | 1326 |  | 
|---|
 | 1327 |     // restore preemption | 
|---|
 | 1328 |         if( this->type == THREAD_RPC ) hal_restore_irq( sr_save ); | 
|---|
 | 1329 |  | 
|---|
 | 1330 | }  // end rpc_send_sync() | 
|---|
 | 1331 |  | 
|---|
 | 1332 |  | 
|---|
 | 1333 |  | 
|---|
 | 1334 | /***************************************************************************************/ | 
|---|
 | 1335 | /************ Generic functions supporting RPCs : server side **************************/ | 
|---|
 | 1336 | /***************************************************************************************/ | 
|---|
 | 1337 |  | 
|---|
 | 1338 | /////////////////////////////////////////// | 
|---|
 | 1339 | void rpc_fifo_init( rpc_fifo_t * rpc_fifo ) | 
|---|
 | 1340 | { | 
|---|
 | 1341 |         rpc_fifo->count       = 0; | 
|---|
 | 1342 |         rpc_fifo->owner       = 0; | 
|---|
 | 1343 |         local_fifo_init( &rpc_fifo->fifo ); | 
|---|
 | 1344 | } | 
|---|
 | 1345 |  | 
|---|
 | 1346 | //////////////////////////////////////////////// | 
|---|
 | 1347 | error_t rpc_execute_all( rpc_fifo_t * rpc_fifo ) | 
|---|
 | 1348 | { | 
|---|
 | 1349 |         xptr_t         xp;             // extended pointer on RPC descriptor | 
|---|
 | 1350 |         uint32_t       count;          // handled RPC request counter | 
|---|
 | 1351 |         thread_t     * this;           // pointer on this RPC thread | 
|---|
 | 1352 |     core_t       * core;           // pointer on core running this thread | 
|---|
 | 1353 |     rpc_desc_t   * desc;           // pointer on RPC descriptor  | 
|---|
 | 1354 |     uint32_t       index;          // RPC index  | 
|---|
 | 1355 |     uint32_t       expected;       // number of expected responses  | 
|---|
 | 1356 |     cxy_t          client_cxy;     // client cluster identifier | 
|---|
 | 1357 |         error_t        error; | 
|---|
 | 1358 |        | 
|---|
 | 1359 |         this = CURRENT_THREAD;  | 
|---|
 | 1360 |     core = this->core;    | 
|---|
 | 1361 |  | 
|---|
 | 1362 |  | 
|---|
 | 1363 |     // handle up to CONFIG_RPC_PENDING_MAX requests before exit | 
|---|
 | 1364 |         count = 0; | 
|---|
 | 1365 |         do | 
|---|
 | 1366 |     { | 
|---|
 | 1367 |             error = local_fifo_get_item( &rpc_fifo->fifo,  | 
|---|
| [68] | 1368 |                                      (uint64_t *)&xp ); | 
|---|
| [1] | 1369 |  | 
|---|
 | 1370 |                 if ( error == 0 )  // One RPC request successfully extracted from RPC_FIFO | 
|---|
 | 1371 |         { | 
|---|
 | 1372 |             rpc_dmsg("\n[INFO] %s : RPC_THREAD %x on core %x in cluster %x handles RPC %d\n" | 
|---|
 | 1373 |                                      __FUNCTION__ , this->trdid , core->lid , local_cxy , count ); | 
|---|
 | 1374 |  | 
|---|
 | 1375 |             // get client cluster identifier and pointer on RPC descriptor | 
|---|
 | 1376 |             client_cxy = (cxy_t)GET_CXY( xp ); | 
|---|
 | 1377 |             desc       = (rpc_desc_t *)GET_PTR( xp ); | 
|---|
 | 1378 |  | 
|---|
 | 1379 |             // get rpc index and expected responses from RPC descriptor | 
|---|
 | 1380 |                 index     = hal_remote_lw( XPTR( client_cxy , &desc->index ) ); | 
|---|
 | 1381 |                 expected  = hal_remote_lw( XPTR( client_cxy , &desc->response ) ); | 
|---|
 | 1382 |  | 
|---|
 | 1383 |             // call the relevant server function | 
|---|
 | 1384 |             rpc_server[index]( xp ); | 
|---|
 | 1385 |  | 
|---|
 | 1386 |             // increment handled RPC counter | 
|---|
 | 1387 |                 count++; | 
|---|
 | 1388 |  | 
|---|
 | 1389 |             // notify RPC completion as required | 
|---|
 | 1390 |             if( expected == 1 ) hal_remote_sw( XPTR(client_cxy,&desc->response) , 0 ); | 
|---|
 | 1391 |             if( expected >  1 ) hal_remote_atomic_add( XPTR(client_cxy,&desc->response) , -1 ); | 
|---|
 | 1392 |                 } | 
|---|
 | 1393 |          | 
|---|
 | 1394 |                 // exit loop in three cases: | 
|---|
 | 1395 |         // - fifo is empty | 
|---|
 | 1396 |         // - look has been released (because descheduling) | 
|---|
 | 1397 |         // - max number of RPCs has been reached | 
|---|
 | 1398 |                 if( error ||  | 
|---|
 | 1399 |             (rpc_fifo->owner != this->trdid) ||  | 
|---|
 | 1400 |             (count > CONFIG_RPC_PENDING_MAX) ) break; | 
|---|
 | 1401 |         } | 
|---|
 | 1402 |     while( 1 ) | 
|---|
 | 1403 |  | 
|---|
 | 1404 |         rpc_dmsg("\n[INFO] %s running on core %d in cluster %x exit\n" | 
|---|
 | 1405 |               __FUNCTION__ , CURRENT_CORE->lid , local_cxy ); | 
|---|
 | 1406 |                  | 
|---|
 | 1407 |     // update RPC_FIFO global counter | 
|---|
 | 1408 |         rpc_fifo->count += count; | 
|---|
 | 1409 |  | 
|---|
 | 1410 |         return 0; | 
|---|
 | 1411 | }  // end rpc_execute_all() | 
|---|
 | 1412 |  | 
|---|
 | 1413 | //////////////////////////////////////////////////// | 
|---|
 | 1414 | error_t rpc_activate_thread( rpc_fifo_t * rpc_fifo ) | 
|---|
 | 1415 | { | 
|---|
 | 1416 |         core_t      * core; | 
|---|
 | 1417 |         thread_t    * thread; | 
|---|
 | 1418 |         thread_t    * this; | 
|---|
 | 1419 |     scheduler_t * sched; | 
|---|
 | 1420 |         error_t       error; | 
|---|
 | 1421 |     bool_t        found; | 
|---|
 | 1422 |     reg_t         sr_save; | 
|---|
 | 1423 |  | 
|---|
 | 1424 |         this   = CURRENT_THREAD; | 
|---|
 | 1425 |     core   = this->core; | 
|---|
 | 1426 |     sched  = &core->scheduler; | 
|---|
 | 1427 |     found  = false; | 
|---|
 | 1428 |  | 
|---|
 | 1429 |     // calling thread must be the RPC_FIFO owner | 
|---|
 | 1430 |     if( this->trdid != rpc_fifo->owner ) | 
|---|
 | 1431 |     { | 
|---|
 | 1432 |         printk("\n[PANIC] in %s : calling thread is not RPC_FIFO owner\n", __FUNCTION__ ); | 
|---|
 | 1433 |         hal_core_sleep(); | 
|---|
 | 1434 |     } | 
|---|
 | 1435 |  | 
|---|
 | 1436 |     // makes the calling thread not preemptable | 
|---|
 | 1437 |     // during activation / creation of the RPC thread | 
|---|
 | 1438 |         hal_disable_irq( &sr_save ); | 
|---|
 | 1439 |  | 
|---|
 | 1440 |     // search a free RPC thread (must be in THREAD_BLOCKED_IDLE state)     | 
|---|
 | 1441 |     list_entry_t * iter; | 
|---|
 | 1442 |     LIST_FOREACH( &sched->k_root , iter ) | 
|---|
 | 1443 |     { | 
|---|
 | 1444 |         thread = LIST_ELEMENT( iter , thread_t , sched_list ); | 
|---|
 | 1445 |         if( (thread->type == THREAD_RPC) && (thread->blocked ==  THREAD_BLOCKED_IDLE ) )  | 
|---|
 | 1446 |         { | 
|---|
 | 1447 |             found = true; | 
|---|
 | 1448 |             break; | 
|---|
 | 1449 |         } | 
|---|
 | 1450 |     } | 
|---|
 | 1451 |  | 
|---|
 | 1452 |     if( found )                    // activate this idle RPC thread       | 
|---|
 | 1453 |     { | 
|---|
 | 1454 |         thread->blocked = 0; | 
|---|
 | 1455 |     } | 
|---|
 | 1456 |     else                           // create a new RPC thread | 
|---|
 | 1457 |     { | 
|---|
 | 1458 |         error = thread_kernel_create( &thread, | 
|---|
 | 1459 |                                       THREAD_RPC,  | 
|---|
 | 1460 |                                                   &rpc_thread_func,  | 
|---|
 | 1461 |                                       NULL, | 
|---|
 | 1462 |                                                   core->lid ); | 
|---|
 | 1463 |             if( error )  | 
|---|
 | 1464 |         { | 
|---|
 | 1465 |                 hal_restore_irq( sr_save ); | 
|---|
 | 1466 |             printk("\n[ERROR] in %s : no memory for new RPC thread in cluster %x\n", | 
|---|
 | 1467 |                    __FUNCTION__ , local_cxy ); | 
|---|
 | 1468 |             return ENOMEM; | 
|---|
 | 1469 |         } | 
|---|
 | 1470 |  | 
|---|
 | 1471 |         rpc_dmsg("\n[INFO] %s creates RPC thread %x on core %x in cluster %x at cycle %d\n",  | 
|---|
| [101] | 1472 |                           __FUNCTION__ , thread , core->gid , local_cxy , hal_get_cycles() ); | 
|---|
| [1] | 1473 |  | 
|---|
 | 1474 |         // update core descriptor counter   | 
|---|
| [188] | 1475 |             hal_atomic_add( &core->rpc_threads , 1 ); | 
|---|
| [1] | 1476 |     } | 
|---|
 | 1477 |  | 
|---|
 | 1478 |     // update owner in rpc_fifo | 
|---|
 | 1479 |     rpc_fifo->owner = thread->trdid; | 
|---|
 | 1480 |  | 
|---|
 | 1481 |     rpc_dmsg ("\n[INFO] %s activates RPC thread %x on core %x in cluster %x at cycle %d\n", | 
|---|
| [101] | 1482 |                       __FUNCTION__ , thread , core->gid , local_cxy , hal_get_cycles() ); | 
|---|
| [1] | 1483 |  | 
|---|
 | 1484 |     // current thread deschedules / RPC thread start execution  | 
|---|
 | 1485 |         sched_switch_to( thread ); | 
|---|
 | 1486 |  | 
|---|
 | 1487 |     // restore IRQs for the calling thread  | 
|---|
 | 1488 |         hal_restore_irq( sr_save ); | 
|---|
 | 1489 |  | 
|---|
 | 1490 |     // return success | 
|---|
 | 1491 |         return 0; | 
|---|
 | 1492 |  | 
|---|
 | 1493 | }  // end rpc_activate_thread() | 
|---|
 | 1494 |  | 
|---|
 | 1495 | ////////////////// | 
|---|
 | 1496 | bool_t rpc_check() | 
|---|
 | 1497 | { | 
|---|
 | 1498 |         thread_t   * this     = CURRENT_THREAD; | 
|---|
 | 1499 |         rpc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; | 
|---|
 | 1500 |     error_t      error; | 
|---|
 | 1501 |  | 
|---|
| [5] | 1502 |     // calling thread does nothing if light lock already taken or FIFO empty   | 
|---|
| [1] | 1503 |         if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) ) | 
|---|
 | 1504 |     { | 
|---|
 | 1505 |         return false; | 
|---|
 | 1506 |     } | 
|---|
 | 1507 |  | 
|---|
| [5] | 1508 |         // calling thread tries to take the light lock, | 
|---|
 | 1509 |     // and activates an RPC thread if success | 
|---|
| [1] | 1510 |     if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) | 
|---|
 | 1511 |         { | 
|---|
 | 1512 |         error = rpc_activate_thread( rpc_fifo ); | 
|---|
 | 1513 |  | 
|---|
 | 1514 |         if( error )    // cannot activate an RPC_THREAD  | 
|---|
 | 1515 |         { | 
|---|
 | 1516 |             rpc_fifo->owner = 0; | 
|---|
 | 1517 |  | 
|---|
 | 1518 |             printk("\n[ERROR] in %s : no memory to create a RPC thread for core %d" | 
|---|
 | 1519 |                    " in cluster %x => do nothing\n", | 
|---|
 | 1520 |                    __FUNCTION__ , CURRENT_CORE->lid , local_cxy ); | 
|---|
 | 1521 |         } | 
|---|
 | 1522 |  | 
|---|
 | 1523 |         return true; | 
|---|
 | 1524 |     } | 
|---|
 | 1525 |     else  // light lock taken by another thread | 
|---|
 | 1526 |     { | 
|---|
 | 1527 |         return false; | 
|---|
 | 1528 |     } | 
|---|
| [5] | 1529 | } // end rpc_check() | 
|---|
| [1] | 1530 |  | 
|---|
 | 1531 |  | 
|---|
 | 1532 | ////////////////////// | 
|---|
 | 1533 | void rpc_thread_func() | 
|---|
 | 1534 | { | 
|---|
 | 1535 |     // makes the calling thread not preemptable | 
|---|
 | 1536 |         hal_disable_irq( NULL ); | 
|---|
 | 1537 |    | 
|---|
 | 1538 |         thread_t   * this     = CURRENT_THREAD; | 
|---|
 | 1539 |         rpc_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; | 
|---|
 | 1540 |  | 
|---|
 | 1541 |     rpc_dmsg("\n[INFO] RPC thread %x created on core %d in cluster %x at cycle %d\n", | 
|---|
| [101] | 1542 |              this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); | 
|---|
| [1] | 1543 |  | 
|---|
 | 1544 |     // this infinite loop is not preemptable | 
|---|
 | 1545 |     // the RPC thread deschedule when the RPC_FIFO is empty | 
|---|
 | 1546 |         while(1) | 
|---|
 | 1547 |         { | 
|---|
 | 1548 |         // check fifo ownership (ownership should be given by rpc_activate() | 
|---|
 | 1549 |         if( this->trdid != rpc_fifo->owner ) | 
|---|
 | 1550 |         { | 
|---|
 | 1551 |             printk("\n[PANIC] in %s : RPC_THREAD %x not owner of RPC_FIFO in cluster %x\n", | 
|---|
 | 1552 |                    __FUNCTION__ , this->trdid , local_cxy ); | 
|---|
 | 1553 |             hal_core_sleep(); | 
|---|
 | 1554 |         } | 
|---|
 | 1555 |   | 
|---|
 | 1556 |         // executes pending RPC(s)  | 
|---|
 | 1557 |         rpc_execute_all( rpc_fifo ); | 
|---|
 | 1558 |  | 
|---|
 | 1559 |         // release rpc_fifo ownership (can be lost during RPC execution) | 
|---|
 | 1560 |         if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0; | 
|---|
 | 1561 |  | 
|---|
 | 1562 |  | 
|---|
 | 1563 |         // suicide if too much RPC threads for this core | 
|---|
 | 1564 |                 if( this->core->rpc_threads > CONFIG_RPC_THREADS_MAX )  | 
|---|
 | 1565 |                 { | 
|---|
 | 1566 |             rpc_dmsg("\n[INFO] RPC thread %x suicide on core %d in cluster %x at cycle %d\n",  | 
|---|
| [101] | 1567 |                              this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); | 
|---|
| [1] | 1568 |  | 
|---|
 | 1569 |             // update core descriptor counter | 
|---|
| [188] | 1570 |                 hal_atomic_add( &this->core->rpc_threads , -1 ); | 
|---|
| [1] | 1571 |  | 
|---|
 | 1572 |             // suicide | 
|---|
 | 1573 |                         thread_exit(); | 
|---|
 | 1574 |                 } | 
|---|
 | 1575 |  | 
|---|
 | 1576 |         // block and deschedule | 
|---|
 | 1577 |         rpc_dmsg("\n[INFO] RPC thread %x deschedule on core %d in cluster %x at cycle %d\n",  | 
|---|
| [101] | 1578 |                               this->trdid , this->core->lid , local_cxy , hal_get_cycles() );  | 
|---|
| [1] | 1579 |  | 
|---|
 | 1580 |                 thread_block( this , THREAD_BLOCKED_IDLE ); | 
|---|
 | 1581 |         sched_yield(); | 
|---|
 | 1582 |  | 
|---|
 | 1583 |                 rpc_dmsg("\n[INFO] RPC thread %x wake up on core %d in cluster %x at cycle %d\n",  | 
|---|
| [101] | 1584 |                               this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); | 
|---|
| [1] | 1585 |         } | 
|---|
 | 1586 | } // end rpc_thread_func() | 
|---|
 | 1587 |  | 
|---|