コード例 #1
0
ファイル: pslse.c プロジェクト: KennethWilke/pslse
static void *_client_loop(void *ptr)
{
    struct client *client = (struct client *)ptr;
    uint8_t data[2];
    int rc;

    pthread_mutex_lock(&lock);
    while (client->pending) {
        rc = bytes_ready(client->fd, client->timeout, &(client->abort));
        if (rc == 0) {
            lock_delay(&lock);
            continue;
        }
        if ((rc < 0) || get_bytes(client->fd, 1, data, 10,
                                  &(client->abort), fp, -1, -1) < 0) {
            client_drop(client, PSL_IDLE_CYCLES, CLIENT_NONE);
            break;
        }
        if (data[0] == PSLSE_QUERY) {
            if (get_bytes_silent(client->fd, 1, data, timeout,
                                 &(client->abort)) < 0) {
                debug_msg("_client_loop failed PSLSE_QUERY");
                client_drop(client, PSL_IDLE_CYCLES,
                            CLIENT_NONE);
                break;
            }
            _query(client, data[0]);
            lock_delay(&lock);
            continue;
        }
        if (data[0] == PSLSE_MAX_INT) {
            if (get_bytes(client->fd, 2, data, timeout,
                          &(client->abort), fp, -1, -1) < 0) {
                client_drop(client, PSL_IDLE_CYCLES,
                            CLIENT_NONE);
                break;
            }
            _max_irqs(client, data[0]);
            lock_delay(&lock);
            continue;
        }
        if (data[0] == PSLSE_OPEN) {
            if (get_bytes_silent(client->fd, 2, data, timeout,
                                 &(client->abort)) < 0) {
                client_drop(client, PSL_IDLE_CYCLES,
                            CLIENT_NONE);
                debug_msg("_client_loop: client associate failed; could not communicate with socket");
                break;
            }
            _client_associate(client, data[0], (char)data[1]);
            debug_msg("_client_loop: client associated");
            break;
        }
        client->pending = 0;
        break;
        lock_delay(&lock);
    }
    pthread_mutex_unlock(&lock);

    // Terminate thread
    pthread_exit(NULL);
}
コード例 #2
0
ファイル: psl.c プロジェクト: open-cpu/pslse
static void _handle_client(struct psl *psl, struct client *client)
{
	struct mmio_event *mmio;
	struct cmd_event *cmd;
	uint8_t buffer[MAX_LINE_CHARS];
	int dw = 0;

	// Handle MMIO done
	if (client->mmio_access != NULL) {
		client->idle_cycles = PSL_IDLE_CYCLES;
		client->mmio_access = handle_mmio_done(psl->mmio, client);
	}
	// Client disconnected
	if (client->state == CLIENT_NONE)
		return;

	// Check for event from application
	cmd = (struct cmd_event *)client->mem_access;
	mmio = NULL;
	if (bytes_ready(client->fd, 1, &(client->abort))) {
		if (get_bytes(client->fd, 1, buffer, psl->timeout,
			      &(client->abort), psl->dbg_fp, psl->dbg_id,
			      client->context) < 0) {
			client_drop(client, PSL_IDLE_CYCLES, CLIENT_NONE);
			return;
		}
		switch (buffer[0]) {
		case PSLSE_DETACH:
			client_drop(client, PSL_IDLE_CYCLES, CLIENT_NONE);
			break;
		case PSLSE_ATTACH:
			_attach(psl, client);
			break;
		case PSLSE_MEM_FAILURE:
			if (client->mem_access != NULL)
				handle_aerror(psl->cmd, cmd);
			client->mem_access = NULL;
			break;
		case PSLSE_MEM_SUCCESS:
			if (client->mem_access != NULL)
				handle_mem_return(psl->cmd, cmd, client->fd);
			client->mem_access = NULL;
			break;
		case PSLSE_MMIO_MAP:
			handle_mmio_map(psl->mmio, client);
			break;
		case PSLSE_MMIO_WRITE64:
			dw = 1;
		case PSLSE_MMIO_WRITE32:	/*fall through */
			mmio = handle_mmio(psl->mmio, client, 0, dw);
			break;
		case PSLSE_MMIO_READ64:
			dw = 1;
		case PSLSE_MMIO_READ32:	/*fall through */
			mmio = handle_mmio(psl->mmio, client, 1, dw);
			break;
		default:
			error_msg("Unexpected 0x%02x from client", buffer[0]);
		}

		if (mmio)
			client->mmio_access = (void *)mmio;

		if (client->state == CLIENT_VALID)
			client->idle_cycles = PSL_IDLE_CYCLES;
	}
}
コード例 #3
0
ファイル: libcxl.c プロジェクト: e-shannon/pslse
static void *_psl_loop(void *ptr)
{
	struct cxl_afu_h *afu = (struct cxl_afu_h *)ptr;
	uint8_t buffer[MAX_LINE_CHARS];
	uint8_t size;
	uint64_t addr;
	uint16_t value;
	uint32_t lvalue;
	int rc;

	if (!afu)
		fatal_msg("NULL afu passed to libcxl.c:_psl_loop");
	afu->opened = 1;
	while (afu->opened) {
		_delay_1ms();
		// Send any requests to PSLSE over socket
		if (afu->int_req.state == LIBCXL_REQ_REQUEST)
			_req_max_int(afu);
		if (afu->attach.state == LIBCXL_REQ_REQUEST)
			_pslse_attach(afu);
		if (afu->mmio.state == LIBCXL_REQ_REQUEST) {
			switch (afu->mmio.type) {
			case PSLSE_MMIO_MAP:
				_mmio_map(afu);
				break;
			case PSLSE_MMIO_WRITE64:
				_mmio_write64(afu);
				break;
			case PSLSE_MMIO_WRITE32:
				_mmio_write32(afu);
				break;
			case PSLSE_MMIO_EBREAD:
			case PSLSE_MMIO_READ64:
			case PSLSE_MMIO_READ32:	/*fall through */
				_mmio_read(afu);
				break;
			default:
				break;
			}
		}
		// Process socket input from PSLSE
		rc = bytes_ready(afu->fd, 1000, 0);
		if (rc == 0)
			continue;
		if (rc < 0) {
			warn_msg("Socket failure testing bytes_ready");
			_all_idle(afu);
			break;
		}
		if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
			warn_msg("Socket failure getting PSL event");
			_all_idle(afu);
			break;
		}
		DPRINTF("PSL EVENT\n");
		switch (buffer[0]) {
		case PSLSE_OPEN:
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg("Socket failure getting OPEN context");
				_all_idle(afu);
				break;
			}
			afu->context = (uint16_t) buffer[0];
			afu->open.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_ATTACH:
			afu->attach.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_DETACH:
		        info_msg("detach response from from pslse");
			afu->mapped = 0;
			afu->attached = 0;
			afu->opened = 0;
			afu->open.state = LIBCXL_REQ_IDLE;
			afu->attach.state = LIBCXL_REQ_IDLE;
			afu->mmio.state = LIBCXL_REQ_IDLE;
			afu->int_req.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_MAX_INT:
			size = sizeof(uint16_t);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg
				    ("Socket failure getting max interrupt acknowledge");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&value, (char *)buffer,
			       sizeof(uint16_t));
			afu->irqs_max = ntohs(value);
			afu->int_req.state = LIBCXL_REQ_IDLE;
			break;
		case PSLSE_QUERY: {
			size = sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) +
			    sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) +  
                            sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg("Socket failure getting PSLSE query");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&value, (char *)&(buffer[0]), 2);
			afu->irqs_min = (long)(value);
			memcpy((char *)&value, (char *)&(buffer[2]), 2);
			afu->irqs_max = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[4]), 2);
			afu->modes_supported = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[6]), 8);
			afu->mmio_len = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[14]), 8);
			afu->mmio_off = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[22]), 8);
			//afu->eb_len = (long)ntohll(value);
			afu->eb_len = (long)(value);
                	memcpy((char *)&value, (char *)&(buffer[30]), 2);
			afu->cr_device = (long)ntohs(value);
                        memcpy((char *)&value, (char *)&(buffer[32]), 2);
			afu->cr_vendor = (long)ntohs(value);
                        memcpy((char *)&lvalue, (char *)&(buffer[34]), 4);
			afu->cr_class = ntohl(lvalue);
			//no better place to put this right now
			afu->prefault_mode = CXL_PREFAULT_MODE_NONE;
			break;
		}
		case PSLSE_MEMORY_READ:
			DPRINTF("AFU MEMORY READ\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory read size");
				_all_idle(afu);
				break;
			}
			size = (uint8_t) buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory read addr");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			_handle_read(afu, addr, size);
			break;
		case PSLSE_MEMORY_WRITE:
			DPRINTF("AFU MEMORY WRITE\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory write size");
				_all_idle(afu);
				break;
			}
			size = (uint8_t) buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			if (get_bytes_silent(afu->fd, size, buffer, 1000, 0) <
			    0) {
				warn_msg
				    ("Socket failure getting memory write data");
				_all_idle(afu);
				break;
			}
			_handle_write(afu, addr, size, buffer);
			break;
		case PSLSE_MEMORY_TOUCH:
			DPRINTF("AFU MEMORY TOUCH\n");
			if (get_bytes_silent(afu->fd, 1, buffer, 1000, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory touch size");
				_all_idle(afu);
				break;
			}
			size = buffer[0];
			if (get_bytes_silent(afu->fd, sizeof(uint64_t), buffer,
					     -1, 0) < 0) {
				warn_msg
				    ("Socket failure getting memory touch addr");
				_all_idle(afu);
				break;
			}
			memcpy((char *)&addr, (char *)buffer, sizeof(uint64_t));
			addr = ntohll(addr);
			_handle_touch(afu, addr, size);
			break;
		case PSLSE_MMIO_ACK:
			_handle_ack(afu);
			break;
		case PSLSE_INTERRUPT:
			if (_handle_interrupt(afu) < 0) {
				perror("Interrupt Failure");
				goto psl_fail;
			}
			break;
		case PSLSE_AFU_ERROR:
			if (_handle_afu_error(afu) < 0) {
				perror("AFU ERROR Failure");
				goto psl_fail;
			}
			break;
		default:
			break;
		}
	}

 psl_fail:
	afu->attached = 0;
	pthread_exit(NULL);
}