1*c120c564SAndrew Turner /*
2*c120c564SAndrew Turner * \file trc_pkt_proc_etmv3_impl.cpp
3*c120c564SAndrew Turner * \brief OpenCSD :
4*c120c564SAndrew Turner *
5*c120c564SAndrew Turner * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved.
6*c120c564SAndrew Turner */
7*c120c564SAndrew Turner
8*c120c564SAndrew Turner /*
9*c120c564SAndrew Turner * Redistribution and use in source and binary forms, with or without modification,
10*c120c564SAndrew Turner * are permitted provided that the following conditions are met:
11*c120c564SAndrew Turner *
12*c120c564SAndrew Turner * 1. Redistributions of source code must retain the above copyright notice,
13*c120c564SAndrew Turner * this list of conditions and the following disclaimer.
14*c120c564SAndrew Turner *
15*c120c564SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright notice,
16*c120c564SAndrew Turner * this list of conditions and the following disclaimer in the documentation
17*c120c564SAndrew Turner * and/or other materials provided with the distribution.
18*c120c564SAndrew Turner *
19*c120c564SAndrew Turner * 3. Neither the name of the copyright holder nor the names of its contributors
20*c120c564SAndrew Turner * may be used to endorse or promote products derived from this software without
21*c120c564SAndrew Turner * specific prior written permission.
22*c120c564SAndrew Turner *
23*c120c564SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24*c120c564SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25*c120c564SAndrew Turner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26*c120c564SAndrew Turner * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27*c120c564SAndrew Turner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28*c120c564SAndrew Turner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29*c120c564SAndrew Turner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30*c120c564SAndrew Turner * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*c120c564SAndrew Turner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*c120c564SAndrew Turner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*c120c564SAndrew Turner */
34*c120c564SAndrew Turner
35*c120c564SAndrew Turner #include "trc_pkt_proc_etmv3_impl.h"
36*c120c564SAndrew Turner
EtmV3PktProcImpl()37*c120c564SAndrew Turner EtmV3PktProcImpl::EtmV3PktProcImpl() :
38*c120c564SAndrew Turner m_isInit(false),
39*c120c564SAndrew Turner m_interface(0)
40*c120c564SAndrew Turner {
41*c120c564SAndrew Turner }
42*c120c564SAndrew Turner
~EtmV3PktProcImpl()43*c120c564SAndrew Turner EtmV3PktProcImpl::~EtmV3PktProcImpl()
44*c120c564SAndrew Turner {
45*c120c564SAndrew Turner }
46*c120c564SAndrew Turner
Configure(const EtmV3Config * p_config)47*c120c564SAndrew Turner ocsd_err_t EtmV3PktProcImpl::Configure(const EtmV3Config *p_config)
48*c120c564SAndrew Turner {
49*c120c564SAndrew Turner ocsd_err_t err = OCSD_OK;
50*c120c564SAndrew Turner if(p_config != 0)
51*c120c564SAndrew Turner {
52*c120c564SAndrew Turner m_config = *p_config;
53*c120c564SAndrew Turner m_chanIDCopy = m_config.getTraceID();
54*c120c564SAndrew Turner }
55*c120c564SAndrew Turner else
56*c120c564SAndrew Turner {
57*c120c564SAndrew Turner err = OCSD_ERR_INVALID_PARAM_VAL;
58*c120c564SAndrew Turner if(m_isInit)
59*c120c564SAndrew Turner m_interface->LogError(ocsdError(OCSD_ERR_SEV_ERROR,err));
60*c120c564SAndrew Turner }
61*c120c564SAndrew Turner return err;
62*c120c564SAndrew Turner }
63*c120c564SAndrew Turner
processData(const ocsd_trc_index_t index,const uint32_t dataBlockSize,const uint8_t * pDataBlock,uint32_t * numBytesProcessed)64*c120c564SAndrew Turner ocsd_datapath_resp_t EtmV3PktProcImpl::processData(const ocsd_trc_index_t index,
65*c120c564SAndrew Turner const uint32_t dataBlockSize,
66*c120c564SAndrew Turner const uint8_t *pDataBlock,
67*c120c564SAndrew Turner uint32_t *numBytesProcessed)
68*c120c564SAndrew Turner {
69*c120c564SAndrew Turner ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
70*c120c564SAndrew Turner m_bytesProcessed = 0;
71*c120c564SAndrew Turner
72*c120c564SAndrew Turner while( ( (m_bytesProcessed < dataBlockSize) ||
73*c120c564SAndrew Turner ((m_bytesProcessed == dataBlockSize) && (m_process_state == SEND_PKT)) )
74*c120c564SAndrew Turner && OCSD_DATA_RESP_IS_CONT(resp))
75*c120c564SAndrew Turner {
76*c120c564SAndrew Turner try
77*c120c564SAndrew Turner {
78*c120c564SAndrew Turner switch(m_process_state)
79*c120c564SAndrew Turner {
80*c120c564SAndrew Turner case WAIT_SYNC:
81*c120c564SAndrew Turner if(!m_bStartOfSync)
82*c120c564SAndrew Turner m_packet_index = index + m_bytesProcessed;
83*c120c564SAndrew Turner m_bytesProcessed += waitForSync(dataBlockSize-m_bytesProcessed,pDataBlock+m_bytesProcessed);
84*c120c564SAndrew Turner break;
85*c120c564SAndrew Turner
86*c120c564SAndrew Turner case PROC_HDR:
87*c120c564SAndrew Turner m_packet_index = index + m_bytesProcessed;
88*c120c564SAndrew Turner processHeaderByte(pDataBlock[m_bytesProcessed++]);
89*c120c564SAndrew Turner break;
90*c120c564SAndrew Turner
91*c120c564SAndrew Turner case PROC_DATA:
92*c120c564SAndrew Turner processPayloadByte(pDataBlock [m_bytesProcessed++]);
93*c120c564SAndrew Turner break;
94*c120c564SAndrew Turner
95*c120c564SAndrew Turner case SEND_PKT:
96*c120c564SAndrew Turner resp = outputPacket();
97*c120c564SAndrew Turner break;
98*c120c564SAndrew Turner }
99*c120c564SAndrew Turner }
100*c120c564SAndrew Turner catch(ocsdError &err)
101*c120c564SAndrew Turner {
102*c120c564SAndrew Turner m_interface->LogError(err);
103*c120c564SAndrew Turner if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) ||
104*c120c564SAndrew Turner (err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR))
105*c120c564SAndrew Turner {
106*c120c564SAndrew Turner // send invalid packets up the pipe to let the next stage decide what to do.
107*c120c564SAndrew Turner m_process_state = SEND_PKT;
108*c120c564SAndrew Turner }
109*c120c564SAndrew Turner else
110*c120c564SAndrew Turner {
111*c120c564SAndrew Turner // bail out on any other error.
112*c120c564SAndrew Turner resp = OCSD_RESP_FATAL_INVALID_DATA;
113*c120c564SAndrew Turner }
114*c120c564SAndrew Turner }
115*c120c564SAndrew Turner catch(...)
116*c120c564SAndrew Turner {
117*c120c564SAndrew Turner /// vv bad at this point.
118*c120c564SAndrew Turner resp = OCSD_RESP_FATAL_SYS_ERR;
119*c120c564SAndrew Turner ocsdError fatal = ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_packet_index,m_chanIDCopy);
120*c120c564SAndrew Turner fatal.setMessage("Unknown System Error decoding trace.");
121*c120c564SAndrew Turner m_interface->LogError(fatal);
122*c120c564SAndrew Turner }
123*c120c564SAndrew Turner }
124*c120c564SAndrew Turner
125*c120c564SAndrew Turner *numBytesProcessed = m_bytesProcessed;
126*c120c564SAndrew Turner return resp;
127*c120c564SAndrew Turner }
128*c120c564SAndrew Turner
onEOT()129*c120c564SAndrew Turner ocsd_datapath_resp_t EtmV3PktProcImpl::onEOT()
130*c120c564SAndrew Turner {
131*c120c564SAndrew Turner ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
132*c120c564SAndrew Turner // if we have a partial packet then send to attached sinks
133*c120c564SAndrew Turner if(m_currPacketData.size() != 0)
134*c120c564SAndrew Turner {
135*c120c564SAndrew Turner // TBD: m_curr_packet.updateErrType(ETM4_ETM3_PKT_I_INCOMPLETE_EOT);
136*c120c564SAndrew Turner resp = outputPacket();
137*c120c564SAndrew Turner InitPacketState();
138*c120c564SAndrew Turner }
139*c120c564SAndrew Turner return resp;
140*c120c564SAndrew Turner }
141*c120c564SAndrew Turner
onReset()142*c120c564SAndrew Turner ocsd_datapath_resp_t EtmV3PktProcImpl::onReset()
143*c120c564SAndrew Turner {
144*c120c564SAndrew Turner InitProcessorState();
145*c120c564SAndrew Turner return OCSD_RESP_CONT;
146*c120c564SAndrew Turner }
147*c120c564SAndrew Turner
onFlush()148*c120c564SAndrew Turner ocsd_datapath_resp_t EtmV3PktProcImpl::onFlush()
149*c120c564SAndrew Turner {
150*c120c564SAndrew Turner // packet processor never holds on to flushable data (may have partial packet,
151*c120c564SAndrew Turner // but any full packets are immediately sent)
152*c120c564SAndrew Turner return OCSD_RESP_CONT;
153*c120c564SAndrew Turner }
154*c120c564SAndrew Turner
Initialise(TrcPktProcEtmV3 * p_interface)155*c120c564SAndrew Turner void EtmV3PktProcImpl::Initialise(TrcPktProcEtmV3 *p_interface)
156*c120c564SAndrew Turner {
157*c120c564SAndrew Turner if(p_interface)
158*c120c564SAndrew Turner {
159*c120c564SAndrew Turner m_interface = p_interface;
160*c120c564SAndrew Turner m_isInit = true;
161*c120c564SAndrew Turner
162*c120c564SAndrew Turner }
163*c120c564SAndrew Turner InitProcessorState();
164*c120c564SAndrew Turner /* not using pattern matcher for sync at present
165*c120c564SAndrew Turner static const uint8_t a_sync[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 };
166*c120c564SAndrew Turner m_syncMatch.setPattern(a_sync, sizeof(a_sync));*/
167*c120c564SAndrew Turner }
168*c120c564SAndrew Turner
InitProcessorState()169*c120c564SAndrew Turner void EtmV3PktProcImpl::InitProcessorState()
170*c120c564SAndrew Turner {
171*c120c564SAndrew Turner m_bStreamSync = false; // not synced
172*c120c564SAndrew Turner m_process_state = WAIT_SYNC; // waiting for sync
173*c120c564SAndrew Turner m_bStartOfSync = false; // not seen start of sync packet
174*c120c564SAndrew Turner m_curr_packet.ResetState(); // reset intra packet state
175*c120c564SAndrew Turner InitPacketState(); // set curr packet state
176*c120c564SAndrew Turner m_bSendPartPkt = false;
177*c120c564SAndrew Turner }
178*c120c564SAndrew Turner
InitPacketState()179*c120c564SAndrew Turner void EtmV3PktProcImpl::InitPacketState()
180*c120c564SAndrew Turner {
181*c120c564SAndrew Turner m_bytesExpectedThisPkt = 0;
182*c120c564SAndrew Turner m_BranchPktNeedsException = false;
183*c120c564SAndrew Turner m_bIsync_got_cycle_cnt = false;
184*c120c564SAndrew Turner m_bIsync_get_LSiP_addr = false;
185*c120c564SAndrew Turner m_IsyncInfoIdx = false;
186*c120c564SAndrew Turner m_bExpectingDataAddress = false;
187*c120c564SAndrew Turner m_bFoundDataAddress = false;
188*c120c564SAndrew Turner m_currPacketData.clear();
189*c120c564SAndrew Turner m_currPktIdx = 0; // index into processed bytes in current packet
190*c120c564SAndrew Turner m_curr_packet.Clear();
191*c120c564SAndrew Turner
192*c120c564SAndrew Turner }
193*c120c564SAndrew Turner
outputPacket()194*c120c564SAndrew Turner ocsd_datapath_resp_t EtmV3PktProcImpl::outputPacket()
195*c120c564SAndrew Turner {
196*c120c564SAndrew Turner ocsd_datapath_resp_t dp_resp = OCSD_RESP_FATAL_NOT_INIT;
197*c120c564SAndrew Turner if(m_isInit)
198*c120c564SAndrew Turner {
199*c120c564SAndrew Turner ocsd_etmv3_pkt_type type = m_curr_packet.getType();
200*c120c564SAndrew Turner if(!m_bSendPartPkt)
201*c120c564SAndrew Turner {
202*c120c564SAndrew Turner dp_resp = m_interface->outputOnAllInterfaces(m_packet_index,&m_curr_packet,&type,m_currPacketData);
203*c120c564SAndrew Turner m_process_state = m_bStreamSync ? PROC_HDR : WAIT_SYNC; // need a header next time, or still waiting to sync.
204*c120c564SAndrew Turner m_currPacketData.clear();
205*c120c564SAndrew Turner }
206*c120c564SAndrew Turner else
207*c120c564SAndrew Turner {
208*c120c564SAndrew Turner // sending part packet, still some data in the main packet
209*c120c564SAndrew Turner dp_resp = m_interface->outputOnAllInterfaces(m_packet_index,&m_curr_packet,&type,m_partPktData);
210*c120c564SAndrew Turner m_process_state = m_post_part_pkt_state;
211*c120c564SAndrew Turner m_packet_index += m_partPktData.size();
212*c120c564SAndrew Turner m_bSendPartPkt = false;
213*c120c564SAndrew Turner m_curr_packet.SetType(m_post_part_pkt_type);
214*c120c564SAndrew Turner }
215*c120c564SAndrew Turner }
216*c120c564SAndrew Turner return dp_resp;
217*c120c564SAndrew Turner }
218*c120c564SAndrew Turner
setBytesPartPkt(int numBytes,process_state nextState,const ocsd_etmv3_pkt_type nextType)219*c120c564SAndrew Turner void EtmV3PktProcImpl::setBytesPartPkt(int numBytes, process_state nextState, const ocsd_etmv3_pkt_type nextType)
220*c120c564SAndrew Turner {
221*c120c564SAndrew Turner m_partPktData.clear();
222*c120c564SAndrew Turner for(int i=0; i < numBytes; i++)
223*c120c564SAndrew Turner {
224*c120c564SAndrew Turner m_partPktData.push_back(m_currPacketData[i]);
225*c120c564SAndrew Turner }
226*c120c564SAndrew Turner m_currPacketData.erase(m_currPacketData.begin(), m_currPacketData.begin()+numBytes);
227*c120c564SAndrew Turner m_bSendPartPkt = true;
228*c120c564SAndrew Turner m_post_part_pkt_state = nextState;
229*c120c564SAndrew Turner m_post_part_pkt_type = nextType;
230*c120c564SAndrew Turner }
231*c120c564SAndrew Turner
waitForSync(const uint32_t dataBlockSize,const uint8_t * pDataBlock)232*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::waitForSync(const uint32_t dataBlockSize, const uint8_t *pDataBlock)
233*c120c564SAndrew Turner {
234*c120c564SAndrew Turner uint8_t currByte;
235*c120c564SAndrew Turner uint32_t bytesProcessed = 0;
236*c120c564SAndrew Turner bool bSendBlock = false;
237*c120c564SAndrew Turner
238*c120c564SAndrew Turner // need to wait for the first sync packet
239*c120c564SAndrew Turner while(!bSendBlock && (bytesProcessed < dataBlockSize))
240*c120c564SAndrew Turner {
241*c120c564SAndrew Turner currByte = pDataBlock[bytesProcessed++];
242*c120c564SAndrew Turner // TBD: forced sync point
243*c120c564SAndrew Turner
244*c120c564SAndrew Turner if(m_bStartOfSync)
245*c120c564SAndrew Turner {
246*c120c564SAndrew Turner // need to handle consecutive 0 bytes followed by genuine A-SYNC.
247*c120c564SAndrew Turner
248*c120c564SAndrew Turner m_currPacketData.push_back(currByte);
249*c120c564SAndrew Turner if((currByte == 0x80) && (m_currPacketData.size() >= 6))
250*c120c564SAndrew Turner {
251*c120c564SAndrew Turner // it is a sync packet possibly with leading zeros
252*c120c564SAndrew Turner bSendBlock = true;
253*c120c564SAndrew Turner if(m_currPacketData.size() > 6)
254*c120c564SAndrew Turner {
255*c120c564SAndrew Turner m_currPacketData.pop_back();
256*c120c564SAndrew Turner bytesProcessed--; // return 0x80 to the input buffer to re-process next pass after stripping 0's
257*c120c564SAndrew Turner setBytesPartPkt(m_currPacketData.size()-5,WAIT_SYNC,ETM3_PKT_NOTSYNC);
258*c120c564SAndrew Turner }
259*c120c564SAndrew Turner else
260*c120c564SAndrew Turner {
261*c120c564SAndrew Turner m_bStreamSync = true;
262*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_A_SYNC);
263*c120c564SAndrew Turner }
264*c120c564SAndrew Turner }
265*c120c564SAndrew Turner else if(currByte != 0x00)
266*c120c564SAndrew Turner {
267*c120c564SAndrew Turner m_bStartOfSync = false; // not a sync packet
268*c120c564SAndrew Turner }
269*c120c564SAndrew Turner else if(m_currPacketData.size() >= 13) // 13 0's, strip 8 of them...
270*c120c564SAndrew Turner {
271*c120c564SAndrew Turner setBytesPartPkt(8,WAIT_SYNC,ETM3_PKT_NOTSYNC);
272*c120c564SAndrew Turner bSendBlock = true;
273*c120c564SAndrew Turner }
274*c120c564SAndrew Turner }
275*c120c564SAndrew Turner else // not seen a start of sync candidate yet
276*c120c564SAndrew Turner {
277*c120c564SAndrew Turner if(currByte == 0x00) // could be the start of a-sync
278*c120c564SAndrew Turner {
279*c120c564SAndrew Turner if(m_currPacketData.size() == 0)
280*c120c564SAndrew Turner {
281*c120c564SAndrew Turner m_currPacketData.push_back(currByte);
282*c120c564SAndrew Turner m_bStartOfSync = true;
283*c120c564SAndrew Turner }
284*c120c564SAndrew Turner else
285*c120c564SAndrew Turner {
286*c120c564SAndrew Turner bytesProcessed--;
287*c120c564SAndrew Turner bSendBlock = true; // send none sync packet data, re-process this byte next time.
288*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_NOTSYNC); // send unsynced data packet.
289*c120c564SAndrew Turner }
290*c120c564SAndrew Turner }
291*c120c564SAndrew Turner else
292*c120c564SAndrew Turner {
293*c120c564SAndrew Turner //save a byte - not start of a-sync
294*c120c564SAndrew Turner m_currPacketData.push_back(currByte);
295*c120c564SAndrew Turner
296*c120c564SAndrew Turner // done all data in this block, or got 16 unsynced bytes
297*c120c564SAndrew Turner if((bytesProcessed == dataBlockSize) || (m_currPacketData.size() == 16))
298*c120c564SAndrew Turner {
299*c120c564SAndrew Turner bSendBlock = true; // send none sync packet block
300*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_NOTSYNC); // send unsynced data packet.
301*c120c564SAndrew Turner }
302*c120c564SAndrew Turner }
303*c120c564SAndrew Turner }
304*c120c564SAndrew Turner }
305*c120c564SAndrew Turner if(bSendBlock)
306*c120c564SAndrew Turner SendPacket();
307*c120c564SAndrew Turner return bytesProcessed;
308*c120c564SAndrew Turner }
309*c120c564SAndrew Turner
processHeaderByte(uint8_t by)310*c120c564SAndrew Turner ocsd_err_t EtmV3PktProcImpl::processHeaderByte(uint8_t by)
311*c120c564SAndrew Turner {
312*c120c564SAndrew Turner InitPacketState(); // new packet, clear old single packet state (retains intra packet state).
313*c120c564SAndrew Turner
314*c120c564SAndrew Turner // save byte
315*c120c564SAndrew Turner m_currPacketData.push_back(by);
316*c120c564SAndrew Turner
317*c120c564SAndrew Turner m_process_state = PROC_DATA; // assume next is data packet
318*c120c564SAndrew Turner
319*c120c564SAndrew Turner // check for branch address 0bCxxxxxxx1
320*c120c564SAndrew Turner if((by & 0x01) == 0x01 ) {
321*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_BRANCH_ADDRESS);
322*c120c564SAndrew Turner m_BranchPktNeedsException = false;
323*c120c564SAndrew Turner if((by & 0x80) != 0x80) {
324*c120c564SAndrew Turner // no continuation - 1 byte branch same in alt and std...
325*c120c564SAndrew Turner if((by == 0x01) && (m_interface->getComponentOpMode() & ETMV3_OPFLG_UNFORMATTED_SOURCE))
326*c120c564SAndrew Turner {
327*c120c564SAndrew Turner // TBD: need to fix up for handling bypassed ETM stream at some point.
328*c120c564SAndrew Turner throwUnsupportedErr("Bypassed ETM stream not supported in this version of the decoder.");
329*c120c564SAndrew Turner // could be EOTrace marker from bypassed formatter
330*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_BRANCH_OR_BYPASS_EOT);
331*c120c564SAndrew Turner }
332*c120c564SAndrew Turner else
333*c120c564SAndrew Turner {
334*c120c564SAndrew Turner OnBranchAddress();
335*c120c564SAndrew Turner SendPacket(); // mark ready to send.
336*c120c564SAndrew Turner }
337*c120c564SAndrew Turner }
338*c120c564SAndrew Turner }
339*c120c564SAndrew Turner // check for p-header - 0b1xxxxxx0
340*c120c564SAndrew Turner else if((by & 0x81) == 0x80) {
341*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_P_HDR);
342*c120c564SAndrew Turner if(m_curr_packet.UpdateAtomFromPHdr(by,m_config.isCycleAcc()))
343*c120c564SAndrew Turner SendPacket();
344*c120c564SAndrew Turner else
345*c120c564SAndrew Turner throwPacketHeaderErr("Invalid P-Header.");
346*c120c564SAndrew Turner }
347*c120c564SAndrew Turner // check 0b0000xx00 group
348*c120c564SAndrew Turner else if((by & 0xF3) == 0x00) {
349*c120c564SAndrew Turner
350*c120c564SAndrew Turner // A-Sync
351*c120c564SAndrew Turner if(by == 0x00) {
352*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_A_SYNC);
353*c120c564SAndrew Turner }
354*c120c564SAndrew Turner // cycle count
355*c120c564SAndrew Turner else if(by == 0x04) {
356*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_CYCLE_COUNT);
357*c120c564SAndrew Turner }
358*c120c564SAndrew Turner // I-Sync
359*c120c564SAndrew Turner else if(by == 0x08) {
360*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_I_SYNC);
361*c120c564SAndrew Turner m_bIsync_got_cycle_cnt = false;
362*c120c564SAndrew Turner m_bIsync_get_LSiP_addr = false;
363*c120c564SAndrew Turner }
364*c120c564SAndrew Turner // trigger
365*c120c564SAndrew Turner else if(by == 0x0C) {
366*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_TRIGGER);
367*c120c564SAndrew Turner // no payload - just send it.
368*c120c564SAndrew Turner SendPacket();
369*c120c564SAndrew Turner }
370*c120c564SAndrew Turner }
371*c120c564SAndrew Turner // check remaining 0bxxxxxx00 codes
372*c120c564SAndrew Turner else if((by & 0x03 )== 0x00) {
373*c120c564SAndrew Turner // OoO data 0b0xx0xx00
374*c120c564SAndrew Turner if((by & 0x93 )== 0x00) {
375*c120c564SAndrew Turner if(!m_config.isDataValTrace()) {
376*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
377*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (out of order data) - not tracing data values.");
378*c120c564SAndrew Turner }
379*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_OOO_DATA);
380*c120c564SAndrew Turner uint8_t size = ((by & 0x0C) >> 2);
381*c120c564SAndrew Turner // header contains a count of the data to follow
382*c120c564SAndrew Turner // size 3 == 4 bytes, other sizes == size bytes
383*c120c564SAndrew Turner if(size == 0)
384*c120c564SAndrew Turner {
385*c120c564SAndrew Turner m_curr_packet.SetDataOOOTag((by >> 5) & 0x3);
386*c120c564SAndrew Turner m_curr_packet.SetDataValue(0);
387*c120c564SAndrew Turner SendPacket();
388*c120c564SAndrew Turner }
389*c120c564SAndrew Turner else
390*c120c564SAndrew Turner m_bytesExpectedThisPkt = (short)(1 + ((size == 3) ? 4 : size));
391*c120c564SAndrew Turner }
392*c120c564SAndrew Turner // I-Sync + cycle count
393*c120c564SAndrew Turner else if(by == 0x70) {
394*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_I_SYNC_CYCLE);
395*c120c564SAndrew Turner m_bIsync_got_cycle_cnt = false;
396*c120c564SAndrew Turner m_bIsync_get_LSiP_addr = false;
397*c120c564SAndrew Turner }
398*c120c564SAndrew Turner // store failed
399*c120c564SAndrew Turner else if(by == 0x50) {
400*c120c564SAndrew Turner if(!m_config.isDataValTrace())
401*c120c564SAndrew Turner {
402*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
403*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (store failed) - not tracing data values.");
404*c120c564SAndrew Turner }
405*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_STORE_FAIL);
406*c120c564SAndrew Turner SendPacket();
407*c120c564SAndrew Turner }
408*c120c564SAndrew Turner // OoO placeholder 0b01x1xx00
409*c120c564SAndrew Turner else if((by & 0xD3 )== 0x50) {
410*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_OOO_ADDR_PLC);
411*c120c564SAndrew Turner if(!m_config.isDataTrace())
412*c120c564SAndrew Turner {
413*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
414*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (out of order placeholder) - not tracing data.");
415*c120c564SAndrew Turner }
416*c120c564SAndrew Turner // expecting data address if flagged and address tracing enabled (flag can be set even if address tracing disabled)
417*c120c564SAndrew Turner m_bExpectingDataAddress = ((by & DATA_ADDR_EXPECTED_FLAG) == DATA_ADDR_EXPECTED_FLAG) && m_config.isDataAddrTrace();
418*c120c564SAndrew Turner m_bFoundDataAddress = false;
419*c120c564SAndrew Turner m_curr_packet.SetDataOOOTag((by >> 2) & 0x3);
420*c120c564SAndrew Turner if(!m_bExpectingDataAddress) {
421*c120c564SAndrew Turner SendPacket();
422*c120c564SAndrew Turner }
423*c120c564SAndrew Turner }
424*c120c564SAndrew Turner // vmid 0b00111100
425*c120c564SAndrew Turner else if(by == 0x3c) {
426*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_VMID);
427*c120c564SAndrew Turner }
428*c120c564SAndrew Turner else
429*c120c564SAndrew Turner {
430*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_RESERVED);
431*c120c564SAndrew Turner throwPacketHeaderErr("Packet header reserved encoding");
432*c120c564SAndrew Turner }
433*c120c564SAndrew Turner }
434*c120c564SAndrew Turner // normal data 0b00x0xx10
435*c120c564SAndrew Turner else if((by & 0xD3 )== 0x02) {
436*c120c564SAndrew Turner uint8_t size = ((by & 0x0C) >> 2);
437*c120c564SAndrew Turner if(!m_config.isDataTrace()) {
438*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
439*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (normal data) - not tracing data.");
440*c120c564SAndrew Turner }
441*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_NORM_DATA);
442*c120c564SAndrew Turner m_bExpectingDataAddress = ((by & DATA_ADDR_EXPECTED_FLAG) == DATA_ADDR_EXPECTED_FLAG) && m_config.isDataAddrTrace();
443*c120c564SAndrew Turner m_bFoundDataAddress = false;
444*c120c564SAndrew Turner
445*c120c564SAndrew Turner // set this with the data bytes expected this packet, plus the header byte.
446*c120c564SAndrew Turner m_bytesExpectedThisPkt = (short)( 1 + ((size == 3) ? 4 : size));
447*c120c564SAndrew Turner if(!m_bExpectingDataAddress && (m_bytesExpectedThisPkt == 1)) {
448*c120c564SAndrew Turner // single byte data packet, value = 0;
449*c120c564SAndrew Turner m_curr_packet.SetDataValue(0);
450*c120c564SAndrew Turner SendPacket();
451*c120c564SAndrew Turner }
452*c120c564SAndrew Turner
453*c120c564SAndrew Turner }
454*c120c564SAndrew Turner // data suppressed 0b01100010
455*c120c564SAndrew Turner else if(by == 0x62) {
456*c120c564SAndrew Turner if(!m_config.isDataTrace())
457*c120c564SAndrew Turner {
458*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
459*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (data suppressed) - not tracing data.");
460*c120c564SAndrew Turner }
461*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_DATA_SUPPRESSED);
462*c120c564SAndrew Turner SendPacket();
463*c120c564SAndrew Turner }
464*c120c564SAndrew Turner // value not traced 0b011x1010
465*c120c564SAndrew Turner else if((by & 0xEF )== 0x6A) {
466*c120c564SAndrew Turner if(!m_config.isDataTrace()) {
467*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_TRACEMODE);
468*c120c564SAndrew Turner throwPacketHeaderErr("Invalid data trace header (value not traced) - not tracing data.");
469*c120c564SAndrew Turner }
470*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_VAL_NOT_TRACED);
471*c120c564SAndrew Turner m_bExpectingDataAddress = ((by & DATA_ADDR_EXPECTED_FLAG) == DATA_ADDR_EXPECTED_FLAG) && m_config.isDataAddrTrace();
472*c120c564SAndrew Turner m_bFoundDataAddress = false;
473*c120c564SAndrew Turner if(!m_bExpectingDataAddress) {
474*c120c564SAndrew Turner SendPacket();
475*c120c564SAndrew Turner }
476*c120c564SAndrew Turner }
477*c120c564SAndrew Turner // ignore 0b01100110
478*c120c564SAndrew Turner else if(by == 0x66) {
479*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_IGNORE);
480*c120c564SAndrew Turner SendPacket();
481*c120c564SAndrew Turner }
482*c120c564SAndrew Turner // context ID 0b01101110
483*c120c564SAndrew Turner else if(by == 0x6E) {
484*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_CONTEXT_ID);
485*c120c564SAndrew Turner m_bytesExpectedThisPkt = (short)(1 + m_config.CtxtIDBytes());
486*c120c564SAndrew Turner }
487*c120c564SAndrew Turner // exception return 0b01110110
488*c120c564SAndrew Turner else if(by == 0x76) {
489*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_EXCEPTION_EXIT);
490*c120c564SAndrew Turner SendPacket();
491*c120c564SAndrew Turner }
492*c120c564SAndrew Turner // exception entry 0b01111110
493*c120c564SAndrew Turner else if(by == 0x7E) {
494*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_EXCEPTION_ENTRY);
495*c120c564SAndrew Turner SendPacket();
496*c120c564SAndrew Turner }
497*c120c564SAndrew Turner // timestamp packet 0b01000x10
498*c120c564SAndrew Turner else if((by & 0xFB )== 0x42)
499*c120c564SAndrew Turner {
500*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_TIMESTAMP);
501*c120c564SAndrew Turner }
502*c120c564SAndrew Turner else
503*c120c564SAndrew Turner {
504*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_RESERVED);
505*c120c564SAndrew Turner throwPacketHeaderErr("Packet header reserved encoding.");
506*c120c564SAndrew Turner }
507*c120c564SAndrew Turner return OCSD_OK;
508*c120c564SAndrew Turner }
509*c120c564SAndrew Turner
processPayloadByte(uint8_t by)510*c120c564SAndrew Turner ocsd_err_t EtmV3PktProcImpl::processPayloadByte(uint8_t by)
511*c120c564SAndrew Turner {
512*c120c564SAndrew Turner bool bTopBitSet = false;
513*c120c564SAndrew Turner bool packetDone = false;
514*c120c564SAndrew Turner
515*c120c564SAndrew Turner // pop byte into buffer
516*c120c564SAndrew Turner m_currPacketData.push_back(by);
517*c120c564SAndrew Turner
518*c120c564SAndrew Turner switch(m_curr_packet.getType()) {
519*c120c564SAndrew Turner default:
520*c120c564SAndrew Turner throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_PKT_INTERP_FAIL,m_packet_index,m_chanIDCopy,"Interpreter failed - cannot process payload for unexpected or unsupported packet.");
521*c120c564SAndrew Turner break;
522*c120c564SAndrew Turner
523*c120c564SAndrew Turner case ETM3_PKT_BRANCH_ADDRESS:
524*c120c564SAndrew Turner bTopBitSet = (bool)((by & 0x80) == 0x80);
525*c120c564SAndrew Turner if(m_config.isAltBranch()) // etm implements the alternative branch encoding
526*c120c564SAndrew Turner {
527*c120c564SAndrew Turner if(!bTopBitSet) // no continuation
528*c120c564SAndrew Turner {
529*c120c564SAndrew Turner if(!m_BranchPktNeedsException)
530*c120c564SAndrew Turner {
531*c120c564SAndrew Turner if((by & 0xC0) == 0x40)
532*c120c564SAndrew Turner m_BranchPktNeedsException = true;
533*c120c564SAndrew Turner else
534*c120c564SAndrew Turner packetDone = true;
535*c120c564SAndrew Turner }
536*c120c564SAndrew Turner else
537*c120c564SAndrew Turner packetDone = true;
538*c120c564SAndrew Turner }
539*c120c564SAndrew Turner }
540*c120c564SAndrew Turner else
541*c120c564SAndrew Turner {
542*c120c564SAndrew Turner // standard encoding < 5 bytes cannot be exception branch
543*c120c564SAndrew Turner // 5 byte packet
544*c120c564SAndrew Turner if(m_currPacketData.size() == 5) {
545*c120c564SAndrew Turner if((by & 0xC0) == 0x40)
546*c120c564SAndrew Turner // expecting follow up byte(s)
547*c120c564SAndrew Turner m_BranchPktNeedsException = true;
548*c120c564SAndrew Turner else
549*c120c564SAndrew Turner packetDone = true;
550*c120c564SAndrew Turner }
551*c120c564SAndrew Turner // waiting for exception packet
552*c120c564SAndrew Turner else if(m_BranchPktNeedsException){
553*c120c564SAndrew Turner if(!bTopBitSet)
554*c120c564SAndrew Turner packetDone = true;
555*c120c564SAndrew Turner }
556*c120c564SAndrew Turner else {
557*c120c564SAndrew Turner // not exception - end of packets
558*c120c564SAndrew Turner if(!bTopBitSet)
559*c120c564SAndrew Turner packetDone = true;
560*c120c564SAndrew Turner }
561*c120c564SAndrew Turner }
562*c120c564SAndrew Turner
563*c120c564SAndrew Turner if(packetDone)
564*c120c564SAndrew Turner {
565*c120c564SAndrew Turner OnBranchAddress();
566*c120c564SAndrew Turner SendPacket();
567*c120c564SAndrew Turner }
568*c120c564SAndrew Turner break;
569*c120c564SAndrew Turner
570*c120c564SAndrew Turner case ETM3_PKT_BRANCH_OR_BYPASS_EOT:
571*c120c564SAndrew Turner /*
572*c120c564SAndrew Turner if((by != 0x00) || ( m_currPacketData.size() == ETM3_PKT_BUFF_SIZE)) {
573*c120c564SAndrew Turner if(by == 0x80 && ( m_currPacketData.size() == 7)) {
574*c120c564SAndrew Turner // branch 0 followed by A-sync!
575*c120c564SAndrew Turner m_currPacketData.size() = 1;
576*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_BRANCH_ADDRESS;
577*c120c564SAndrew Turner SendPacket();
578*c120c564SAndrew Turner memcpy(m_currPacketData, &m_currPacketData[1],6);
579*c120c564SAndrew Turner m_currPacketData.size() = 6;
580*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_A_SYNC;
581*c120c564SAndrew Turner SendPacket();
582*c120c564SAndrew Turner }
583*c120c564SAndrew Turner else if( m_currPacketData.size() == 2) {
584*c120c564SAndrew Turner // branch followed by another byte
585*c120c564SAndrew Turner m_currPacketData.size() = 1;
586*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_BRANCH_ADDRESS;
587*c120c564SAndrew Turner SendPacket();
588*c120c564SAndrew Turner ProcessHeaderByte(by);
589*c120c564SAndrew Turner }
590*c120c564SAndrew Turner else if(by == 0x00) {
591*c120c564SAndrew Turner // end of buffer...output something - incomplete / unknown.
592*c120c564SAndrew Turner SendPacket();
593*c120c564SAndrew Turner }
594*c120c564SAndrew Turner else if(by == 0x01) {
595*c120c564SAndrew Turner // 0x01 - 0x00 x N - 0x1
596*c120c564SAndrew Turner // end of buffer...output something
597*c120c564SAndrew Turner m_currPacketData.size()--;
598*c120c564SAndrew Turner SendPacket();
599*c120c564SAndrew Turner ProcessHeaderByte(by);
600*c120c564SAndrew Turner }
601*c120c564SAndrew Turner else {
602*c120c564SAndrew Turner // branch followed by unknown sequence
603*c120c564SAndrew Turner int oldidx = m_currPacketData.size();
604*c120c564SAndrew Turner m_currPacketData.size() = 1;
605*c120c564SAndrew Turner m_curr_packet.SetType(ETM3_PKT_BRANCH_ADDRESS;
606*c120c564SAndrew Turner SendPacket();
607*c120c564SAndrew Turner oldidx--;
608*c120c564SAndrew Turner memcpy(m_currPacketData, &m_currPacketData[1],oldidx);
609*c120c564SAndrew Turner m_currPacketData.size() = oldidx;
610*c120c564SAndrew Turner SendBadPacket("ERROR : unknown sequence");
611*c120c564SAndrew Turner }
612*c120c564SAndrew Turner }*/
613*c120c564SAndrew Turner // just ignore zeros
614*c120c564SAndrew Turner break;
615*c120c564SAndrew Turner
616*c120c564SAndrew Turner
617*c120c564SAndrew Turner
618*c120c564SAndrew Turner case ETM3_PKT_A_SYNC:
619*c120c564SAndrew Turner if(by == 0x00) {
620*c120c564SAndrew Turner if( m_currPacketData.size() > 5) {
621*c120c564SAndrew Turner // extra 0, need to lose one
622*c120c564SAndrew Turner
623*c120c564SAndrew Turner // set error type
624*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_SEQUENCE);
625*c120c564SAndrew Turner // mark extra 0 for sending, retain remaining, restart in A-SYNC processing mode.
626*c120c564SAndrew Turner setBytesPartPkt(1,PROC_DATA,ETM3_PKT_A_SYNC);
627*c120c564SAndrew Turner throwMalformedPacketErr("A-Sync ?: Extra 0x00 in sequence");
628*c120c564SAndrew Turner }
629*c120c564SAndrew Turner }
630*c120c564SAndrew Turner else if((by == 0x80) && ( m_currPacketData.size() == 6)) {
631*c120c564SAndrew Turner SendPacket();
632*c120c564SAndrew Turner m_bStreamSync = true;
633*c120c564SAndrew Turner }
634*c120c564SAndrew Turner else
635*c120c564SAndrew Turner {
636*c120c564SAndrew Turner m_curr_packet.SetErrType(ETM3_PKT_BAD_SEQUENCE);
637*c120c564SAndrew Turner m_bytesProcessed--; // remove the last byte from the number processed to re-try
638*c120c564SAndrew Turner m_currPacketData.pop_back(); // remove the last byte processed from the packet
639*c120c564SAndrew Turner throwMalformedPacketErr("A-Sync ? : Unexpected byte in sequence");
640*c120c564SAndrew Turner }
641*c120c564SAndrew Turner break;
642*c120c564SAndrew Turner
643*c120c564SAndrew Turner case ETM3_PKT_CYCLE_COUNT:
644*c120c564SAndrew Turner bTopBitSet = ((by & 0x80) == 0x80);
645*c120c564SAndrew Turner if(!bTopBitSet || ( m_currPacketData.size() >= 6)) {
646*c120c564SAndrew Turner m_currPktIdx = 1;
647*c120c564SAndrew Turner m_curr_packet.SetCycleCount(extractCycleCount());
648*c120c564SAndrew Turner SendPacket();
649*c120c564SAndrew Turner }
650*c120c564SAndrew Turner break;
651*c120c564SAndrew Turner
652*c120c564SAndrew Turner case ETM3_PKT_I_SYNC_CYCLE:
653*c120c564SAndrew Turner if(!m_bIsync_got_cycle_cnt) {
654*c120c564SAndrew Turner if(((by & 0x80) != 0x80) || ( m_currPacketData.size() >= 6)) {
655*c120c564SAndrew Turner m_bIsync_got_cycle_cnt = true;
656*c120c564SAndrew Turner }
657*c120c564SAndrew Turner break;
658*c120c564SAndrew Turner }
659*c120c564SAndrew Turner // fall through when we have the first non-cycle count byte
660*c120c564SAndrew Turner case ETM3_PKT_I_SYNC:
661*c120c564SAndrew Turner if(m_bytesExpectedThisPkt == 0) {
662*c120c564SAndrew Turner int cycCountBytes = m_currPacketData.size() - 2;
663*c120c564SAndrew Turner int ctxtIDBytes = m_config.CtxtIDBytes();
664*c120c564SAndrew Turner // bytes expected = header + n x ctxt id + info byte + 4 x addr;
665*c120c564SAndrew Turner if(m_config.isInstrTrace())
666*c120c564SAndrew Turner m_bytesExpectedThisPkt = cycCountBytes + 6 + ctxtIDBytes;
667*c120c564SAndrew Turner else
668*c120c564SAndrew Turner m_bytesExpectedThisPkt = 2 + ctxtIDBytes;
669*c120c564SAndrew Turner m_IsyncInfoIdx = 1 + cycCountBytes + ctxtIDBytes;
670*c120c564SAndrew Turner }
671*c120c564SAndrew Turner if(( m_currPacketData.size() - 1) == (unsigned)m_IsyncInfoIdx) {
672*c120c564SAndrew Turner m_bIsync_get_LSiP_addr = ((m_currPacketData[m_IsyncInfoIdx] & 0x80) == 0x80);
673*c120c564SAndrew Turner }
674*c120c564SAndrew Turner
675*c120c564SAndrew Turner // if bytes collected >= bytes expected
676*c120c564SAndrew Turner if( m_currPacketData.size() >= m_bytesExpectedThisPkt) {
677*c120c564SAndrew Turner // if we still need the LSip Addr, then this is not part of the expected
678*c120c564SAndrew Turner // count as we have no idea how long it is
679*c120c564SAndrew Turner if(m_bIsync_get_LSiP_addr) {
680*c120c564SAndrew Turner if((by & 0x80) != 0x80) {
681*c120c564SAndrew Turner OnISyncPacket();
682*c120c564SAndrew Turner }
683*c120c564SAndrew Turner }
684*c120c564SAndrew Turner else {
685*c120c564SAndrew Turner // otherwise, output now
686*c120c564SAndrew Turner OnISyncPacket();
687*c120c564SAndrew Turner }
688*c120c564SAndrew Turner }
689*c120c564SAndrew Turner break;
690*c120c564SAndrew Turner
691*c120c564SAndrew Turner case ETM3_PKT_NORM_DATA:
692*c120c564SAndrew Turner if(m_bExpectingDataAddress && !m_bFoundDataAddress) {
693*c120c564SAndrew Turner // look for end of continuation bits
694*c120c564SAndrew Turner if((by & 0x80) != 0x80) {
695*c120c564SAndrew Turner m_bFoundDataAddress = true;
696*c120c564SAndrew Turner // add on the bytes we have found for the address to the expected data bytes
697*c120c564SAndrew Turner m_bytesExpectedThisPkt += ( m_currPacketData.size() - 1);
698*c120c564SAndrew Turner }
699*c120c564SAndrew Turner else
700*c120c564SAndrew Turner break;
701*c120c564SAndrew Turner }
702*c120c564SAndrew Turner // found any data address we were expecting
703*c120c564SAndrew Turner else if(m_bytesExpectedThisPkt == m_currPacketData.size()) {
704*c120c564SAndrew Turner m_currPktIdx = 1;
705*c120c564SAndrew Turner if(m_bExpectingDataAddress)
706*c120c564SAndrew Turner {
707*c120c564SAndrew Turner uint8_t bits = 0, beVal = 0;
708*c120c564SAndrew Turner bool updateBE = false;
709*c120c564SAndrew Turner uint32_t dataAddress = extractDataAddress(bits,updateBE,beVal);
710*c120c564SAndrew Turner m_curr_packet.UpdateDataAddress(dataAddress, bits);
711*c120c564SAndrew Turner if(updateBE)
712*c120c564SAndrew Turner m_curr_packet.UpdateDataEndian(beVal);
713*c120c564SAndrew Turner }
714*c120c564SAndrew Turner m_curr_packet.SetDataValue(extractDataValue((m_currPacketData[0] >> 2) & 0x3));
715*c120c564SAndrew Turner SendPacket();
716*c120c564SAndrew Turner }
717*c120c564SAndrew Turner break;
718*c120c564SAndrew Turner
719*c120c564SAndrew Turner case ETM3_PKT_OOO_DATA:
720*c120c564SAndrew Turner if(m_bytesExpectedThisPkt == m_currPacketData.size())
721*c120c564SAndrew Turner {
722*c120c564SAndrew Turner m_currPktIdx = 1;
723*c120c564SAndrew Turner m_curr_packet.SetDataValue(extractDataValue((m_currPacketData[0] >> 2) & 0x3));
724*c120c564SAndrew Turner m_curr_packet.SetDataOOOTag((m_currPacketData[0] >> 5) & 0x3);
725*c120c564SAndrew Turner SendPacket();
726*c120c564SAndrew Turner }
727*c120c564SAndrew Turner if(m_bytesExpectedThisPkt < m_currPacketData.size())
728*c120c564SAndrew Turner throwMalformedPacketErr("Malformed out of order data packet.");
729*c120c564SAndrew Turner break;
730*c120c564SAndrew Turner
731*c120c564SAndrew Turner // both these expect an address only.
732*c120c564SAndrew Turner case ETM3_PKT_VAL_NOT_TRACED:
733*c120c564SAndrew Turner case ETM3_PKT_OOO_ADDR_PLC: // we set the tag earlier.
734*c120c564SAndrew Turner if(m_bExpectingDataAddress) {
735*c120c564SAndrew Turner // look for end of continuation bits
736*c120c564SAndrew Turner if((by & 0x80) != 0x80) {
737*c120c564SAndrew Turner uint8_t bits = 0, beVal = 0;
738*c120c564SAndrew Turner bool updateBE = false;
739*c120c564SAndrew Turner m_currPktIdx = 1;
740*c120c564SAndrew Turner uint32_t dataAddress = extractDataAddress(bits,updateBE,beVal);
741*c120c564SAndrew Turner m_curr_packet.UpdateDataAddress(dataAddress, bits);
742*c120c564SAndrew Turner if(updateBE)
743*c120c564SAndrew Turner m_curr_packet.UpdateDataEndian(beVal);
744*c120c564SAndrew Turner SendPacket();
745*c120c564SAndrew Turner }
746*c120c564SAndrew Turner }
747*c120c564SAndrew Turner break;
748*c120c564SAndrew Turner
749*c120c564SAndrew Turner case ETM3_PKT_CONTEXT_ID:
750*c120c564SAndrew Turner if(m_bytesExpectedThisPkt == m_currPacketData.size()) {
751*c120c564SAndrew Turner m_currPktIdx = 1;
752*c120c564SAndrew Turner m_curr_packet.UpdateContextID(extractCtxtID());
753*c120c564SAndrew Turner SendPacket();
754*c120c564SAndrew Turner }
755*c120c564SAndrew Turner if(m_bytesExpectedThisPkt < m_currPacketData.size())
756*c120c564SAndrew Turner throwMalformedPacketErr("Malformed context id packet.");
757*c120c564SAndrew Turner break;
758*c120c564SAndrew Turner
759*c120c564SAndrew Turner case ETM3_PKT_TIMESTAMP:
760*c120c564SAndrew Turner if((by & 0x80) != 0x80) {
761*c120c564SAndrew Turner uint8_t tsBits = 0;
762*c120c564SAndrew Turner m_currPktIdx = 1;
763*c120c564SAndrew Turner uint64_t tsVal = extractTimestamp(tsBits);
764*c120c564SAndrew Turner m_curr_packet.UpdateTimestamp(tsVal,tsBits);
765*c120c564SAndrew Turner SendPacket();
766*c120c564SAndrew Turner }
767*c120c564SAndrew Turner break;
768*c120c564SAndrew Turner
769*c120c564SAndrew Turner case ETM3_PKT_VMID:
770*c120c564SAndrew Turner // single byte payload
771*c120c564SAndrew Turner m_curr_packet.UpdateVMID(by);
772*c120c564SAndrew Turner SendPacket();
773*c120c564SAndrew Turner break;
774*c120c564SAndrew Turner }
775*c120c564SAndrew Turner
776*c120c564SAndrew Turner return OCSD_OK;
777*c120c564SAndrew Turner }
778*c120c564SAndrew Turner
779*c120c564SAndrew Turner // extract branch address packet at current location in packet data.
OnBranchAddress()780*c120c564SAndrew Turner void EtmV3PktProcImpl::OnBranchAddress()
781*c120c564SAndrew Turner {
782*c120c564SAndrew Turner int validBits = 0;
783*c120c564SAndrew Turner ocsd_vaddr_t partAddr = 0;
784*c120c564SAndrew Turner
785*c120c564SAndrew Turner partAddr = extractBrAddrPkt(validBits);
786*c120c564SAndrew Turner m_curr_packet.UpdateAddress(partAddr,validBits);
787*c120c564SAndrew Turner }
788*c120c564SAndrew Turner
extractBrAddrPkt(int & nBitsOut)789*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::extractBrAddrPkt(int &nBitsOut)
790*c120c564SAndrew Turner {
791*c120c564SAndrew Turner static int addrshift[] = {
792*c120c564SAndrew Turner 2, // ARM_ISA
793*c120c564SAndrew Turner 1, // thumb
794*c120c564SAndrew Turner 1, // thumb EE
795*c120c564SAndrew Turner 0 // jazelle
796*c120c564SAndrew Turner };
797*c120c564SAndrew Turner
798*c120c564SAndrew Turner static uint8_t addrMask[] = { // byte 5 masks
799*c120c564SAndrew Turner 0x7, // ARM_ISA
800*c120c564SAndrew Turner 0xF, // thumb
801*c120c564SAndrew Turner 0xF, // thumb EE
802*c120c564SAndrew Turner 0x1F // jazelle
803*c120c564SAndrew Turner };
804*c120c564SAndrew Turner
805*c120c564SAndrew Turner static int addrBits[] = { // address bits in byte 5
806*c120c564SAndrew Turner 3, // ARM_ISA
807*c120c564SAndrew Turner 4, // thumb
808*c120c564SAndrew Turner 4, // thumb EE
809*c120c564SAndrew Turner 5 // jazelle
810*c120c564SAndrew Turner };
811*c120c564SAndrew Turner
812*c120c564SAndrew Turner static ocsd_armv7_exception exceptionTypeARMdeprecated[] = {
813*c120c564SAndrew Turner Excp_Reset,
814*c120c564SAndrew Turner Excp_IRQ,
815*c120c564SAndrew Turner Excp_Reserved,
816*c120c564SAndrew Turner Excp_Reserved,
817*c120c564SAndrew Turner Excp_Jazelle,
818*c120c564SAndrew Turner Excp_FIQ,
819*c120c564SAndrew Turner Excp_AsyncDAbort,
820*c120c564SAndrew Turner Excp_DebugHalt
821*c120c564SAndrew Turner };
822*c120c564SAndrew Turner
823*c120c564SAndrew Turner bool CBit = true;
824*c120c564SAndrew Turner int bytecount = 0;
825*c120c564SAndrew Turner int bitcount = 0;
826*c120c564SAndrew Turner int shift = 0;
827*c120c564SAndrew Turner int isa_idx = 0;
828*c120c564SAndrew Turner uint32_t value = 0;
829*c120c564SAndrew Turner uint8_t addrbyte;
830*c120c564SAndrew Turner bool byte5AddrUpdate = false;
831*c120c564SAndrew Turner
832*c120c564SAndrew Turner while(CBit && bytecount < 4)
833*c120c564SAndrew Turner {
834*c120c564SAndrew Turner checkPktLimits();
835*c120c564SAndrew Turner addrbyte = m_currPacketData[m_currPktIdx++];
836*c120c564SAndrew Turner CBit = (bool)((addrbyte & 0x80) != 0);
837*c120c564SAndrew Turner shift = bitcount;
838*c120c564SAndrew Turner if(bytecount == 0)
839*c120c564SAndrew Turner {
840*c120c564SAndrew Turner addrbyte &= ~0x81;
841*c120c564SAndrew Turner bitcount+=6;
842*c120c564SAndrew Turner addrbyte >>= 1;
843*c120c564SAndrew Turner }
844*c120c564SAndrew Turner else
845*c120c564SAndrew Turner {
846*c120c564SAndrew Turner // bytes 2-4, no continuation, alt format uses bit 6 to indicate following exception bytes
847*c120c564SAndrew Turner if(m_config.isAltBranch() && !CBit)
848*c120c564SAndrew Turner {
849*c120c564SAndrew Turner // last compressed address byte with exception
850*c120c564SAndrew Turner if((addrbyte & 0x40) == 0x40)
851*c120c564SAndrew Turner extractExceptionData();
852*c120c564SAndrew Turner addrbyte &= 0x3F;
853*c120c564SAndrew Turner bitcount+=6;
854*c120c564SAndrew Turner }
855*c120c564SAndrew Turner else
856*c120c564SAndrew Turner {
857*c120c564SAndrew Turner addrbyte &= 0x7F;
858*c120c564SAndrew Turner bitcount+=7;
859*c120c564SAndrew Turner }
860*c120c564SAndrew Turner }
861*c120c564SAndrew Turner value |= ((uint32_t)addrbyte) << shift;
862*c120c564SAndrew Turner bytecount++;
863*c120c564SAndrew Turner }
864*c120c564SAndrew Turner
865*c120c564SAndrew Turner // byte 5 - indicates following exception bytes (or not!)
866*c120c564SAndrew Turner if(CBit)
867*c120c564SAndrew Turner {
868*c120c564SAndrew Turner checkPktLimits();
869*c120c564SAndrew Turner addrbyte = m_currPacketData[m_currPktIdx++];
870*c120c564SAndrew Turner
871*c120c564SAndrew Turner // deprecated original byte 5 encoding - ARM state exception only
872*c120c564SAndrew Turner if(addrbyte & 0x80)
873*c120c564SAndrew Turner {
874*c120c564SAndrew Turner uint8_t excep_num = (addrbyte >> 3) & 0x7;
875*c120c564SAndrew Turner m_curr_packet.UpdateISA(ocsd_isa_arm);
876*c120c564SAndrew Turner m_curr_packet.SetException(exceptionTypeARMdeprecated[excep_num], excep_num, (addrbyte & 0x40) ? true : false,m_config.isV7MArch());
877*c120c564SAndrew Turner }
878*c120c564SAndrew Turner else
879*c120c564SAndrew Turner // normal 5 byte branch, or uses exception bytes.
880*c120c564SAndrew Turner {
881*c120c564SAndrew Turner // go grab the exception bits to correctly interpret the ISA state
882*c120c564SAndrew Turner if((addrbyte & 0x40) == 0x40)
883*c120c564SAndrew Turner extractExceptionData();
884*c120c564SAndrew Turner
885*c120c564SAndrew Turner if((addrbyte & 0xB8) == 0x08)
886*c120c564SAndrew Turner m_curr_packet.UpdateISA(ocsd_isa_arm);
887*c120c564SAndrew Turner else if ((addrbyte & 0xB0) == 0x10)
888*c120c564SAndrew Turner m_curr_packet.UpdateISA(m_curr_packet.AltISA() ? ocsd_isa_tee : ocsd_isa_thumb2);
889*c120c564SAndrew Turner else if ((addrbyte & 0xA0) == 0x20)
890*c120c564SAndrew Turner m_curr_packet.UpdateISA(ocsd_isa_jazelle);
891*c120c564SAndrew Turner else
892*c120c564SAndrew Turner throwMalformedPacketErr("Malformed Packet - Unknown ISA.");
893*c120c564SAndrew Turner }
894*c120c564SAndrew Turner
895*c120c564SAndrew Turner byte5AddrUpdate = true; // need to update the address value from byte 5
896*c120c564SAndrew Turner }
897*c120c564SAndrew Turner
898*c120c564SAndrew Turner // figure out the correct ISA shifts for the address bits
899*c120c564SAndrew Turner switch(m_curr_packet.ISA())
900*c120c564SAndrew Turner {
901*c120c564SAndrew Turner case ocsd_isa_thumb2: isa_idx = 1; break;
902*c120c564SAndrew Turner case ocsd_isa_tee: isa_idx = 2; break;
903*c120c564SAndrew Turner case ocsd_isa_jazelle: isa_idx = 3; break;
904*c120c564SAndrew Turner default: break;
905*c120c564SAndrew Turner }
906*c120c564SAndrew Turner
907*c120c564SAndrew Turner if(byte5AddrUpdate)
908*c120c564SAndrew Turner {
909*c120c564SAndrew Turner value |= ((uint32_t)(addrbyte & addrMask[isa_idx])) << bitcount;
910*c120c564SAndrew Turner bitcount += addrBits[isa_idx];
911*c120c564SAndrew Turner }
912*c120c564SAndrew Turner
913*c120c564SAndrew Turner // finally align according to ISA
914*c120c564SAndrew Turner shift = addrshift[isa_idx];
915*c120c564SAndrew Turner value <<= shift;
916*c120c564SAndrew Turner bitcount += shift;
917*c120c564SAndrew Turner
918*c120c564SAndrew Turner nBitsOut = bitcount;
919*c120c564SAndrew Turner return value;
920*c120c564SAndrew Turner }
921*c120c564SAndrew Turner
922*c120c564SAndrew Turner // extract exception data from bytes after address.
extractExceptionData()923*c120c564SAndrew Turner void EtmV3PktProcImpl::extractExceptionData()
924*c120c564SAndrew Turner {
925*c120c564SAndrew Turner static const ocsd_armv7_exception exceptionTypesStd[] = {
926*c120c564SAndrew Turner Excp_NoException, Excp_DebugHalt, Excp_SMC, Excp_Hyp,
927*c120c564SAndrew Turner Excp_AsyncDAbort, Excp_Jazelle, Excp_Reserved, Excp_Reserved,
928*c120c564SAndrew Turner Excp_Reset, Excp_Undef, Excp_SVC, Excp_PrefAbort,
929*c120c564SAndrew Turner Excp_SyncDataAbort, Excp_Generic, Excp_IRQ, Excp_FIQ
930*c120c564SAndrew Turner };
931*c120c564SAndrew Turner
932*c120c564SAndrew Turner static const ocsd_armv7_exception exceptionTypesCM[] = {
933*c120c564SAndrew Turner Excp_NoException, Excp_CMIRQn, Excp_CMIRQn, Excp_CMIRQn,
934*c120c564SAndrew Turner Excp_CMIRQn, Excp_CMIRQn, Excp_CMIRQn, Excp_CMIRQn,
935*c120c564SAndrew Turner Excp_CMIRQn, Excp_CMUsageFault, Excp_CMNMI, Excp_SVC,
936*c120c564SAndrew Turner Excp_CMDebugMonitor, Excp_CMMemManage, Excp_CMPendSV, Excp_CMSysTick,
937*c120c564SAndrew Turner Excp_Reserved, Excp_Reset, Excp_Reserved, Excp_CMHardFault,
938*c120c564SAndrew Turner Excp_Reserved, Excp_CMBusFault, Excp_Reserved, Excp_Reserved
939*c120c564SAndrew Turner };
940*c120c564SAndrew Turner
941*c120c564SAndrew Turner uint16_t exceptionNum = 0;
942*c120c564SAndrew Turner ocsd_armv7_exception excep_type = Excp_Reserved;
943*c120c564SAndrew Turner int resume = 0;
944*c120c564SAndrew Turner int irq_n = 0;
945*c120c564SAndrew Turner bool cancel_prev_instr = 0;
946*c120c564SAndrew Turner bool Byte2 = false;
947*c120c564SAndrew Turner
948*c120c564SAndrew Turner checkPktLimits();
949*c120c564SAndrew Turner
950*c120c564SAndrew Turner //**** exception info Byte 0
951*c120c564SAndrew Turner uint8_t dataByte = m_currPacketData[m_currPktIdx++];
952*c120c564SAndrew Turner
953*c120c564SAndrew Turner m_curr_packet.UpdateNS(dataByte & 0x1);
954*c120c564SAndrew Turner exceptionNum |= (dataByte >> 1) & 0xF;
955*c120c564SAndrew Turner cancel_prev_instr = (dataByte & 0x20) ? true : false;
956*c120c564SAndrew Turner m_curr_packet.UpdateAltISA(((dataByte & 0x40) != 0) ? 1 : 0);
957*c120c564SAndrew Turner
958*c120c564SAndrew Turner //** another byte?
959*c120c564SAndrew Turner if(dataByte & 0x80)
960*c120c564SAndrew Turner {
961*c120c564SAndrew Turner checkPktLimits();
962*c120c564SAndrew Turner dataByte = m_currPacketData[m_currPktIdx++];
963*c120c564SAndrew Turner
964*c120c564SAndrew Turner if(dataByte & 0x40)
965*c120c564SAndrew Turner Byte2 = true; //** immediate info byte 2, skipping 1
966*c120c564SAndrew Turner else
967*c120c564SAndrew Turner {
968*c120c564SAndrew Turner //**** exception info Byte 1
969*c120c564SAndrew Turner if(m_config.isV7MArch())
970*c120c564SAndrew Turner {
971*c120c564SAndrew Turner exceptionNum |= ((uint16_t)(dataByte & 0x1F)) << 4;
972*c120c564SAndrew Turner }
973*c120c564SAndrew Turner m_curr_packet.UpdateHyp(dataByte & 0x20 ? 1 : 0);
974*c120c564SAndrew Turner
975*c120c564SAndrew Turner if(dataByte & 0x80)
976*c120c564SAndrew Turner {
977*c120c564SAndrew Turner checkPktLimits();
978*c120c564SAndrew Turner dataByte = m_currPacketData[m_currPktIdx++];
979*c120c564SAndrew Turner Byte2 = true;
980*c120c564SAndrew Turner }
981*c120c564SAndrew Turner }
982*c120c564SAndrew Turner //**** exception info Byte 2
983*c120c564SAndrew Turner if(Byte2)
984*c120c564SAndrew Turner {
985*c120c564SAndrew Turner resume = dataByte & 0xF;
986*c120c564SAndrew Turner }
987*c120c564SAndrew Turner }
988*c120c564SAndrew Turner
989*c120c564SAndrew Turner // set the exception type - according to the number and core profile
990*c120c564SAndrew Turner if(m_config.isV7MArch())
991*c120c564SAndrew Turner {
992*c120c564SAndrew Turner exceptionNum &= 0x1FF;
993*c120c564SAndrew Turner if(exceptionNum < 0x018)
994*c120c564SAndrew Turner excep_type= exceptionTypesCM[exceptionNum];
995*c120c564SAndrew Turner else
996*c120c564SAndrew Turner excep_type = Excp_CMIRQn;
997*c120c564SAndrew Turner
998*c120c564SAndrew Turner if(excep_type == Excp_CMIRQn)
999*c120c564SAndrew Turner {
1000*c120c564SAndrew Turner if(exceptionNum > 0x018)
1001*c120c564SAndrew Turner irq_n = exceptionNum - 0x10;
1002*c120c564SAndrew Turner else if(exceptionNum == 0x008)
1003*c120c564SAndrew Turner irq_n = 0;
1004*c120c564SAndrew Turner else
1005*c120c564SAndrew Turner irq_n = exceptionNum;
1006*c120c564SAndrew Turner }
1007*c120c564SAndrew Turner }
1008*c120c564SAndrew Turner else
1009*c120c564SAndrew Turner {
1010*c120c564SAndrew Turner exceptionNum &= 0xF;
1011*c120c564SAndrew Turner excep_type = exceptionTypesStd[exceptionNum];
1012*c120c564SAndrew Turner }
1013*c120c564SAndrew Turner m_curr_packet.SetException(excep_type, exceptionNum, cancel_prev_instr,m_config.isV7MArch(), irq_n,resume);
1014*c120c564SAndrew Turner }
1015*c120c564SAndrew Turner
checkPktLimits()1016*c120c564SAndrew Turner void EtmV3PktProcImpl::checkPktLimits()
1017*c120c564SAndrew Turner {
1018*c120c564SAndrew Turner // index running off the end of the packet means a malformed packet.
1019*c120c564SAndrew Turner if(m_currPktIdx >= m_currPacketData.size())
1020*c120c564SAndrew Turner throwMalformedPacketErr("Malformed Packet - oversized packet.");
1021*c120c564SAndrew Turner }
1022*c120c564SAndrew Turner
extractCtxtID()1023*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::extractCtxtID()
1024*c120c564SAndrew Turner {
1025*c120c564SAndrew Turner uint32_t ctxtID = 0;
1026*c120c564SAndrew Turner int size = m_config.CtxtIDBytes();
1027*c120c564SAndrew Turner
1028*c120c564SAndrew Turner // check we have enough data
1029*c120c564SAndrew Turner if((m_currPktIdx + size) > m_currPacketData.size())
1030*c120c564SAndrew Turner throwMalformedPacketErr("Too few bytes to extract context ID.");
1031*c120c564SAndrew Turner
1032*c120c564SAndrew Turner switch(size)
1033*c120c564SAndrew Turner {
1034*c120c564SAndrew Turner case 1:
1035*c120c564SAndrew Turner ctxtID = (uint32_t)m_currPacketData[m_currPktIdx];
1036*c120c564SAndrew Turner m_currPktIdx++;
1037*c120c564SAndrew Turner break;
1038*c120c564SAndrew Turner
1039*c120c564SAndrew Turner case 2:
1040*c120c564SAndrew Turner ctxtID = (uint32_t)m_currPacketData[m_currPktIdx]
1041*c120c564SAndrew Turner | ((uint32_t)m_currPacketData[m_currPktIdx+1]) << 8;
1042*c120c564SAndrew Turner m_currPktIdx+=2;
1043*c120c564SAndrew Turner break;
1044*c120c564SAndrew Turner
1045*c120c564SAndrew Turner case 4:
1046*c120c564SAndrew Turner ctxtID = (uint32_t)m_currPacketData[m_currPktIdx]
1047*c120c564SAndrew Turner | ((uint32_t)m_currPacketData[m_currPktIdx+1]) << 8
1048*c120c564SAndrew Turner | ((uint32_t)m_currPacketData[m_currPktIdx+2]) << 16
1049*c120c564SAndrew Turner | ((uint32_t)m_currPacketData[m_currPktIdx+3]) << 24;
1050*c120c564SAndrew Turner m_currPktIdx+=4;
1051*c120c564SAndrew Turner break;
1052*c120c564SAndrew Turner }
1053*c120c564SAndrew Turner return ctxtID;
1054*c120c564SAndrew Turner }
1055*c120c564SAndrew Turner
extractTimestamp(uint8_t & tsBits)1056*c120c564SAndrew Turner uint64_t EtmV3PktProcImpl::extractTimestamp(uint8_t &tsBits)
1057*c120c564SAndrew Turner {
1058*c120c564SAndrew Turner uint64_t ts = 0;
1059*c120c564SAndrew Turner unsigned tsMaxBytes = m_config.TSPkt64() ? 9 : 7;
1060*c120c564SAndrew Turner unsigned tsCurrBytes = 0;
1061*c120c564SAndrew Turner bool bCont = true;
1062*c120c564SAndrew Turner uint8_t mask = 0x7F;
1063*c120c564SAndrew Turner uint8_t last_mask = m_config.TSPkt64() ? 0xFF : 0x3F;
1064*c120c564SAndrew Turner uint8_t ts_iter_bits = 7;
1065*c120c564SAndrew Turner uint8_t ts_last_iter_bits = m_config.TSPkt64() ? 8 : 6;
1066*c120c564SAndrew Turner uint8_t currByte;
1067*c120c564SAndrew Turner tsBits = 0;
1068*c120c564SAndrew Turner
1069*c120c564SAndrew Turner while((tsCurrBytes < tsMaxBytes) && bCont)
1070*c120c564SAndrew Turner {
1071*c120c564SAndrew Turner if(m_currPacketData.size() < (m_currPktIdx + tsCurrBytes + 1))
1072*c120c564SAndrew Turner throwMalformedPacketErr("Insufficient bytes to extract timestamp.");
1073*c120c564SAndrew Turner
1074*c120c564SAndrew Turner currByte = m_currPacketData[m_currPktIdx+tsCurrBytes];
1075*c120c564SAndrew Turner ts |= ((uint64_t)(currByte & mask)) << (7 * tsCurrBytes);
1076*c120c564SAndrew Turner tsCurrBytes++;
1077*c120c564SAndrew Turner tsBits += ts_iter_bits;
1078*c120c564SAndrew Turner bCont = ((0x80 & currByte) == 0x80);
1079*c120c564SAndrew Turner if(tsCurrBytes == (tsMaxBytes - 1))
1080*c120c564SAndrew Turner {
1081*c120c564SAndrew Turner mask = last_mask;
1082*c120c564SAndrew Turner ts_iter_bits = ts_last_iter_bits;
1083*c120c564SAndrew Turner }
1084*c120c564SAndrew Turner }
1085*c120c564SAndrew Turner m_currPktIdx += tsCurrBytes;
1086*c120c564SAndrew Turner return ts;
1087*c120c564SAndrew Turner }
1088*c120c564SAndrew Turner
1089*c120c564SAndrew Turner
extractDataAddress(uint8_t & bits,bool & updateBE,uint8_t & beVal)1090*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::extractDataAddress(uint8_t &bits, bool &updateBE, uint8_t &beVal)
1091*c120c564SAndrew Turner {
1092*c120c564SAndrew Turner uint32_t dataAddr = 0;
1093*c120c564SAndrew Turner int bytesIdx = 0;
1094*c120c564SAndrew Turner bool bCont = true;
1095*c120c564SAndrew Turner uint8_t currByte = 0;
1096*c120c564SAndrew Turner
1097*c120c564SAndrew Turner updateBE = false;
1098*c120c564SAndrew Turner bits = 0;
1099*c120c564SAndrew Turner
1100*c120c564SAndrew Turner while(bCont)
1101*c120c564SAndrew Turner {
1102*c120c564SAndrew Turner checkPktLimits();
1103*c120c564SAndrew Turner currByte = m_currPacketData[m_currPktIdx++] & ((bytesIdx == 4) ? 0x0F : 0x7F);
1104*c120c564SAndrew Turner dataAddr |= (((uint32_t)currByte) << (bytesIdx * 7));
1105*c120c564SAndrew Turner bCont = ((currByte & 0x80) == 0x80);
1106*c120c564SAndrew Turner if(bytesIdx == 4)
1107*c120c564SAndrew Turner {
1108*c120c564SAndrew Turner bits += 4;
1109*c120c564SAndrew Turner updateBE = true;
1110*c120c564SAndrew Turner beVal = ((currByte >> 4) & 0x1);
1111*c120c564SAndrew Turner bCont = false;
1112*c120c564SAndrew Turner }
1113*c120c564SAndrew Turner else
1114*c120c564SAndrew Turner bits+=7;
1115*c120c564SAndrew Turner bytesIdx++;
1116*c120c564SAndrew Turner }
1117*c120c564SAndrew Turner return dataAddr;
1118*c120c564SAndrew Turner }
1119*c120c564SAndrew Turner
extractDataValue(const int dataByteSize)1120*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::extractDataValue(const int dataByteSize)
1121*c120c564SAndrew Turner {
1122*c120c564SAndrew Turner static int bytesReqTable[] = { 0,1,2,4 };
1123*c120c564SAndrew Turner
1124*c120c564SAndrew Turner uint32_t dataVal = 0;
1125*c120c564SAndrew Turner int bytesUsed = 0;
1126*c120c564SAndrew Turner int bytesReq = bytesReqTable[dataByteSize & 0x3];
1127*c120c564SAndrew Turner while(bytesUsed < bytesReq)
1128*c120c564SAndrew Turner {
1129*c120c564SAndrew Turner checkPktLimits();
1130*c120c564SAndrew Turner dataVal |= (((uint32_t)m_currPacketData[m_currPktIdx++]) << (bytesUsed * 8));
1131*c120c564SAndrew Turner bytesUsed++;
1132*c120c564SAndrew Turner }
1133*c120c564SAndrew Turner return dataVal;
1134*c120c564SAndrew Turner }
1135*c120c564SAndrew Turner
1136*c120c564SAndrew Turner
extractCycleCount()1137*c120c564SAndrew Turner uint32_t EtmV3PktProcImpl::extractCycleCount()
1138*c120c564SAndrew Turner {
1139*c120c564SAndrew Turner uint32_t cycleCount = 0;
1140*c120c564SAndrew Turner int byteIdx = 0;
1141*c120c564SAndrew Turner uint8_t mask = 0x7F;
1142*c120c564SAndrew Turner bool bCond = true;
1143*c120c564SAndrew Turner uint8_t currByte = 0;
1144*c120c564SAndrew Turner
1145*c120c564SAndrew Turner while(bCond)
1146*c120c564SAndrew Turner {
1147*c120c564SAndrew Turner checkPktLimits();
1148*c120c564SAndrew Turner currByte = m_currPacketData[m_currPktIdx++];
1149*c120c564SAndrew Turner cycleCount |= ((uint32_t)(currByte & mask)) << (7 * byteIdx);
1150*c120c564SAndrew Turner bCond = ((currByte & 0x80) == 0x80);
1151*c120c564SAndrew Turner byteIdx++;
1152*c120c564SAndrew Turner
1153*c120c564SAndrew Turner if(byteIdx == 4)
1154*c120c564SAndrew Turner mask = 0x0F;
1155*c120c564SAndrew Turner
1156*c120c564SAndrew Turner if(byteIdx == 5)
1157*c120c564SAndrew Turner bCond = false;
1158*c120c564SAndrew Turner }
1159*c120c564SAndrew Turner return cycleCount;
1160*c120c564SAndrew Turner }
1161*c120c564SAndrew Turner
OnISyncPacket()1162*c120c564SAndrew Turner void EtmV3PktProcImpl::OnISyncPacket()
1163*c120c564SAndrew Turner {
1164*c120c564SAndrew Turner uint8_t iSyncInfoByte = 0;
1165*c120c564SAndrew Turner uint32_t instrAddr = 0, LSiPAddr = 0;
1166*c120c564SAndrew Turner int LSiPBits = 0;
1167*c120c564SAndrew Turner uint8_t T = 0, J = 0, AltISA = 0;
1168*c120c564SAndrew Turner
1169*c120c564SAndrew Turner m_currPktIdx = 1;
1170*c120c564SAndrew Turner if(m_bIsync_got_cycle_cnt)
1171*c120c564SAndrew Turner {
1172*c120c564SAndrew Turner m_curr_packet.SetCycleCount(extractCycleCount());
1173*c120c564SAndrew Turner m_curr_packet.SetISyncHasCC();
1174*c120c564SAndrew Turner }
1175*c120c564SAndrew Turner
1176*c120c564SAndrew Turner if(m_config.CtxtIDBytes() != 0)
1177*c120c564SAndrew Turner {
1178*c120c564SAndrew Turner m_curr_packet.UpdateContextID(extractCtxtID());
1179*c120c564SAndrew Turner }
1180*c120c564SAndrew Turner
1181*c120c564SAndrew Turner // extract context info
1182*c120c564SAndrew Turner iSyncInfoByte = m_currPacketData[m_currPktIdx++];
1183*c120c564SAndrew Turner m_curr_packet.SetISyncReason((ocsd_iSync_reason)((iSyncInfoByte >> 5) & 0x3));
1184*c120c564SAndrew Turner J = (iSyncInfoByte >> 4) & 0x1;
1185*c120c564SAndrew Turner AltISA = m_config.MinorRev() >= 3 ? (iSyncInfoByte >> 2) & 0x1 : 0;
1186*c120c564SAndrew Turner m_curr_packet.UpdateNS((iSyncInfoByte >> 3) & 0x1);
1187*c120c564SAndrew Turner if(m_config.hasVirtExt())
1188*c120c564SAndrew Turner m_curr_packet.UpdateHyp((iSyncInfoByte >> 1) & 0x1);
1189*c120c564SAndrew Turner
1190*c120c564SAndrew Turner // main address value - full 32 bit address value
1191*c120c564SAndrew Turner if(m_config.isInstrTrace())
1192*c120c564SAndrew Turner {
1193*c120c564SAndrew Turner for(int i = 0; i < 4; i++)
1194*c120c564SAndrew Turner instrAddr |= ((uint32_t)m_currPacketData[m_currPktIdx++]) << (8*i);
1195*c120c564SAndrew Turner T = instrAddr & 0x1; // get the T bit.
1196*c120c564SAndrew Turner instrAddr &= ~0x1; // remove from address.
1197*c120c564SAndrew Turner m_curr_packet.UpdateAddress(instrAddr,32);
1198*c120c564SAndrew Turner
1199*c120c564SAndrew Turner // enough data now to set the instruction set.
1200*c120c564SAndrew Turner ocsd_isa currISA = ocsd_isa_arm;
1201*c120c564SAndrew Turner if(J)
1202*c120c564SAndrew Turner currISA = ocsd_isa_jazelle;
1203*c120c564SAndrew Turner else if(T)
1204*c120c564SAndrew Turner currISA = AltISA ? ocsd_isa_tee : ocsd_isa_thumb2;
1205*c120c564SAndrew Turner m_curr_packet.UpdateISA(currISA);
1206*c120c564SAndrew Turner
1207*c120c564SAndrew Turner // possible follow up address value - rarely uses unless trace enabled during
1208*c120c564SAndrew Turner // load and store instruction executing on top of other instruction.
1209*c120c564SAndrew Turner if(m_bIsync_get_LSiP_addr)
1210*c120c564SAndrew Turner {
1211*c120c564SAndrew Turner LSiPAddr = extractBrAddrPkt(LSiPBits);
1212*c120c564SAndrew Turner // follow up address value is compressed relative to the main value
1213*c120c564SAndrew Turner // we store this in the data address value temporarily.
1214*c120c564SAndrew Turner m_curr_packet.UpdateDataAddress(instrAddr,32);
1215*c120c564SAndrew Turner m_curr_packet.UpdateDataAddress(LSiPAddr,LSiPBits);
1216*c120c564SAndrew Turner }
1217*c120c564SAndrew Turner }
1218*c120c564SAndrew Turner else
1219*c120c564SAndrew Turner m_curr_packet.SetISyncNoAddr();
1220*c120c564SAndrew Turner
1221*c120c564SAndrew Turner SendPacket(); // mark ready to send
1222*c120c564SAndrew Turner }
1223*c120c564SAndrew Turner
1224*c120c564SAndrew Turner /* End of File trc_pkt_proc_etmv3_impl.cpp */
1225