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