ocsd_datapath_resp_t TrcPktDecodeEtmV3::onFlush() { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; if(m_curr_state == SEND_PKTS) { resp = m_outputElemList.sendElements(); if(OCSD_DATA_RESP_IS_CONT(resp)) m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS; } return resp; }
int cs_etm_decoder__process_data_block(struct cs_etm_decoder *decoder, u64 indx, const u8 *buf, size_t len, size_t *consumed) { int ret = 0; ocsd_datapath_resp_t cur = OCSD_RESP_CONT; ocsd_datapath_resp_t prev_return = decoder->prev_return; size_t processed = 0; u32 count; while (processed < len) { if (OCSD_DATA_RESP_IS_WAIT(prev_return)) { cur = ocsd_dt_process_data(decoder->dcd_tree, OCSD_OP_FLUSH, 0, 0, NULL, NULL); } else if (OCSD_DATA_RESP_IS_CONT(prev_return)) { cur = ocsd_dt_process_data(decoder->dcd_tree, OCSD_OP_DATA, indx + processed, len - processed, &buf[processed], &count); processed += count; } else { ret = -EINVAL; break; } /* * Return to the input code if the packet buffer is full. * Flushing will get done once the packet buffer has been * processed. */ if (OCSD_DATA_RESP_IS_WAIT(cur)) break; prev_return = cur; } decoder->prev_return = cur; *consumed = processed; return ret; }
ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT() { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; OcsdTraceElement *pElem = 0; try { pElem = GetNextOpElem(resp); pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE); m_outputElemList.commitAllPendElem(); m_curr_state = SEND_PKTS; resp = m_outputElemList.sendElements(); if(OCSD_DATA_RESP_IS_CONT(resp)) m_curr_state = DECODE_PKTS; } catch(ocsdError &err) { LogError(err); resetDecoder(); // mark decoder as unsynced - dump any current state. } return resp; }
/* implementation packet decoding interface */ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPacket() { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; bool bPktDone = false; if(!m_config) return OCSD_RESP_FATAL_NOT_INIT; // iterate round the state machine, waiting for sync, then decoding packets. while(!bPktDone) { switch(m_curr_state) { case NO_SYNC: // output the initial not synced packet to the sink resp = sendUnsyncPacket(); m_curr_state = WAIT_ASYNC; // immediate wait for ASync and actually check out the packet break; case WAIT_ASYNC: // if async, wait for ISync, but this packet done. if(m_curr_packet_in->getType() == ETM3_PKT_A_SYNC) m_curr_state = WAIT_ISYNC; bPktDone = true; break; case WAIT_ISYNC: m_bWaitISync = true; // we are waiting for ISync if((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC) || (m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE)) { // process the ISync immediately as the first ISync seen. resp = processISync((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE),true); m_curr_state = SEND_PKTS; m_bWaitISync = false; } // something like TS, CC, PHDR+CC, which after ASYNC may be valid prior to ISync else if(preISyncValid(m_curr_packet_in->getType())) { // decode anything that might be valid - send will be set automatically resp = decodePacket(bPktDone); } else bPktDone = true; break; case DECODE_PKTS: resp = decodePacket(bPktDone); break; case SEND_PKTS: resp = m_outputElemList.sendElements(); if(OCSD_DATA_RESP_IS_CONT(resp)) m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS; bPktDone = true; break; default: bPktDone = true; LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,"Unknown Decoder State")); resetDecoder(); // mark decoder as unsynced - dump any current state. resp = OCSD_RESP_FATAL_SYS_ERR; break; } } return resp; }