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