// 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; }
// 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; }