2 * \file trc_pkt_proc_etmv4i_impl.cpp
5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
35 #include "trc_pkt_proc_etmv4i_impl.h"
37 EtmV4IPktProcImpl::EtmV4IPktProcImpl() :
40 m_first_trace_info(false)
45 EtmV4IPktProcImpl::~EtmV4IPktProcImpl()
49 void EtmV4IPktProcImpl::Initialise(TrcPktProcEtmV4I *p_interface)
53 m_interface = p_interface;
59 ocsd_err_t EtmV4IPktProcImpl::Configure(const EtmV4Config *p_config)
61 ocsd_err_t err = OCSD_OK;
68 err = OCSD_ERR_INVALID_PARAM_VAL;
70 m_interface->LogError(ocsdError(OCSD_ERR_SEV_ERROR,err));
75 ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t index,
76 const uint32_t dataBlockSize,
77 const uint8_t *pDataBlock,
78 uint32_t *numBytesProcessed)
80 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
81 m_blockBytesProcessed = 0;
84 while( ( (m_blockBytesProcessed < dataBlockSize) ||
85 ((m_blockBytesProcessed == dataBlockSize) && (m_process_state == SEND_PKT)) ) &&
86 OCSD_DATA_RESP_IS_CONT(resp))
88 currByte = pDataBlock[m_blockBytesProcessed];
91 switch(m_process_state)
94 m_packet_index = m_blockIndex + m_blockBytesProcessed;
97 m_pIPktFn = m_i_table[currByte].pptkFn;
98 m_curr_packet.type = m_i_table[currByte].pkt_type;
102 // unsynced - process data until we see a sync point
103 m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
104 m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
106 m_process_state = PROC_DATA;
109 m_currPacketData.push_back(pDataBlock[m_blockBytesProcessed]);
110 m_blockBytesProcessed++;
111 (this->*m_pIPktFn)();
115 resp = outputPacket();
117 m_process_state = PROC_HDR;
121 resp = outputUnsyncedRawPacket();
122 if(m_update_on_unsync_packet_index != 0)
124 m_packet_index = m_update_on_unsync_packet_index;
125 m_update_on_unsync_packet_index = 0;
127 m_process_state = PROC_DATA; // after dumping unsynced data, still in data mode.
131 catch(ocsdError &err)
133 m_interface->LogError(err);
134 if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) ||
135 (err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR))
137 // send invalid packets up the pipe to let the next stage decide what to do.
138 m_process_state = SEND_PKT;
142 // bail out on any other error.
143 resp = OCSD_RESP_FATAL_INVALID_DATA;
148 /// vv bad at this point.
149 resp = OCSD_RESP_FATAL_SYS_ERR;
150 const ocsdError &fatal = ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_packet_index,m_config.getTraceID(),"Unknown System Error decoding trace.");
151 m_interface->LogError(fatal);
155 *numBytesProcessed = m_blockBytesProcessed;
159 ocsd_datapath_resp_t EtmV4IPktProcImpl::onEOT()
161 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
162 // if we have a partial packet then send to attached sinks
163 if(m_currPacketData.size() != 0)
165 m_curr_packet.updateErrType(ETM4_PKT_I_INCOMPLETE_EOT);
166 resp = outputPacket();
172 ocsd_datapath_resp_t EtmV4IPktProcImpl::onReset()
174 // prepare for new decoding session
175 InitProcessorState();
176 return OCSD_RESP_CONT;
179 ocsd_datapath_resp_t EtmV4IPktProcImpl::onFlush()
181 // packet processor never holds on to flushable data (may have partial packet,
182 // but any full packets are immediately sent)
183 return OCSD_RESP_CONT;
186 void EtmV4IPktProcImpl::InitPacketState()
188 m_currPacketData.clear();
189 m_curr_packet.initNextPacket(); // clear for next packet.
190 m_update_on_unsync_packet_index = 0;
193 void EtmV4IPktProcImpl::InitProcessorState()
196 m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
199 m_first_trace_info = false;
200 m_sent_notsync_packet = false;
201 m_process_state = PROC_HDR;
202 m_curr_packet.initStartState();
205 ocsd_datapath_resp_t EtmV4IPktProcImpl::outputPacket()
207 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
208 resp = m_interface->outputOnAllInterfaces(m_packet_index,&m_curr_packet,&m_curr_packet.type,m_currPacketData);
212 ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket()
214 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
217 m_interface->outputRawPacketToMonitor(m_packet_index,&m_curr_packet,m_dump_unsynced_bytes,&m_currPacketData[0]);
219 if(!m_sent_notsync_packet)
221 resp = m_interface->outputDecodedPacket(m_packet_index,&m_curr_packet);
222 m_sent_notsync_packet = true;
225 if(m_currPacketData.size() <= m_dump_unsynced_bytes)
226 m_currPacketData.clear();
228 m_currPacketData.erase(m_currPacketData.begin(),m_currPacketData.begin()+m_dump_unsynced_bytes);
233 void EtmV4IPktProcImpl::iNotSync()
235 uint8_t lastByte = m_currPacketData.back(); // peek at the byte being processed...
237 // is it an extension byte?
238 if(lastByte == 0x00) // TBD : add check for forced sync in here?
240 if(m_currPacketData.size() > 1)
242 m_dump_unsynced_bytes = m_currPacketData.size() - 1;
243 m_process_state = SEND_UNSYNCED;
244 // outputting some data then update packet index after so output indexes accurate
245 m_update_on_unsync_packet_index = m_blockIndex + m_blockBytesProcessed - 1;
248 m_packet_index = m_blockIndex + m_blockBytesProcessed - 1; // set it up now otherwise.
250 m_pIPktFn = m_i_table[lastByte].pptkFn;
252 else if(m_currPacketData.size() >= 8)
254 m_dump_unsynced_bytes = m_currPacketData.size();
255 m_process_state = SEND_UNSYNCED;
256 // outputting some data then update packet index after so output indexes accurate
257 m_update_on_unsync_packet_index = m_blockIndex + m_blockBytesProcessed;
261 void EtmV4IPktProcImpl::iPktNoPayload()
263 // some expansion may be required...
264 uint8_t lastByte = m_currPacketData.back();
265 switch(m_curr_packet.type)
267 case ETM4_PKT_I_ADDR_MATCH:
268 m_curr_packet.setAddressExactMatch(lastByte & 0x3);
271 case ETM4_PKT_I_EVENT:
272 m_curr_packet.setEvent(lastByte & 0xF);
275 case ETM4_PKT_I_NUM_DS_MKR:
276 case ETM4_PKT_I_UNNUM_DS_MKR:
277 m_curr_packet.setDataSyncMarker(lastByte & 0x7);
280 // these just need the packet type - no processing required.
281 case ETM4_PKT_I_COND_FLUSH:
282 case ETM4_PKT_I_EXCEPT_RTN:
283 case ETM4_PKT_I_TRACE_ON:
286 m_process_state = SEND_PKT; // now just send it....
289 void EtmV4IPktProcImpl::iPktReserved()
291 m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED); // swap type for err type
292 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR,m_packet_index,m_config.getTraceID());
295 void EtmV4IPktProcImpl::iPktExtension()
297 uint8_t lastByte = m_currPacketData.back();
298 if(m_currPacketData.size() == 2)
300 // not sync and not next by 0x00 - not sync sequence
301 if(!m_is_sync && (lastByte != 0x00))
303 m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
304 m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
310 case 0x03: // discard packet.
311 m_curr_packet.type = ETM4_PKT_I_DISCARD;
312 m_process_state = SEND_PKT;
316 m_curr_packet.type = ETM4_PKT_I_OVERFLOW;
317 m_process_state = SEND_PKT;
321 m_curr_packet.type = ETM4_PKT_I_ASYNC;
322 m_pIPktFn = &EtmV4IPktProcImpl::iPktASync; // handle subsequent bytes as async
326 m_curr_packet.err_type = m_curr_packet.type;
327 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
328 m_process_state = SEND_PKT;
334 void EtmV4IPktProcImpl::iPktASync()
336 uint8_t lastByte = m_currPacketData.back();
339 // not sync and not next by 0x00 - not sync sequence if < 12
340 if(!m_is_sync && m_currPacketData.size() != 12)
342 m_pIPktFn = &EtmV4IPktProcImpl::iNotSync;
343 m_curr_packet.type = ETM4_PKT_I_NOTSYNC;
347 // 12 bytes and not valid sync sequence - not possible even if not synced
348 m_process_state = SEND_PKT;
349 if((m_currPacketData.size() != 12) || (lastByte != 0x80))
351 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
352 m_curr_packet.err_type = ETM4_PKT_I_ASYNC;
355 m_is_sync = true; // found a sync packet, mark decoder as synchronised.
357 else if(m_currPacketData.size() == 12)
361 // if we are not yet synced then ignore extra leading 0x00.
362 m_dump_unsynced_bytes = 1;
363 m_process_state = SEND_UNSYNCED;
367 // bad periodic ASYNC sequence.
368 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
369 m_curr_packet.err_type = ETM4_PKT_I_ASYNC;
370 m_process_state = SEND_PKT;
375 void EtmV4IPktProcImpl::iPktTraceInfo()
377 uint8_t lastByte = m_currPacketData.back();
378 if(m_currPacketData.size() == 1) // header
381 m_tinfo_sections.sectFlags = 0; // mark all sections as incomplete.
382 m_tinfo_sections.ctrlBytes = 1; // assume only a single control section byte for now
385 else if(m_currPacketData.size() == 2) // first payload control byte
387 // figure out which sections are absent and set to true - opposite of bitfeild in byte;
388 m_tinfo_sections.sectFlags = (~lastByte) & TINFO_ALL_SECT;
390 // see if there is an extended control section, otherwise this byte is it.
391 if((lastByte & 0x80) == 0x0)
392 m_tinfo_sections.sectFlags |= TINFO_CTRL;
397 if(!(m_tinfo_sections.sectFlags & TINFO_CTRL))
399 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_CTRL;
400 m_tinfo_sections.ctrlBytes++;
402 else if(!(m_tinfo_sections.sectFlags & TINFO_INFO_SECT))
403 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_INFO_SECT;
404 else if(!(m_tinfo_sections.sectFlags & TINFO_KEY_SECT))
405 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_KEY_SECT;
406 else if(!(m_tinfo_sections.sectFlags & TINFO_SPEC_SECT))
407 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_SPEC_SECT;
408 else if(!(m_tinfo_sections.sectFlags & TINFO_CYCT_SECT))
409 m_tinfo_sections.sectFlags |= (lastByte & 0x80) ? 0 : TINFO_CYCT_SECT;
412 // all sections accounted for?
413 if(m_tinfo_sections.sectFlags == TINFO_ALL)
415 // index of first section is number of payload control bytes + 1 for header byte
416 unsigned idx = m_tinfo_sections.ctrlBytes + 1;
417 uint32_t fieldVal = 0;
418 uint8_t presSect = m_currPacketData[1] & TINFO_ALL_SECT; // first payload control byte
420 m_curr_packet.clearTraceInfo();
422 if((presSect & TINFO_INFO_SECT) && (idx < m_currPacketData.size()))
424 idx += extractContField(m_currPacketData,idx,fieldVal);
425 m_curr_packet.setTraceInfo(fieldVal);
427 if((presSect & TINFO_KEY_SECT) && (idx < m_currPacketData.size()))
429 idx += extractContField(m_currPacketData,idx,fieldVal);
430 m_curr_packet.setTraceInfoKey(fieldVal);
432 if((presSect & TINFO_SPEC_SECT) && (idx < m_currPacketData.size()))
434 idx += extractContField(m_currPacketData,idx,fieldVal);
435 m_curr_packet.setTraceInfoSpec(fieldVal);
437 if((presSect & TINFO_CYCT_SECT) && (idx < m_currPacketData.size()))
439 idx += extractContField(m_currPacketData,idx,fieldVal);
440 m_curr_packet.setTraceInfoCyct(fieldVal);
442 m_process_state = SEND_PKT;
443 m_first_trace_info = true;
448 void EtmV4IPktProcImpl::iPktTimestamp()
450 // save the latest byte
451 uint8_t lastByte = m_currPacketData.back();
453 // process the header byte
454 if(m_currPacketData.size() == 1)
456 m_ccount_done = (bool)((lastByte & 0x1) == 0); // 0 = not present
465 m_ts_done = (m_ts_bytes == 9) || ((lastByte & 0x80) == 0);
467 else if(!m_ccount_done)
469 m_ccount_done = (bool)((lastByte & 0x80) == 0);
470 // TBD: check for oorange ccount - bad packet.
474 if(m_ts_done && m_ccount_done)
478 int ts_bytes = extractContField64(m_currPacketData, idx, tsVal);
479 int ts_bits = ts_bytes < 7 ? ts_bytes * 7 : 64;
481 if(!m_curr_packet.pkt_valid.bits.ts_valid && m_first_trace_info)
482 ts_bits = 64; // after trace info, missing bits are all 0.
484 m_curr_packet.setTS(tsVal,(uint8_t)ts_bits);
486 if((m_currPacketData[0] & 0x1) == 0x1)
488 uint32_t countVal, countMask;
491 extractContField(m_currPacketData, idx, countVal, 3); // only 3 possible count bytes.
492 countMask = (((uint32_t)1UL << m_config.ccSize()) - 1); // mask of the CC size
493 countVal &= countMask;
494 m_curr_packet.setCycleCount(countVal);
497 m_process_state = SEND_PKT;
501 void EtmV4IPktProcImpl::iPktException()
503 uint8_t lastByte = m_currPacketData.back();
505 switch(m_currPacketData.size())
507 case 1: m_excep_size = 3; break;
508 case 2: if((lastByte & 0x80) == 0x00)
513 if(m_currPacketData.size() == (unsigned)m_excep_size)
515 uint16_t excep_type = (m_currPacketData[1] >> 1) & 0x1F;
516 uint8_t addr_interp = (m_currPacketData[1] & 0x40) >> 5 | (m_currPacketData[1] & 0x1);
517 uint8_t m_fault_pending = 0;
518 uint8_t m_type = (m_config.coreProfile() == profile_CortexM) ? 1 : 0;
520 // extended exception packet (probably M class);
521 if(m_currPacketData[1] & 0x80)
523 excep_type |= ((uint16_t)m_currPacketData[2] & 0x1F) << 5;
524 m_fault_pending = (m_currPacketData[2] >> 5) & 0x1;
526 m_curr_packet.setExceptionInfo(excep_type,addr_interp,m_fault_pending, m_type);
527 m_process_state = SEND_PKT;
529 // allow the standard address packet handlers to process the address packet field for the exception.
533 void EtmV4IPktProcImpl::iPktCycleCntF123()
535 ocsd_etmv4_i_pkt_type format = m_curr_packet.type;
537 uint8_t lastByte = m_currPacketData.back();
538 if( m_currPacketData.size() == 1)
540 m_count_done = m_commit_done = false;
543 if(format == ETM4_PKT_I_CCNT_F3)
545 // no commit section for TRCIDR0.COMMOPT == 1
546 if(!m_config.commitOpt1())
548 m_curr_packet.setCommitElements(((lastByte >> 2) & 0x3) + 1);
550 // TBD: warning of non-valid CC threshold here?
551 m_curr_packet.setCycleCount(m_curr_packet.getCCThreshold() + (lastByte & 0x3));
552 m_process_state = SEND_PKT;
554 else if(format == ETM4_PKT_I_CCNT_F1)
556 if((lastByte & 0x1) == 0x1)
562 // no commit section for TRCIDR0.COMMOPT == 1
563 if(m_config.commitOpt1())
564 m_commit_done = true;
567 else if((format == ETM4_PKT_I_CCNT_F2) && ( m_currPacketData.size() == 2))
569 int commit_offset = ((lastByte & 0x1) == 0x1) ? ((int)m_config.MaxSpecDepth() - 15) : 1;
570 int commit_elements = ((lastByte >> 4) & 0xF);
571 commit_elements += commit_offset;
573 // TBD: warning if commit elements < 0?
575 m_curr_packet.setCycleCount(m_curr_packet.getCCThreshold() + (lastByte & 0xF));
576 m_curr_packet.setCommitElements(commit_elements);
577 m_process_state = SEND_PKT;
581 // F1 and size 2 or more
583 m_commit_done = ((lastByte & 0x80) == 0x00);
584 else if(!m_count_done)
585 m_count_done = ((lastByte & 0x80) == 0x00);
588 if((format == ETM4_PKT_I_CCNT_F1) && m_commit_done && m_count_done)
590 int idx = 1; // index into buffer for payload data.
591 uint32_t field_value = 0;
592 // no commit section for TRCIDR0.COMMOPT == 1
593 if(!m_config.commitOpt1())
595 idx += extractContField(m_currPacketData,idx,field_value);
596 m_curr_packet.setCommitElements(field_value);
600 extractContField(m_currPacketData, idx, field_value, 3);
601 m_curr_packet.setCycleCount(field_value + m_curr_packet.getCCThreshold());
604 m_curr_packet.setCycleCount(0); /* unknown CC marked as 0 after overflow */
605 m_process_state = SEND_PKT;
609 void EtmV4IPktProcImpl::iPktSpeclRes()
611 uint8_t lastByte = m_currPacketData.back();
612 if(m_currPacketData.size() == 1)
614 switch(m_curr_packet.getType())
616 case ETM4_PKT_I_MISPREDICT:
617 case ETM4_PKT_I_CANCEL_F2:
618 switch(lastByte & 0x3)
620 case 0x1: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x1, 1); break; // E
621 case 0x2: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x3, 2); break; // EE
622 case 0x3: m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x0, 1); break; // N
624 if(m_curr_packet.getType() == ETM4_PKT_I_CANCEL_F2)
625 m_curr_packet.setCancelElements(1);
626 m_process_state = SEND_PKT;
629 case ETM4_PKT_I_CANCEL_F3:
631 m_curr_packet.setAtomPacket(ATOM_PATTERN, 0x1, 1); // E
632 m_curr_packet.setCancelElements(((lastByte >> 1) & 0x3) + 2);
633 m_process_state = SEND_PKT;
639 if((lastByte & 0x80) == 0x00)
641 uint32_t field_val = 0;
642 extractContField(m_currPacketData,1,field_val);
643 if(m_curr_packet.getType() == ETM4_PKT_I_COMMIT)
644 m_curr_packet.setCommitElements(field_val);
646 m_curr_packet.setCancelElements(field_val);
647 // TBD: sanity check with max spec depth here?
648 m_process_state = SEND_PKT;
653 void EtmV4IPktProcImpl::iPktCondInstr()
655 uint8_t lastByte = m_currPacketData.back();
656 bool bF1Done = false;
658 if(m_currPacketData.size() == 1)
660 if(m_curr_packet.getType() == ETM4_PKT_I_COND_I_F2)
662 m_curr_packet.setCondIF2(lastByte & 0x3);
663 m_process_state = SEND_PKT;
667 else if(m_currPacketData.size() == 2)
669 if(m_curr_packet.getType() == ETM4_PKT_I_COND_I_F3) // f3 two bytes long
671 uint8_t num_c_elem = ((lastByte >> 1) & 0x3F) + (lastByte & 0x1);
672 m_curr_packet.setCondIF3(num_c_elem,(bool)((lastByte & 0x1) == 0x1));
673 // TBD: check for 0 num_c_elem in here.
674 m_process_state = SEND_PKT;
678 bF1Done = ((lastByte & 0x80) == 0x00);
683 bF1Done = ((lastByte & 0x80) == 0x00);
688 uint32_t cond_key = 0;
689 extractContField(m_currPacketData, 1, cond_key);
690 m_process_state = SEND_PKT;
694 void EtmV4IPktProcImpl::iPktCondResult()
696 //static ocsd_etmv4_i_pkt_type format = ETM4_PKT_I_COND_RES_F1; // conditional result formats F1-F4
697 uint8_t lastByte = m_currPacketData.back();
698 if(m_currPacketData.size() == 1)
700 m_F1P1_done = false; // F1 payload 1 done
701 m_F1P2_done = false; // F1 payload 2 done
702 m_F1has_P2 = false; // F1 has a payload 2
704 switch(m_curr_packet.getType())
706 case ETM4_PKT_I_COND_RES_F1:
709 if((lastByte & 0xFC) == 0x6C)// only one payload set
716 case ETM4_PKT_I_COND_RES_F2:
717 m_curr_packet.setCondRF2((lastByte & 0x4) ? 2 : 1, lastByte & 0x3);
718 m_process_state = SEND_PKT;
721 case ETM4_PKT_I_COND_RES_F3:
724 case ETM4_PKT_I_COND_RES_F4:
725 m_curr_packet.setCondRF4(lastByte & 0x3);
726 m_process_state = SEND_PKT;
730 else if((m_curr_packet.getType() == ETM4_PKT_I_COND_RES_F3) && (m_currPacketData.size() == 2))
733 uint16_t f3_tokens = 0;
734 f3_tokens = (uint16_t)m_currPacketData[1];
735 f3_tokens |= ((uint16_t)m_currPacketData[0] & 0xf) << 8;
736 m_curr_packet.setCondRF3(f3_tokens);
737 m_process_state = SEND_PKT;
739 else // !first packet - F1
742 m_F1P1_done = ((lastByte & 0x80) == 0x00);
743 else if(!m_F1P2_done)
744 m_F1P2_done = ((lastByte & 0x80) == 0x00);
746 if(m_F1P1_done && m_F1P2_done)
753 st_idx+= extractCondResult(m_currPacketData,st_idx,key[0],result[0]);
754 CI[0] = m_currPacketData[0] & 0x1;
755 if(m_F1has_P2) // 2nd payload?
757 extractCondResult(m_currPacketData,st_idx,key[1],result[1]);
758 CI[1] = (m_currPacketData[0] >> 1) & 0x1;
760 m_curr_packet.setCondRF1(key,result,CI,m_F1has_P2);
761 m_process_state = SEND_PKT;
766 void EtmV4IPktProcImpl::iPktContext()
768 bool bSendPacket = false;
769 uint8_t lastByte = m_currPacketData.back();
770 if(m_currPacketData.size() == 1)
772 if((lastByte & 0x1) == 0)
774 m_curr_packet.setContextInfo(false); // no update context packet (ctxt same as last time).
775 m_process_state = SEND_PKT;
778 else if(m_currPacketData.size() == 2)
780 if((lastByte & 0xC0) == 0) // no VMID or CID
786 m_vmidBytes = ((lastByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0;
787 m_ctxtidBytes = ((lastByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0;
790 else // 3rd byte onwards
794 else if(m_ctxtidBytes > 0)
797 if((m_ctxtidBytes == 0) && (m_vmidBytes == 0))
803 extractAndSetContextInfo(m_currPacketData,1);
804 m_process_state = SEND_PKT;
808 void EtmV4IPktProcImpl::extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx)
810 // on input, buffer index points at the info byte - always present
811 uint8_t infoByte = m_currPacketData[st_idx];
813 m_curr_packet.setContextInfo(true, (infoByte & 0x3), (infoByte >> 5) & 0x1, (infoByte >> 4) & 0x1);
815 // see if there are VMID and CID bytes, and how many.
816 int nVMID_bytes = ((infoByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0;
817 int nCtxtID_bytes = ((infoByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0;
819 // extract any VMID and CID
820 int payload_idx = st_idx+1;
824 for(int i = 0; i < nVMID_bytes; i++)
826 VMID |= ((uint32_t)m_currPacketData[i+payload_idx] << i*8);
828 payload_idx += nVMID_bytes;
829 m_curr_packet.setContextVMID(VMID);
835 for(int i = 0; i < nCtxtID_bytes; i++)
837 CID |= ((uint32_t)m_currPacketData[i+payload_idx] << i*8);
839 m_curr_packet.setContextCID(CID);
843 void EtmV4IPktProcImpl::iPktAddrCtxt()
845 uint8_t lastByte = m_currPacketData.back();
847 if( m_currPacketData.size() == 1)
851 m_bAddr64bit = false;
854 m_bCtxtInfoDone = false;
856 switch(m_curr_packet.type)
858 case ETM4_PKT_I_ADDR_CTXT_L_32IS1:
860 case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
863 case ETM4_PKT_I_ADDR_CTXT_L_64IS1:
865 case ETM4_PKT_I_ADDR_CTXT_L_64IS0:
875 if(m_bCtxtInfoDone == false)
877 m_bCtxtInfoDone = true;
878 m_vmidBytes = ((lastByte & 0x40) == 0x40) ? (m_config.vmidSize()/8) : 0;
879 m_ctxtidBytes = ((lastByte & 0x80) == 0x80) ? (m_config.cidSize()/8) : 0;
885 else if(m_ctxtidBytes > 0)
892 if((m_addrBytes == 0) && m_bCtxtInfoDone && (m_vmidBytes == 0) && (m_ctxtidBytes == 0))
898 st_idx+=extract64BitLongAddr(m_currPacketData,st_idx,m_addrIS,val64);
899 m_curr_packet.set64BitAddress(val64,m_addrIS);
904 st_idx+=extract32BitLongAddr(m_currPacketData,st_idx,m_addrIS,val32);
905 m_curr_packet.set32BitAddress(val32,m_addrIS);
907 extractAndSetContextInfo(m_currPacketData,st_idx);
908 m_process_state = SEND_PKT;
913 void EtmV4IPktProcImpl::iPktShortAddr()
915 uint8_t lastByte = m_currPacketData.back();
916 if(m_currPacketData.size() == 1)
919 m_addrIS = (lastByte == ETM4_PKT_I_ADDR_S_IS0) ? 0 : 1;
921 else if(!m_addr_done)
923 m_addr_done = (m_currPacketData.size() == 3) || ((lastByte & 0x80) == 0x00);
928 uint32_t addr_val = 0;
931 extractShortAddr(m_currPacketData,1,m_addrIS,addr_val,bits);
932 m_curr_packet.updateShortAddress(addr_val,m_addrIS,(uint8_t)bits);
933 m_process_state = SEND_PKT;
937 int EtmV4IPktProcImpl::extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits)
939 int IS_shift = (IS == 0) ? 2 : 1;
942 bits = 7; // at least 7 bits
944 value |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << IS_shift;
946 if(m_currPacketData[st_idx+idx] & 0x80)
949 value |= ((uint32_t)m_currPacketData[st_idx+idx]) << (7 + IS_shift);
957 void EtmV4IPktProcImpl::iPktLongAddr()
959 if(m_currPacketData.size() == 1)
961 // init the intra-byte data
963 m_bAddr64bit = false;
966 switch(m_curr_packet.type)
968 case ETM4_PKT_I_ADDR_L_32IS1:
970 case ETM4_PKT_I_ADDR_L_32IS0:
974 case ETM4_PKT_I_ADDR_L_64IS1:
976 case ETM4_PKT_I_ADDR_L_64IS0:
982 if(m_currPacketData.size() == (unsigned)(1+m_addrBytes))
988 st_idx+=extract64BitLongAddr(m_currPacketData,st_idx,m_addrIS,val64);
989 m_curr_packet.set64BitAddress(val64,m_addrIS);
994 st_idx+=extract32BitLongAddr(m_currPacketData,st_idx,m_addrIS,val32);
995 m_curr_packet.set32BitAddress(val32,m_addrIS);
997 m_process_state = SEND_PKT;
1001 void EtmV4IPktProcImpl::iPktQ()
1003 uint8_t lastByte = m_currPacketData.back();
1005 if(m_currPacketData.size() == 1)
1007 m_Q_type = lastByte & 0xF;
1010 m_count_done = false;
1012 m_addr_short = true;
1013 m_addr_match = false;
1019 // count only - implied address.
1023 m_addr_match = true;
1025 m_QE = m_Q_type & 0x3;
1029 // count + short address
1034 m_addrBytes = 2; // short IS0/1
1037 // count + long address
1042 m_addr_short = false;
1043 m_addrBytes = 4; // long IS0/1
1046 // no count, no address
1048 m_count_done = true;
1051 // reserved values 0x3, 0x4, 0x7, 0x8, 0x9, 0xD, 0xE
1053 m_curr_packet.err_type = m_curr_packet.type;
1054 m_curr_packet.type = ETM4_PKT_I_BAD_SEQUENCE;
1055 //SendBadIPacket( PKT_BAD_SEQUENCE, "ERROR: Bad Q packet type", PKT_Q );
1063 if(m_addr_short && m_addrBytes == 2) // short
1065 if((lastByte & 0x80) == 0x00)
1066 m_addrBytes--; // short version can have just single byte.
1070 else if(!m_count_done)
1072 m_count_done = ((lastByte & 0x80) == 0x00);
1076 if(((m_addrBytes == 0) && m_count_done))
1078 int idx = 1; // move past the header
1087 m_curr_packet.setAddressExactMatch(m_QE);
1089 else if(m_addr_short)
1091 idx+=extractShortAddr(m_currPacketData,idx,m_addrIS,q_addr,bits);
1092 m_curr_packet.updateShortAddress(q_addr,m_addrIS,(uint8_t)bits);
1096 idx+=extract32BitLongAddr(m_currPacketData,idx,m_addrIS,q_addr);
1097 m_curr_packet.set32BitAddress(q_addr,m_addrIS);
1103 extractContField(m_currPacketData,idx,q_count);
1104 m_curr_packet.setQType(true,q_count,m_has_addr,m_addr_match,m_Q_type);
1108 m_curr_packet.setQType(false,0,false,false,0xF);
1110 m_process_state = SEND_PKT;
1115 void EtmV4IPktProcImpl::iAtom()
1117 // patterns lsbit = oldest atom, ms bit = newest.
1118 static const uint32_t f4_patterns[] = {
1125 uint8_t lastByte = m_currPacketData.back();
1126 uint8_t pattIdx = 0, pattCount = 0;
1129 // atom packets are single byte, no payload.
1130 switch(m_curr_packet.type)
1132 case ETM4_PKT_I_ATOM_F1:
1133 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x1), 1); // 1xE or N
1136 case ETM4_PKT_I_ATOM_F2:
1137 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x3), 2); // 2x (E or N)
1140 case ETM4_PKT_I_ATOM_F3:
1141 m_curr_packet.setAtomPacket(ATOM_PATTERN,(lastByte & 0x7), 3); // 3x (E or N)
1144 case ETM4_PKT_I_ATOM_F4:
1145 m_curr_packet.setAtomPacket(ATOM_PATTERN,f4_patterns[(lastByte & 0x3)], 4); // 4 atom pattern
1148 case ETM4_PKT_I_ATOM_F5:
1149 pattIdx = ((lastByte & 0x20) >> 3) | (lastByte & 0x3);
1153 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x1E, 5); // 5 atom pattern EEEEN
1157 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x00, 5); // 5 atom pattern NNNNN
1161 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x0A, 5); // 5 atom pattern NENEN
1165 m_curr_packet.setAtomPacket(ATOM_PATTERN,0x15, 5); // 5 atom pattern ENENE
1169 // TBD: warn about invalid pattern in here.
1174 case ETM4_PKT_I_ATOM_F6:
1175 pattCount = (lastByte & 0x1F) + 3; // count of E's
1176 // TBD: check 23 or less at this point?
1177 pattern = ((uint32_t)0x1 << pattCount) - 1; // set pattern to string of E's
1178 if((lastByte & 0x20) == 0x00) // last atom is E?
1179 pattern |= ((uint32_t)0x1 << pattCount);
1180 m_curr_packet.setAtomPacket(ATOM_PATTERN,pattern, pattCount+1);
1184 m_process_state = SEND_PKT;
1187 // header byte processing is table driven.
1188 void EtmV4IPktProcImpl::BuildIPacketTable()
1190 // initialise everything as reserved.
1191 for(int i = 0; i < 256; i++)
1193 m_i_table[i].pkt_type = ETM4_PKT_I_RESERVED;
1194 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iPktReserved;
1198 m_i_table[0x00].pkt_type = ETM4_PKT_I_EXTENSION;
1199 m_i_table[0x00].pptkFn = &EtmV4IPktProcImpl::iPktExtension;
1201 // 0x01 - Trace info
1202 m_i_table[0x01].pkt_type = ETM4_PKT_I_TRACE_INFO;
1203 m_i_table[0x01].pptkFn = &EtmV4IPktProcImpl::iPktTraceInfo;
1205 // b0000001x - timestamp
1206 m_i_table[0x02].pkt_type = ETM4_PKT_I_TIMESTAMP;
1207 m_i_table[0x02].pptkFn = &EtmV4IPktProcImpl::iPktTimestamp;
1208 m_i_table[0x03].pkt_type = ETM4_PKT_I_TIMESTAMP;
1209 m_i_table[0x03].pptkFn = &EtmV4IPktProcImpl::iPktTimestamp;
1211 // b0000 0100 - trace on
1212 m_i_table[0x04].pkt_type = ETM4_PKT_I_TRACE_ON;
1213 m_i_table[0x04].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1215 // b0000 0110 - exception
1216 m_i_table[0x06].pkt_type = ETM4_PKT_I_EXCEPT;
1217 m_i_table[0x06].pptkFn = &EtmV4IPktProcImpl::iPktException;
1219 // b0000 0111 - exception return
1220 m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN;
1221 m_i_table[0x07].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1223 // b0000 110x - cycle count f2
1224 // b0000 111x - cycle count f1
1225 for(int i = 0; i < 4; i++)
1227 m_i_table[0x0C+i].pkt_type = (i >= 2) ? ETM4_PKT_I_CCNT_F1 : ETM4_PKT_I_CCNT_F2;
1228 m_i_table[0x0C+i].pptkFn = &EtmV4IPktProcImpl::iPktCycleCntF123;
1231 // b0001 xxxx - cycle count f3
1232 for(int i = 0; i < 16; i++)
1234 m_i_table[0x10+i].pkt_type = ETM4_PKT_I_CCNT_F3;
1235 m_i_table[0x10+i].pptkFn = &EtmV4IPktProcImpl::iPktCycleCntF123;
1238 // b0010 0xxx - NDSM
1239 for(int i = 0; i < 8; i++)
1241 m_i_table[0x20+i].pkt_type = ETM4_PKT_I_NUM_DS_MKR;
1242 m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1245 // b0010 10xx, b0010 1100 - UDSM
1246 for(int i = 0; i < 5; i++)
1248 m_i_table[0x28+i].pkt_type = ETM4_PKT_I_UNNUM_DS_MKR;
1249 m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1252 // b0010 1101 - commit
1253 m_i_table[0x2D].pkt_type = ETM4_PKT_I_COMMIT;
1254 m_i_table[0x2D].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
1257 // b0010 111x - cancel f1
1258 for(int i = 0; i < 2; i++)
1260 // G++ doesn't understand [0x2E+i] so...
1262 m_i_table[idx].pkt_type = ETM4_PKT_I_CANCEL_F1;
1263 m_i_table[idx].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
1266 // b0011 00xx - mis predict
1267 for(int i = 0; i < 4; i++)
1269 m_i_table[0x30+i].pkt_type = ETM4_PKT_I_MISPREDICT;
1270 m_i_table[0x30+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
1273 // b0011 01xx - cancel f2
1274 for(int i = 0; i < 4; i++)
1276 m_i_table[0x34+i].pkt_type = ETM4_PKT_I_CANCEL_F2;
1277 m_i_table[0x34+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
1280 // b0011 1xxx - cancel f3
1281 for(int i = 0; i < 8; i++)
1283 m_i_table[0x38+i].pkt_type = ETM4_PKT_I_CANCEL_F3;
1284 m_i_table[0x38+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
1287 // b0100 000x, b0100 0010 - cond I f2
1288 for(int i = 0; i < 3; i++)
1290 m_i_table[0x40+i].pkt_type = ETM4_PKT_I_COND_I_F2;
1291 m_i_table[0x40+i].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
1294 // b0100 0011 - cond flush
1295 m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH;
1296 m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1298 // b0100 010x, b0100 0110 - cond res f4
1299 for(int i = 0; i < 3; i++)
1301 m_i_table[0x44+i].pkt_type = ETM4_PKT_I_COND_RES_F4;
1302 m_i_table[0x44+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1305 // b0100 100x, b0100 0110 - cond res f2
1306 // b0100 110x, b0100 1110 - cond res f2
1307 for(int i = 0; i < 3; i++)
1309 m_i_table[0x48+i].pkt_type = ETM4_PKT_I_COND_RES_F2;
1310 m_i_table[0x48+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1312 for(int i = 0; i < 3; i++)
1314 m_i_table[0x4C+i].pkt_type = ETM4_PKT_I_COND_RES_F2;
1315 m_i_table[0x4C+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1318 // b0101xxxx - cond res f3
1319 for(int i = 0; i < 16; i++)
1321 m_i_table[0x50+i].pkt_type = ETM4_PKT_I_COND_RES_F3;
1322 m_i_table[0x50+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1325 // b011010xx - cond res f1
1326 for(int i = 0; i < 4; i++)
1328 m_i_table[0x68+i].pkt_type = ETM4_PKT_I_COND_RES_F1;
1329 m_i_table[0x68+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1332 // b0110 1100 - cond instr f1
1333 m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1;
1334 m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
1336 // b0110 1101 - cond instr f3
1337 m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3;
1338 m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr;
1340 // b0110111x - cond res f1
1341 for(int i = 0; i < 2; i++)
1343 // G++ cannot understand [0x6E+i] so change these round
1344 m_i_table[i+0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1;
1345 m_i_table[i+0x6E].pptkFn = &EtmV4IPktProcImpl::iPktCondResult;
1348 // b01110001 - b01111111 - cond res f1
1349 for(int i = 0; i < 15; i++)
1351 m_i_table[0x71+i].pkt_type = ETM4_PKT_I_EVENT;
1352 m_i_table[0x71+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1355 // 0b1000 000x - context
1356 for(int i = 0; i < 2; i++)
1358 m_i_table[0x80+i].pkt_type = ETM4_PKT_I_CTXT;
1359 m_i_table[0x80+i].pptkFn = &EtmV4IPktProcImpl::iPktContext;
1362 // 0b1000 0010 to b1000 0011 - addr with ctxt
1363 // 0b1000 0101 to b1000 0110 - addr with ctxt
1364 for(int i = 0; i < 2; i++)
1366 m_i_table[0x82+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_32IS0 : ETM4_PKT_I_ADDR_CTXT_L_32IS1;
1367 m_i_table[0x82+i].pptkFn = &EtmV4IPktProcImpl::iPktAddrCtxt;
1370 for(int i = 0; i < 2; i++)
1372 m_i_table[0x85+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_CTXT_L_64IS0 : ETM4_PKT_I_ADDR_CTXT_L_64IS1;
1373 m_i_table[0x85+i].pptkFn = &EtmV4IPktProcImpl::iPktAddrCtxt;
1376 // 0b1001 0000 to b1001 0010 - exact match addr
1377 for(int i = 0; i < 3; i++)
1379 m_i_table[0x90+i].pkt_type = ETM4_PKT_I_ADDR_MATCH;
1380 m_i_table[0x90+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
1383 // b1001 0101 - b1001 0110 - addr short address
1384 for(int i = 0; i < 2; i++)
1386 m_i_table[0x95+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_S_IS0 : ETM4_PKT_I_ADDR_S_IS1;
1387 m_i_table[0x95+i].pptkFn = &EtmV4IPktProcImpl::iPktShortAddr;
1390 // b10011010 - b10011011 - addr long address
1391 // b10011101 - b10011110 - addr long address
1392 for(int i = 0; i < 2; i++)
1394 m_i_table[0x9A+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_32IS0 : ETM4_PKT_I_ADDR_L_32IS1;
1395 m_i_table[0x9A+i].pptkFn = &EtmV4IPktProcImpl::iPktLongAddr;
1397 for(int i = 0; i < 2; i++)
1399 m_i_table[0x9D+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_64IS0 : ETM4_PKT_I_ADDR_L_64IS1;
1400 m_i_table[0x9D+i].pptkFn = &EtmV4IPktProcImpl::iPktLongAddr;
1403 // b1010xxxx - Q packet
1404 for(int i = 0; i < 16; i++)
1406 m_i_table[0xA0+i].pkt_type = ETM4_PKT_I_Q;
1407 m_i_table[0xA0+i].pptkFn = &EtmV4IPktProcImpl::iPktQ;
1410 // Atom Packets - all no payload but have specific pattern generation fn
1411 for(int i = 0xC0; i <= 0xD4; i++) // atom f6
1413 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6;
1414 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1416 for(int i = 0xD5; i <= 0xD7; i++) // atom f5
1418 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F5;
1419 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1421 for(int i = 0xD8; i <= 0xDB; i++) // atom f2
1423 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F2;
1424 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1426 for(int i = 0xDC; i <= 0xDF; i++) // atom f4
1428 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F4;
1429 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1431 for(int i = 0xE0; i <= 0xF4; i++) // atom f6
1433 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F6;
1434 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1438 m_i_table[0xF5].pkt_type = ETM4_PKT_I_ATOM_F5;
1439 m_i_table[0xF5].pptkFn = &EtmV4IPktProcImpl::iAtom;
1441 for(int i = 0xF6; i <= 0xF7; i++) // atom f1
1443 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F1;
1444 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1446 for(int i = 0xF8; i <= 0xFF; i++) // atom f3
1448 m_i_table[i].pkt_type = ETM4_PKT_I_ATOM_F3;
1449 m_i_table[i].pptkFn = &EtmV4IPktProcImpl::iAtom;
1453 unsigned EtmV4IPktProcImpl::extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit /*= 5*/)
1456 bool lastByte = false;
1459 while(!lastByte && (idx < byte_limit)) // max 5 bytes for 32 bit value;
1461 if(buffer.size() > (st_idx + idx))
1463 // each byte has seven bits + cont bit
1464 byteVal = buffer[(st_idx + idx)];
1465 lastByte = (byteVal & 0x80) != 0x80;
1466 value |= ((uint32_t)(byteVal & 0x7F)) << (idx * 7);
1471 throwBadSequenceError("Invalid 32 bit continuation fields in packet");
1477 unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit /*= 9*/)
1480 bool lastByte = false;
1483 while(!lastByte && (idx < byte_limit)) // max 9 bytes for 64 bit value;
1485 if(buffer.size() > (st_idx + idx))
1487 // each byte has seven bits + cont bit
1488 byteVal = buffer[(st_idx + idx)];
1489 lastByte = (byteVal & 0x80) != 0x80;
1490 value |= ((uint64_t)(byteVal & 0x7F)) << (idx * 7);
1495 throwBadSequenceError("Invalid 64 bit continuation fields in packet");
1501 unsigned EtmV4IPktProcImpl::extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result)
1504 bool lastByte = false;
1509 while(!lastByte && (idx < 6)) // cannot be more than 6 bytes for res + 32 bit key
1511 if(buffer.size() > (st_idx + idx))
1515 result = buffer[st_idx+idx];
1516 key = (buffer[st_idx+idx] >> 4) & 0x7;
1521 key |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << incr;
1524 lastByte = (bool)((buffer[st_idx+idx] & 0x80) == 0);
1529 throwBadSequenceError("Invalid continuation fields in packet");
1535 int EtmV4IPktProcImpl::extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value)
1540 value |= ((uint64_t)(buffer[st_idx+0] & 0x7F)) << 2;
1541 value |= ((uint64_t)(buffer[st_idx+1] & 0x7F)) << 9;
1545 value |= ((uint64_t)(buffer[st_idx+0] & 0x7F)) << 1;
1546 value |= ((uint64_t)buffer[st_idx+1]) << 8;
1548 value |= ((uint64_t)buffer[st_idx+2]) << 16;
1549 value |= ((uint64_t)buffer[st_idx+3]) << 24;
1550 value |= ((uint64_t)buffer[st_idx+4]) << 32;
1551 value |= ((uint64_t)buffer[st_idx+5]) << 40;
1552 value |= ((uint64_t)buffer[st_idx+6]) << 48;
1553 value |= ((uint64_t)buffer[st_idx+7]) << 56;
1557 int EtmV4IPktProcImpl::extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value)
1562 value |= ((uint32_t)(buffer[st_idx+0] & 0x7F)) << 2;
1563 value |= ((uint32_t)(buffer[st_idx+1] & 0x7F)) << 9;
1567 value |= ((uint32_t)(buffer[st_idx+0] & 0x7F)) << 1;
1568 value |= ((uint32_t)buffer[st_idx+1]) << 8;
1570 value |= ((uint32_t)buffer[st_idx+2]) << 16;
1571 value |= ((uint32_t)buffer[st_idx+3]) << 24;
1575 void EtmV4IPktProcImpl::throwBadSequenceError(const char *pszExtMsg)
1577 m_curr_packet.updateErrType(ETM4_PKT_I_BAD_SEQUENCE); // swap type for err type
1578 throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_BAD_PACKET_SEQ,m_packet_index,m_config.getTraceID(),pszExtMsg);
1582 /* End of File trc_pkt_proc_etmv4i_impl.cpp */