xref: /freebsd-src/contrib/opencsd/decoder/source/trc_frame_deformatter.cpp (revision c120c5646da1a1d2c4d90fd069a7e2a8d559eb46)
1*c120c564SAndrew Turner /*
2*c120c564SAndrew Turner  * \file       trc_frame_deformatter.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 #include <cstring>
35*c120c564SAndrew Turner 
36*c120c564SAndrew Turner #include "common/trc_frame_deformatter.h"
37*c120c564SAndrew Turner #include "trc_frame_deformatter_impl.h"
38*c120c564SAndrew Turner 
39*c120c564SAndrew Turner /***************************************************************/
40*c120c564SAndrew Turner /* Implementation */
41*c120c564SAndrew Turner /***************************************************************/
42*c120c564SAndrew Turner 
43*c120c564SAndrew Turner #ifdef __GNUC__
44*c120c564SAndrew Turner // G++ doesn't like the ## pasting
45*c120c564SAndrew Turner #define DEFORMATTER_NAME "DFMT_CSFRAMES"
46*c120c564SAndrew Turner #else
47*c120c564SAndrew Turner // VC is fine
48*c120c564SAndrew Turner #define DEFORMATTER_NAME OCSD_CMPNAME_PREFIX_FRAMEDEFORMATTER##"_CSFRAMES"
49*c120c564SAndrew Turner #endif
50*c120c564SAndrew Turner 
51*c120c564SAndrew Turner TraceFmtDcdImpl::TraceFmtDcdImpl() : TraceComponent(DEFORMATTER_NAME),
52*c120c564SAndrew Turner     m_cfgFlags(0),
53*c120c564SAndrew Turner     m_force_sync_idx(0),
54*c120c564SAndrew Turner     m_use_force_sync(false),
55*c120c564SAndrew Turner     m_alignment(16), // assume frame aligned data as default.
56*c120c564SAndrew Turner     m_b_output_packed_raw(false),
57*c120c564SAndrew Turner     m_b_output_unpacked_raw(false)
58*c120c564SAndrew Turner 
59*c120c564SAndrew Turner {
60*c120c564SAndrew Turner     resetStateParams();
61*c120c564SAndrew Turner     setRawChanFilterAll(true);
62*c120c564SAndrew Turner }
63*c120c564SAndrew Turner 
64*c120c564SAndrew Turner TraceFmtDcdImpl::TraceFmtDcdImpl(int instNum) : TraceComponent(DEFORMATTER_NAME, instNum),
65*c120c564SAndrew Turner     m_cfgFlags(0),
66*c120c564SAndrew Turner     m_force_sync_idx(0),
67*c120c564SAndrew Turner     m_use_force_sync(false),
68*c120c564SAndrew Turner     m_alignment(16)
69*c120c564SAndrew Turner {
70*c120c564SAndrew Turner     resetStateParams();
71*c120c564SAndrew Turner     setRawChanFilterAll(true);
72*c120c564SAndrew Turner }
73*c120c564SAndrew Turner 
74*c120c564SAndrew Turner TraceFmtDcdImpl::~TraceFmtDcdImpl()
75*c120c564SAndrew Turner {
76*c120c564SAndrew Turner }
77*c120c564SAndrew Turner 
78*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFmtDcdImpl::TraceDataIn(
79*c120c564SAndrew Turner     const ocsd_datapath_op_t op,
80*c120c564SAndrew Turner     const ocsd_trc_index_t index,
81*c120c564SAndrew Turner     const uint32_t dataBlockSize,
82*c120c564SAndrew Turner     const uint8_t *pDataBlock,
83*c120c564SAndrew Turner     uint32_t *numBytesProcessed)
84*c120c564SAndrew Turner {
85*c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_INVALID_OP;
86*c120c564SAndrew Turner     InitCollateDataPathResp();
87*c120c564SAndrew Turner 
88*c120c564SAndrew Turner     m_b_output_packed_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_PACKED_RAW_OUT) != 0);
89*c120c564SAndrew Turner     m_b_output_unpacked_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_UNPACKED_RAW_OUT) != 0);
90*c120c564SAndrew Turner 
91*c120c564SAndrew Turner     switch(op)
92*c120c564SAndrew Turner     {
93*c120c564SAndrew Turner     case OCSD_OP_RESET:
94*c120c564SAndrew Turner         resp = Reset();
95*c120c564SAndrew Turner         break;
96*c120c564SAndrew Turner 
97*c120c564SAndrew Turner     case OCSD_OP_FLUSH:
98*c120c564SAndrew Turner         resp = Flush();
99*c120c564SAndrew Turner         break;
100*c120c564SAndrew Turner 
101*c120c564SAndrew Turner     case OCSD_OP_EOT:
102*c120c564SAndrew Turner         // local 'flush' here?
103*c120c564SAndrew Turner         // pass on EOT to connected ID streams
104*c120c564SAndrew Turner         resp = executeNoneDataOpAllIDs(OCSD_OP_EOT);
105*c120c564SAndrew Turner         break;
106*c120c564SAndrew Turner 
107*c120c564SAndrew Turner     case OCSD_OP_DATA:
108*c120c564SAndrew Turner         if((dataBlockSize <= 0) || ( pDataBlock == 0) || (numBytesProcessed == 0))
109*c120c564SAndrew Turner             resp = OCSD_RESP_FATAL_INVALID_PARAM;
110*c120c564SAndrew Turner         else
111*c120c564SAndrew Turner             resp = processTraceData(index,dataBlockSize, pDataBlock, numBytesProcessed);
112*c120c564SAndrew Turner         break;
113*c120c564SAndrew Turner 
114*c120c564SAndrew Turner     default:
115*c120c564SAndrew Turner         break;
116*c120c564SAndrew Turner     }
117*c120c564SAndrew Turner 
118*c120c564SAndrew Turner     return resp;
119*c120c564SAndrew Turner }
120*c120c564SAndrew Turner 
121*c120c564SAndrew Turner /* enable / disable ID streams - default as all enabled */
122*c120c564SAndrew Turner ocsd_err_t TraceFmtDcdImpl::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
123*c120c564SAndrew Turner {
124*c120c564SAndrew Turner     ocsd_err_t err =  OCSD_OK;
125*c120c564SAndrew Turner     std::vector<uint8_t>::iterator iter = id_list.begin();
126*c120c564SAndrew Turner     uint8_t id = 0;
127*c120c564SAndrew Turner 
128*c120c564SAndrew Turner     while((iter < id_list.end()) && (err == OCSD_OK))
129*c120c564SAndrew Turner     {
130*c120c564SAndrew Turner         id = *iter;
131*c120c564SAndrew Turner         if(id > 128)
132*c120c564SAndrew Turner             err = OCSD_ERR_INVALID_ID;
133*c120c564SAndrew Turner         else
134*c120c564SAndrew Turner         {
135*c120c564SAndrew Turner             m_IDStreams[id].set_enabled(bEnable);
136*c120c564SAndrew Turner             m_raw_chan_enable[id] = bEnable;
137*c120c564SAndrew Turner         }
138*c120c564SAndrew Turner         iter++;
139*c120c564SAndrew Turner     }
140*c120c564SAndrew Turner     return err;
141*c120c564SAndrew Turner }
142*c120c564SAndrew Turner 
143*c120c564SAndrew Turner ocsd_err_t TraceFmtDcdImpl::OutputFilterAllIDs(bool bEnable)
144*c120c564SAndrew Turner {
145*c120c564SAndrew Turner     for(uint8_t id = 0; id < 128; id++)
146*c120c564SAndrew Turner     {
147*c120c564SAndrew Turner         m_IDStreams[id].set_enabled(bEnable);
148*c120c564SAndrew Turner     }
149*c120c564SAndrew Turner     setRawChanFilterAll(bEnable);
150*c120c564SAndrew Turner     return OCSD_OK;
151*c120c564SAndrew Turner }
152*c120c564SAndrew Turner 
153*c120c564SAndrew Turner void TraceFmtDcdImpl::setRawChanFilterAll(bool bEnable)
154*c120c564SAndrew Turner {
155*c120c564SAndrew Turner     for(int i=0; i<128; i++)
156*c120c564SAndrew Turner     {
157*c120c564SAndrew Turner         m_raw_chan_enable[i] = bEnable;
158*c120c564SAndrew Turner     }
159*c120c564SAndrew Turner }
160*c120c564SAndrew Turner 
161*c120c564SAndrew Turner const bool TraceFmtDcdImpl::rawChanEnabled(const uint8_t id) const
162*c120c564SAndrew Turner {
163*c120c564SAndrew Turner     if(id < 128)
164*c120c564SAndrew Turner         return m_raw_chan_enable[id];
165*c120c564SAndrew Turner     return false;
166*c120c564SAndrew Turner }
167*c120c564SAndrew Turner 
168*c120c564SAndrew Turner /* decode control */
169*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFmtDcdImpl::Reset()
170*c120c564SAndrew Turner {
171*c120c564SAndrew Turner     resetStateParams();
172*c120c564SAndrew Turner     InitCollateDataPathResp();
173*c120c564SAndrew Turner     return executeNoneDataOpAllIDs(OCSD_OP_RESET);
174*c120c564SAndrew Turner }
175*c120c564SAndrew Turner 
176*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFmtDcdImpl::Flush()
177*c120c564SAndrew Turner {
178*c120c564SAndrew Turner     executeNoneDataOpAllIDs(OCSD_OP_FLUSH);    // flush any upstream data.
179*c120c564SAndrew Turner     if(dataPathCont())
180*c120c564SAndrew Turner         outputFrame();  // try to flush any partial frame data remaining
181*c120c564SAndrew Turner     return highestDataPathResp();
182*c120c564SAndrew Turner }
183*c120c564SAndrew Turner 
184*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFmtDcdImpl::executeNoneDataOpAllIDs(ocsd_datapath_op_t op,
185*c120c564SAndrew Turner                                                               const ocsd_trc_index_t index /* = 0*/)
186*c120c564SAndrew Turner {
187*c120c564SAndrew Turner     ITrcDataIn *pTrcComp = 0;
188*c120c564SAndrew Turner     for(uint8_t id = 0; id < 128; id++)
189*c120c564SAndrew Turner     {
190*c120c564SAndrew Turner         if(m_IDStreams[id].num_attached())
191*c120c564SAndrew Turner         {
192*c120c564SAndrew Turner             pTrcComp = m_IDStreams[id].first();
193*c120c564SAndrew Turner             while(pTrcComp)
194*c120c564SAndrew Turner             {
195*c120c564SAndrew Turner                 CollateDataPathResp(pTrcComp->TraceDataIn(op,index,0,0,0));
196*c120c564SAndrew Turner                 pTrcComp = m_IDStreams[id].next();
197*c120c564SAndrew Turner             }
198*c120c564SAndrew Turner         }
199*c120c564SAndrew Turner     }
200*c120c564SAndrew Turner 
201*c120c564SAndrew Turner     if( m_RawTraceFrame.num_attached())
202*c120c564SAndrew Turner     {
203*c120c564SAndrew Turner         if(m_RawTraceFrame.first())
204*c120c564SAndrew Turner             m_RawTraceFrame.first()->TraceRawFrameIn(op,0,OCSD_FRM_NONE,0,0,0);
205*c120c564SAndrew Turner     }
206*c120c564SAndrew Turner     return highestDataPathResp();
207*c120c564SAndrew Turner }
208*c120c564SAndrew Turner 
209*c120c564SAndrew Turner void TraceFmtDcdImpl::outputRawMonBytes(const ocsd_datapath_op_t op,
210*c120c564SAndrew Turner                            const ocsd_trc_index_t index,
211*c120c564SAndrew Turner                            const ocsd_rawframe_elem_t frame_element,
212*c120c564SAndrew Turner                            const int dataBlockSize,
213*c120c564SAndrew Turner                            const uint8_t *pDataBlock,
214*c120c564SAndrew Turner                            const uint8_t traceID)
215*c120c564SAndrew Turner {
216*c120c564SAndrew Turner     if( m_RawTraceFrame.num_attached())
217*c120c564SAndrew Turner     {
218*c120c564SAndrew Turner         if(m_RawTraceFrame.first())
219*c120c564SAndrew Turner             m_RawTraceFrame.first()->TraceRawFrameIn(op,index,frame_element,dataBlockSize, pDataBlock,traceID);
220*c120c564SAndrew Turner     }
221*c120c564SAndrew Turner }
222*c120c564SAndrew Turner 
223*c120c564SAndrew Turner void TraceFmtDcdImpl::CollateDataPathResp(const ocsd_datapath_resp_t resp)
224*c120c564SAndrew Turner {
225*c120c564SAndrew Turner     // simple most severe error across multiple IDs.
226*c120c564SAndrew Turner     if(resp > m_highestResp) m_highestResp = resp;
227*c120c564SAndrew Turner }
228*c120c564SAndrew Turner 
229*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFmtDcdImpl::processTraceData(
230*c120c564SAndrew Turner                                         const ocsd_trc_index_t index,
231*c120c564SAndrew Turner                                         const uint32_t dataBlockSize,
232*c120c564SAndrew Turner                                         const uint8_t *pDataBlock,
233*c120c564SAndrew Turner                                         uint32_t *numBytesProcessed
234*c120c564SAndrew Turner                                         )
235*c120c564SAndrew Turner {
236*c120c564SAndrew Turner     try {
237*c120c564SAndrew Turner 
238*c120c564SAndrew Turner         if(!m_first_data)  // is this the initial data block?
239*c120c564SAndrew Turner         {
240*c120c564SAndrew Turner             m_trc_curr_idx = index;
241*c120c564SAndrew Turner         }
242*c120c564SAndrew Turner         else
243*c120c564SAndrew Turner         {
244*c120c564SAndrew Turner             if(m_trc_curr_idx != index) // none continuous trace data - throw an error.
245*c120c564SAndrew Turner                 throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_DFMTR_NOTCONTTRACE,index);
246*c120c564SAndrew Turner         }
247*c120c564SAndrew Turner 
248*c120c564SAndrew Turner         if(dataBlockSize % m_alignment) // must be correctly aligned data
249*c120c564SAndrew Turner         {
250*c120c564SAndrew Turner             ocsdError err(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PARAM_VAL);
251*c120c564SAndrew Turner             char msg_buffer[64];
252*c120c564SAndrew Turner             sprintf(msg_buffer,"Input block incorrect size, must be %d byte multiple", m_alignment);
253*c120c564SAndrew Turner             err.setMessage(msg_buffer);
254*c120c564SAndrew Turner             throw ocsdError(&err);
255*c120c564SAndrew Turner         }
256*c120c564SAndrew Turner 
257*c120c564SAndrew Turner         // record the incoming block for extraction routines to use.
258*c120c564SAndrew Turner         m_in_block_base = pDataBlock;
259*c120c564SAndrew Turner         m_in_block_size = dataBlockSize;
260*c120c564SAndrew Turner         m_in_block_processed = 0;
261*c120c564SAndrew Turner 
262*c120c564SAndrew Turner         // processing loop...
263*c120c564SAndrew Turner         if(checkForSync())
264*c120c564SAndrew Turner         {
265*c120c564SAndrew Turner             bool bProcessing = true;
266*c120c564SAndrew Turner             while(bProcessing)
267*c120c564SAndrew Turner             {
268*c120c564SAndrew Turner                 bProcessing = extractFrame();   // will stop on end of input data.
269*c120c564SAndrew Turner                 if(bProcessing)
270*c120c564SAndrew Turner                     bProcessing = unpackFrame();
271*c120c564SAndrew Turner                 if(bProcessing)
272*c120c564SAndrew Turner                     bProcessing = outputFrame(); // will stop on data path halt.
273*c120c564SAndrew Turner             }
274*c120c564SAndrew Turner         }
275*c120c564SAndrew Turner     }
276*c120c564SAndrew Turner     catch(const ocsdError &err) {
277*c120c564SAndrew Turner         LogError(err);
278*c120c564SAndrew Turner         CollateDataPathResp(OCSD_RESP_FATAL_INVALID_DATA);
279*c120c564SAndrew Turner     }
280*c120c564SAndrew Turner     catch(...) {
281*c120c564SAndrew Turner         LogError(ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_FAIL));
282*c120c564SAndrew Turner         CollateDataPathResp(OCSD_RESP_FATAL_SYS_ERR);
283*c120c564SAndrew Turner     }
284*c120c564SAndrew Turner 
285*c120c564SAndrew Turner     if(!m_first_data)
286*c120c564SAndrew Turner         m_first_data = true;
287*c120c564SAndrew Turner 
288*c120c564SAndrew Turner     // update the outputs.
289*c120c564SAndrew Turner     *numBytesProcessed = m_in_block_processed;
290*c120c564SAndrew Turner 
291*c120c564SAndrew Turner     return highestDataPathResp();
292*c120c564SAndrew Turner }
293*c120c564SAndrew Turner 
294*c120c564SAndrew Turner ocsd_err_t  TraceFmtDcdImpl::DecodeConfigure(uint32_t flags)
295*c120c564SAndrew Turner {
296*c120c564SAndrew Turner     const char *pszErrMsg = "";
297*c120c564SAndrew Turner     ocsd_err_t err = OCSD_OK;
298*c120c564SAndrew Turner 
299*c120c564SAndrew Turner     if((flags & ~OCSD_DFRMTR_VALID_MASK) != 0)
300*c120c564SAndrew Turner     {
301*c120c564SAndrew Turner         err = OCSD_ERR_INVALID_PARAM_VAL;
302*c120c564SAndrew Turner         pszErrMsg = "Unknown Config Flags";
303*c120c564SAndrew Turner     }
304*c120c564SAndrew Turner 
305*c120c564SAndrew Turner     if((flags & OCSD_DFRMTR_VALID_MASK) == 0)
306*c120c564SAndrew Turner     {
307*c120c564SAndrew Turner         err = OCSD_ERR_INVALID_PARAM_VAL;
308*c120c564SAndrew Turner         pszErrMsg = "No Config Flags Set";
309*c120c564SAndrew Turner     }
310*c120c564SAndrew Turner 
311*c120c564SAndrew Turner     if((flags & (OCSD_DFRMTR_HAS_FSYNCS | OCSD_DFRMTR_HAS_HSYNCS)) &&
312*c120c564SAndrew Turner        (flags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
313*c120c564SAndrew Turner        )
314*c120c564SAndrew Turner     {
315*c120c564SAndrew Turner         err = OCSD_ERR_INVALID_PARAM_VAL;
316*c120c564SAndrew Turner         pszErrMsg = "Invalid Config Flag Combination Set";
317*c120c564SAndrew Turner     }
318*c120c564SAndrew Turner 
319*c120c564SAndrew Turner     if(err != OCSD_OK)
320*c120c564SAndrew Turner     {
321*c120c564SAndrew Turner         ocsdError errObj(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL);
322*c120c564SAndrew Turner         errObj.setMessage(pszErrMsg);
323*c120c564SAndrew Turner         LogError(errObj);
324*c120c564SAndrew Turner     }
325*c120c564SAndrew Turner     else
326*c120c564SAndrew Turner     {
327*c120c564SAndrew Turner         m_cfgFlags = flags;
328*c120c564SAndrew Turner         m_alignment = 16;
329*c120c564SAndrew Turner         if(flags & OCSD_DFRMTR_HAS_FSYNCS)
330*c120c564SAndrew Turner             m_alignment = 4;
331*c120c564SAndrew Turner         else if(flags & OCSD_DFRMTR_HAS_HSYNCS)
332*c120c564SAndrew Turner             m_alignment = 2;
333*c120c564SAndrew Turner     }
334*c120c564SAndrew Turner     return err;
335*c120c564SAndrew Turner }
336*c120c564SAndrew Turner 
337*c120c564SAndrew Turner void TraceFmtDcdImpl::resetStateParams()
338*c120c564SAndrew Turner {
339*c120c564SAndrew Turner     // overall dynamic state - intra frame
340*c120c564SAndrew Turner     m_trc_curr_idx = OCSD_BAD_TRC_INDEX;    /* source index of current trace data */
341*c120c564SAndrew Turner     m_frame_synced = false;
342*c120c564SAndrew Turner     m_first_data = false;
343*c120c564SAndrew Turner     m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
344*c120c564SAndrew Turner 
345*c120c564SAndrew Turner     // current frame processing
346*c120c564SAndrew Turner     m_ex_frm_n_bytes = 0;
347*c120c564SAndrew Turner     m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
348*c120c564SAndrew Turner }
349*c120c564SAndrew Turner 
350*c120c564SAndrew Turner bool TraceFmtDcdImpl::checkForSync()
351*c120c564SAndrew Turner {
352*c120c564SAndrew Turner     // we can sync on:-
353*c120c564SAndrew Turner     // 16 byte alignment - standard input buffers such as ETB
354*c120c564SAndrew Turner     // FSYNC packets in the stream
355*c120c564SAndrew Turner     // forced index programmed into the object.
356*c120c564SAndrew Turner     uint32_t unsynced_bytes = 0;
357*c120c564SAndrew Turner 
358*c120c564SAndrew Turner     if(!m_frame_synced)
359*c120c564SAndrew Turner     {
360*c120c564SAndrew Turner         if(m_use_force_sync)
361*c120c564SAndrew Turner         {
362*c120c564SAndrew Turner             // is the force sync point in this block?
363*c120c564SAndrew Turner             if((m_force_sync_idx >= m_trc_curr_idx) && (m_force_sync_idx < (m_trc_curr_idx + m_in_block_size)))
364*c120c564SAndrew Turner             {
365*c120c564SAndrew Turner                 unsynced_bytes = m_force_sync_idx - m_trc_curr_idx;
366*c120c564SAndrew Turner                 m_frame_synced = true;
367*c120c564SAndrew Turner             }
368*c120c564SAndrew Turner             else
369*c120c564SAndrew Turner             {
370*c120c564SAndrew Turner                 unsynced_bytes = m_in_block_size;
371*c120c564SAndrew Turner             }
372*c120c564SAndrew Turner         }
373*c120c564SAndrew Turner         else if( m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS)   // memory aligned data
374*c120c564SAndrew Turner         {
375*c120c564SAndrew Turner              unsynced_bytes = findfirstFSync();
376*c120c564SAndrew Turner 
377*c120c564SAndrew Turner         }
378*c120c564SAndrew Turner         else
379*c120c564SAndrew Turner         {
380*c120c564SAndrew Turner             // OCSD_DFRMTR_FRAME_MEM_ALIGN - this has guaranteed 16 byte frame size and alignment.
381*c120c564SAndrew Turner             m_frame_synced = true;
382*c120c564SAndrew Turner         }
383*c120c564SAndrew Turner 
384*c120c564SAndrew Turner         if(unsynced_bytes)
385*c120c564SAndrew Turner         {
386*c120c564SAndrew Turner             outputUnsyncedBytes(unsynced_bytes);
387*c120c564SAndrew Turner             m_in_block_processed = unsynced_bytes;
388*c120c564SAndrew Turner             m_trc_curr_idx += unsynced_bytes;
389*c120c564SAndrew Turner         }
390*c120c564SAndrew Turner     }
391*c120c564SAndrew Turner     return m_frame_synced;
392*c120c564SAndrew Turner }
393*c120c564SAndrew Turner 
394*c120c564SAndrew Turner uint32_t TraceFmtDcdImpl::findfirstFSync()
395*c120c564SAndrew Turner {
396*c120c564SAndrew Turner     uint32_t processed = 0;
397*c120c564SAndrew Turner     const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
398*c120c564SAndrew Turner     const uint8_t *dataPtr = m_in_block_base;
399*c120c564SAndrew Turner 
400*c120c564SAndrew Turner     while (processed < (m_in_block_size - 3))
401*c120c564SAndrew Turner     {
402*c120c564SAndrew Turner         if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
403*c120c564SAndrew Turner         {
404*c120c564SAndrew Turner             m_frame_synced = true;
405*c120c564SAndrew Turner             break;
406*c120c564SAndrew Turner         }
407*c120c564SAndrew Turner         processed++;
408*c120c564SAndrew Turner         dataPtr++;
409*c120c564SAndrew Turner     }
410*c120c564SAndrew Turner     return processed;
411*c120c564SAndrew Turner }
412*c120c564SAndrew Turner 
413*c120c564SAndrew Turner void TraceFmtDcdImpl::outputUnsyncedBytes(uint32_t /*num_bytes*/)
414*c120c564SAndrew Turner {
415*c120c564SAndrew Turner     //**TBD:
416*c120c564SAndrew Turner }
417*c120c564SAndrew Turner 
418*c120c564SAndrew Turner int TraceFmtDcdImpl::checkForResetFSyncPatterns()
419*c120c564SAndrew Turner {
420*c120c564SAndrew Turner 	const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
421*c120c564SAndrew Turner 	bool check_for_fsync = true;
422*c120c564SAndrew Turner 	int num_fsyncs = 0;
423*c120c564SAndrew Turner 	const uint8_t *dataPtr = m_in_block_base + m_in_block_processed;
424*c120c564SAndrew Turner 
425*c120c564SAndrew Turner 	while (check_for_fsync && (m_in_block_processed < m_in_block_size))
426*c120c564SAndrew Turner 	{
427*c120c564SAndrew Turner 		// look for consecutive fsyncs as padding or for reset downstream - both cases will reset downstream....
428*c120c564SAndrew Turner 		if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
429*c120c564SAndrew Turner 		{
430*c120c564SAndrew Turner 			dataPtr += sizeof(uint32_t);
431*c120c564SAndrew Turner 			num_fsyncs++;
432*c120c564SAndrew Turner 		}
433*c120c564SAndrew Turner 		else
434*c120c564SAndrew Turner 			check_for_fsync = false;
435*c120c564SAndrew Turner 	}
436*c120c564SAndrew Turner 
437*c120c564SAndrew Turner 	if (num_fsyncs)
438*c120c564SAndrew Turner 	{
439*c120c564SAndrew Turner         printf("Frame deformatter: Found %d FSYNCS\n",num_fsyncs);
440*c120c564SAndrew Turner 		if ((num_fsyncs % 4) == 0)
441*c120c564SAndrew Turner         {
442*c120c564SAndrew Turner             // reset the upstream decoders
443*c120c564SAndrew Turner 			executeNoneDataOpAllIDs(OCSD_OP_RESET,m_trc_curr_idx);
444*c120c564SAndrew Turner 
445*c120c564SAndrew Turner             // reset the intra frame parameters
446*c120c564SAndrew Turner             m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
447*c120c564SAndrew Turner             m_ex_frm_n_bytes = 0;
448*c120c564SAndrew Turner             m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
449*c120c564SAndrew Turner         }
450*c120c564SAndrew Turner 		else
451*c120c564SAndrew Turner 		{
452*c120c564SAndrew Turner 			// TBD: throw processing error, none frame size block of fsyncs
453*c120c564SAndrew Turner 		}
454*c120c564SAndrew Turner 	}
455*c120c564SAndrew Turner     return num_fsyncs * 4;
456*c120c564SAndrew Turner }
457*c120c564SAndrew Turner 
458*c120c564SAndrew Turner 
459*c120c564SAndrew Turner bool TraceFmtDcdImpl::extractFrame()
460*c120c564SAndrew Turner {
461*c120c564SAndrew Turner 	const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
462*c120c564SAndrew Turner 	const uint16_t HSYNC_PATTERN = 0x7FFF;        // LE host pattern for HSYNC
463*c120c564SAndrew Turner 
464*c120c564SAndrew Turner 
465*c120c564SAndrew Turner 	bool cont_process = true;   // continue processing after extraction.
466*c120c564SAndrew Turner     uint32_t f_sync_bytes = 0; // skipped f sync bytes
467*c120c564SAndrew Turner     uint32_t h_sync_bytes = 0; // skipped h sync bytes
468*c120c564SAndrew Turner     uint32_t ex_bytes = 0;  // extracted this pass (may be filling out part frame)
469*c120c564SAndrew Turner 
470*c120c564SAndrew Turner     // memory aligned sources are always multiples of frames, aligned to start.
471*c120c564SAndrew Turner     if( m_cfgFlags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
472*c120c564SAndrew Turner     {
473*c120c564SAndrew Turner 		// some linux drivers (e.g. for perf) will insert FSYNCS to pad or differentiate
474*c120c564SAndrew Turner         // between blocks of aligned data, always in frame aligned complete 16 byte frames.
475*c120c564SAndrew Turner         if (m_cfgFlags & OCSD_DFRMTR_RESET_ON_4X_FSYNC)
476*c120c564SAndrew Turner         {
477*c120c564SAndrew Turner             f_sync_bytes = checkForResetFSyncPatterns();
478*c120c564SAndrew Turner 
479*c120c564SAndrew Turner             /* in this case the FSYNC pattern is output on both packed and unpacked cases */
480*c120c564SAndrew Turner             if (f_sync_bytes && (m_b_output_packed_raw || m_b_output_unpacked_raw))
481*c120c564SAndrew Turner             {
482*c120c564SAndrew Turner                 outputRawMonBytes(OCSD_OP_DATA,
483*c120c564SAndrew Turner                     m_trc_curr_idx,
484*c120c564SAndrew Turner                     OCSD_FRM_FSYNC,
485*c120c564SAndrew Turner                     f_sync_bytes,
486*c120c564SAndrew Turner                     m_in_block_base + m_in_block_processed,
487*c120c564SAndrew Turner                     0);
488*c120c564SAndrew Turner             }
489*c120c564SAndrew Turner         }
490*c120c564SAndrew Turner 
491*c120c564SAndrew Turner         if((m_in_block_processed+f_sync_bytes) == m_in_block_size)
492*c120c564SAndrew Turner         {
493*c120c564SAndrew Turner             m_ex_frm_n_bytes = 0;
494*c120c564SAndrew Turner             cont_process = false;   // end of input data.
495*c120c564SAndrew Turner         }
496*c120c564SAndrew Turner 		else
497*c120c564SAndrew Turner 		{
498*c120c564SAndrew Turner 			// always a complete frame.
499*c120c564SAndrew Turner 			m_ex_frm_n_bytes = OCSD_DFRMTR_FRAME_SIZE;
500*c120c564SAndrew Turner 			memcpy(m_ex_frm_data, m_in_block_base + m_in_block_processed + f_sync_bytes, m_ex_frm_n_bytes);
501*c120c564SAndrew Turner 			m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
502*c120c564SAndrew Turner 			ex_bytes = OCSD_DFRMTR_FRAME_SIZE;
503*c120c564SAndrew Turner         }
504*c120c564SAndrew Turner     }
505*c120c564SAndrew Turner     else
506*c120c564SAndrew Turner     {
507*c120c564SAndrew Turner         // extract data accounting for frame syncs and hsyncs if present.
508*c120c564SAndrew Turner         // we know we are aligned at this point - could be FSYNC or HSYNCs here.
509*c120c564SAndrew Turner 
510*c120c564SAndrew Turner         // check what we a looking for
511*c120c564SAndrew Turner         bool hasFSyncs =  ((m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) == OCSD_DFRMTR_HAS_FSYNCS);
512*c120c564SAndrew Turner         bool hasHSyncs =  ((m_cfgFlags & OCSD_DFRMTR_HAS_HSYNCS) == OCSD_DFRMTR_HAS_HSYNCS);
513*c120c564SAndrew Turner 
514*c120c564SAndrew Turner         const uint8_t *dataPtr = m_in_block_base+m_in_block_processed;
515*c120c564SAndrew Turner         const uint8_t *eodPtr = m_in_block_base+m_in_block_size;
516*c120c564SAndrew Turner 
517*c120c564SAndrew Turner         cont_process = (bool)(dataPtr < eodPtr);
518*c120c564SAndrew Turner 
519*c120c564SAndrew Turner         // can have FSYNCS at start of frame (in middle is an error).
520*c120c564SAndrew Turner         if(hasFSyncs && cont_process && (m_ex_frm_n_bytes == 0))
521*c120c564SAndrew Turner         {
522*c120c564SAndrew Turner             while((*((uint32_t *)(dataPtr)) == FSYNC_PATTERN) && cont_process)
523*c120c564SAndrew Turner             {
524*c120c564SAndrew Turner                 f_sync_bytes += 4;
525*c120c564SAndrew Turner                 dataPtr += 4;
526*c120c564SAndrew Turner                 cont_process = (bool)(dataPtr < eodPtr);
527*c120c564SAndrew Turner             }
528*c120c564SAndrew Turner         }
529*c120c564SAndrew Turner 
530*c120c564SAndrew Turner         // not an FSYNC
531*c120c564SAndrew Turner         while((m_ex_frm_n_bytes < OCSD_DFRMTR_FRAME_SIZE) && cont_process)
532*c120c564SAndrew Turner         {
533*c120c564SAndrew Turner             // check for illegal out of sequence FSYNC
534*c120c564SAndrew Turner             if((m_ex_frm_n_bytes % 4) == 0)
535*c120c564SAndrew Turner             {
536*c120c564SAndrew Turner                 if(*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
537*c120c564SAndrew Turner                 {
538*c120c564SAndrew Turner                     // throw an illegal FSYNC error
539*c120c564SAndrew Turner                     throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad FSYNC in frame.");
540*c120c564SAndrew Turner                 }
541*c120c564SAndrew Turner             }
542*c120c564SAndrew Turner 
543*c120c564SAndrew Turner             // mark start of frame after FSyncs
544*c120c564SAndrew Turner             if(m_ex_frm_n_bytes == 0)
545*c120c564SAndrew Turner                 m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
546*c120c564SAndrew Turner 
547*c120c564SAndrew Turner             m_ex_frm_data[m_ex_frm_n_bytes] = dataPtr[0];
548*c120c564SAndrew Turner             m_ex_frm_data[m_ex_frm_n_bytes+1] = dataPtr[1];
549*c120c564SAndrew Turner             m_ex_frm_n_bytes+=2;
550*c120c564SAndrew Turner             ex_bytes +=2;
551*c120c564SAndrew Turner 
552*c120c564SAndrew Turner             // check pair is not HSYNC
553*c120c564SAndrew Turner             if(*((uint16_t *)(dataPtr)) == HSYNC_PATTERN)
554*c120c564SAndrew Turner             {
555*c120c564SAndrew Turner                 if(hasHSyncs)
556*c120c564SAndrew Turner                 {
557*c120c564SAndrew Turner                     m_ex_frm_n_bytes-=2;
558*c120c564SAndrew Turner                     ex_bytes -= 2;
559*c120c564SAndrew Turner                     h_sync_bytes+=2;
560*c120c564SAndrew Turner                 }
561*c120c564SAndrew Turner                 else
562*c120c564SAndrew Turner                 {
563*c120c564SAndrew Turner                     // throw illegal HSYNC error.
564*c120c564SAndrew Turner                     throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad HSYNC in frame.");
565*c120c564SAndrew Turner                 }
566*c120c564SAndrew Turner             }
567*c120c564SAndrew Turner 
568*c120c564SAndrew Turner             dataPtr += 2;
569*c120c564SAndrew Turner             cont_process = (bool)(dataPtr < eodPtr);
570*c120c564SAndrew Turner         }
571*c120c564SAndrew Turner 
572*c120c564SAndrew Turner         // if we hit the end of data but still have a complete frame waiting,
573*c120c564SAndrew Turner         // need to continue processing to allow it to be used.
574*c120c564SAndrew Turner         if(!cont_process && (m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE))
575*c120c564SAndrew Turner             cont_process = true;
576*c120c564SAndrew Turner     }
577*c120c564SAndrew Turner 
578*c120c564SAndrew Turner     // total bytes processed this pass
579*c120c564SAndrew Turner     uint32_t total_processed = ex_bytes + f_sync_bytes + h_sync_bytes;
580*c120c564SAndrew Turner 
581*c120c564SAndrew Turner     // output raw data on raw frame channel - packed raw.
582*c120c564SAndrew Turner     if (((m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE) || !cont_process) && m_b_output_packed_raw)
583*c120c564SAndrew Turner     {
584*c120c564SAndrew Turner         outputRawMonBytes(  OCSD_OP_DATA,
585*c120c564SAndrew Turner                             m_trc_curr_idx,
586*c120c564SAndrew Turner                             OCSD_FRM_PACKED,
587*c120c564SAndrew Turner                             total_processed,
588*c120c564SAndrew Turner                             m_in_block_base+m_in_block_processed,
589*c120c564SAndrew Turner                             0);
590*c120c564SAndrew Turner     }
591*c120c564SAndrew Turner 
592*c120c564SAndrew Turner     // update the processed count for the buffer
593*c120c564SAndrew Turner     m_in_block_processed += total_processed;
594*c120c564SAndrew Turner 
595*c120c564SAndrew Turner     // update index past the processed data
596*c120c564SAndrew Turner     m_trc_curr_idx += total_processed;
597*c120c564SAndrew Turner 
598*c120c564SAndrew Turner     return cont_process;
599*c120c564SAndrew Turner }
600*c120c564SAndrew Turner 
601*c120c564SAndrew Turner bool TraceFmtDcdImpl::unpackFrame()
602*c120c564SAndrew Turner {
603*c120c564SAndrew Turner     // unpack cannot fail as never called on incomplete frame.
604*c120c564SAndrew Turner     uint8_t frameFlagBit = 0x1;
605*c120c564SAndrew Turner     uint8_t newSrcID = OCSD_BAD_CS_SRC_ID;
606*c120c564SAndrew Turner     bool PrevIDandIDChange = false;
607*c120c564SAndrew Turner 
608*c120c564SAndrew Turner     // init output processing
609*c120c564SAndrew Turner     m_out_data_idx = 0;
610*c120c564SAndrew Turner     m_out_processed = 0;
611*c120c564SAndrew Turner 
612*c120c564SAndrew Turner     // set up first out data packet...
613*c120c564SAndrew Turner     m_out_data[m_out_data_idx].id = m_curr_src_ID;
614*c120c564SAndrew Turner     m_out_data[m_out_data_idx].valid = 0;
615*c120c564SAndrew Turner     m_out_data[m_out_data_idx].index =  m_trc_curr_idx_sof;
616*c120c564SAndrew Turner     m_out_data[m_out_data_idx].used = 0;
617*c120c564SAndrew Turner 
618*c120c564SAndrew Turner     // work on byte pairs - bytes 0 - 13.
619*c120c564SAndrew Turner     for(int i = 0; i < 14; i+=2)
620*c120c564SAndrew Turner     {
621*c120c564SAndrew Turner         PrevIDandIDChange = false;
622*c120c564SAndrew Turner 
623*c120c564SAndrew Turner         // it's an ID + data
624*c120c564SAndrew Turner         if(m_ex_frm_data[i] & 0x1)
625*c120c564SAndrew Turner         {
626*c120c564SAndrew Turner             newSrcID = (m_ex_frm_data[i] >> 1) & 0x7f;
627*c120c564SAndrew Turner             if(newSrcID != m_curr_src_ID)   // ID change
628*c120c564SAndrew Turner             {
629*c120c564SAndrew Turner                 PrevIDandIDChange = ((frameFlagBit & m_ex_frm_data[15]) != 0);
630*c120c564SAndrew Turner 
631*c120c564SAndrew Turner                 // following byte for old id?
632*c120c564SAndrew Turner                 if(PrevIDandIDChange)
633*c120c564SAndrew Turner                     // 2nd byte always data
634*c120c564SAndrew Turner                     m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
635*c120c564SAndrew Turner 
636*c120c564SAndrew Turner                 // change ID
637*c120c564SAndrew Turner                 m_curr_src_ID = newSrcID;
638*c120c564SAndrew Turner 
639*c120c564SAndrew Turner                 // if we already have data in this buffer
640*c120c564SAndrew Turner                 if(m_out_data[m_out_data_idx].valid > 0)
641*c120c564SAndrew Turner                 {
642*c120c564SAndrew Turner                     m_out_data_idx++; // move to next buffer
643*c120c564SAndrew Turner                     m_out_data[m_out_data_idx].valid = 0;
644*c120c564SAndrew Turner                     m_out_data[m_out_data_idx].used = 0;
645*c120c564SAndrew Turner                     m_out_data[m_out_data_idx].index = m_trc_curr_idx_sof + i;
646*c120c564SAndrew Turner                 }
647*c120c564SAndrew Turner 
648*c120c564SAndrew Turner                 // set new ID on buffer
649*c120c564SAndrew Turner                 m_out_data[m_out_data_idx].id = m_curr_src_ID;
650*c120c564SAndrew Turner 
651*c120c564SAndrew Turner                 /// TBD - ID indexing in here.
652*c120c564SAndrew Turner             }
653*c120c564SAndrew Turner         }
654*c120c564SAndrew Turner         else
655*c120c564SAndrew Turner         // it's just data
656*c120c564SAndrew Turner         {
657*c120c564SAndrew Turner             m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i] | ((frameFlagBit & m_ex_frm_data[15]) ? 0x1 : 0x0);
658*c120c564SAndrew Turner         }
659*c120c564SAndrew Turner 
660*c120c564SAndrew Turner         // 2nd byte always data
661*c120c564SAndrew Turner         if(!PrevIDandIDChange) // output only if we didn't for an ID change + prev ID.
662*c120c564SAndrew Turner             m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
663*c120c564SAndrew Turner 
664*c120c564SAndrew Turner         frameFlagBit <<= 1;
665*c120c564SAndrew Turner     }
666*c120c564SAndrew Turner 
667*c120c564SAndrew Turner     // unpack byte 14;
668*c120c564SAndrew Turner 
669*c120c564SAndrew Turner     // it's an ID
670*c120c564SAndrew Turner     if(m_ex_frm_data[14] & 0x1)
671*c120c564SAndrew Turner     {
672*c120c564SAndrew Turner         // no matter if change or not, no associated data in byte 15 anyway so just set.
673*c120c564SAndrew Turner         m_curr_src_ID = (m_ex_frm_data[14] >> 1) & 0x7f;
674*c120c564SAndrew Turner     }
675*c120c564SAndrew Turner     // it's data
676*c120c564SAndrew Turner     else
677*c120c564SAndrew Turner     {
678*c120c564SAndrew Turner         m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[14] | ((frameFlagBit & m_ex_frm_data[15]) ? 0x1 : 0x0);
679*c120c564SAndrew Turner     }
680*c120c564SAndrew Turner     m_ex_frm_n_bytes = 0;   // mark frame as empty;
681*c120c564SAndrew Turner     return true;
682*c120c564SAndrew Turner }
683*c120c564SAndrew Turner 
684*c120c564SAndrew Turner // output data to channels.
685*c120c564SAndrew Turner bool TraceFmtDcdImpl::outputFrame()
686*c120c564SAndrew Turner {
687*c120c564SAndrew Turner     bool cont_processing = true;
688*c120c564SAndrew Turner     ITrcDataIn *pDataIn = 0;
689*c120c564SAndrew Turner     uint32_t bytes_used;
690*c120c564SAndrew Turner 
691*c120c564SAndrew Turner     // output each valid ID within the frame - stopping if we get a wait or error
692*c120c564SAndrew Turner     while((m_out_processed < (m_out_data_idx + 1)) && cont_processing)
693*c120c564SAndrew Turner     {
694*c120c564SAndrew Turner 
695*c120c564SAndrew Turner         // may have data prior to a valid ID appearing
696*c120c564SAndrew Turner         if(m_out_data[m_out_processed].id != OCSD_BAD_CS_SRC_ID)
697*c120c564SAndrew Turner         {
698*c120c564SAndrew Turner             if((pDataIn = m_IDStreams[m_out_data[m_out_processed].id].first()) != 0)
699*c120c564SAndrew Turner             {
700*c120c564SAndrew Turner                 // log the stuff we are about to put out early so as to make it visible before interpretation
701*c120c564SAndrew Turner                 // however, don't re-output if only part used first time round.
702*c120c564SAndrew Turner                 if(m_b_output_unpacked_raw && (m_out_data[m_out_processed].used == 0) && rawChanEnabled( m_out_data[m_out_processed].id))
703*c120c564SAndrew Turner                 {
704*c120c564SAndrew Turner                     outputRawMonBytes( OCSD_OP_DATA,
705*c120c564SAndrew Turner                             m_out_data[m_out_processed].index,
706*c120c564SAndrew Turner                             OCSD_FRM_ID_DATA,
707*c120c564SAndrew Turner                             m_out_data[m_out_processed].valid,
708*c120c564SAndrew Turner                             m_out_data[m_out_processed].data,
709*c120c564SAndrew Turner                             m_out_data[m_out_processed].id);
710*c120c564SAndrew Turner                 }
711*c120c564SAndrew Turner 
712*c120c564SAndrew Turner                 // output to the connected packet process
713*c120c564SAndrew Turner                 CollateDataPathResp(pDataIn->TraceDataIn(OCSD_OP_DATA,
714*c120c564SAndrew Turner                     m_out_data[m_out_processed].index + m_out_data[m_out_processed].used,
715*c120c564SAndrew Turner                     m_out_data[m_out_processed].valid - m_out_data[m_out_processed].used,
716*c120c564SAndrew Turner                     m_out_data[m_out_processed].data + m_out_data[m_out_processed].used,
717*c120c564SAndrew Turner                     &bytes_used));
718*c120c564SAndrew Turner 
719*c120c564SAndrew Turner                 if(!dataPathCont())
720*c120c564SAndrew Turner                 {
721*c120c564SAndrew Turner                     cont_processing = false;
722*c120c564SAndrew Turner                     m_out_data[m_out_processed].used += bytes_used;
723*c120c564SAndrew Turner                     if(m_out_data[m_out_processed].used == m_out_data[m_out_processed].valid)
724*c120c564SAndrew Turner                         m_out_processed++; // we have used up all this data.
725*c120c564SAndrew Turner                 }
726*c120c564SAndrew Turner                 else
727*c120c564SAndrew Turner                 {
728*c120c564SAndrew Turner                     m_out_processed++; // we have sent this data;
729*c120c564SAndrew Turner                 }
730*c120c564SAndrew Turner             }
731*c120c564SAndrew Turner             else
732*c120c564SAndrew Turner             {
733*c120c564SAndrew Turner                 // optional raw output for debugging / monitor tools
734*c120c564SAndrew Turner                 if(m_b_output_unpacked_raw && rawChanEnabled( m_out_data[m_out_processed].id))
735*c120c564SAndrew Turner                 {
736*c120c564SAndrew Turner                     outputRawMonBytes(  OCSD_OP_DATA,
737*c120c564SAndrew Turner                         m_out_data[m_out_processed].index,
738*c120c564SAndrew Turner                         OCSD_FRM_ID_DATA,
739*c120c564SAndrew Turner                         m_out_data[m_out_processed].valid,
740*c120c564SAndrew Turner                         m_out_data[m_out_processed].data,
741*c120c564SAndrew Turner                         m_out_data[m_out_processed].id);
742*c120c564SAndrew Turner                 }
743*c120c564SAndrew Turner                 m_out_processed++; // skip past this data.
744*c120c564SAndrew Turner             }
745*c120c564SAndrew Turner         }
746*c120c564SAndrew Turner         else
747*c120c564SAndrew Turner         {
748*c120c564SAndrew Turner             // optional raw output for debugging / monitor tools of unknown src ID data
749*c120c564SAndrew Turner             if(m_b_output_unpacked_raw)
750*c120c564SAndrew Turner             {
751*c120c564SAndrew Turner                 outputRawMonBytes(  OCSD_OP_DATA,
752*c120c564SAndrew Turner                     m_out_data[m_out_processed].index,
753*c120c564SAndrew Turner                     OCSD_FRM_ID_DATA,
754*c120c564SAndrew Turner                     m_out_data[m_out_processed].valid,
755*c120c564SAndrew Turner                     m_out_data[m_out_processed].data,
756*c120c564SAndrew Turner                     m_out_data[m_out_processed].id);
757*c120c564SAndrew Turner             }
758*c120c564SAndrew Turner             m_out_processed++; // skip past this data.
759*c120c564SAndrew Turner         }
760*c120c564SAndrew Turner     }
761*c120c564SAndrew Turner     return cont_processing;
762*c120c564SAndrew Turner }
763*c120c564SAndrew Turner 
764*c120c564SAndrew Turner /***************************************************************/
765*c120c564SAndrew Turner /* interface */
766*c120c564SAndrew Turner /***************************************************************/
767*c120c564SAndrew Turner TraceFormatterFrameDecoder::TraceFormatterFrameDecoder() : m_pDecoder(0)
768*c120c564SAndrew Turner {
769*c120c564SAndrew Turner     m_instNum = -1;
770*c120c564SAndrew Turner }
771*c120c564SAndrew Turner 
772*c120c564SAndrew Turner TraceFormatterFrameDecoder::TraceFormatterFrameDecoder(int instNum) : m_pDecoder(0)
773*c120c564SAndrew Turner {
774*c120c564SAndrew Turner     m_instNum = instNum;
775*c120c564SAndrew Turner }
776*c120c564SAndrew Turner 
777*c120c564SAndrew Turner TraceFormatterFrameDecoder::~TraceFormatterFrameDecoder()
778*c120c564SAndrew Turner {
779*c120c564SAndrew Turner     if(m_pDecoder)
780*c120c564SAndrew Turner     {
781*c120c564SAndrew Turner         delete m_pDecoder;
782*c120c564SAndrew Turner         m_pDecoder = 0;
783*c120c564SAndrew Turner     }
784*c120c564SAndrew Turner }
785*c120c564SAndrew Turner 
786*c120c564SAndrew Turner     /* the data input interface from the reader / source */
787*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFormatterFrameDecoder::TraceDataIn(  const ocsd_datapath_op_t op,
788*c120c564SAndrew Turner                                                                 const ocsd_trc_index_t index,
789*c120c564SAndrew Turner                                                                 const uint32_t dataBlockSize,
790*c120c564SAndrew Turner                                                                 const uint8_t *pDataBlock,
791*c120c564SAndrew Turner                                                                 uint32_t *numBytesProcessed)
792*c120c564SAndrew Turner {
793*c120c564SAndrew Turner     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
794*c120c564SAndrew Turner }
795*c120c564SAndrew Turner 
796*c120c564SAndrew Turner /* attach a data processor to a stream ID output */
797*c120c564SAndrew Turner componentAttachPt<ITrcDataIn> *TraceFormatterFrameDecoder::getIDStreamAttachPt(uint8_t ID)
798*c120c564SAndrew Turner {
799*c120c564SAndrew Turner     componentAttachPt<ITrcDataIn> *pAttachPt = 0;
800*c120c564SAndrew Turner     if((ID < 128) && (m_pDecoder != 0))
801*c120c564SAndrew Turner         pAttachPt = &(m_pDecoder->m_IDStreams[ID]);
802*c120c564SAndrew Turner     return pAttachPt;
803*c120c564SAndrew Turner }
804*c120c564SAndrew Turner 
805*c120c564SAndrew Turner /* attach a data processor to the raw frame output */
806*c120c564SAndrew Turner componentAttachPt<ITrcRawFrameIn> *TraceFormatterFrameDecoder::getTrcRawFrameAttachPt()
807*c120c564SAndrew Turner {
808*c120c564SAndrew Turner     return (m_pDecoder != 0) ? &m_pDecoder->m_RawTraceFrame : 0;
809*c120c564SAndrew Turner }
810*c120c564SAndrew Turner 
811*c120c564SAndrew Turner 
812*c120c564SAndrew Turner componentAttachPt<ITrcSrcIndexCreator> *TraceFormatterFrameDecoder::getTrcSrcIndexAttachPt()
813*c120c564SAndrew Turner {
814*c120c564SAndrew Turner     return (m_pDecoder != 0) ? &m_pDecoder->m_SrcIndexer : 0;
815*c120c564SAndrew Turner }
816*c120c564SAndrew Turner 
817*c120c564SAndrew Turner componentAttachPt<ITraceErrorLog> *TraceFormatterFrameDecoder::getErrLogAttachPt()
818*c120c564SAndrew Turner {
819*c120c564SAndrew Turner     return (m_pDecoder != 0) ? m_pDecoder->getErrorLogAttachPt() : 0;
820*c120c564SAndrew Turner }
821*c120c564SAndrew Turner 
822*c120c564SAndrew Turner /* configuration - set operational mode for incoming stream (has FSYNCS etc) */
823*c120c564SAndrew Turner ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags)
824*c120c564SAndrew Turner {
825*c120c564SAndrew Turner     if(!m_pDecoder)
826*c120c564SAndrew Turner     {
827*c120c564SAndrew Turner         if(m_instNum >= 0)
828*c120c564SAndrew Turner             m_pDecoder = new (std::nothrow) TraceFmtDcdImpl(m_instNum);
829*c120c564SAndrew Turner         else
830*c120c564SAndrew Turner             m_pDecoder = new (std::nothrow) TraceFmtDcdImpl();
831*c120c564SAndrew Turner         if(!m_pDecoder) return OCSD_ERR_MEM;
832*c120c564SAndrew Turner     }
833*c120c564SAndrew Turner     m_pDecoder->DecodeConfigure(cfg_flags);
834*c120c564SAndrew Turner     return OCSD_OK;
835*c120c564SAndrew Turner }
836*c120c564SAndrew Turner 
837*c120c564SAndrew Turner const uint32_t TraceFormatterFrameDecoder::getConfigFlags() const
838*c120c564SAndrew Turner {
839*c120c564SAndrew Turner     uint32_t flags = 0;
840*c120c564SAndrew Turner     if(m_pDecoder)
841*c120c564SAndrew Turner         flags = m_pDecoder->m_cfgFlags;
842*c120c564SAndrew Turner     return flags;
843*c120c564SAndrew Turner }
844*c120c564SAndrew Turner 
845*c120c564SAndrew Turner 
846*c120c564SAndrew Turner /* enable / disable ID streams - default as all enabled */
847*c120c564SAndrew Turner ocsd_err_t TraceFormatterFrameDecoder::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
848*c120c564SAndrew Turner {
849*c120c564SAndrew Turner     return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterIDs(id_list,bEnable);
850*c120c564SAndrew Turner }
851*c120c564SAndrew Turner 
852*c120c564SAndrew Turner ocsd_err_t TraceFormatterFrameDecoder::OutputFilterAllIDs(bool bEnable)
853*c120c564SAndrew Turner {
854*c120c564SAndrew Turner     return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterAllIDs(bEnable);
855*c120c564SAndrew Turner }
856*c120c564SAndrew Turner 
857*c120c564SAndrew Turner /* decode control */
858*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFormatterFrameDecoder::Reset()
859*c120c564SAndrew Turner {
860*c120c564SAndrew Turner     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Reset();
861*c120c564SAndrew Turner }
862*c120c564SAndrew Turner 
863*c120c564SAndrew Turner ocsd_datapath_resp_t TraceFormatterFrameDecoder::Flush()
864*c120c564SAndrew Turner {
865*c120c564SAndrew Turner     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Flush();
866*c120c564SAndrew Turner }
867*c120c564SAndrew Turner 
868*c120c564SAndrew Turner 
869*c120c564SAndrew Turner /* End of File trc_frame_deformatter.cpp */
870