Exemple #1
0
// See if AFU changed any of the aux2 signals and handle accordingly
int handle_aux2(struct job *job, uint32_t * parity, uint32_t * latency,
		uint64_t * error)
{
	struct job_event *event;
	uint32_t job_running;
	uint32_t job_done;
	uint32_t job_cack_llcmd;
	uint64_t job_error;
	uint32_t job_yield;
	uint32_t tb_request;
	uint32_t par_enable;
	uint32_t read_latency;
	uint8_t dbg_aux2;
	int reset, reset_complete;

	if (job == NULL)
		return 0;

	// See if AFU is driving AUX2 signal changes
	dbg_aux2 = reset = reset_complete = *error = 0;
	if (psl_get_aux2_change(job->afu_event, &job_running, &job_done,
				&job_cack_llcmd, &job_error, &job_yield,
				&tb_request, &par_enable, &read_latency) ==
	    PSL_SUCCESS) {
		// Handle job_done
		if (job_done) {
			dbg_aux2 |= DBG_AUX2_DONE;
			*error = job_error;
			if (job->job != NULL) {
				event = job->job;
				// Is job_done for reset or start?
				if (event->code == PSL_JOB_RESET)
					reset_complete = 1;
				else
					reset = 1;
				job->job = event->_next;
				free(event);
				if (job->job != NULL)
					assert(job->job->_next != job->job);
			}
			if (*(job->psl_state) == PSLSE_RESET) {
				*(job->psl_state) = PSLSE_IDLE;
			}
		}
		// Handle job_running
		if (job_running) {
			*(job->psl_state) = PSLSE_RUNNING;
			dbg_aux2 |= DBG_AUX2_RUNNING;
		}
		if (job_cack_llcmd) {
			dbg_aux2 |= DBG_AUX2_LLCACK;
		}
		if (tb_request) {
			dbg_aux2 |= DBG_AUX2_TBREQ;
		}
		if (par_enable) {
			dbg_aux2 |= DBG_AUX2_PAREN;
		}
		dbg_aux2 |= read_latency & DBG_AUX2_LAT_MASK;
		if (job_done && job_running)
			error_msg("ah_jdone & ah_jrunning asserted together");
		if ((read_latency != 1) && (read_latency != 3))
			warn_msg("ah_brlat must be either 1 or 3");
		*parity = par_enable;
		*latency = read_latency;

		// DEBUG
		debug_job_aux2(job->dbg_fp, job->dbg_id, dbg_aux2);
	}

	if (reset)
		add_job(job, PSL_JOB_RESET, 0L);

	return reset_complete;
}
Exemple #2
0
// See if AFU changed any of the aux2 signals and handle accordingly
int _handle_aux2(struct psl *psl, uint32_t * parity, uint32_t * latency,
		uint64_t * error)
{
        struct job *job;
	struct job_event *_prev;
	struct job_event *cacked_pe;
	struct job_event *event;
	uint32_t job_running;
	uint32_t job_done;
	uint32_t job_cack_llcmd;
	uint64_t job_error;
	uint32_t job_yield;
	uint32_t tb_request;
	uint32_t par_enable;
	uint32_t read_latency;
	uint8_t dbg_aux2;
	int reset, reset_complete;
	uint64_t llcmd;
	uint64_t context;
	uint8_t ack = PSLSE_DETACH;

	job = psl->job;
	if (job == NULL)
		return 0;

	// See if AFU is driving AUX2 signal changes
	dbg_aux2 = reset = reset_complete = *error = 0;
	if (psl_get_aux2_change(job->afu_event, &job_running, &job_done,
				&job_cack_llcmd, &job_error, &job_yield,
				&tb_request, &par_enable, &read_latency) == PSL_SUCCESS) {
		// Handle job_done
		if (job_done) {
			debug_msg("%s:_handle_aux2: JOB done", job->afu_name);
			dbg_aux2 |= DBG_AUX2_DONE;
			*error = job_error;
		        //debug_msg("%s,%d:_handle_aux2, jerror is %x ", 
			//	  job->afu_name, job->dbg_id, job_error );
			if (job->job != NULL) {
				event = job->job;
				// Is job_done for reset or start?
				if (event->code == PSL_JOB_RESET)
					reset_complete = 1;
				else
					reset = 1;
				job->job = event->_next;
				free(event);
				if (job->job != NULL)
					assert(job->job->_next != job->job);
			}
			if (*(job->psl_state) == PSLSE_RESET) {
				*(job->psl_state) = PSLSE_IDLE;
			}
		}
		// Handle job_running
		if (job_running) {
			debug_msg("%s:_handle_aux2: JOB running", job->afu_name);
			*(job->psl_state) = PSLSE_RUNNING;
			dbg_aux2 |= DBG_AUX2_RUNNING;
		}
		// Handle job cack llcmd
		if (job_cack_llcmd) {
		        // remove the current pending pe from the list
		        // loop through the pe's for the current pending one;
		        // copy its _next to _prev's _next
		        // remove the current pe
		        debug_msg("%s,%d:_handle_aux2, jcack, complete llcmd and remove pe", 
				  job->afu_name, job->dbg_id );
			cacked_pe = NULL;
			if (job->pe != NULL) {		  
			  if (job->pe->state == PSLSE_PENDING) {
			    // remove the first entry in the list
			    debug_msg("%s,%d:_handle_aux2, jcack, first pe is pending, job=0x%016"PRIx64", pe=0x%016"PRIx64, 
				      job->afu_name, job->dbg_id, job, job->pe );
			    cacked_pe = job->pe;
			    job->pe = job->pe->_next;
			  } else {
			    _prev = job->pe;
			    while (_prev->_next != NULL) {
			      debug_msg("%s,%d:_handle_aux2, jcack, looking for pending pe, _prev=0x%016"PRIx64", _next=0x%016"PRIx64, 
					job->afu_name, job->dbg_id, _prev, _prev->_next );
			      if (_prev->_next->state == PSLSE_PENDING) {
				// remove this entry in the list
				debug_msg("%s,%d:_handle_aux2, jcack, found pending pe, _next=0x%016"PRIx64, 
					job->afu_name, job->dbg_id, _prev->_next );
				cacked_pe = _prev->_next;
				_prev->_next = _prev->_next->_next;
			      } else {
				_prev = _prev->_next;
			      }
			    }
			  }
			}
			if (cacked_pe != NULL) {
			  // this is the pe that I want to "finish" processing
			  // get just the llcmd part of the addr
			  llcmd = cacked_pe->addr & PSL_LLCMD_MASK;
			  context = cacked_pe->addr & PSL_LLCMD_CONTEXT_MASK;
			  debug_msg("%s,%d:_handle_aux2: llcmd addr = 0x%016"PRIx64"; llcmd = 0x%016"PRIx64"; context = 0x%016"PRIx64, 
				    job->afu_name, job->dbg_id, cacked_pe->addr, llcmd, context);
			  switch ( llcmd ) {
			  case PSL_LLCMD_ADD:
			    // if it is a start, just keep going, print a message
			    debug_msg("%s,%d:_handle_aux2: LLCMD ADD acked", job->afu_name, job->dbg_id );
			    break;
			  case PSL_LLCMD_TERMINATE:
			    // if it is a terminate, make sure the cmd list is empty, warn if not empty
			    debug_msg("%s,%d:_handle_aux2: LLCMD TERMINATE acked", job->afu_name, job->dbg_id );
			    if ( _is_cmd_pending(psl, context) ) {
			      warn_msg( "%s,%d:AFU command for context %d still pending when LLCMD TERMINATE acked", 
					job->afu_name, job->dbg_id, context);
			    }
			    break;
			  case PSL_LLCMD_REMOVE:
			    // if it is a remove, send the detach response to the client and close up the client
			    debug_msg("%s,%d:_handle_aux2: LLCMD REMOVE acked", job->afu_name, job->dbg_id );
			    debug_msg("%s,%d:_handle_aux2: detach response sent to host on socket %d", 
				      job->afu_name, job->dbg_id, psl->client[context]->fd);
			    put_bytes(psl->client[context]->fd, 1, &ack,
			    	      psl->dbg_fp, psl->dbg_id,
			    	      psl->client[context]->context);
			    _free( psl, psl->client[context] );
			    psl->client[context] = NULL;  // I don't like this part...
			    break;
			  default:
			    debug_msg("%s,%d:_handle_aux2: acked llcmd %d did not match an LLCMD pe", 
				      job->afu_name, job->dbg_id, llcmd );
			    break;
			  }
			  debug_msg("%s,%d:_handle_aux2, jcack, free pe, addr=0x%016"PRIx64, 
				      job->afu_name, job->dbg_id, cacked_pe );
			  free( cacked_pe );
			} else {
			  debug_msg("%s,%d:_handle_aux2, jcack, no pe's to remove - why???", 
				    job->afu_name, job->dbg_id );	  
			}
			dbg_aux2 |= DBG_AUX2_LLCACK;
		}
		if (tb_request) {
			dbg_aux2 |= DBG_AUX2_TBREQ;
		}
		if (par_enable) {
			dbg_aux2 |= DBG_AUX2_PAREN;
		}
		dbg_aux2 |= read_latency & DBG_AUX2_LAT_MASK;
		if (job_done && job_running)
			error_msg("_handle_aux2: ah_jdone & ah_jrunning asserted together");
#if defined PSL9lite || defined PSL9
		if ((read_latency != 0) && (read_latency != 1) && (read_latency != 2))
			warn_msg("_handle_aux2: ah_brlat must be either 0, 1 or 2");
#else
		if ((read_latency != 1) && (read_latency != 3))
			warn_msg("_handle_aux2: ah_brlat must be either 1 or 3");
#endif 
		*parity = par_enable;
		*latency = read_latency;

		// DEBUG
		debug_job_aux2(job->dbg_fp, job->dbg_id, dbg_aux2);
	}

	if (reset)
		add_job(job, PSL_JOB_RESET, 0L);

	return reset_complete;
}