1 /* 2 * \file trc_pkt_proc_etmv4i.cpp 3 * \brief OpenCSD : Packet processor for ETMv4 4 * 5 * \copyright Copyright (c) 2015, 2019, 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/etmv4/trc_pkt_proc_etmv4.h" 36 #include "common/ocsd_error.h" 37 38 #ifdef __GNUC__ 39 // G++ doesn't like the ## pasting 40 #define ETMV4I_PKTS_NAME "PKTP_ETMV4I" 41 #else 42 // VC++ is fine 43 #define ETMV4I_PKTS_NAME OCSD_CMPNAME_PREFIX_PKTPROC##"_ETMV4I" 44 #endif 45 46 static const uint32_t ETMV4_SUPPORTED_OP_FLAGS = OCSD_OPFLG_PKTPROC_COMMON; 47 48 /* trace etmv4 packet processing class */ 49 TrcPktProcEtmV4I::TrcPktProcEtmV4I() : TrcPktProcBase(ETMV4I_PKTS_NAME), 50 m_isInit(false), 51 m_first_trace_info(false) 52 { 53 m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS; 54 } 55 56 TrcPktProcEtmV4I::TrcPktProcEtmV4I(int instIDNum) : TrcPktProcBase(ETMV4I_PKTS_NAME, instIDNum), 57 m_isInit(false), 58 m_first_trace_info(false) 59 { 60 m_supported_op_flags = ETMV4_SUPPORTED_OP_FLAGS; 61 } 62 63 64 TrcPktProcEtmV4I::~TrcPktProcEtmV4I() 65 { 66 } 67 68 ocsd_err_t TrcPktProcEtmV4I::onProtocolConfig() 69 { 70 InitProcessorState(); 71 m_config = *TrcPktProcBase::getProtocolConfig(); 72 BuildIPacketTable(); // packet table based on config 73 m_isInit = true; 74 return OCSD_OK; 75 } 76 77 ocsd_datapath_resp_t TrcPktProcEtmV4I::processData( const ocsd_trc_index_t index, 78 const uint32_t dataBlockSize, 79 const uint8_t *pDataBlock, 80 uint32_t *numBytesProcessed) 81 { 82 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 83 84 if (!m_isInit) 85 return OCSD_RESP_FATAL_NOT_INIT; 86 87 m_trcIn.init(dataBlockSize, pDataBlock, &m_currPacketData); 88 m_blockIndex = index; 89 bool done = false; 90 uint8_t nextByte; 91 92 do 93 { 94 try 95 { 96 while ( (!m_trcIn.empty() || (m_process_state == SEND_PKT)) && 97 OCSD_DATA_RESP_IS_CONT(resp) 98 ) 99 { 100 switch (m_process_state) 101 { 102 case PROC_HDR: 103 m_packet_index = m_blockIndex + m_trcIn.processed(); 104 if (m_is_sync) 105 { 106 nextByte = m_trcIn.peekNextByte(); 107 m_pIPktFn = m_i_table[nextByte].pptkFn; 108 m_curr_packet.type = m_i_table[nextByte].pkt_type; 109 } 110 else 111 { 112 // unsynced - process data until we see a sync point 113 m_pIPktFn = &TrcPktProcEtmV4I::iNotSync; 114 m_curr_packet.type = ETM4_PKT_I_NOTSYNC; 115 } 116 m_process_state = PROC_DATA; 117 118 case PROC_DATA: 119 // loop till full packet or no more data... 120 while (!m_trcIn.empty() && (m_process_state == PROC_DATA)) 121 { 122 nextByte = m_trcIn.peekNextByte(); 123 m_trcIn.copyByteToPkt(); // move next byte into the packet 124 (this->*m_pIPktFn)(nextByte); 125 } 126 break; 127 128 case SEND_PKT: 129 resp = outputPacket(); 130 InitPacketState(); 131 m_process_state = PROC_HDR; 132 break; 133 134 case SEND_UNSYNCED: 135 resp = outputUnsyncedRawPacket(); 136 if (m_update_on_unsync_packet_index != 0) 137 { 138 m_packet_index = m_update_on_unsync_packet_index; 139 m_update_on_unsync_packet_index = 0; 140 } 141 m_process_state = PROC_DATA; // after dumping unsynced data, still in data mode. 142 break; 143 } 144 } 145 done = true; 146 } 147 catch(ocsdError &err) 148 { 149 done = true; 150 LogError(err); 151 if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) || 152 (err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR)) 153 { 154 // send invalid packets up the pipe to let the next stage decide what to do. 155 m_process_state = SEND_PKT; 156 done = false; 157 } 158 else 159 { 160 // bail out on any other error. 161 resp = OCSD_RESP_FATAL_INVALID_DATA; 162 } 163 } 164 catch(...) 165 { 166 done = true; 167 /// vv bad at this point. 168 resp = OCSD_RESP_FATAL_SYS_ERR; 169 const ocsdError &fatal = ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_packet_index,m_config.getTraceID(),"Unknown System Error decoding trace."); 170 LogError(fatal); 171 } 172 } while (!done); 173 174 *numBytesProcessed = m_trcIn.processed(); 175 return resp; 176 } 177 178 ocsd_datapath_resp_t TrcPktProcEtmV4I::onEOT() 179 { 180 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 181 if (!m_isInit) 182 return OCSD_RESP_FATAL_NOT_INIT; 183 184 // if we have a partial packet then send to attached sinks 185 if(m_currPacketData.size() != 0) 186 { 187 m_curr_packet.updateErrType(ETM4_PKT_I_INCOMPLETE_EOT); 188 resp = outputPacket(); 189 InitPacketState(); 190 } 191 return resp; 192 } 193 194 ocsd_datapath_resp_t TrcPktProcEtmV4I::onReset() 195 { 196 if (!m_isInit) 197 return OCSD_RESP_FATAL_NOT_INIT; 198 199 // prepare for new decoding session 200 InitProcessorState(); 201 return OCSD_RESP_CONT; 202 } 203 204 ocsd_datapath_resp_t TrcPktProcEtmV4I::onFlush() 205 { 206 if (!m_isInit) 207 return OCSD_RESP_FATAL_NOT_INIT; 208 209 // packet processor never holds on to flushable data (may have partial packet, 210 // but any full packets are immediately sent) 211 return OCSD_RESP_CONT; 212 } 213 214 void TrcPktProcEtmV4I::InitPacketState() 215 { 216 m_currPacketData.clear(); 217 m_curr_packet.initNextPacket(); // clear for next packet. 218 m_update_on_unsync_packet_index = 0; 219 } 220 221 void TrcPktProcEtmV4I::InitProcessorState() 222 { 223 InitPacketState(); 224 m_pIPktFn = &TrcPktProcEtmV4I::iNotSync; 225 m_packet_index = 0; 226 m_is_sync = false; 227 m_first_trace_info = false; 228 m_sent_notsync_packet = false; 229 m_process_state = PROC_HDR; 230 m_curr_packet.initStartState(); 231 } 232 233 ocsd_datapath_resp_t TrcPktProcEtmV4I::outputPacket() 234 { 235 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 236 resp = outputOnAllInterfaces(m_packet_index,&m_curr_packet,&m_curr_packet.type,m_currPacketData); 237 return resp; 238 } 239 240 ocsd_datapath_resp_t TrcPktProcEtmV4I::outputUnsyncedRawPacket() 241 { 242 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 243 244 245 outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]); 246 247 if(!m_sent_notsync_packet) 248 { 249 resp = outputDecodedPacket(m_packet_index,&m_curr_packet); 250 m_sent_notsync_packet = true; 251 } 252 253 if(m_currPacketData.size() <= m_dump_unsynced_bytes) 254 m_currPacketData.clear(); 255 else 256 m_currPacketData.erase(m_currPacketData.begin(),m_currPacketData.begin()+m_dump_unsynced_bytes); 257 258 return resp; 259 } 260 261 void TrcPktProcEtmV4I::iNotSync(const uint8_t lastByte) 262 { 263 // is it an extension byte? 264 if (lastByte == 0x00) // TBD : add check for forced sync in here? 265 { 266 if (m_currPacketData.size() > 1) 267 { 268 m_dump_unsynced_bytes = m_currPacketData.size() - 1; 269 m_process_state = SEND_UNSYNCED; 270 // outputting some data then update packet index after so output indexes accurate 271 m_update_on_unsync_packet_index = m_blockIndex + m_trcIn.processed() - 1; 272 } 273 else 274 m_packet_index = m_blockIndex + m_trcIn.processed() - 1; // set it up now otherwise. 275 276 m_pIPktFn = m_i_table[lastByte].pptkFn; 277 } 278 else if (m_currPacketData.size() >= 8) 279 { 280 m_dump_unsynced_bytes = m_currPacketData.size(); 281 m_process_state = SEND_UNSYNCED; 282 // outputting some data then update packet index after so output indexes accurate 283 m_update_on_unsync_packet_index = m_blockIndex + m_trcIn.processed(); 284 } 285 } 286 287 void TrcPktProcEtmV4I::iPktNoPayload(const uint8_t lastByte) 288 { 289 // some expansion may be required... 290 switch(m_curr_packet.type) 291 { 292 case ETM4_PKT_I_ADDR_MATCH: 293 m_curr_packet.setAddressExactMatch(lastByte & 0x3); 294 break; 295 296 case ETM4_PKT_I_EVENT: 297 m_curr_packet.setEvent(lastByte & 0xF); 298 break; 299 300 case ETM4_PKT_I_NUM_DS_MKR: 301 case ETM4_PKT_I_UNNUM_DS_MKR: 302 m_curr_packet.setDataSyncMarker(lastByte & 0x7); 303 break; 304 305 // these just need the packet type - no processing required. 306 case ETM4_PKT_I_COND_FLUSH: 307 case ETM4_PKT_I_EXCEPT_RTN: 308 case ETM4_PKT_I_TRACE_ON: 309 case ETM4_PKT_I_FUNC_RET: 310 case ETM4_PKT_I_IGNORE: 311 default: break; 312 } 313 m_process_state = SEND_PKT; // now just send it.... 314 } 315 316 void TrcPktProcEtmV4I::iPktReserved(const uint8_t lastByte) 317 { 318 m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED, lastByte); // swap type for err type 319 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR,m_packet_index,m_config.getTraceID()); 320 } 321 322 void TrcPktProcEtmV4I::iPktInvalidCfg(const uint8_t lastByte) 323 { 324 m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED_CFG, lastByte); // swap type for err type 325 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR, m_packet_index, m_config.getTraceID()); 326 } 327 328 void TrcPktProcEtmV4I::iPktExtension(const uint8_t lastByte) 329 { 330 if(m_currPacketData.size() == 2) 331 { 332 // not sync and not next by 0x00 - not sync sequence 333 if(!m_is_sync && (lastByte != 0x00)) 334 { 335 m_pIPktFn = &TrcPktProcEtmV4I::iNotSync; 336 m_curr_packet.type = ETM4_PKT_I_NOTSYNC; 337 return; 338 } 339 340 switch(lastByte) 341 { 342 case 0x03: // discard packet. 343 m_curr_packet.type = ETM4_PKT_I_DISCARD; 344 m_process_state = SEND_PKT; 345 break; 346 347 case 0x05: 348 m_curr_packet.type = ETM4_PKT_I_OVERFLOW; 349 m_process_state = SEND_PKT; 350 break; 351 352 case 0x00: 353 m_curr_packet.type = ETM4_PKT_I_ASYNC; 354 m_pIPktFn = &TrcPktProcEtmV4I::iPktASync; // handle subsequent bytes as async 355 break; 356 357 default: 358 m_curr_packet.err_type = m_curr_packet.type; 359 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE; 360 m_process_state = SEND_PKT; 361 break; 362 } 363 } 364 } 365 366 void TrcPktProcEtmV4I::iPktASync(const uint8_t lastByte) 367 { 368 if(lastByte != 0x00) 369 { 370 // not sync and not next by 0x00 - not sync sequence if < 12 371 if(!m_is_sync && m_currPacketData.size() != 12) 372 { 373 m_pIPktFn = &TrcPktProcEtmV4I::iNotSync; 374 m_curr_packet.type = ETM4_PKT_I_NOTSYNC; 375 return; 376 } 377 378 // 12 bytes and not valid sync sequence - not possible even if not synced 379 m_process_state = SEND_PKT; 380 if((m_currPacketData.size() != 12) || (lastByte != 0x80)) 381 { 382 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE; 383 m_curr_packet.err_type = ETM4_PKT_I_ASYNC; 384 } 385 else 386 m_is_sync = true; // found a sync packet, mark decoder as synchronised. 387 } 388 else if(m_currPacketData.size() == 12) 389 { 390 if(!m_is_sync) 391 { 392 // if we are not yet synced then ignore extra leading 0x00. 393 m_dump_unsynced_bytes = 1; 394 m_process_state = SEND_UNSYNCED; 395 } 396 else 397 { 398 // bad periodic ASYNC sequence. 399 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE; 400 m_curr_packet.err_type = ETM4_PKT_I_ASYNC; 401 m_process_state = SEND_PKT; 402 } 403 } 404 } 405 406 void TrcPktProcEtmV4I::iPktTraceInfo(const uint8_t lastByte) 407 { 408 if(m_currPacketData.size() == 1) // header 409 { 410 //clear flags 411 m_tinfo_sections.sectFlags = 0; // mark all sections as incomplete. 412 m_tinfo_sections.ctrlBytes = 1; // assume only a single control section byte for now 413 414 } 415 else if(m_currPacketData.size() == 2) // first payload control byte 416 { 417 // figure out which sections are absent and set to true - opposite of bitfeild in byte; 418 m_tinfo_sections.sectFlags = (~lastByte) & TINFO_ALL_SECT; 419 420 // see if there is an extended control section, otherwise this byte is it. 421 if((lastByte & 0x80) == 0x0) 422 m_tinfo_sections.sectFlags |= TINFO_CTRL; 423 424 } 425 else 426 { 427 if(!(m_tinfo_sections.sectFlags & TINFO_CTRL)) 428 { 429 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_CTRL; 430 m_tinfo_sections.ctrlBytes++; 431 } 432 else if(!(m_tinfo_sections.sectFlags & TINFO_INFO_SECT)) 433 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_INFO_SECT; 434 else if(!(m_tinfo_sections.sectFlags & TINFO_KEY_SECT)) 435 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_KEY_SECT; 436 else if(!(m_tinfo_sections.sectFlags & TINFO_SPEC_SECT)) 437 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_SPEC_SECT; 438 else if(!(m_tinfo_sections.sectFlags & TINFO_CYCT_SECT)) 439 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_CYCT_SECT; 440 } 441 442 // all sections accounted for? 443 if(m_tinfo_sections.sectFlags == TINFO_ALL) 444 { 445 // index of first section is number of payload control bytes + 1 for header byte 446 unsigned idx = m_tinfo_sections.ctrlBytes + 1; 447 uint32_t fieldVal = 0; 448 uint8_t presSect = m_currPacketData[1] & TINFO_ALL_SECT; // first payload control byte 449 450 m_curr_packet.clearTraceInfo(); 451 452 if((presSect & TINFO_INFO_SECT) && (idx < m_currPacketData.size())) 453 { 454 idx += extractContField(m_currPacketData,idx,fieldVal); 455 m_curr_packet.setTraceInfo(fieldVal); 456 } 457 if((presSect & TINFO_KEY_SECT) && (idx < m_currPacketData.size())) 458 { 459 idx += extractContField(m_currPacketData,idx,fieldVal); 460 m_curr_packet.setTraceInfoKey(fieldVal); 461 } 462 if((presSect & TINFO_SPEC_SECT) && (idx < m_currPacketData.size())) 463 { 464 idx += extractContField(m_currPacketData,idx,fieldVal); 465 m_curr_packet.setTraceInfoSpec(fieldVal); 466 } 467 if((presSect & TINFO_CYCT_SECT) && (idx < m_currPacketData.size())) 468 { 469 idx += extractContField(m_currPacketData,idx,fieldVal); 470 m_curr_packet.setTraceInfoCyct(fieldVal); 471 } 472 m_process_state = SEND_PKT; 473 m_first_trace_info = true; 474 } 475 476 } 477 478 void TrcPktProcEtmV4I::iPktTimestamp(const uint8_t lastByte) 479 { 480 // process the header byte 481 if(m_currPacketData.size() == 1) 482 { 483 m_ccount_done = (bool)((lastByte & 0x1) == 0); // 0 = not present 484 m_ts_done = false; 485 m_ts_bytes = 0; 486 } 487 else 488 { 489 if(!m_ts_done) 490 { 491 m_ts_bytes++; 492 m_ts_done = (m_ts_bytes == 9) || ((lastByte & 0x80) == 0); 493 } 494 else if(!m_ccount_done) 495 { 496 m_ccount_done = (bool)((lastByte & 0x80) == 0); 497 // TBD: check for oorange ccount - bad packet. 498 } 499 } 500 501 if(m_ts_done && m_ccount_done) 502 { 503 int idx = 1; 504 uint64_t tsVal; 505 int ts_bytes = extractContField64(m_currPacketData, idx, tsVal); 506 int ts_bits = ts_bytes < 7 ? ts_bytes * 7 : 64; 507 508 if(!m_curr_packet.pkt_valid.bits.ts_valid && m_first_trace_info) 509 ts_bits = 64; // after trace info, missing bits are all 0. 510 511 m_curr_packet.setTS(tsVal,(uint8_t)ts_bits); 512 513 if((m_currPacketData[0] & 0x1) == 0x1) 514 { 515 uint32_t countVal, countMask; 516 517 idx += ts_bytes; 518 extractContField(m_currPacketData, idx, countVal, 3); // only 3 possible count bytes. 519 countMask = (((uint32_t)1UL << m_config.ccSize()) - 1); // mask of the CC size 520 countVal &= countMask; 521 m_curr_packet.setCycleCount(countVal); 522 } 523 524 m_process_state = SEND_PKT; 525 } 526 } 527 528 void TrcPktProcEtmV4I::iPktException(const uint8_t lastByte) 529 { 530 uint16_t excep_type = 0; 531 532 switch(m_currPacketData.size()) 533 { 534 case 1: m_excep_size = 3; break; 535 case 2: if((lastByte & 0x80) == 0x00) 536 m_excep_size = 2; 537 break; 538 } 539 540 if(m_currPacketData.size() == (unsigned)m_excep_size) 541 { 542 excep_type = (m_currPacketData[1] >> 1) & 0x1F; 543 uint8_t addr_interp = (m_currPacketData[1] & 0x40) >> 5 | (m_currPacketData[1] & 0x1); 544 uint8_t m_fault_pending = 0; 545 uint8_t m_type = (m_config.coreProfile() == profile_CortexM) ? 1 : 0; 546 547 // extended exception packet (probably M class); 548 if(m_currPacketData[1] & 0x80) 549 { 550 excep_type |= ((uint16_t)m_currPacketData[2] & 0x1F) << 5; 551 m_fault_pending = (m_currPacketData[2] >> 5) & 0x1; 552 } 553 m_curr_packet.setExceptionInfo(excep_type,addr_interp,m_fault_pending, m_type); 554 m_process_state = SEND_PKT; 555 556 // allow the standard address packet handlers to process the address packet field for the exception. 557 } 558 } 559 560 void TrcPktProcEtmV4I::iPktCycleCntF123(const uint8_t lastByte) 561 { 562 ocsd_etmv4_i_pkt_type format = m_curr_packet.type; 563 564 if( m_currPacketData.size() == 1) 565 { 566 m_count_done = m_commit_done = false; 567 m_has_count = true; 568 569 if(format == ETM4_PKT_I_CCNT_F3) 570 { 571 // no commit section for TRCIDR0.COMMOPT == 1 572 if(!m_config.commitOpt1()) 573 { 574 m_curr_packet.setCommitElements(((lastByte >> 2) & 0x3) + 1); 575 } 576 // TBD: warning of non-valid CC threshold here? 577 m_curr_packet.setCycleCount(m_curr_packet.getCCThreshold() + (lastByte & 0x3)); 578 m_process_state = SEND_PKT; 579 } 580 else if(format == ETM4_PKT_I_CCNT_F1) 581 { 582 if((lastByte & 0x1) == 0x1) 583 { 584 m_has_count = false; 585 m_count_done = true; 586 } 587 588 // no commit section for TRCIDR0.COMMOPT == 1 589 if(m_config.commitOpt1()) 590 m_commit_done = true; 591 } 592 } 593 else if((format == ETM4_PKT_I_CCNT_F2) && ( m_currPacketData.size() == 2)) 594 { 595 int commit_offset = ((lastByte & 0x1) == 0x1) ? ((int)m_config.MaxSpecDepth() - 15) : 1; 596 int commit_elements = ((lastByte >> 4) & 0xF); 597 commit_elements += commit_offset; 598 599 // TBD: warning if commit elements < 0? 600 601 m_curr_packet.setCycleCount(m_curr_packet.getCCThreshold() + (lastByte & 0xF)); 602 m_curr_packet.setCommitElements(commit_elements); 603 m_process_state = SEND_PKT; 604 } 605 else 606 { 607 // F1 and size 2 or more 608 if(!m_commit_done) 609 m_commit_done = ((lastByte & 0x80) == 0x00); 610 else if(!m_count_done) 611 m_count_done = ((lastByte & 0x80) == 0x00); 612 } 613 614 if((format == ETM4_PKT_I_CCNT_F1) && m_commit_done && m_count_done) 615 { 616 int idx = 1; // index into buffer for payload data. 617 uint32_t field_value = 0; 618 // no commit section for TRCIDR0.COMMOPT == 1 619 if(!m_config.commitOpt1()) 620 { 621 idx += extractContField(m_currPacketData,idx,field_value); 622 m_curr_packet.setCommitElements(field_value); 623 } 624 if (m_has_count) 625 { 626 extractContField(m_currPacketData, idx, field_value, 3); 627 m_curr_packet.setCycleCount(field_value + m_curr_packet.getCCThreshold()); 628 } 629 else 630 m_curr_packet.setCycleCount(0); /* unknown CC marked as 0 after overflow */ 631 m_process_state = SEND_PKT; 632 } 633 } 634 635 void TrcPktProcEtmV4I::iPktSpeclRes(const uint8_t lastByte) 636 { 637 if(m_currPacketData.size() == 1) 638 { 639 switch(m_curr_packet.getType()) 640 { 641 case ETM4_PKT_I_MISPREDICT: 642 case ETM4_PKT_I_CANCEL_F2: 643 switch(lastByte & 0x3) 644 { 645 case 0x1: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x1, 1); break; // E 646 case 0x2: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x3, 2); break; // EE 647 case 0x3: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x0, 1); break; // N 648 } 649 if (m_curr_packet.getType() == ETM4_PKT_I_CANCEL_F2) 650 m_curr_packet.setCancelElements(1); 651 else 652 m_curr_packet.setCancelElements(0); 653 m_process_state = SEND_PKT; 654 break; 655 656 case ETM4_PKT_I_CANCEL_F3: 657 if(lastByte & 0x1) 658 m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x1, 1); // E 659 m_curr_packet.setCancelElements(((lastByte >> 1) & 0x3) + 2); 660 m_process_state = SEND_PKT; 661 break; 662 } 663 } 664 else 665 { 666 if((lastByte & 0x80) == 0x00) 667 { 668 uint32_t field_val = 0; 669 extractContField(m_currPacketData,1,field_val); 670 if(m_curr_packet.getType() == ETM4_PKT_I_COMMIT) 671 m_curr_packet.setCommitElements(field_val); 672 else 673 m_curr_packet.setCancelElements(field_val); 674 m_process_state = SEND_PKT; 675 } 676 } 677 } 678 679 void TrcPktProcEtmV4I::iPktCondInstr(const uint8_t lastByte) 680 { 681 bool bF1Done = false; 682 683 if(m_currPacketData.size() == 1) 684 { 685 if(m_curr_packet.getType() == ETM4_PKT_I_COND_I_F2) 686 { 687 m_curr_packet.setCondIF2(lastByte & 0x3); 688 m_process_state = SEND_PKT; 689 } 690 691 } 692 else if(m_currPacketData.size() == 2) 693 { 694 if(m_curr_packet.getType() == ETM4_PKT_I_COND_I_F3) // f3 two bytes long 695 { 696 uint8_t num_c_elem = ((lastByte >> 1) & 0x3F) + (lastByte & 0x1); 697 m_curr_packet.setCondIF3(num_c_elem,(bool)((lastByte & 0x1) == 0x1)); 698 // TBD: check for 0 num_c_elem in here. 699 m_process_state = SEND_PKT; 700 } 701 else 702 { 703 bF1Done = ((lastByte & 0x80) == 0x00); 704 } 705 } 706 else 707 { 708 bF1Done = ((lastByte & 0x80) == 0x00); 709 } 710 711 if(bF1Done) 712 { 713 uint32_t cond_key = 0; 714 extractContField(m_currPacketData, 1, cond_key); 715 m_process_state = SEND_PKT; 716 } 717 } 718 719 void TrcPktProcEtmV4I::iPktCondResult(const uint8_t lastByte) 720 { 721 if(m_currPacketData.size() == 1) 722 { 723 m_F1P1_done = false; // F1 payload 1 done 724 m_F1P2_done = false; // F1 payload 2 done 725 m_F1has_P2 = false; // F1 has a payload 2 726 727 switch(m_curr_packet.getType()) 728 { 729 case ETM4_PKT_I_COND_RES_F1: 730 731 m_F1has_P2 = true; 732 if((lastByte & 0xFC) == 0x6C)// only one payload set 733 { 734 m_F1P2_done = true; 735 m_F1has_P2 = false; 736 } 737 break; 738 739 case ETM4_PKT_I_COND_RES_F2: 740 m_curr_packet.setCondRF2((lastByte & 0x4) ? 2 : 1, lastByte & 0x3); 741 m_process_state = SEND_PKT; 742 break; 743 744 case ETM4_PKT_I_COND_RES_F3: 745 break; 746 747 case ETM4_PKT_I_COND_RES_F4: 748 m_curr_packet.setCondRF4(lastByte & 0x3); 749 m_process_state = SEND_PKT; 750 break; 751 } 752 } 753 else if((m_curr_packet.getType() == ETM4_PKT_I_COND_RES_F3) && (m_currPacketData.size() == 2)) 754 { 755 // 2nd F3 packet 756 uint16_t f3_tokens = 0; 757 f3_tokens = (uint16_t)m_currPacketData[1]; 758 f3_tokens |= ((uint16_t)m_currPacketData[0] & 0xf) << 8; 759 m_curr_packet.setCondRF3(f3_tokens); 760 m_process_state = SEND_PKT; 761 } 762 else // !first packet - F1 763 { 764 if(!m_F1P1_done) 765 m_F1P1_done = ((lastByte & 0x80) == 0x00); 766 else if(!m_F1P2_done) 767 m_F1P2_done = ((lastByte & 0x80) == 0x00); 768 769 if(m_F1P1_done && m_F1P2_done) 770 { 771 int st_idx = 1; 772 uint32_t key[2]; 773 uint8_t result[2]; 774 uint8_t CI[2]; 775 776 st_idx+= extractCondResult(m_currPacketData,st_idx,key[0],result[0]); 777 CI[0] = m_currPacketData[0] & 0x1; 778 if(m_F1has_P2) // 2nd payload? 779 { 780 extractCondResult(m_currPacketData,st_idx,key[1],result[1]); 781 CI[1] = (m_currPacketData[0] >> 1) & 0x1; 782 } 783 m_curr_packet.setCondRF1(key,result,CI,m_F1has_P2); 784 m_process_state = SEND_PKT; 785 } 786 } 787 } 788 789 void TrcPktProcEtmV4I::iPktContext(const uint8_t lastByte) 790 { 791 bool bSendPacket = false; 792 793 if(m_currPacketData.size() == 1) 794 { 795 if((lastByte & 0x1) == 0) 796 { 797 m_curr_packet.setContextInfo(false); // no update context packet (ctxt same as last time). 798 m_process_state = SEND_PKT; 799 } 800 } 801 else if(m_currPacketData.size() == 2) 802 { 803 if((lastByte & 0xC0) == 0) // no VMID or CID 804 { 805 bSendPacket = true; 806 } 807 else 808 { 809 m_vmidBytes = ((lastByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0; 810 m_ctxtidBytes = ((lastByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0; 811 } 812 } 813 else // 3rd byte onwards 814 { 815 if(m_vmidBytes > 0) 816 m_vmidBytes--; 817 else if(m_ctxtidBytes > 0) 818 m_ctxtidBytes--; 819 820 if((m_ctxtidBytes == 0) && (m_vmidBytes == 0)) 821 bSendPacket = true; 822 } 823 824 if(bSendPacket) 825 { 826 extractAndSetContextInfo(m_currPacketData,1); 827 m_process_state = SEND_PKT; 828 } 829 } 830 831 void TrcPktProcEtmV4I::extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx) 832 { 833 // on input, buffer index points at the info byte - always present 834 uint8_t infoByte = m_currPacketData[st_idx]; 835 836 m_curr_packet.setContextInfo(true, (infoByte & 0x3), (infoByte >> 5) & 0x1, (infoByte >> 4) & 0x1); 837 838 // see if there are VMID and CID bytes, and how many. 839 int nVMID_bytes = ((infoByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0; 840 int nCtxtID_bytes = ((infoByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0; 841 842 // extract any VMID and CID 843 int payload_idx = st_idx+1; 844 if(nVMID_bytes) 845 { 846 uint32_t VMID = 0; 847 for(int i = 0; i < nVMID_bytes; i++) 848 { 849 VMID |= ((uint32_t)m_currPacketData[i+payload_idx] << i*8); 850 } 851 payload_idx += nVMID_bytes; 852 m_curr_packet.setContextVMID(VMID); 853 } 854 855 if(nCtxtID_bytes) 856 { 857 uint32_t CID = 0; 858 for(int i = 0; i < nCtxtID_bytes; i++) 859 { 860 CID |= ((uint32_t)m_currPacketData[i+payload_idx] << i*8); 861 } 862 m_curr_packet.setContextCID(CID); 863 } 864 } 865 866 void TrcPktProcEtmV4I::iPktAddrCtxt(const uint8_t lastByte) 867 { 868 if( m_currPacketData.size() == 1) 869 { 870 m_addrIS = 0; 871 m_addrBytes = 4; 872 m_bAddr64bit = false; 873 m_vmidBytes = 0; 874 m_ctxtidBytes = 0; 875 m_bCtxtInfoDone = false; 876 877 switch(m_curr_packet.type) 878 { 879 case ETM4_PKT_I_ADDR_CTXT_L_32IS1: 880 m_addrIS = 1; 881 case ETM4_PKT_I_ADDR_CTXT_L_32IS0: 882 break; 883 884 case ETM4_PKT_I_ADDR_CTXT_L_64IS1: 885 m_addrIS = 1; 886 case ETM4_PKT_I_ADDR_CTXT_L_64IS0: 887 m_addrBytes = 8; 888 m_bAddr64bit = true; 889 break; 890 } 891 } 892 else 893 { 894 if(m_addrBytes == 0) 895 { 896 if(m_bCtxtInfoDone == false) 897 { 898 m_bCtxtInfoDone = true; 899 m_vmidBytes = ((lastByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0; 900 m_ctxtidBytes = ((lastByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0; 901 } 902 else 903 { 904 if( m_vmidBytes > 0) 905 m_vmidBytes--; 906 else if(m_ctxtidBytes > 0) 907 m_ctxtidBytes--; 908 } 909 } 910 else 911 m_addrBytes--; 912 913 if((m_addrBytes == 0) && m_bCtxtInfoDone && (m_vmidBytes == 0) && (m_ctxtidBytes == 0)) 914 { 915 int st_idx = 1; 916 if(m_bAddr64bit) 917 { 918 uint64_t val64; 919 st_idx+=extract64BitLongAddr(m_currPacketData,st_idx,m_addrIS,val64); 920 m_curr_packet.set64BitAddress(val64,m_addrIS); 921 } 922 else 923 { 924 uint32_t val32; 925 st_idx+=extract32BitLongAddr(m_currPacketData,st_idx,m_addrIS,val32); 926 m_curr_packet.set32BitAddress(val32,m_addrIS); 927 } 928 extractAndSetContextInfo(m_currPacketData,st_idx); 929 m_process_state = SEND_PKT; 930 } 931 } 932 } 933 934 void TrcPktProcEtmV4I::iPktShortAddr(const uint8_t lastByte) 935 { 936 if (m_currPacketData.size() == 1) 937 { 938 m_addr_done = false; 939 m_addrIS = 0; 940 if (lastByte == ETM4_PKT_I_ADDR_S_IS1) 941 m_addrIS = 1; 942 } 943 else if(!m_addr_done) 944 { 945 m_addr_done = (m_currPacketData.size() == 3) || ((lastByte & 0x80) == 0x00); 946 } 947 948 if(m_addr_done) 949 { 950 uint32_t addr_val = 0; 951 int bits = 0; 952 953 extractShortAddr(m_currPacketData,1,m_addrIS,addr_val,bits); 954 m_curr_packet.updateShortAddress(addr_val,m_addrIS,(uint8_t)bits); 955 m_process_state = SEND_PKT; 956 } 957 } 958 959 int TrcPktProcEtmV4I::extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits) 960 { 961 int IS_shift = (IS == 0) ? 2 : 1; 962 int idx = 0; 963 964 bits = 7; // at least 7 bits 965 value = 0; 966 value |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << IS_shift; 967 968 if(m_currPacketData[st_idx+idx] & 0x80) 969 { 970 idx++; 971 value |= ((uint32_t)m_currPacketData[st_idx+idx]) << (7 + IS_shift); 972 bits += 8; 973 } 974 idx++; 975 bits += IS_shift; 976 return idx; 977 } 978 979 void TrcPktProcEtmV4I::iPktLongAddr(const uint8_t lastByte) 980 { 981 if(m_currPacketData.size() == 1) 982 { 983 // init the intra-byte data 984 m_addrIS = 0; 985 m_bAddr64bit = false; 986 m_addrBytes = 4; 987 988 switch(m_curr_packet.type) 989 { 990 case ETM4_PKT_I_ADDR_L_32IS1: 991 m_addrIS = 1; 992 case ETM4_PKT_I_ADDR_L_32IS0: 993 m_addrBytes = 4; 994 break; 995 996 case ETM4_PKT_I_ADDR_L_64IS1: 997 m_addrIS = 1; 998 case ETM4_PKT_I_ADDR_L_64IS0: 999 m_addrBytes = 8; 1000 m_bAddr64bit = true; 1001 break; 1002 } 1003 } 1004 if(m_currPacketData.size() == (unsigned)(1+m_addrBytes)) 1005 { 1006 int st_idx = 1; 1007 if(m_bAddr64bit) 1008 { 1009 uint64_t val64; 1010 st_idx+=extract64BitLongAddr(m_currPacketData,st_idx,m_addrIS,val64); 1011 m_curr_packet.set64BitAddress(val64,m_addrIS); 1012 } 1013 else 1014 { 1015 uint32_t val32; 1016 st_idx+=extract32BitLongAddr(m_currPacketData,st_idx,m_addrIS,val32); 1017 m_curr_packet.set32BitAddress(val32,m_addrIS); 1018 } 1019 m_process_state = SEND_PKT; 1020 } 1021 } 1022 1023 void TrcPktProcEtmV4I::iPktQ(const uint8_t lastByte) 1024 { 1025 if(m_currPacketData.size() == 1) 1026 { 1027 m_Q_type = lastByte & 0xF; 1028 1029 m_addrBytes = 0; 1030 m_count_done = false; 1031 m_has_addr = false; 1032 m_addr_short = true; 1033 m_addr_match = false; 1034 m_addrIS = 1; 1035 m_QE = 0; 1036 1037 switch(m_Q_type) 1038 { 1039 // count only - implied address. 1040 case 0x0: 1041 case 0x1: 1042 case 0x2: 1043 m_addr_match = true; 1044 m_has_addr = true; 1045 m_QE = m_Q_type & 0x3; 1046 case 0xC: 1047 break; 1048 1049 // count + short address 1050 case 0x5: 1051 m_addrIS = 0; 1052 case 0x6: 1053 m_has_addr = true; 1054 m_addrBytes = 2; // short IS0/1 1055 break; 1056 1057 // count + long address 1058 case 0xA: 1059 m_addrIS = 0; 1060 case 0xB: 1061 m_has_addr = true; 1062 m_addr_short = false; 1063 m_addrBytes = 4; // long IS0/1 1064 break; 1065 1066 // no count, no address 1067 case 0xF: 1068 m_count_done = true; 1069 break; 1070 1071 // reserved values 0x3, 0x4, 0x7, 0x8, 0x9, 0xD, 0xE 1072 default: 1073 m_curr_packet.err_type = m_curr_packet.type; 1074 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE; 1075 m_process_state = SEND_PKT; 1076 break; 1077 } 1078 } 1079 else 1080 { 1081 if(m_addrBytes > 0) 1082 { 1083 if(m_addr_short && m_addrBytes == 2) // short 1084 { 1085 if((lastByte & 0x80) == 0x00) 1086 m_addrBytes--; // short version can have just single byte. 1087 } 1088 m_addrBytes--; 1089 } 1090 else if(!m_count_done) 1091 { 1092 m_count_done = ((lastByte & 0x80) == 0x00); 1093 } 1094 } 1095 1096 if(((m_addrBytes == 0) && m_count_done)) 1097 { 1098 int idx = 1; // move past the header 1099 int bits = 0; 1100 uint32_t q_addr; 1101 uint32_t q_count; 1102 1103 if(m_has_addr) 1104 { 1105 if(m_addr_match) 1106 { 1107 m_curr_packet.setAddressExactMatch(m_QE); 1108 } 1109 else if(m_addr_short) 1110 { 1111 idx+=extractShortAddr(m_currPacketData,idx,m_addrIS,q_addr,bits); 1112 m_curr_packet.updateShortAddress(q_addr,m_addrIS,(uint8_t)bits); 1113 } 1114 else 1115 { 1116 idx+=extract32BitLongAddr(m_currPacketData,idx,m_addrIS,q_addr); 1117 m_curr_packet.set32BitAddress(q_addr,m_addrIS); 1118 } 1119 } 1120 1121 if(m_Q_type != 0xF) 1122 { 1123 extractContField(m_currPacketData,idx,q_count); 1124 m_curr_packet.setQType(true,q_count,m_has_addr,m_addr_match,m_Q_type); 1125 } 1126 else 1127 { 1128 m_curr_packet.setQType(false,0,false,false,0xF); 1129 } 1130 m_process_state = SEND_PKT; 1131 } 1132 1133 } 1134 1135 void TrcPktProcEtmV4I::iAtom(const uint8_t lastByte) 1136 { 1137 // patterns lsbit = oldest atom, ms bit = newest. 1138 static const uint32_t f4_patterns[] = { 1139 0xE, // EEEN 1140 0x0, // NNNN 1141 0xA, // ENEN 1142 0x5 // NENE 1143 }; 1144 1145 uint8_t pattIdx = 0, pattCount = 0; 1146 uint32_t pattern; 1147 1148 // atom packets are single byte, no payload. 1149 switch(m_curr_packet.type) 1150 { 1151 case ETM4_PKT_I_ATOM_F1: 1152 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x1), 1); // 1xE or N 1153 break; 1154 1155 case ETM4_PKT_I_ATOM_F2: 1156 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x3), 2); // 2x (E or N) 1157 break; 1158 1159 case ETM4_PKT_I_ATOM_F3: 1160 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x7), 3); // 3x (E or N) 1161 break; 1162 1163 case ETM4_PKT_I_ATOM_F4: 1164 m_curr_packet.setAtomPacket(ATOM_PATTERN,f4_patterns[(lastByte & 0x3)], 4); // 4 atom pattern 1165 break; 1166 1167 case ETM4_PKT_I_ATOM_F5: 1168 pattIdx = ((lastByte & 0x20) >> 3) | (lastByte & 0x3); 1169 switch(pattIdx) 1170 { 1171 case 5: // 0b101 1172 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x1E, 5); // 5 atom pattern EEEEN 1173 break; 1174 1175 case 1: // 0b001 1176 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x00, 5); // 5 atom pattern NNNNN 1177 break; 1178 1179 case 2: //0b010 1180 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x0A, 5); // 5 atom pattern NENEN 1181 break; 1182 1183 case 3: //0b011 1184 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x15, 5); // 5 atom pattern ENENE 1185 break; 1186 1187 default: 1188 // TBD: warn about invalid pattern in here. 1189 break; 1190 } 1191 break; 1192 1193 case ETM4_PKT_I_ATOM_F6: 1194 pattCount = (lastByte & 0x1F) + 3; // count of E's 1195 // TBD: check 23 or less at this point? 1196 pattern = ((uint32_t)0x1 << pattCount) - 1; // set pattern to string of E's 1197 if((lastByte & 0x20) == 0x00) // last atom is E? 1198 pattern |= ((uint32_t)0x1 << pattCount); 1199 m_curr_packet.setAtomPacket(ATOM_PATTERN,pattern, pattCount+1); 1200 break; 1201 } 1202 1203 m_process_state = SEND_PKT; 1204 } 1205 1206 // header byte processing is table driven. 1207 void TrcPktProcEtmV4I::BuildIPacketTable() 1208 { 1209 // initialise everything as reserved. 1210 for(int i = 0; i < 256; i++) 1211 { 1212 m_i_table[i].pkt_type = ETM4_PKT_I_RESERVED; 1213 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iPktReserved; 1214 } 1215 1216 // 0x00 - extension 1217 m_i_table[0x00].pkt_type = ETM4_PKT_I_EXTENSION; 1218 m_i_table[0x00].pptkFn = &TrcPktProcEtmV4I::iPktExtension; 1219 1220 // 0x01 - Trace info 1221 m_i_table[0x01].pkt_type = ETM4_PKT_I_TRACE_INFO; 1222 m_i_table[0x01].pptkFn = &TrcPktProcEtmV4I::iPktTraceInfo; 1223 1224 // b0000001x - timestamp 1225 m_i_table[0x02].pkt_type = ETM4_PKT_I_TIMESTAMP; 1226 m_i_table[0x02].pptkFn = &TrcPktProcEtmV4I::iPktTimestamp; 1227 m_i_table[0x03].pkt_type = ETM4_PKT_I_TIMESTAMP; 1228 m_i_table[0x03].pptkFn = &TrcPktProcEtmV4I::iPktTimestamp; 1229 1230 // b0000 0100 - trace on 1231 m_i_table[0x04].pkt_type = ETM4_PKT_I_TRACE_ON; 1232 m_i_table[0x04].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1233 1234 1235 // b0000 0101 - Funct ret V8M 1236 m_i_table[0x05].pkt_type = ETM4_PKT_I_FUNC_RET; 1237 if ((m_config.coreProfile() == profile_CortexM) && 1238 (OCSD_IS_V8_ARCH(m_config.archVersion())) && 1239 (m_config.FullVersion() >= 0x42)) 1240 { 1241 m_i_table[0x05].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1242 } 1243 1244 // b0000 0110 - exception 1245 m_i_table[0x06].pkt_type = ETM4_PKT_I_EXCEPT; 1246 m_i_table[0x06].pptkFn = &TrcPktProcEtmV4I::iPktException; 1247 1248 // b0000 0111 - exception return 1249 m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN; 1250 m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1251 1252 // b0000 110x - cycle count f2 1253 // b0000 111x - cycle count f1 1254 for(int i = 0; i < 4; i++) 1255 { 1256 m_i_table[0x0C+i].pkt_type = (i >= 2) ? ETM4_PKT_I_CCNT_F1 : ETM4_PKT_I_CCNT_F2; 1257 m_i_table[0x0C+i].pptkFn = &TrcPktProcEtmV4I::iPktCycleCntF123; 1258 } 1259 1260 // b0001 xxxx - cycle count f3 1261 for(int i = 0; i < 16; i++) 1262 { 1263 m_i_table[0x10+i].pkt_type = ETM4_PKT_I_CCNT_F3; 1264 m_i_table[0x10+i].pptkFn = &TrcPktProcEtmV4I::iPktCycleCntF123; 1265 } 1266 1267 // b0010 0xxx - NDSM 1268 for(int i = 0; i < 8; i++) 1269 { 1270 m_i_table[0x20 + i].pkt_type = ETM4_PKT_I_NUM_DS_MKR; 1271 if (m_config.enabledDataTrace()) 1272 m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1273 else 1274 m_i_table[0x20+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1275 } 1276 1277 // b0010 10xx, b0010 1100 - UDSM 1278 for(int i = 0; i < 5; i++) 1279 { 1280 m_i_table[0x28+i].pkt_type = ETM4_PKT_I_UNNUM_DS_MKR; 1281 if (m_config.enabledDataTrace()) 1282 m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1283 else 1284 m_i_table[0x28+i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1285 } 1286 1287 // b0010 1101 - commit 1288 m_i_table[0x2D].pkt_type = ETM4_PKT_I_COMMIT; 1289 m_i_table[0x2D].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1290 1291 // b0010 111x - cancel f1 (mis pred) 1292 m_i_table[0x2E].pkt_type = ETM4_PKT_I_CANCEL_F1; 1293 m_i_table[0x2E].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1294 m_i_table[0x2F].pkt_type = ETM4_PKT_I_CANCEL_F1_MISPRED; 1295 m_i_table[0x2F].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1296 1297 // b0011 00xx - mis predict 1298 for(int i = 0; i < 4; i++) 1299 { 1300 m_i_table[0x30+i].pkt_type = ETM4_PKT_I_MISPREDICT; 1301 m_i_table[0x30+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1302 } 1303 1304 // b0011 01xx - cancel f2 1305 for(int i = 0; i < 4; i++) 1306 { 1307 m_i_table[0x34+i].pkt_type = ETM4_PKT_I_CANCEL_F2; 1308 m_i_table[0x34+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1309 } 1310 1311 // b0011 1xxx - cancel f3 1312 for(int i = 0; i < 8; i++) 1313 { 1314 m_i_table[0x38+i].pkt_type = ETM4_PKT_I_CANCEL_F3; 1315 m_i_table[0x38+i].pptkFn = &TrcPktProcEtmV4I::iPktSpeclRes; 1316 } 1317 1318 bool bCondValid = m_config.hasCondTrace() && m_config.enabledCondITrace(); 1319 1320 // b0100 000x, b0100 0010 - cond I f2 1321 for (int i = 0; i < 3; i++) 1322 { 1323 m_i_table[0x40 + i].pkt_type = ETM4_PKT_I_COND_I_F2; 1324 if (bCondValid) 1325 m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr; 1326 else 1327 m_i_table[0x40 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1328 } 1329 1330 // b0100 0011 - cond flush 1331 m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH; 1332 if (bCondValid) 1333 m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1334 else 1335 m_i_table[0x43].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1336 1337 // b0100 010x, b0100 0110 - cond res f4 1338 for (int i = 0; i < 3; i++) 1339 { 1340 m_i_table[0x44 + i].pkt_type = ETM4_PKT_I_COND_RES_F4; 1341 if (bCondValid) 1342 m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1343 else 1344 m_i_table[0x44 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1345 } 1346 1347 // b0100 100x, b0100 0110 - cond res f2 1348 // b0100 110x, b0100 1110 - cond res f2 1349 for (int i = 0; i < 3; i++) 1350 { 1351 m_i_table[0x48 + i].pkt_type = ETM4_PKT_I_COND_RES_F2; 1352 if (bCondValid) 1353 m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1354 else 1355 m_i_table[0x48 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1356 } 1357 for (int i = 0; i < 3; i++) 1358 { 1359 m_i_table[0x4C + i].pkt_type = ETM4_PKT_I_COND_RES_F2; 1360 if (bCondValid) 1361 m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1362 else 1363 m_i_table[0x4C + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1364 } 1365 1366 // b0101xxxx - cond res f3 1367 for (int i = 0; i < 16; i++) 1368 { 1369 m_i_table[0x50 + i].pkt_type = ETM4_PKT_I_COND_RES_F3; 1370 if (bCondValid) 1371 m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1372 else 1373 m_i_table[0x50 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1374 } 1375 1376 // b011010xx - cond res f1 1377 for (int i = 0; i < 4; i++) 1378 { 1379 m_i_table[0x68 + i].pkt_type = ETM4_PKT_I_COND_RES_F1; 1380 if (bCondValid) 1381 m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1382 else 1383 m_i_table[0x68 + i].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1384 } 1385 1386 // b0110 1100 - cond instr f1 1387 m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1; 1388 if (bCondValid) 1389 m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr; 1390 else 1391 m_i_table[0x6C].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1392 1393 // b0110 1101 - cond instr f3 1394 m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3; 1395 if (bCondValid) 1396 m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktCondInstr; 1397 else 1398 m_i_table[0x6D].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1399 1400 // b0110111x - cond res f1 1401 for (int i = 0; i < 2; i++) 1402 { 1403 // G++ cannot understand [0x6E+i] so change these round 1404 m_i_table[i + 0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1; 1405 if (bCondValid) 1406 m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktCondResult; 1407 else 1408 m_i_table[i + 0x6E].pptkFn = &TrcPktProcEtmV4I::iPktInvalidCfg; 1409 } 1410 1411 // ETM 4.3 introduces ignore packets 1412 if (m_config.FullVersion() >= 0x43) 1413 { 1414 m_i_table[0x70].pkt_type = ETM4_PKT_I_IGNORE; 1415 m_i_table[0x70].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1416 } 1417 1418 // b01110001 - b01111111 - event trace 1419 for(int i = 0; i < 15; i++) 1420 { 1421 m_i_table[0x71+i].pkt_type = ETM4_PKT_I_EVENT; 1422 m_i_table[0x71+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1423 } 1424 1425 // 0b1000 000x - context 1426 for(int i = 0; i < 2; i++) 1427 { 1428 m_i_table[0x80+i].pkt_type = ETM4_PKT_I_CTXT; 1429 m_i_table[0x80+i].pptkFn = &TrcPktProcEtmV4I::iPktContext; 1430 } 1431 1432 // 0b1000 0010 to b1000 0011 - addr with ctxt 1433 // 0b1000 0101 to b1000 0110 - addr with ctxt 1434 for(int i = 0; i < 2; i++) 1435 { 1436 m_i_table[0x82+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_32IS0 : ETM4_PKT_I_ADDR_CTXT_L_32IS1; 1437 m_i_table[0x82+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt; 1438 } 1439 1440 for(int i = 0; i < 2; i++) 1441 { 1442 m_i_table[0x85+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_64IS0 : ETM4_PKT_I_ADDR_CTXT_L_64IS1; 1443 m_i_table[0x85+i].pptkFn = &TrcPktProcEtmV4I::iPktAddrCtxt; 1444 } 1445 1446 // 0b1001 0000 to b1001 0010 - exact match addr 1447 for(int i = 0; i < 3; i++) 1448 { 1449 m_i_table[0x90+i].pkt_type = ETM4_PKT_I_ADDR_MATCH; 1450 m_i_table[0x90+i].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload; 1451 } 1452 1453 // b1001 0101 - b1001 0110 - addr short address 1454 for(int i = 0; i < 2; i++) 1455 { 1456 m_i_table[0x95+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_S_IS0 : ETM4_PKT_I_ADDR_S_IS1; 1457 m_i_table[0x95+i].pptkFn = &TrcPktProcEtmV4I::iPktShortAddr; 1458 } 1459 1460 // b10011010 - b10011011 - addr long address 1461 // b10011101 - b10011110 - addr long address 1462 for(int i = 0; i < 2; i++) 1463 { 1464 m_i_table[0x9A+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_32IS0 : ETM4_PKT_I_ADDR_L_32IS1; 1465 m_i_table[0x9A+i].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr; 1466 } 1467 for(int i = 0; i < 2; i++) 1468 { 1469 m_i_table[0x9D+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_64IS0 : ETM4_PKT_I_ADDR_L_64IS1; 1470 m_i_table[0x9D+i].pptkFn = &TrcPktProcEtmV4I::iPktLongAddr; 1471 } 1472 1473 // b1010xxxx - Q packet 1474 for (int i = 0; i < 16; i++) 1475 { 1476 m_i_table[0xA0 + i].pkt_type = ETM4_PKT_I_Q; 1477 // certain Q type codes are reserved. 1478 switch (i) { 1479 case 0x3: 1480 case 0x4: 1481 case 0x7: 1482 case 0x8: 1483 case 0x9: 1484 case 0xD: 1485 case 0xE: 1486 // don't update pkt fn - leave at default reserved. 1487 break; 1488 default: 1489 // if this config supports Q elem - otherwise reserved again. 1490 if (m_config.hasQElem()) 1491 m_i_table[0xA0 + i].pptkFn = &TrcPktProcEtmV4I::iPktQ; 1492 } 1493 } 1494 1495 // Atom Packets - all no payload but have specific pattern generation fn 1496 for(int i = 0xC0; i <= 0xD4; i++) // atom f6 1497 { 1498 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6; 1499 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1500 } 1501 for(int i = 0xD5; i <= 0xD7; i++) // atom f5 1502 { 1503 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F5; 1504 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1505 } 1506 for(int i = 0xD8; i <= 0xDB; i++) // atom f2 1507 { 1508 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F2; 1509 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1510 } 1511 for(int i = 0xDC; i <= 0xDF; i++) // atom f4 1512 { 1513 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F4; 1514 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1515 } 1516 for(int i = 0xE0; i <= 0xF4; i++) // atom f6 1517 { 1518 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6; 1519 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1520 } 1521 1522 // atom f5 1523 m_i_table[0xF5].pkt_type = ETM4_PKT_I_ATOM_F5; 1524 m_i_table[0xF5].pptkFn = &TrcPktProcEtmV4I::iAtom; 1525 1526 for(int i = 0xF6; i <= 0xF7; i++) // atom f1 1527 { 1528 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F1; 1529 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1530 } 1531 for(int i = 0xF8; i <= 0xFF; i++) // atom f3 1532 { 1533 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F3; 1534 m_i_table[i].pptkFn = &TrcPktProcEtmV4I::iAtom; 1535 } 1536 } 1537 1538 unsigned TrcPktProcEtmV4I::extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit /*= 5*/) 1539 { 1540 unsigned idx = 0; 1541 bool lastByte = false; 1542 uint8_t byteVal; 1543 value = 0; 1544 while(!lastByte && (idx < byte_limit)) // max 5 bytes for 32 bit value; 1545 { 1546 if(buffer.size() > (st_idx + idx)) 1547 { 1548 // each byte has seven bits + cont bit 1549 byteVal = buffer[(st_idx + idx)]; 1550 lastByte = (byteVal & 0x80) != 0x80; 1551 value |= ((uint32_t)(byteVal & 0x7F)) << (idx * 7); 1552 idx++; 1553 } 1554 else 1555 { 1556 throwBadSequenceError("Invalid 32 bit continuation fields in packet"); 1557 } 1558 } 1559 return idx; 1560 } 1561 1562 unsigned TrcPktProcEtmV4I::extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit /*= 9*/) 1563 { 1564 unsigned idx = 0; 1565 bool lastByte = false; 1566 uint8_t byteVal; 1567 value = 0; 1568 while(!lastByte && (idx < byte_limit)) // max 9 bytes for 64 bit value; 1569 { 1570 if(buffer.size() > (st_idx + idx)) 1571 { 1572 // each byte has seven bits + cont bit 1573 byteVal = buffer[(st_idx + idx)]; 1574 lastByte = (byteVal & 0x80) != 0x80; 1575 value |= ((uint64_t)(byteVal & 0x7F)) << (idx * 7); 1576 idx++; 1577 } 1578 else 1579 { 1580 throwBadSequenceError("Invalid 64 bit continuation fields in packet"); 1581 } 1582 } 1583 return idx; 1584 } 1585 1586 unsigned TrcPktProcEtmV4I::extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result) 1587 { 1588 unsigned idx = 0; 1589 bool lastByte = false; 1590 int incr = 0; 1591 1592 key = 0; 1593 1594 while(!lastByte && (idx < 6)) // cannot be more than 6 bytes for res + 32 bit key 1595 { 1596 if(buffer.size() > (st_idx + idx)) 1597 { 1598 if(idx == 0) 1599 { 1600 result = buffer[st_idx+idx]; 1601 key = (buffer[st_idx+idx] >> 4) & 0x7; 1602 incr+=3; 1603 } 1604 else 1605 { 1606 key |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << incr; 1607 incr+=7; 1608 } 1609 lastByte = (bool)((buffer[st_idx+idx] & 0x80) == 0); 1610 idx++; 1611 } 1612 else 1613 { 1614 throwBadSequenceError("Invalid continuation fields in packet"); 1615 } 1616 } 1617 return idx; 1618 } 1619 1620 int TrcPktProcEtmV4I::extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value) 1621 { 1622 value = 0; 1623 if(IS == 0) 1624 { 1625 value |= ((uint64_t)(buffer[st_idx+0] & 0x7F)) << 2; 1626 value |= ((uint64_t)(buffer[st_idx+1] & 0x7F)) << 9; 1627 } 1628 else 1629 { 1630 value |= ((uint64_t)(buffer[st_idx+0] & 0x7F)) << 1; 1631 value |= ((uint64_t)buffer[st_idx+1]) << 8; 1632 } 1633 value |= ((uint64_t)buffer[st_idx+2]) << 16; 1634 value |= ((uint64_t)buffer[st_idx+3]) << 24; 1635 value |= ((uint64_t)buffer[st_idx+4]) << 32; 1636 value |= ((uint64_t)buffer[st_idx+5]) << 40; 1637 value |= ((uint64_t)buffer[st_idx+6]) << 48; 1638 value |= ((uint64_t)buffer[st_idx+7]) << 56; 1639 return 8; 1640 } 1641 1642 int TrcPktProcEtmV4I::extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value) 1643 { 1644 value = 0; 1645 if(IS == 0) 1646 { 1647 value |= ((uint32_t)(buffer[st_idx+0] & 0x7F)) << 2; 1648 value |= ((uint32_t)(buffer[st_idx+1] & 0x7F)) << 9; 1649 } 1650 else 1651 { 1652 value |= ((uint32_t)(buffer[st_idx+0] & 0x7F)) << 1; 1653 value |= ((uint32_t)buffer[st_idx+1]) << 8; 1654 } 1655 value |= ((uint32_t)buffer[st_idx+2]) << 16; 1656 value |= ((uint32_t)buffer[st_idx+3]) << 24; 1657 return 4; 1658 } 1659 1660 void TrcPktProcEtmV4I::throwBadSequenceError(const char *pszExtMsg) 1661 { 1662 m_curr_packet.updateErrType(ETM4_PKT_I_BAD_SEQUENCE); // swap type for err type 1663 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_BAD_PACKET_SEQ,m_packet_index,m_config.getTraceID(),pszExtMsg); 1664 } 1665 1666 1667 /* End of File trc_pkt_proc_etmv4i.cpp */ 1668