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