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