aboutsummaryrefslogtreecommitdiff
path: root/contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp')
-rw-r--r--contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp671
1 files changed, 0 insertions, 671 deletions
diff --git a/contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp b/contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp
deleted file mode 100644
index 0a15a33c42fb..000000000000
--- a/contrib/opencsd/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp
+++ /dev/null
@@ -1,671 +0,0 @@
-/*!
- * \file trc_pkt_decode_etmv3.cpp
- * \brief OpenCSD : ETMv3 trace packet decode.
- *
- * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the copyright holder nor the names of its contributors
- * may be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opencsd/etmv3/trc_pkt_decode_etmv3.h"
-
-#define DCD_NAME "DCD_ETMV3"
-
-TrcPktDecodeEtmV3::TrcPktDecodeEtmV3() :
- TrcPktDecodeBase(DCD_NAME)
-{
- initDecoder();
-}
-
-TrcPktDecodeEtmV3::TrcPktDecodeEtmV3(int instIDNum) :
- TrcPktDecodeBase(DCD_NAME, instIDNum)
-{
- initDecoder();
-}
-
-TrcPktDecodeEtmV3::~TrcPktDecodeEtmV3()
-{
-}
-
-
-/* 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;
-}
-
-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;
-}
-
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset()
-{
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- resetDecoder();
- return resp;
-}
-
-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;
-}
-
-ocsd_err_t TrcPktDecodeEtmV3::onProtocolConfig()
-{
- ocsd_err_t err = OCSD_OK;
- if(m_config)
- {
- // set some static config elements
- m_CSID = m_config->getTraceID();
-
- // check config compatible with current decoder support level.
- // at present no data trace;
- if(m_config->GetTraceMode() != EtmV3Config::TM_INSTR_ONLY)
- {
- err = OCSD_ERR_HW_CFG_UNSUPP;
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,"ETMv3 trace decoder : data trace decode not yet supported"));
- }
-
- // need to set up core profile info in follower
- ocsd_arch_profile_t arch_profile;
- arch_profile.arch = m_config->getArchVersion();
- arch_profile.profile = m_config->getCoreProfile();
- m_code_follower.setArchProfile(arch_profile);
- m_code_follower.setMemSpaceCSID(m_CSID);
- m_outputElemList.initCSID(m_CSID);
- }
- else
- err = OCSD_ERR_NOT_INIT;
- return err;
-}
-
-/* local decode methods */
-
-// initialise on creation
-void TrcPktDecodeEtmV3::initDecoder()
-{
- m_CSID = 0;
- resetDecoder();
- m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt());
- m_outputElemList.initSendIf(getTraceElemOutAttachPt());
-}
-
-// reset for first use / re-use.
-void TrcPktDecodeEtmV3::resetDecoder()
-{
- m_curr_state = NO_SYNC; // mark as not synced
- m_bNeedAddr = true;
- m_bSentUnknown = false;
- m_bWaitISync = false;
- m_outputElemList.reset();
-}
-
-OcsdTraceElement *TrcPktDecodeEtmV3::GetNextOpElem(ocsd_datapath_resp_t &resp)
-{
- OcsdTraceElement *pElem = m_outputElemList.getNextElem(m_index_curr_pkt);
- if(pElem == 0)
- {
- resp = OCSD_RESP_FATAL_NOT_INIT;
- throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_MEM,m_index_curr_pkt,m_CSID,"Memory Allocation Error - fatal");
- }
- return pElem;
-}
-
-bool TrcPktDecodeEtmV3::preISyncValid(ocsd_etmv3_pkt_type pkt_type)
-{
- bool bValid = false;
- // its a timestamp
- if((pkt_type == ETM3_PKT_TIMESTAMP) ||
- // or we are cycleacc and its a packet that can have CC in it
- (m_config->isCycleAcc() && ((pkt_type == ETM3_PKT_CYCLE_COUNT) || (pkt_type == ETM3_PKT_P_HDR)))
- )
- bValid = true;
- return bValid;
-}
-
-// simple packet transforms handled here, more complex processing passed on to specific routines.
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone)
-{
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- bool bISyncHasCC = false;
- OcsdTraceElement *pElem = 0;
- pktDone = false;
-
- // there may be pended packets that can now be committed.
- // only the branch address with exception and cancel element can cancel
- // if not one of those, commit immediately, otherwise defer to branch address handler.
- if(m_curr_packet_in->getType() != ETM3_PKT_BRANCH_ADDRESS)
- m_outputElemList.commitAllPendElem();
-
- try {
-
- switch(m_curr_packet_in->getType())
- {
-
- case ETM3_PKT_NOTSYNC:
- // mark as not synced - must have lost sync in the packet processor somehow
- throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Trace Packet Synchronisation Lost");
- break;
-
- // no action for these packets - ignore and continue
- case ETM3_PKT_INCOMPLETE_EOT:
- case ETM3_PKT_A_SYNC:
- case ETM3_PKT_IGNORE:
- break;
-
- // markers for valid packets
- case ETM3_PKT_CYCLE_COUNT:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
- pElem->setCycleCount(m_curr_packet_in->getCycleCount());
- break;
-
- case ETM3_PKT_TRIGGER:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_EVENT);
- pElem->setEvent(EVENT_TRIGGER,0);
- break;
-
- case ETM3_PKT_BRANCH_ADDRESS:
- resp = processBranchAddr();
- break;
-
- case ETM3_PKT_I_SYNC_CYCLE:
- bISyncHasCC = true;
- case ETM3_PKT_I_SYNC:
- resp = processISync(bISyncHasCC);
- break;
-
- case ETM3_PKT_P_HDR:
- resp = processPHdr();
- break;
-
- case ETM3_PKT_CONTEXT_ID:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
- m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID());
- pElem->setContext(m_PeContext);
- break;
-
- case ETM3_PKT_VMID:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
- m_PeContext.setVMID(m_curr_packet_in->getVMID());
- pElem->setContext(m_PeContext);
- break;
-
- case ETM3_PKT_EXCEPTION_ENTRY:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION);
- pElem->setExcepMarker(); // exception entries are always v7M data markers in ETMv3 trace.
- break;
-
- case ETM3_PKT_EXCEPTION_EXIT:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION_RET);
- pendExceptionReturn();
- break;
-
- case ETM3_PKT_TIMESTAMP:
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_TIMESTAMP);
- pElem->setTS(m_curr_packet_in->getTS());
- break;
-
- // data packets - data trace not supported at present
- case ETM3_PKT_STORE_FAIL:
- case ETM3_PKT_OOO_DATA:
- case ETM3_PKT_OOO_ADDR_PLC:
- case ETM3_PKT_NORM_DATA:
- case ETM3_PKT_DATA_SUPPRESSED:
- case ETM3_PKT_VAL_NOT_TRACED:
- case ETM3_PKT_BAD_TRACEMODE:
- resp = OCSD_RESP_FATAL_INVALID_DATA;
- throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,m_index_curr_pkt,m_CSID,"Invalid packet type : Data Tracing decode not supported.");
- break;
-
- // packet errors
- case ETM3_PKT_BAD_SEQUENCE:
- resp = OCSD_RESP_FATAL_INVALID_DATA;
- throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Bad Packet sequence.");
- break;
-
- default:
- case ETM3_PKT_RESERVED:
- resp = OCSD_RESP_FATAL_INVALID_DATA;
- throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Reserved or unknown packet ID.");
- break;
- }
- m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
- pktDone = !m_outputElemList.elemToSend();
- }
- catch(ocsdError &err)
- {
- LogError(err);
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- pktDone = true;
- }
- catch(...)
- {
- LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,m_CSID,"Bad Packet sequence."));
- resp = OCSD_RESP_FATAL_SYS_ERR;
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- pktDone = true;
- }
- return resp;
-}
-
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::sendUnsyncPacket()
-{
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- OcsdTraceElement *pElem = 0;
- try {
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
- resp = m_outputElemList.sendElements();
- }
- catch(ocsdError &err)
- {
- LogError(err);
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- }
- return resp;
-}
-
-void TrcPktDecodeEtmV3::setNeedAddr(bool bNeedAddr)
-{
- m_bNeedAddr = bNeedAddr;
- m_bSentUnknown = false;
-}
-
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::processISync(const bool withCC, const bool firstSync /* = false */)
-{
- // map ISync reason to generic reason codes.
- static trace_on_reason_t on_map[] = { TRACE_ON_NORMAL, TRACE_ON_NORMAL,
- TRACE_ON_OVERFLOW, TRACE_ON_EX_DEBUG };
-
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- bool ctxtUpdate = m_curr_packet_in->isCtxtUpdated();
- OcsdTraceElement *pElem = 0;
-
- try {
-
- pElem = GetNextOpElem(resp);
-
- if(firstSync || (m_curr_packet_in->getISyncReason() != iSync_Periodic))
- {
- pElem->setType(OCSD_GEN_TRC_ELEM_TRACE_ON);
- pElem->setTraceOnReason(on_map[(int)m_curr_packet_in->getISyncReason()]);
- pElem = GetNextOpElem(resp);
- }
-
- // look for context changes....
- if(ctxtUpdate || firstSync)
- {
- // if not first time out, read existing context in output element,
- // otherwise we are setting it new.
- if(firstSync)
- m_PeContext.resetCtxt();
-
- if(m_curr_packet_in->isCtxtIDUpdated())
- m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID());
- if(m_curr_packet_in->isVMIDUpdated())
- m_PeContext.setVMID(m_curr_packet_in->getVMID());
- if(m_curr_packet_in->isCtxtFlagsUpdated())
- {
- m_PeContext.setEL(m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown);
- m_PeContext.setSecLevel(m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure);
- }
-
- // prepare the context packet
- pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
- pElem->setContext(m_PeContext);
- pElem->setISA(m_curr_packet_in->ISA());
-
- // with cycle count...
- if(m_curr_packet_in->getISyncHasCC())
- pElem->setCycleCount(m_curr_packet_in->getCycleCount());
-
- }
-
- // set ISync address - if it is a valid I address
- if(!m_curr_packet_in->getISyncNoAddr())
- {
- if(m_curr_packet_in->getISyncIsLSiPAddr())
- {
- // TBD: handle extra data processing instruction for data trace
- // need to output E atom relating to the data instruction
- // rare - on start-up case.
-
- // main instruction address saved in data address for this packet type.
- m_IAddr = m_curr_packet_in->getDataAddr();
- }
- else
- {
- m_IAddr = m_curr_packet_in->getAddr();
- }
- setNeedAddr(false); // ready to process atoms.
- }
- m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
- }
- catch(ocsdError &err)
- {
- LogError(err);
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- }
- return resp;
-}
-
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::processBranchAddr()
-{
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- OcsdTraceElement *pElem = 0;
- bool bUpdatePEContext = false;
-
- // might need to cancel something ... if the last output was an instruction range or excep return
- if(m_curr_packet_in->isExcepCancel())
- m_outputElemList.cancelPendElem();
- else
- m_outputElemList.commitAllPendElem(); // otherwise commit any pending elements.
-
- // record the address
- m_IAddr = m_curr_packet_in->getAddr();
- setNeedAddr(false); // no longer need an address.
-
- // exception packet - may need additional output
- if(m_curr_packet_in->isExcepPkt())
- {
- // exeception packet may have exception, context change, or both.
- // check for context change
- if(m_curr_packet_in->isCtxtUpdated())
- {
-
- ocsd_sec_level sec = m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure;
- if(sec != m_PeContext.getSecLevel())
- {
- m_PeContext.setSecLevel(sec);
- bUpdatePEContext = true;
- }
- ocsd_ex_level pkt_el = m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown;
- if(pkt_el != m_PeContext.getEL())
- {
- m_PeContext.setEL(pkt_el);
- bUpdatePEContext = true;
- }
- }
-
- // now decide if we need to send any packets out.
- try {
-
- if(bUpdatePEContext)
- {
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT);
- pElem->setContext(m_PeContext);
- }
-
- // check for exception
- if(m_curr_packet_in->excepNum() != 0)
- {
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION);
- pElem->setExceptionNum(m_curr_packet_in->excepNum());
- }
-
- // finally - do we have anything to send yet?
- m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
- }
- catch(ocsdError &err)
- {
- LogError(err);
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- }
- }
- return resp;
-}
-
-
-ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr()
-{
- ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
- OcsdTraceElement *pElem = 0;
- ocsd_isa isa;
- Etmv3Atoms atoms(m_config->isCycleAcc());
-
- atoms.initAtomPkt(m_curr_packet_in,m_index_curr_pkt);
- isa = m_curr_packet_in->ISA();
- m_code_follower.setMemSpaceAccess((m_PeContext.getSecLevel() == ocsd_sec_secure) ? OCSD_MEM_SPACE_S : OCSD_MEM_SPACE_N);
-
- try
- {
- do
- {
- // if we do not have a valid address then send any cycle count elements
- // and stop processing
- if(m_bNeedAddr)
- {
- // output unknown address packet or a cycle count packet
- if(!m_bSentUnknown || m_config->isCycleAcc())
- {
- pElem = GetNextOpElem(resp);
- if(m_bSentUnknown || !atoms.numAtoms())
- pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
- else
- pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN);
- if(m_config->isCycleAcc())
- pElem->setCycleCount(atoms.getRemainCC());
- m_bSentUnknown = true;
- }
- atoms.clearAll(); // skip remaining atoms
- }
- else // have an address, can process atoms
- {
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE);
-
- // cycle accurate may have a cycle count to use
- if(m_config->isCycleAcc())
- {
- // note: it is possible to have a CC only atom packet.
- if(!atoms.numAtoms()) // override type if CC only
- pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT);
- // set cycle count
- pElem->setCycleCount(atoms.getAtomCC());
- }
-
- // now process the atom
- if(atoms.numAtoms())
- {
- m_code_follower.setISA(isa);
- m_code_follower.followSingleAtom(m_IAddr,atoms.getCurrAtomVal());
-
- // valid code range
- if(m_code_follower.hasRange())
- {
- pElem->setAddrRange(m_IAddr,m_code_follower.getRangeEn());
- pElem->setLastInstrInfo(atoms.getCurrAtomVal() == ATOM_E,
- m_code_follower.getInstrType(),
- m_code_follower.getInstrSubType(),m_code_follower.getInstrSize());
- pElem->setLastInstrCond(m_code_follower.isCondInstr());
- pElem->setISA(isa);
- if(m_code_follower.hasNextAddr())
- m_IAddr = m_code_follower.getNextAddr();
- else
- setNeedAddr(true);
- }
-
- // next address has new ISA?
- if(m_code_follower.ISAChanged())
- isa = m_code_follower.nextISA();
-
- // there is a nacc
- if(m_code_follower.isNacc())
- {
- if(m_code_follower.hasRange())
- {
- pElem = GetNextOpElem(resp);
- pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
- }
- else
- pElem->updateType(OCSD_GEN_TRC_ELEM_ADDR_NACC);
- pElem->setAddrStart(m_code_follower.getNaccAddr());
- setNeedAddr(true);
- m_code_follower.clearNacc(); // we have generated some code for the nacc.
- }
- }
-
- atoms.clearAtom(); // next atom
- }
- }
- while(atoms.numAtoms());
-
- // is tha last element an atom?
- int numElem = m_outputElemList.getNumElem();
- if(numElem >= 1)
- {
- // if the last thing is an instruction range, pend it - could be cancelled later.
- if(m_outputElemList.getElemType(numElem-1) == OCSD_GEN_TRC_ELEM_INSTR_RANGE)
- m_outputElemList.pendLastNElem(1);
- }
-
- // finally - do we have anything to send yet?
- m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS;
- }
- catch(ocsdError &err)
- {
- LogError(err);
- resetDecoder(); // mark decoder as unsynced - dump any current state.
- }
- return resp;
-}
-
-// if v7M -> pend only ERET, if V7A/R pend ERET and prev instr.
-void TrcPktDecodeEtmV3::pendExceptionReturn()
-{
- int pendElem = 1;
- if(m_config->getCoreProfile() != profile_CortexM)
- {
- int nElem = m_outputElemList.getNumElem();
- if(nElem > 1)
- {
- if(m_outputElemList.getElemType(nElem - 2) == OCSD_GEN_TRC_ELEM_INSTR_RANGE)
- pendElem = 2; // need to pend instr+eret for A/R
- }
- }
- m_outputElemList.pendLastNElem(pendElem);
-}
-
-/* End of File trc_pkt_decode_etmv3.cpp */