1 /*! 2 * \file trc_pkt_decode_etmv3.cpp 3 * \brief OpenCSD : ETMv3 trace packet decode. 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 8 /* 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the copyright holder nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "opencsd/etmv3/trc_pkt_decode_etmv3.h" 36 37 #define DCD_NAME "DCD_ETMV3" 38 39 TrcPktDecodeEtmV3::TrcPktDecodeEtmV3() : 40 TrcPktDecodeBase(DCD_NAME) 41 { 42 initDecoder(); 43 } 44 45 TrcPktDecodeEtmV3::TrcPktDecodeEtmV3(int instIDNum) : 46 TrcPktDecodeBase(DCD_NAME, instIDNum) 47 { 48 initDecoder(); 49 } 50 51 TrcPktDecodeEtmV3::~TrcPktDecodeEtmV3() 52 { 53 } 54 55 56 /* implementation packet decoding interface */ 57 ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPacket() 58 { 59 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 60 bool bPktDone = false; 61 62 if(!m_config) 63 return OCSD_RESP_FATAL_NOT_INIT; 64 65 // iterate round the state machine, waiting for sync, then decoding packets. 66 while(!bPktDone) 67 { 68 switch(m_curr_state) 69 { 70 case NO_SYNC: 71 // output the initial not synced packet to the sink 72 resp = sendUnsyncPacket(); 73 m_curr_state = WAIT_ASYNC; // immediate wait for ASync and actually check out the packet 74 break; 75 76 case WAIT_ASYNC: 77 // if async, wait for ISync, but this packet done. 78 if(m_curr_packet_in->getType() == ETM3_PKT_A_SYNC) 79 m_curr_state = WAIT_ISYNC; 80 bPktDone = true; 81 break; 82 83 case WAIT_ISYNC: 84 m_bWaitISync = true; // we are waiting for ISync 85 if((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC) || 86 (m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE)) 87 { 88 // process the ISync immediately as the first ISync seen. 89 resp = processISync((m_curr_packet_in->getType() == ETM3_PKT_I_SYNC_CYCLE),true); 90 m_curr_state = SEND_PKTS; 91 m_bWaitISync = false; 92 } 93 // something like TS, CC, PHDR+CC, which after ASYNC may be valid prior to ISync 94 else if(preISyncValid(m_curr_packet_in->getType())) 95 { 96 // decode anything that might be valid - send will be set automatically 97 resp = decodePacket(bPktDone); 98 } 99 else 100 bPktDone = true; 101 break; 102 103 case DECODE_PKTS: 104 resp = decodePacket(bPktDone); 105 break; 106 107 case SEND_PKTS: 108 resp = m_outputElemList.sendElements(); 109 if(OCSD_DATA_RESP_IS_CONT(resp)) 110 m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS; 111 bPktDone = true; 112 break; 113 114 default: 115 bPktDone = true; 116 LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,"Unknown Decoder State")); 117 resetDecoder(); // mark decoder as unsynced - dump any current state. 118 resp = OCSD_RESP_FATAL_SYS_ERR; 119 break; 120 } 121 } 122 123 return resp; 124 } 125 126 ocsd_datapath_resp_t TrcPktDecodeEtmV3::onEOT() 127 { 128 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 129 OcsdTraceElement *pElem = 0; 130 try { 131 pElem = GetNextOpElem(resp); 132 pElem->setType(OCSD_GEN_TRC_ELEM_EO_TRACE); 133 m_outputElemList.commitAllPendElem(); 134 m_curr_state = SEND_PKTS; 135 resp = m_outputElemList.sendElements(); 136 if(OCSD_DATA_RESP_IS_CONT(resp)) 137 m_curr_state = DECODE_PKTS; 138 } 139 catch(ocsdError &err) 140 { 141 LogError(err); 142 resetDecoder(); // mark decoder as unsynced - dump any current state. 143 } 144 return resp; 145 } 146 147 ocsd_datapath_resp_t TrcPktDecodeEtmV3::onReset() 148 { 149 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 150 resetDecoder(); 151 return resp; 152 } 153 154 ocsd_datapath_resp_t TrcPktDecodeEtmV3::onFlush() 155 { 156 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 157 if(m_curr_state == SEND_PKTS) 158 { 159 resp = m_outputElemList.sendElements(); 160 if(OCSD_DATA_RESP_IS_CONT(resp)) 161 m_curr_state = m_bWaitISync ? WAIT_ISYNC : DECODE_PKTS; 162 } 163 return resp; 164 } 165 166 ocsd_err_t TrcPktDecodeEtmV3::onProtocolConfig() 167 { 168 ocsd_err_t err = OCSD_OK; 169 if(m_config) 170 { 171 // set some static config elements 172 m_CSID = m_config->getTraceID(); 173 174 // check config compatible with current decoder support level. 175 // at present no data trace; 176 if(m_config->GetTraceMode() != EtmV3Config::TM_INSTR_ONLY) 177 { 178 err = OCSD_ERR_HW_CFG_UNSUPP; 179 LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_HW_CFG_UNSUPP,"ETMv3 trace decoder : data trace decode not yet supported")); 180 } 181 182 // need to set up core profile info in follower 183 ocsd_arch_profile_t arch_profile; 184 arch_profile.arch = m_config->getArchVersion(); 185 arch_profile.profile = m_config->getCoreProfile(); 186 m_code_follower.setArchProfile(arch_profile); 187 m_code_follower.setMemSpaceCSID(m_CSID); 188 m_outputElemList.initCSID(m_CSID); 189 } 190 else 191 err = OCSD_ERR_NOT_INIT; 192 return err; 193 } 194 195 /* local decode methods */ 196 197 // initialise on creation 198 void TrcPktDecodeEtmV3::initDecoder() 199 { 200 m_CSID = 0; 201 resetDecoder(); 202 m_code_follower.initInterfaces(getMemoryAccessAttachPt(),getInstrDecodeAttachPt()); 203 m_outputElemList.initSendIf(getTraceElemOutAttachPt()); 204 } 205 206 // reset for first use / re-use. 207 void TrcPktDecodeEtmV3::resetDecoder() 208 { 209 m_curr_state = NO_SYNC; // mark as not synced 210 m_bNeedAddr = true; 211 m_bSentUnknown = false; 212 m_bWaitISync = false; 213 m_outputElemList.reset(); 214 } 215 216 OcsdTraceElement *TrcPktDecodeEtmV3::GetNextOpElem(ocsd_datapath_resp_t &resp) 217 { 218 OcsdTraceElement *pElem = m_outputElemList.getNextElem(m_index_curr_pkt); 219 if(pElem == 0) 220 { 221 resp = OCSD_RESP_FATAL_NOT_INIT; 222 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_MEM,m_index_curr_pkt,m_CSID,"Memory Allocation Error - fatal"); 223 } 224 return pElem; 225 } 226 227 bool TrcPktDecodeEtmV3::preISyncValid(ocsd_etmv3_pkt_type pkt_type) 228 { 229 bool bValid = false; 230 // its a timestamp 231 if((pkt_type == ETM3_PKT_TIMESTAMP) || 232 // or we are cycleacc and its a packet that can have CC in it 233 (m_config->isCycleAcc() && ((pkt_type == ETM3_PKT_CYCLE_COUNT) || (pkt_type == ETM3_PKT_P_HDR))) 234 ) 235 bValid = true; 236 return bValid; 237 } 238 239 // simple packet transforms handled here, more complex processing passed on to specific routines. 240 ocsd_datapath_resp_t TrcPktDecodeEtmV3::decodePacket(bool &pktDone) 241 { 242 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 243 bool bISyncHasCC = false; 244 OcsdTraceElement *pElem = 0; 245 pktDone = false; 246 247 // there may be pended packets that can now be committed. 248 // only the branch address with exception and cancel element can cancel 249 // if not one of those, commit immediately, otherwise defer to branch address handler. 250 if(m_curr_packet_in->getType() != ETM3_PKT_BRANCH_ADDRESS) 251 m_outputElemList.commitAllPendElem(); 252 253 try { 254 255 switch(m_curr_packet_in->getType()) 256 { 257 258 case ETM3_PKT_NOTSYNC: 259 // mark as not synced - must have lost sync in the packet processor somehow 260 throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Trace Packet Synchronisation Lost"); 261 break; 262 263 // no action for these packets - ignore and continue 264 case ETM3_PKT_INCOMPLETE_EOT: 265 case ETM3_PKT_A_SYNC: 266 case ETM3_PKT_IGNORE: 267 break; 268 269 // markers for valid packets 270 case ETM3_PKT_CYCLE_COUNT: 271 pElem = GetNextOpElem(resp); 272 pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT); 273 pElem->setCycleCount(m_curr_packet_in->getCycleCount()); 274 break; 275 276 case ETM3_PKT_TRIGGER: 277 pElem = GetNextOpElem(resp); 278 pElem->setType(OCSD_GEN_TRC_ELEM_EVENT); 279 pElem->setEvent(EVENT_TRIGGER,0); 280 break; 281 282 case ETM3_PKT_BRANCH_ADDRESS: 283 resp = processBranchAddr(); 284 break; 285 286 case ETM3_PKT_I_SYNC_CYCLE: 287 bISyncHasCC = true; 288 case ETM3_PKT_I_SYNC: 289 resp = processISync(bISyncHasCC); 290 break; 291 292 case ETM3_PKT_P_HDR: 293 resp = processPHdr(); 294 break; 295 296 case ETM3_PKT_CONTEXT_ID: 297 pElem = GetNextOpElem(resp); 298 pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT); 299 m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID()); 300 pElem->setContext(m_PeContext); 301 break; 302 303 case ETM3_PKT_VMID: 304 pElem = GetNextOpElem(resp); 305 pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT); 306 m_PeContext.setVMID(m_curr_packet_in->getVMID()); 307 pElem->setContext(m_PeContext); 308 break; 309 310 case ETM3_PKT_EXCEPTION_ENTRY: 311 pElem = GetNextOpElem(resp); 312 pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION); 313 pElem->setExcepMarker(); // exception entries are always v7M data markers in ETMv3 trace. 314 break; 315 316 case ETM3_PKT_EXCEPTION_EXIT: 317 pElem = GetNextOpElem(resp); 318 pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION_RET); 319 pendExceptionReturn(); 320 break; 321 322 case ETM3_PKT_TIMESTAMP: 323 pElem = GetNextOpElem(resp); 324 pElem->setType(OCSD_GEN_TRC_ELEM_TIMESTAMP); 325 pElem->setTS(m_curr_packet_in->getTS()); 326 break; 327 328 // data packets - data trace not supported at present 329 case ETM3_PKT_STORE_FAIL: 330 case ETM3_PKT_OOO_DATA: 331 case ETM3_PKT_OOO_ADDR_PLC: 332 case ETM3_PKT_NORM_DATA: 333 case ETM3_PKT_DATA_SUPPRESSED: 334 case ETM3_PKT_VAL_NOT_TRACED: 335 case ETM3_PKT_BAD_TRACEMODE: 336 resp = OCSD_RESP_FATAL_INVALID_DATA; 337 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."); 338 break; 339 340 // packet errors 341 case ETM3_PKT_BAD_SEQUENCE: 342 resp = OCSD_RESP_FATAL_INVALID_DATA; 343 throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Bad Packet sequence."); 344 break; 345 346 default: 347 case ETM3_PKT_RESERVED: 348 resp = OCSD_RESP_FATAL_INVALID_DATA; 349 throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_BAD_PACKET_SEQ,m_index_curr_pkt,m_CSID,"Reserved or unknown packet ID."); 350 break; 351 } 352 m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS; 353 pktDone = !m_outputElemList.elemToSend(); 354 } 355 catch(ocsdError &err) 356 { 357 LogError(err); 358 resetDecoder(); // mark decoder as unsynced - dump any current state. 359 pktDone = true; 360 } 361 catch(...) 362 { 363 LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_index_curr_pkt,m_CSID,"Bad Packet sequence.")); 364 resp = OCSD_RESP_FATAL_SYS_ERR; 365 resetDecoder(); // mark decoder as unsynced - dump any current state. 366 pktDone = true; 367 } 368 return resp; 369 } 370 371 ocsd_datapath_resp_t TrcPktDecodeEtmV3::sendUnsyncPacket() 372 { 373 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 374 OcsdTraceElement *pElem = 0; 375 try { 376 pElem = GetNextOpElem(resp); 377 pElem->setType(OCSD_GEN_TRC_ELEM_NO_SYNC); 378 resp = m_outputElemList.sendElements(); 379 } 380 catch(ocsdError &err) 381 { 382 LogError(err); 383 resetDecoder(); // mark decoder as unsynced - dump any current state. 384 } 385 return resp; 386 } 387 388 void TrcPktDecodeEtmV3::setNeedAddr(bool bNeedAddr) 389 { 390 m_bNeedAddr = bNeedAddr; 391 m_bSentUnknown = false; 392 } 393 394 ocsd_datapath_resp_t TrcPktDecodeEtmV3::processISync(const bool withCC, const bool firstSync /* = false */) 395 { 396 // map ISync reason to generic reason codes. 397 static trace_on_reason_t on_map[] = { TRACE_ON_NORMAL, TRACE_ON_NORMAL, 398 TRACE_ON_OVERFLOW, TRACE_ON_EX_DEBUG }; 399 400 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 401 bool ctxtUpdate = m_curr_packet_in->isCtxtUpdated(); 402 OcsdTraceElement *pElem = 0; 403 404 try { 405 406 pElem = GetNextOpElem(resp); 407 408 if(firstSync || (m_curr_packet_in->getISyncReason() != iSync_Periodic)) 409 { 410 pElem->setType(OCSD_GEN_TRC_ELEM_TRACE_ON); 411 pElem->setTraceOnReason(on_map[(int)m_curr_packet_in->getISyncReason()]); 412 pElem = GetNextOpElem(resp); 413 } 414 415 // look for context changes.... 416 if(ctxtUpdate || firstSync) 417 { 418 // if not first time out, read existing context in output element, 419 // otherwise we are setting it new. 420 if(firstSync) 421 m_PeContext.resetCtxt(); 422 423 if(m_curr_packet_in->isCtxtIDUpdated()) 424 m_PeContext.setCtxtID(m_curr_packet_in->getCtxtID()); 425 if(m_curr_packet_in->isVMIDUpdated()) 426 m_PeContext.setVMID(m_curr_packet_in->getVMID()); 427 if(m_curr_packet_in->isCtxtFlagsUpdated()) 428 { 429 m_PeContext.setEL(m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown); 430 m_PeContext.setSecLevel(m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure); 431 } 432 433 // prepare the context packet 434 pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT); 435 pElem->setContext(m_PeContext); 436 pElem->setISA(m_curr_packet_in->ISA()); 437 438 // with cycle count... 439 if(m_curr_packet_in->getISyncHasCC()) 440 pElem->setCycleCount(m_curr_packet_in->getCycleCount()); 441 442 } 443 444 // set ISync address - if it is a valid I address 445 if(!m_curr_packet_in->getISyncNoAddr()) 446 { 447 if(m_curr_packet_in->getISyncIsLSiPAddr()) 448 { 449 // TBD: handle extra data processing instruction for data trace 450 // need to output E atom relating to the data instruction 451 // rare - on start-up case. 452 453 // main instruction address saved in data address for this packet type. 454 m_IAddr = m_curr_packet_in->getDataAddr(); 455 } 456 else 457 { 458 m_IAddr = m_curr_packet_in->getAddr(); 459 } 460 setNeedAddr(false); // ready to process atoms. 461 } 462 m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS; 463 } 464 catch(ocsdError &err) 465 { 466 LogError(err); 467 resetDecoder(); // mark decoder as unsynced - dump any current state. 468 } 469 return resp; 470 } 471 472 ocsd_datapath_resp_t TrcPktDecodeEtmV3::processBranchAddr() 473 { 474 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 475 OcsdTraceElement *pElem = 0; 476 bool bUpdatePEContext = false; 477 478 // might need to cancel something ... if the last output was an instruction range or excep return 479 if(m_curr_packet_in->isExcepCancel()) 480 m_outputElemList.cancelPendElem(); 481 else 482 m_outputElemList.commitAllPendElem(); // otherwise commit any pending elements. 483 484 // record the address 485 m_IAddr = m_curr_packet_in->getAddr(); 486 setNeedAddr(false); // no longer need an address. 487 488 // exception packet - may need additional output 489 if(m_curr_packet_in->isExcepPkt()) 490 { 491 // exeception packet may have exception, context change, or both. 492 // check for context change 493 if(m_curr_packet_in->isCtxtUpdated()) 494 { 495 496 ocsd_sec_level sec = m_curr_packet_in->isNS() ? ocsd_sec_nonsecure : ocsd_sec_secure; 497 if(sec != m_PeContext.getSecLevel()) 498 { 499 m_PeContext.setSecLevel(sec); 500 bUpdatePEContext = true; 501 } 502 ocsd_ex_level pkt_el = m_curr_packet_in->isHyp() ? ocsd_EL2 : ocsd_EL_unknown; 503 if(pkt_el != m_PeContext.getEL()) 504 { 505 m_PeContext.setEL(pkt_el); 506 bUpdatePEContext = true; 507 } 508 } 509 510 // now decide if we need to send any packets out. 511 try { 512 513 if(bUpdatePEContext) 514 { 515 pElem = GetNextOpElem(resp); 516 pElem->setType(OCSD_GEN_TRC_ELEM_PE_CONTEXT); 517 pElem->setContext(m_PeContext); 518 } 519 520 // check for exception 521 if(m_curr_packet_in->excepNum() != 0) 522 { 523 pElem = GetNextOpElem(resp); 524 pElem->setType(OCSD_GEN_TRC_ELEM_EXCEPTION); 525 pElem->setExceptionNum(m_curr_packet_in->excepNum()); 526 } 527 528 // finally - do we have anything to send yet? 529 m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS; 530 } 531 catch(ocsdError &err) 532 { 533 LogError(err); 534 resetDecoder(); // mark decoder as unsynced - dump any current state. 535 } 536 } 537 return resp; 538 } 539 540 541 ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr() 542 { 543 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 544 OcsdTraceElement *pElem = 0; 545 ocsd_isa isa; 546 Etmv3Atoms atoms(m_config->isCycleAcc()); 547 548 atoms.initAtomPkt(m_curr_packet_in,m_index_curr_pkt); 549 isa = m_curr_packet_in->ISA(); 550 m_code_follower.setMemSpaceAccess((m_PeContext.getSecLevel() == ocsd_sec_secure) ? OCSD_MEM_SPACE_S : OCSD_MEM_SPACE_N); 551 552 try 553 { 554 do 555 { 556 // if we do not have a valid address then send any cycle count elements 557 // and stop processing 558 if(m_bNeedAddr) 559 { 560 // output unknown address packet or a cycle count packet 561 if(!m_bSentUnknown || m_config->isCycleAcc()) 562 { 563 pElem = GetNextOpElem(resp); 564 if(m_bSentUnknown || !atoms.numAtoms()) 565 pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT); 566 else 567 pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN); 568 if(m_config->isCycleAcc()) 569 pElem->setCycleCount(atoms.getRemainCC()); 570 m_bSentUnknown = true; 571 } 572 atoms.clearAll(); // skip remaining atoms 573 } 574 else // have an address, can process atoms 575 { 576 pElem = GetNextOpElem(resp); 577 pElem->setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); 578 579 // cycle accurate may have a cycle count to use 580 if(m_config->isCycleAcc()) 581 { 582 // note: it is possible to have a CC only atom packet. 583 if(!atoms.numAtoms()) // override type if CC only 584 pElem->setType(OCSD_GEN_TRC_ELEM_CYCLE_COUNT); 585 // set cycle count 586 pElem->setCycleCount(atoms.getAtomCC()); 587 } 588 589 // now process the atom 590 if(atoms.numAtoms()) 591 { 592 m_code_follower.setISA(isa); 593 m_code_follower.followSingleAtom(m_IAddr,atoms.getCurrAtomVal()); 594 595 // valid code range 596 if(m_code_follower.hasRange()) 597 { 598 pElem->setAddrRange(m_IAddr,m_code_follower.getRangeEn()); 599 pElem->setLastInstrInfo(atoms.getCurrAtomVal() == ATOM_E, 600 m_code_follower.getInstrType(), 601 m_code_follower.getInstrSubType()); 602 pElem->setISA(isa); 603 if(m_code_follower.hasNextAddr()) 604 m_IAddr = m_code_follower.getNextAddr(); 605 else 606 setNeedAddr(true); 607 } 608 609 // next address has new ISA? 610 if(m_code_follower.ISAChanged()) 611 isa = m_code_follower.nextISA(); 612 613 // there is a nacc 614 if(m_code_follower.isNacc()) 615 { 616 if(m_code_follower.hasRange()) 617 { 618 pElem = GetNextOpElem(resp); 619 pElem->setType(OCSD_GEN_TRC_ELEM_ADDR_NACC); 620 } 621 else 622 pElem->updateType(OCSD_GEN_TRC_ELEM_ADDR_NACC); 623 pElem->setAddrStart(m_code_follower.getNaccAddr()); 624 setNeedAddr(true); 625 m_code_follower.clearNacc(); // we have generated some code for the nacc. 626 } 627 } 628 629 atoms.clearAtom(); // next atom 630 } 631 } 632 while(atoms.numAtoms()); 633 634 // is tha last element an atom? 635 int numElem = m_outputElemList.getNumElem(); 636 if(numElem >= 1) 637 { 638 // if the last thing is an instruction range, pend it - could be cancelled later. 639 if(m_outputElemList.getElemType(numElem-1) == OCSD_GEN_TRC_ELEM_INSTR_RANGE) 640 m_outputElemList.pendLastNElem(1); 641 } 642 643 // finally - do we have anything to send yet? 644 m_curr_state = m_outputElemList.elemToSend() ? SEND_PKTS : DECODE_PKTS; 645 } 646 catch(ocsdError &err) 647 { 648 LogError(err); 649 resetDecoder(); // mark decoder as unsynced - dump any current state. 650 } 651 return resp; 652 } 653 654 // if v7M -> pend only ERET, if V7A/R pend ERET and prev instr. 655 void TrcPktDecodeEtmV3::pendExceptionReturn() 656 { 657 int pendElem = 1; 658 if(m_config->getCoreProfile() != profile_CortexM) 659 { 660 int nElem = m_outputElemList.getNumElem(); 661 if(nElem > 1) 662 { 663 if(m_outputElemList.getElemType(nElem - 2) == OCSD_GEN_TRC_ELEM_INSTR_RANGE) 664 pendElem = 2; // need to pend instr+eret for A/R 665 } 666 } 667 m_outputElemList.pendLastNElem(pendElem); 668 } 669 670 /* End of File trc_pkt_decode_etmv3.cpp */ 671