/*! @brief Sets the process's parameter buffer. Sets the process's parameter buffer to the given RAM dataspace. Only support a RAM dataspace which orginated from the process server's own dataspace implementation, does not support an external dataspace. */ refos_err_t proc_set_parambuffer_handler(void *rpc_userptr , seL4_CPtr rpc_dataspace , uint32_t rpc_size) { struct proc_pcb *pcb = (struct proc_pcb*) rpc_userptr; struct procserv_msg *m = (struct procserv_msg*) pcb->rpcClient.userptr; assert(pcb->magic == REFOS_PCB_MAGIC); struct ram_dspace *dataspace; /* Special case zero size and NULL parameter buffer - means unset the parameter buffer. */ if (rpc_size == 0 && rpc_dataspace == 0) { proc_set_parambuffer(pcb, NULL); return ESUCCESS; } if (!check_dispatch_caps(m, 0x00000001, 1)) { return EINVALIDPARAM; } /* Check if the given badge is a RAM dataspace. */ if (!dispatcher_badge_dspace(rpc_dataspace)) { return EINVALIDPARAM; } /* Retrieve RAM dataspace structure. */ dataspace = ram_dspace_get_badge(&procServ.dspaceList, rpc_dataspace); if (!dataspace) { dvprintf("No such dataspace!.\n"); return EINVALID; } /* Set new parameter buffer. */ proc_set_parambuffer(pcb, dataspace); return ESUCCESS; }
int srv_common_init(srv_common_t *s, srv_common_config_t config) { assert(s); dprintf("Initialising %s common server state...\n", config.serverName); memset(s, 0, sizeof(srv_common_t)); s->config = config; /* Create sync anon EP. */ dprintf(" creating %s anon endpoint...\n", config.serverName); s->anonEP = proc_new_endpoint(); if (!s->anonEP) { ROS_ERROR("srv_common_init could not create endpoint for %s.", config.serverName); return ENOMEM; } /* Create async EP. */ dprintf(" creating %s async endpoint...\n", config.serverName); s->notifyAsyncEP = proc_new_async_endpoint(); if (!s->notifyAsyncEP) { ROS_ERROR("srv_common_init could not create async endpoint."); return ENOMEM; } /* Mint badged async EP. */ dprintf(" creating async death and/or fault notification badged EP...\n"); s->notifyClientFaultDeathAsyncEP = srv_mint(config.faultDeathNotifyBadge, s->notifyAsyncEP); if (!s->notifyClientFaultDeathAsyncEP) { ROS_ERROR("srv_common_init could not create minted async endpoint."); return EINVALID; } /* Bind the notification AEP. */ dprintf(" binding notification AEP...\n"); int error = seL4_TCB_BindNotification(REFOS_THREAD_TCB, s->notifyAsyncEP); if (error != seL4_NoError) { ROS_ERROR("srv_common_init could not bind async endpoint."); return EINVALID; } /* Register ourselves under our mountpoint name. */ if (config.mountPointPath != NULL) { dprintf(" registering under the mountpoint [%s]...\n", config.mountPointPath); error = nsv_register(config.nameServEP, config.mountPointPath, s->anonEP); if (error != ESUCCESS) { ROS_ERROR("srv_common_init could not register anon ep."); return error; } } /* Initialise client table. */ if (config.maxClients > 0) { dprintf(" initialising client table for %s...\n", config.serverName); client_table_init(&s->clientTable, config.maxClients, config.clientBadgeBase, config.clientMagic, s->anonEP); dprintf(" initialising client table default handlers for %s...\n", config.serverName); s->ctable_connect_direct_handler = srv_ctable_connect_direct_handler; s->ctable_set_param_buffer_handler = srv_ctable_set_param_buffer_handler; s->ctable_disconnect_direct_handler = srv_ctable_disconnect_direct_handler; } /* Set up our server --> process server notification buffer. */ if (config.notificationBufferSize > 0) { /* Open and map the notification buffer on our side. */ dprintf(" initialising notification buffer for %s...\n", config.serverName); s->notifyBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0, config.notificationBufferSize, -1); if (s->notifyBuffer.err != ESUCCESS) { ROS_ERROR("srv_common_init failed to open & map anon dspace for notifications."); return s->notifyBuffer.err; } /* Share and set the notification buffer on the procserv side. */ assert(s->notifyBuffer.dataspace); error = proc_notification_buffer(s->notifyBuffer.dataspace); if (error != ESUCCESS) { ROS_ERROR("srv_common_init failed to set notification buffer."); return error; } s->notifyBufferStart = 0; } /* Set up our server --> process server parameter buffer. */ if (config.paramBufferSize > 0) { dprintf(" initialising procserv param buffer for %s...\n", config.serverName); s->procServParamBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0, config.paramBufferSize, -1); if (s->procServParamBuffer.err != ESUCCESS) { ROS_ERROR("srv_common_init failed to open & map anon dspace for param buffer."); return s->procServParamBuffer.err; } error = proc_set_parambuffer(s->procServParamBuffer.dataspace, config.paramBufferSize); if (error != ESUCCESS) { ROS_ERROR("srv_common_init failed to set procserv param buffer."); return error; } } s->magic = SRV_MAGIC; return ESUCCESS; }