Example #1
0
void LoadCommand::send_command(AFU_EVENT *afu_event, uint32_t new_tag, uint64_t address, uint16_t command_size, uint8_t abort, uint16_t context){
	if(Command::state != IDLE)
		error_msg("LoadCommand: Attempting to send command before previous command is completed");

	Command::completed = false;

	uint32_t tag_parity = (command_tag_parity)? generate_parity(new_tag + 1, ODD_PARITY) : generate_parity(new_tag, ODD_PARITY);
	uint32_t code_parity = (command_code_parity)? generate_parity(Command::code + 1, ODD_PARITY) : generate_parity(Command::code, ODD_PARITY);
	uint32_t address_parity = (command_address_parity)? generate_parity(address + 1, ODD_PARITY) : generate_parity(address, ODD_PARITY);

	if(psl_afu_command(afu_event, new_tag, tag_parity, Command::code, code_parity, address, address_parity, command_size, abort, context) != PSL_SUCCESS)
		error_msg("LoadCommand: Failed to send command");

	info_msg("LoadCommand: handle=0x%x address=0x%016lx code=0x%04x size=0x%02x", context, address, Command::code, command_size);
	Command::state = WAITING_DATA;
	Command::tag = new_tag;
}
Example #2
0
static void generate_cl_parity(uint8_t *data, uint8_t *parity) {
	int i;
	uint64_t dw;
	uint8_t p;

	for (i=0; i<DWORDS_PER_CACHELINE; i++) {
		memcpy(&dw, &(data[BYTES_PER_DWORD*i]), BYTES_PER_DWORD);
		if ((i%BYTES_PER_DWORD)==0)
			parity[i/BYTES_PER_DWORD]=0;
		parity[i/BYTES_PER_DWORD]<<=1;
		p=generate_parity(dw, ODD_PARITY);
		parity[i/BYTES_PER_DWORD]+=p;
	}
}
Example #3
0
File: cmd.c Project: open-cpu/pslse
// See if a command was sent by AFU and process if so
void handle_cmd(struct cmd *cmd, uint32_t parity_enabled, uint32_t latency)
{
	struct cmd_event *event;
	uint64_t address, address_parity;
	uint32_t command, command_parity, tag, tag_parity, size, abort, handle;
	uint8_t parity, fail;
	int rc;

	if (cmd == NULL)
		return;

	// Check for command from AFU
	rc = psl_get_command(cmd->afu_event, &command, &command_parity, &tag,
			     &tag_parity, &address, &address_parity, &size,
			     &abort, &handle);

	// No command ready
	if (rc != PSL_SUCCESS)
		return;

	debug_msg
	    ("%s:COMMAND tag=0x%02x code=0x%04x size=0x%02x abt=%d cch=0x%04x",
	     cmd->afu_name, tag, command, size, abort, handle);
	debug_msg("%s:COMMAND tag=0x%02x addr=0x%016" PRIx64, cmd->afu_name,
		  tag, address);

	// Is AFU running?
	if (*(cmd->psl_state) != PSLSE_RUNNING) {
		warn_msg("Command without jrunning, tag=0x%02x", tag);
		return;
	}
	// Check parity
	fail = 0;
	if (parity_enabled) {
		parity = generate_parity(address, ODD_PARITY);
		if (parity != address_parity) {
			_cmd_parity_error("address", (uint64_t) address,
					  address_parity);
			fail = 1;
		}
		parity = generate_parity(tag, ODD_PARITY);
		if (parity != tag_parity) {
			_cmd_parity_error("tag", (uint64_t) tag, tag_parity);
			fail = 1;
		}
		parity = generate_parity(command, ODD_PARITY);
		if (parity != command_parity) {
			_cmd_parity_error("code", (uint64_t) command,
					  command_parity);
			fail = 1;
		}
	}
	// Add failed command
	if (fail) {
		_add_other(cmd, handle, tag, command, abort,
			   PSL_RESPONSE_FAILED);
		return;
	}
	// Check credits and parse
	if (!cmd->credits) {
		warn_msg("AFU issued command without any credits");
		_add_other(cmd, handle, tag, command, abort,
			   PSL_RESPONSE_FAILED);
		return;
	}

	cmd->credits--;

	// Client not connected
	if ((cmd == NULL) || (cmd->client == NULL) ||
	    (handle >= cmd->max_clients) || ((cmd->client[handle]) == NULL)) {
		_add_other(cmd, handle, tag, command, abort,
			   PSL_RESPONSE_FAILED);
		return;
	}
	// Client is flushing new commands
	if ((cmd->client[handle]->flushing == FLUSH_FLUSHING) &&
	    (command != PSL_COMMAND_RESTART)) {
		_add_other(cmd, handle, tag, command, abort,
			   PSL_RESPONSE_FLUSHED);
		return;
	}
	// Check for duplicate tag
	event = cmd->list;
	while (event != NULL) {
		if (event->tag == tag) {
			error_msg("Duplicate tag 0x%02x", tag);
			return;
		}
		event = event->_next;
	}

	// Parse command
	_parse_cmd(cmd, command, tag, address, size, abort, handle, latency);
}