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