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;
}
Beispiel #2
0
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;
}