Exemple #1
0
void handle_buffer_data(struct cmd *cmd, uint32_t parity_enable)
{
	uint8_t *parity_check;
	int rc;
	struct cmd_event *event;
	int quadrant, byte;

	// Has struct been initialized?
	if ((cmd == NULL) || (cmd->buffer_read == NULL))
		return;

	// Check if buffer read data has returned from AFU
	event = cmd->buffer_read;
	rc = psl_get_buffer_read_data(cmd->afu_event, event->data,
				      event->parity);
	if (rc == PSL_SUCCESS) {
		debug_msg("%s:BUFFER READ tag=0x%02x", cmd->afu_name,
			  event->tag);
		for (quadrant = 0; quadrant < 4; quadrant++) {
			DPRINTF("DEBUG: Q%d 0x", quadrant);
			for (byte = 0; byte < CACHELINE_BYTES / 4; byte++) {
				DPRINTF("%02x", event->data[byte]);
			}
			DPRINTF("\n");
		}
		if (parity_enable) {
			parity_check =
			    (uint8_t *) malloc(DWORDS_PER_CACHELINE / 8);
			generate_cl_parity(event->data, parity_check);
			if (strncmp((char *)event->parity,
				    (char *)parity_check,
				    DWORDS_PER_CACHELINE / 8)) {
				error_msg("Buffer read parity error tag=0x%02x",
					  event->tag);
			}
			free(parity_check);
		}
		// Free buffer interface for another event
		cmd->buffer_read = NULL;

		// Randomly decide to not send data to client yet
		if (!event->buffer_activity && allow_buffer(cmd->parms)) {
			event->state = MEM_TOUCHED;
			event->buffer_activity = 1;
			return;
		}

		event->state = MEM_RECEIVED;
	}

}
Exemple #2
0
static void handle_psl_events (struct cxl_afu_h* afu) {
	uint32_t tag, size;
	uint8_t *addr;
	uint8_t parity[DWORDS_PER_CACHELINE];

	if (status.event->aux2_change) {
		status.event->aux2_change = 0;
		if (afu->running != status.event->job_running) {
			status.event_occurred = 1-status.event->job_running;
		}
		if (status.event->job_running)
			afu->running = 1;
		if (status.event->job_done) {
			if (status.cmd.request==AFU_RESET)
				status.cmd.request = AFU_IDLE;
			afu->running = 0;
		}
#ifdef DEBUG
		printf ("AUX2 jrunning=%d jdone=%d", status.event->job_running,
			status.event->job_done);
		if (status.event->job_done) {
			printf (" jerror=0x%016llx", (long long)
				status.event->job_error);
		}
		printf ("\n");
#endif /* #ifdef DEBUG */
	}
	if (psl_get_mmio_acknowledge (status.event, (uint64_t *)
	    &(status.mmio.data), (uint32_t *) &(status.mmio.parity)) ==
	    PSL_SUCCESS) {
#ifdef DEBUG
		printf ("MMIO Acknowledge\n");
#endif /* #ifdef DEBUG */
		status.mmio.request = AFU_IDLE;
	}
	if (status.first_br && status.psl_state==PSL_FLUSHING) {
		add_resp (status.first_br->tag, PSL_RESPONSE_FLUSHED);
		remove_buffer_read();
	}
	else if (status.first_br) {
		uint8_t *buffer = (uint8_t *) malloc (CACHELINE_BYTES);
		if (psl_get_buffer_read_data (status.event, buffer, parity)
		    == PSL_SUCCESS) {
			uint64_t offset = (uint64_t) status.first_br->addr;
			offset &= 0x7Fll;
			memcpy (status.first_br->addr, &(buffer[offset]),
				status.first_br->size);
			++status.credits;
#ifdef DEBUG
			printf ("Response tag=0x%02x\n", status.first_br->tag);
#endif /* #ifdef DEBUG */
			if ((status.first_br->resp_type==RESP_UNLOCK) &&
			    ((status.psl_state==PSL_LOCK) ||
		             (status.psl_state==PSL_NLOCK))) {
#ifdef DEBUG
				printf ("Lock sequence completed\n");
				fflush (stdout);
#endif /* #ifdef DEBUG */
				status.psl_state = PSL_RUNNING;
			}
			// Inject random "Paged" response
			if (!PAGED_RANDOMIZER || (rand() % PAGED_RANDOMIZER)) {
				add_resp (status.first_br->tag,
					  PSL_RESPONSE_DONE);
			}
			else {
				add_resp (status.first_br->tag,
					  PSL_RESPONSE_PAGED);
				status.psl_state = PSL_FLUSHING;
			}
			// Stop remembing status.first_br
			remove_buffer_read();
		}
	}
	if (status.event->command_valid) {
#ifdef DEBUG
		printf ("Command tag=0x%02x\n", status.event->command_tag);
#endif /* #ifdef DEBUG */
		status.event->command_valid = 0;
		tag = status.event->command_tag;
		size = status.event->command_size;
		if ((status.psl_state==PSL_FLUSHING) &&
		    (status.event->command_code != 1)) {
#ifdef DEBUG
			printf ("Response FLUSHED tag=0x%02x\n", tag);
			fflush (stdout);
#endif /* #ifdef DEBUG */
			add_resp (tag, PSL_RESPONSE_FLUSHED);
			return;
		}
		--status.credits;
		addr = (uint8_t *) status.event->command_address;

		if (((status.psl_state==PSL_LOCK) &&
		     (status.event->command_code!=PSL_COMMAND_WRITE_UNLOCK)) ||
		    (status.psl_state==PSL_NLOCK)) {
#ifdef DEBUG
			printf ("Response NLOCK tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
			add_resp (tag, PSL_RESPONSE_NLOCK);
			status.psl_state=PSL_NLOCK;
			update_pending_resps (PSL_RESPONSE_NLOCK);
#ifdef DEBUG
			printf ("Dumping lock intervening command, tag=0x%02x\n", tag);
			fflush (stdout);
#endif /* #ifdef DEBUG */
			return;
		}

		uint8_t resp_type = RESP_NORMAL;
		switch (status.event->command_code) {
		// Interrupt
		case PSL_COMMAND_INTREQ:
			printf ("AFU interrupt command received\n");
			status.event_occurred = 1;
#ifdef DEBUG
			printf ("Response tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
			add_resp (tag, PSL_RESPONSE_FLUSHED);
			break;
		// Restart
		case PSL_COMMAND_RESTART:
			status.psl_state = PSL_RUNNING;
#ifdef DEBUG
			printf ("AFU restart command received\n");
			printf ("Response tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
			add_resp (tag, PSL_RESPONSE_DONE);
			break;
		// Memory Reads
		case PSL_COMMAND_READ_CL_LCK:
			update_pending_resps (PSL_RESPONSE_NLOCK);
			status.psl_state = PSL_LOCK;
#ifdef DEBUG
			printf ("Starting lock sequence, tag=0x%02x\n", tag);
			fflush (stdout);
#endif /* #ifdef DEBUG */
		case PSL_COMMAND_READ_CL_RES:
		case PSL_COMMAND_READ_CL_S:
		case PSL_COMMAND_READ_CL_M:
		case PSL_COMMAND_READ_CL_NA:
		case PSL_COMMAND_READ_PNA:
		case PSL_COMMAND_READ_LS:
		case PSL_COMMAND_READ_LM:
		case PSL_COMMAND_RD_GO_S:
		case PSL_COMMAND_RD_GO_M:
#ifdef DEBUG
			printf ("Read command size=%d tag=0x%02x\n", size, tag);
#endif /* #ifdef DEBUG */
			buffer_event (0, tag, addr);
			break;
		// Memory Writes
		case PSL_COMMAND_WRITE_UNLOCK:
			resp_type = RESP_UNLOCK;
		case PSL_COMMAND_WRITE_C:
		case PSL_COMMAND_WRITE_MI:
		case PSL_COMMAND_WRITE_MS:
		case PSL_COMMAND_WRITE_NA:
		case PSL_COMMAND_WRITE_INJ:
		case PSL_COMMAND_WRITE_LM:
#ifdef DEBUG
			printf ("Write command size=%d, tag=0x%02x\n", size,
				tag);
#endif /* #ifdef DEBUG */
			//printf ("Memory write request 0x%02x\n", tag);
			// Only issue buffer read if no other pending
			if (!status.first_br) {
				//printf ("Buffer read request 0x%02x\n", tag);
				buffer_event (1, tag, addr);
			}
			add_buffer_read (tag, size, addr, resp_type);
			// Remember tag and addr
			break;
		default:
			break;
		}
	}
}