コード例 #1
0
ファイル: endpoints.c プロジェクト: TUM-LIS/optimsoc
uint32_t endpoint_channel_get_fillstate(struct endpoint *ep) {
    return ep->buffer->size - endpoint_channel_get_credit(ep) - 1;
}
コード例 #2
0
ファイル: control.c プロジェクト: chethann/optimsoc
// The following handler is called by the message interrupt service routine
void control_msg_handler(unsigned int* buffer,int len) {
    // Extract sender information
    unsigned int src = EXTRACT(buffer[0],OPTIMSOC_SRC_MSB,OPTIMSOC_SRC_LSB);
    // Extract request type
    int req = EXTRACT(buffer[0],CTRL_REQUEST_MSB,CTRL_REQUEST_LSB);

    // Reply buffer
    uint32_t rbuffer[5];

    // Handle the respective request
    switch (req) {
    case CTRL_REQUEST_GETEP_REQ:
    {
        trace_ep_get_req_recv(src, buffer[1], buffer[2]);

        // This is the request to get an endpoint handle
        // Flit 1: node number
        // Flit 2: port number

        // Return the get endpoint response to sender
        rbuffer[0] = (src << OPTIMSOC_DEST_LSB) |
                     (1 << OPTIMSOC_CLASS_LSB) |
                     (optimsoc_get_tileid() << OPTIMSOC_SRC_LSB) |
                     (CTRL_REQUEST_GETEP_RESP << CTRL_REQUEST_LSB);

        // Get endpoint handle for <thisdomain,node,port> where
        // this domain is the tile id
        struct endpoint_handle *eph = endpoint_get(optimsoc_get_tileid(),
                                                   buffer[1], buffer[2]);

        // If valid numbers and endpoint handle found
        if (
                //buffer[1] < MCA_MAX_NODES &&
                //buffer[2] < MCAPI_MAX_ENDPOINTS &&
                (eph!=0)) {
            // Return endpoint
            rbuffer[1] = (unsigned int) eph->ep;
        } else {
            // Signal this is an invalid endpoint
            rbuffer[1] = (int) -1;
        }

        trace_ep_get_resp_send(src, (struct endpoint*) rbuffer[1]);
        optimsoc_mp_simple_send(2,rbuffer);
        break;
    }
    case CTRL_REQUEST_MSG_ALLOC_REQ:
    {
        rbuffer[0] = (src << OPTIMSOC_DEST_LSB) |
                (1 << OPTIMSOC_CLASS_LSB) |
                (optimsoc_get_tileid() << OPTIMSOC_SRC_LSB) |
                (CTRL_REQUEST_MSG_ALLOC_RESP << CTRL_REQUEST_LSB);

        struct endpoint *ep = (struct endpoint*) buffer[1];
        unsigned int size = buffer[2];

        trace_msg_alloc_req_recv(src, ep, size);

        uint32_t ptr;
        int rv = endpoint_alloc(ep, size, &ptr);
        if (rv == 0) {
            rbuffer[1] = CTRL_REQUEST_ACK;
            rbuffer[2] = ptr;
            trace_msg_alloc_resp_send(src, ep, ptr);
            optimsoc_mp_simple_send(3, rbuffer);

        } else {
            rbuffer[1] = CTRL_REQUEST_NACK;
            trace_msg_alloc_resp_send(src, ep, -1);
            optimsoc_mp_simple_send(2,rbuffer);
        }

        break;
    }
    case CTRL_REQUEST_MSG_DATA:
    {
        struct endpoint *ep = (struct endpoint*) buffer[1];

        endpoint_write(ep, buffer[2], buffer[3], (uint32_t*) &buffer[4], len-4);

        break;
    }
    case CTRL_REQUEST_MSG_COMPLETE:
    {
        struct endpoint *ep = (struct endpoint*) buffer[1];

        endpoint_write_complete(ep, buffer[2], buffer[3]);

#ifdef RUNTIME
        if (ep->waiting) {
                thread_resume(ep->waiting_thread);
                ep->waiting = 0;
            }
#endif
        break;
    }
    case CTRL_REQUEST_CHAN_CONNECT_REQ:
    {
        struct endpoint *ep = (struct endpoint *) buffer[1];
        ep->remotedomain = (uint32_t) buffer[2];
        ep->remote = (struct endpoint *) buffer[3];

        rbuffer[0] = (src << OPTIMSOC_DEST_LSB) |
                (1 << OPTIMSOC_CLASS_LSB) |
                (optimsoc_get_tileid() << OPTIMSOC_SRC_LSB) |
                (CTRL_REQUEST_CHAN_CONNECT_RESP << CTRL_REQUEST_LSB);

        rbuffer[1] = endpoint_channel_get_credit(ep);
        optimsoc_mp_simple_send(2, rbuffer);
        break;
    }
    case CTRL_REQUEST_CHAN_DATA:
    {
        struct endpoint *ep = (struct endpoint *) buffer[1];
        uint32_t offset = buffer[2];
        uint32_t eom = buffer[3];

        endpoint_write(ep, ep->buffer->write_ptr, offset, (uint32_t*) &buffer[4], len-4);

        if (eom) {
            ep->buffer->data_size[ep->buffer->write_ptr] = offset + len - 4;
            ep->buffer->write_ptr = _endpoint_addptrwrap(ep, ep->buffer->write_ptr, 1);
            trace_ep_bufferstate(ep, endpoint_channel_get_fillstate(ep));
        }


        break;
    }
    case CTRL_REQUEST_CHAN_CREDIT:
    {
      struct endpoint *ep = (struct endpoint *) buffer[1];
        uint32_t credit = buffer[2];

        if (credit == 0) {
            ep->remotecredit = 0;
        } else {
            ep->remotecredit += credit;
        }

        break;
    }
    case CTRL_REQUEST_GETEP_RESP:
    case CTRL_REQUEST_MSG_ALLOC_RESP:
    case CTRL_REQUEST_CHAN_CONNECT_RESP:
        // Forward the responses to the handler
        ctrl_request.buffer[0] = buffer[0];
        ctrl_request.buffer[1] = buffer[1];
        ctrl_request.buffer[2] = buffer[2];
        ctrl_request.buffer[3] = buffer[3];
        ctrl_request.buffer[4] = buffer[4];
        ctrl_request.done = 1;
        break;
    default:
        printf("Unknown request: %d\n",req);
        break;
    }
}