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