Beispiel #1
0
/*! @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;
}
Beispiel #2
0
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;
}