Пример #1
0
// Handle randomly selected pending write
void handle_buffer_read(struct cmd *cmd)
{
	struct cmd_event *event;

	// Check that cmd struct is valid buffer read is available
	if ((cmd == NULL) || (cmd->buffer_read != NULL))
		return;

	// Randomly select a pending write (or none)
	event = cmd->list;
	while (event != NULL) {
		if ((event->type == CMD_WRITE) &&
		    (event->state == MEM_TOUCHED) &&
		    ((event->client_state != CLIENT_VALID) ||
		     !allow_reorder(cmd->parms))) {
			break;
		}
		event = event->_next;
	}

	// Test for client disconnect
	if ((event == NULL) || (_get_client(cmd, event) == NULL))
		return;

	// Send buffer read request to AFU.  Setting cmd->buffer_read
	// will block any more buffer read requests until buffer read
	// data is returned and handled in handle_buffer_data().
	if (psl_buffer_read(cmd->afu_event, event->tag, event->addr,
			    CACHELINE_BYTES) == PSL_SUCCESS) {
		cmd->buffer_read = event;
		debug_cmd_buffer_read(cmd->dbg_fp, cmd->dbg_id, event->tag);
		event->state = MEM_BUFFER;
	}
}
Пример #2
0
static void buffer_event (int rnw, uint32_t tag, uint8_t *addr) {
	uint8_t par[2];

	if (status.psl_state==PSL_FLUSHING) {
#ifdef DEBUG
		printf ("Response FLUSHED tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
		add_resp (tag, PSL_RESPONSE_FLUSHED);
		return;
	}

	if (!testmemaddr (addr)) {
		printf ("AFU attempted ");
		if (rnw)
			printf ("write");
		else
			printf ("read");
		printf (" to invalid address 0x%016llx\n",(long long) addr);
#ifdef DEBUG
		printf ("Response AERROR tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
		add_resp (tag, PSL_RESPONSE_AERROR);
		status.psl_state = PSL_FLUSHING;
		return;
	}

	if (rnw) {
#ifdef DEBUG
		printf ("Buffer Read tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
		psl_buffer_read (status.event, tag, (uint64_t) addr,
				 CACHELINE_BYTES);
	}
	else {
#ifdef DEBUG
		printf ("Buffer Write tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
		generate_cl_parity(addr, par);
		psl_buffer_write (status.event, tag, (uint64_t) addr,
				  CACHELINE_BYTES,
				  addr, par);
		++status.credits;
#ifdef DEBUG
		printf ("Response tag=0x%02x\n", tag);
#endif /* #ifdef DEBUG */
		if (status.psl_state==PSL_NLOCK) {
#ifdef DEBUG
			printf ("Nlock response for read, tag=0x%02x\n", tag);
			fflush (stdout);
#endif /* #ifdef DEBUG */
			add_resp (tag, PSL_RESPONSE_NLOCK);
		}
		else if (!PAGED_RANDOMIZER || (rand() % PAGED_RANDOMIZER)) {
			// Inject random "Paged" response
			add_resp (tag, PSL_RESPONSE_DONE);
		}
		else {
			add_resp (tag, PSL_RESPONSE_PAGED);
			status.psl_state = PSL_FLUSHING;
		}
	}
}