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