117f65170SRuslan Bukin /*
217f65170SRuslan Bukin  * \file       trc_frame_deformatter.cpp
317f65170SRuslan Bukin  * \brief      OpenCSD :
417f65170SRuslan Bukin  *
517f65170SRuslan Bukin  * \copyright  Copyright (c) 2015, ARM Limited. All Rights Reserved.
617f65170SRuslan Bukin  */
717f65170SRuslan Bukin 
817f65170SRuslan Bukin /*
917f65170SRuslan Bukin  * Redistribution and use in source and binary forms, with or without modification,
1017f65170SRuslan Bukin  * are permitted provided that the following conditions are met:
1117f65170SRuslan Bukin  *
1217f65170SRuslan Bukin  * 1. Redistributions of source code must retain the above copyright notice,
1317f65170SRuslan Bukin  * this list of conditions and the following disclaimer.
1417f65170SRuslan Bukin  *
1517f65170SRuslan Bukin  * 2. Redistributions in binary form must reproduce the above copyright notice,
1617f65170SRuslan Bukin  * this list of conditions and the following disclaimer in the documentation
1717f65170SRuslan Bukin  * and/or other materials provided with the distribution.
1817f65170SRuslan Bukin  *
1917f65170SRuslan Bukin  * 3. Neither the name of the copyright holder nor the names of its contributors
2017f65170SRuslan Bukin  * may be used to endorse or promote products derived from this software without
2117f65170SRuslan Bukin  * specific prior written permission.
2217f65170SRuslan Bukin  *
2317f65170SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
2417f65170SRuslan Bukin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2517f65170SRuslan Bukin  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2617f65170SRuslan Bukin  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2717f65170SRuslan Bukin  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2817f65170SRuslan Bukin  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2917f65170SRuslan Bukin  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3017f65170SRuslan Bukin  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3117f65170SRuslan Bukin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3217f65170SRuslan Bukin  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3317f65170SRuslan Bukin  */
3417f65170SRuslan Bukin #include <cstring>
3517f65170SRuslan Bukin 
3617f65170SRuslan Bukin #include "common/trc_frame_deformatter.h"
3717f65170SRuslan Bukin #include "trc_frame_deformatter_impl.h"
3817f65170SRuslan Bukin 
3917f65170SRuslan Bukin /***************************************************************/
4017f65170SRuslan Bukin /* Implementation */
4117f65170SRuslan Bukin /***************************************************************/
4217f65170SRuslan Bukin 
4317f65170SRuslan Bukin #ifdef __GNUC__
4417f65170SRuslan Bukin // G++ doesn't like the ## pasting
4517f65170SRuslan Bukin #define DEFORMATTER_NAME "DFMT_CSFRAMES"
4617f65170SRuslan Bukin #else
4717f65170SRuslan Bukin // VC is fine
4817f65170SRuslan Bukin #define DEFORMATTER_NAME OCSD_CMPNAME_PREFIX_FRAMEDEFORMATTER##"_CSFRAMES"
4917f65170SRuslan Bukin #endif
5017f65170SRuslan Bukin 
TraceFmtDcdImpl()5117f65170SRuslan Bukin TraceFmtDcdImpl::TraceFmtDcdImpl() : TraceComponent(DEFORMATTER_NAME),
5217f65170SRuslan Bukin     m_cfgFlags(0),
5317f65170SRuslan Bukin     m_force_sync_idx(0),
5417f65170SRuslan Bukin     m_use_force_sync(false),
5517f65170SRuslan Bukin     m_alignment(16), // assume frame aligned data as default.
5617f65170SRuslan Bukin     m_b_output_packed_raw(false),
5717f65170SRuslan Bukin     m_b_output_unpacked_raw(false)
5817f65170SRuslan Bukin 
5917f65170SRuslan Bukin {
6017f65170SRuslan Bukin     resetStateParams();
6117f65170SRuslan Bukin     setRawChanFilterAll(true);
6217f65170SRuslan Bukin }
6317f65170SRuslan Bukin 
TraceFmtDcdImpl(int instNum)6417f65170SRuslan Bukin TraceFmtDcdImpl::TraceFmtDcdImpl(int instNum) : TraceComponent(DEFORMATTER_NAME, instNum),
6517f65170SRuslan Bukin     m_cfgFlags(0),
6617f65170SRuslan Bukin     m_force_sync_idx(0),
6717f65170SRuslan Bukin     m_use_force_sync(false),
6817f65170SRuslan Bukin     m_alignment(16)
6917f65170SRuslan Bukin {
7017f65170SRuslan Bukin     resetStateParams();
7117f65170SRuslan Bukin     setRawChanFilterAll(true);
7217f65170SRuslan Bukin }
7317f65170SRuslan Bukin 
~TraceFmtDcdImpl()7417f65170SRuslan Bukin TraceFmtDcdImpl::~TraceFmtDcdImpl()
7517f65170SRuslan Bukin {
7617f65170SRuslan Bukin }
7717f65170SRuslan 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)7817f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::TraceDataIn(
7917f65170SRuslan Bukin     const ocsd_datapath_op_t op,
8017f65170SRuslan Bukin     const ocsd_trc_index_t index,
8117f65170SRuslan Bukin     const uint32_t dataBlockSize,
8217f65170SRuslan Bukin     const uint8_t *pDataBlock,
8317f65170SRuslan Bukin     uint32_t *numBytesProcessed)
8417f65170SRuslan Bukin {
8517f65170SRuslan Bukin     ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_INVALID_OP;
8617f65170SRuslan Bukin     InitCollateDataPathResp();
8717f65170SRuslan Bukin 
8817f65170SRuslan Bukin     m_b_output_packed_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_PACKED_RAW_OUT) != 0);
8917f65170SRuslan Bukin     m_b_output_unpacked_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_UNPACKED_RAW_OUT) != 0);
9017f65170SRuslan Bukin 
9117f65170SRuslan Bukin     switch(op)
9217f65170SRuslan Bukin     {
9317f65170SRuslan Bukin     case OCSD_OP_RESET:
9417f65170SRuslan Bukin         resp = Reset();
9517f65170SRuslan Bukin         break;
9617f65170SRuslan Bukin 
9717f65170SRuslan Bukin     case OCSD_OP_FLUSH:
9817f65170SRuslan Bukin         resp = Flush();
9917f65170SRuslan Bukin         break;
10017f65170SRuslan Bukin 
10117f65170SRuslan Bukin     case OCSD_OP_EOT:
10217f65170SRuslan Bukin         // local 'flush' here?
10317f65170SRuslan Bukin         // pass on EOT to connected ID streams
10417f65170SRuslan Bukin         resp = executeNoneDataOpAllIDs(OCSD_OP_EOT);
10517f65170SRuslan Bukin         break;
10617f65170SRuslan Bukin 
10717f65170SRuslan Bukin     case OCSD_OP_DATA:
10817f65170SRuslan Bukin         if((dataBlockSize <= 0) || ( pDataBlock == 0) || (numBytesProcessed == 0))
10917f65170SRuslan Bukin             resp = OCSD_RESP_FATAL_INVALID_PARAM;
11017f65170SRuslan Bukin         else
11117f65170SRuslan Bukin             resp = processTraceData(index,dataBlockSize, pDataBlock, numBytesProcessed);
11217f65170SRuslan Bukin         break;
11317f65170SRuslan Bukin 
11417f65170SRuslan Bukin     default:
11517f65170SRuslan Bukin         break;
11617f65170SRuslan Bukin     }
11717f65170SRuslan Bukin 
11817f65170SRuslan Bukin     return resp;
11917f65170SRuslan Bukin }
12017f65170SRuslan Bukin 
12117f65170SRuslan Bukin /* enable / disable ID streams - default as all enabled */
OutputFilterIDs(std::vector<uint8_t> & id_list,bool bEnable)12217f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
12317f65170SRuslan Bukin {
12417f65170SRuslan Bukin     ocsd_err_t err =  OCSD_OK;
12517f65170SRuslan Bukin     std::vector<uint8_t>::iterator iter = id_list.begin();
12617f65170SRuslan Bukin     uint8_t id = 0;
12717f65170SRuslan Bukin 
12817f65170SRuslan Bukin     while((iter < id_list.end()) && (err == OCSD_OK))
12917f65170SRuslan Bukin     {
13017f65170SRuslan Bukin         id = *iter;
13117f65170SRuslan Bukin         if(id > 128)
13217f65170SRuslan Bukin             err = OCSD_ERR_INVALID_ID;
13317f65170SRuslan Bukin         else
13417f65170SRuslan Bukin         {
13517f65170SRuslan Bukin             m_IDStreams[id].set_enabled(bEnable);
13617f65170SRuslan Bukin             m_raw_chan_enable[id] = bEnable;
13717f65170SRuslan Bukin         }
13817f65170SRuslan Bukin         iter++;
13917f65170SRuslan Bukin     }
14017f65170SRuslan Bukin     return err;
14117f65170SRuslan Bukin }
14217f65170SRuslan Bukin 
OutputFilterAllIDs(bool bEnable)14317f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::OutputFilterAllIDs(bool bEnable)
14417f65170SRuslan Bukin {
14517f65170SRuslan Bukin     for(uint8_t id = 0; id < 128; id++)
14617f65170SRuslan Bukin     {
14717f65170SRuslan Bukin         m_IDStreams[id].set_enabled(bEnable);
14817f65170SRuslan Bukin     }
14917f65170SRuslan Bukin     setRawChanFilterAll(bEnable);
15017f65170SRuslan Bukin     return OCSD_OK;
15117f65170SRuslan Bukin }
15217f65170SRuslan Bukin 
setRawChanFilterAll(bool bEnable)15317f65170SRuslan Bukin void TraceFmtDcdImpl::setRawChanFilterAll(bool bEnable)
15417f65170SRuslan Bukin {
15517f65170SRuslan Bukin     for(int i=0; i<128; i++)
15617f65170SRuslan Bukin     {
15717f65170SRuslan Bukin         m_raw_chan_enable[i] = bEnable;
15817f65170SRuslan Bukin     }
15917f65170SRuslan Bukin }
16017f65170SRuslan Bukin 
rawChanEnabled(const uint8_t id) const16117f65170SRuslan Bukin const bool TraceFmtDcdImpl::rawChanEnabled(const uint8_t id) const
16217f65170SRuslan Bukin {
16317f65170SRuslan Bukin     if(id < 128)
16417f65170SRuslan Bukin         return m_raw_chan_enable[id];
16517f65170SRuslan Bukin     return false;
16617f65170SRuslan Bukin }
16717f65170SRuslan Bukin 
16817f65170SRuslan Bukin /* decode control */
Reset()16917f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::Reset()
17017f65170SRuslan Bukin {
17117f65170SRuslan Bukin     resetStateParams();
17217f65170SRuslan Bukin     InitCollateDataPathResp();
17317f65170SRuslan Bukin     return executeNoneDataOpAllIDs(OCSD_OP_RESET);
17417f65170SRuslan Bukin }
17517f65170SRuslan Bukin 
Flush()17617f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::Flush()
17717f65170SRuslan Bukin {
17817f65170SRuslan Bukin     executeNoneDataOpAllIDs(OCSD_OP_FLUSH);    // flush any upstream data.
17917f65170SRuslan Bukin     if(dataPathCont())
18017f65170SRuslan Bukin         outputFrame();  // try to flush any partial frame data remaining
18117f65170SRuslan Bukin     return highestDataPathResp();
18217f65170SRuslan Bukin }
18317f65170SRuslan Bukin 
executeNoneDataOpAllIDs(ocsd_datapath_op_t op,const ocsd_trc_index_t index)18417f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::executeNoneDataOpAllIDs(ocsd_datapath_op_t op,
18517f65170SRuslan Bukin                                                               const ocsd_trc_index_t index /* = 0*/)
18617f65170SRuslan Bukin {
18717f65170SRuslan Bukin     ITrcDataIn *pTrcComp = 0;
18817f65170SRuslan Bukin     for(uint8_t id = 0; id < 128; id++)
18917f65170SRuslan Bukin     {
19017f65170SRuslan Bukin         if(m_IDStreams[id].num_attached())
19117f65170SRuslan Bukin         {
19217f65170SRuslan Bukin             pTrcComp = m_IDStreams[id].first();
19317f65170SRuslan Bukin             while(pTrcComp)
19417f65170SRuslan Bukin             {
19517f65170SRuslan Bukin                 CollateDataPathResp(pTrcComp->TraceDataIn(op,index,0,0,0));
19617f65170SRuslan Bukin                 pTrcComp = m_IDStreams[id].next();
19717f65170SRuslan Bukin             }
19817f65170SRuslan Bukin         }
19917f65170SRuslan Bukin     }
20017f65170SRuslan Bukin 
20117f65170SRuslan Bukin     if( m_RawTraceFrame.num_attached())
20217f65170SRuslan Bukin     {
20317f65170SRuslan Bukin         if(m_RawTraceFrame.first())
20417f65170SRuslan Bukin             m_RawTraceFrame.first()->TraceRawFrameIn(op,0,OCSD_FRM_NONE,0,0,0);
20517f65170SRuslan Bukin     }
20617f65170SRuslan Bukin     return highestDataPathResp();
20717f65170SRuslan Bukin }
20817f65170SRuslan 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)20917f65170SRuslan Bukin void TraceFmtDcdImpl::outputRawMonBytes(const ocsd_datapath_op_t op,
21017f65170SRuslan Bukin                            const ocsd_trc_index_t index,
21117f65170SRuslan Bukin                            const ocsd_rawframe_elem_t frame_element,
21217f65170SRuslan Bukin                            const int dataBlockSize,
21317f65170SRuslan Bukin                            const uint8_t *pDataBlock,
21417f65170SRuslan Bukin                            const uint8_t traceID)
21517f65170SRuslan Bukin {
21617f65170SRuslan Bukin     if( m_RawTraceFrame.num_attached())
21717f65170SRuslan Bukin     {
21817f65170SRuslan Bukin         if(m_RawTraceFrame.first())
21917f65170SRuslan Bukin             m_RawTraceFrame.first()->TraceRawFrameIn(op,index,frame_element,dataBlockSize, pDataBlock,traceID);
22017f65170SRuslan Bukin     }
22117f65170SRuslan Bukin }
22217f65170SRuslan Bukin 
CollateDataPathResp(const ocsd_datapath_resp_t resp)22317f65170SRuslan Bukin void TraceFmtDcdImpl::CollateDataPathResp(const ocsd_datapath_resp_t resp)
22417f65170SRuslan Bukin {
22517f65170SRuslan Bukin     // simple most severe error across multiple IDs.
22617f65170SRuslan Bukin     if(resp > m_highestResp) m_highestResp = resp;
22717f65170SRuslan Bukin }
22817f65170SRuslan Bukin 
processTraceData(const ocsd_trc_index_t index,const uint32_t dataBlockSize,const uint8_t * pDataBlock,uint32_t * numBytesProcessed)22917f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::processTraceData(
23017f65170SRuslan Bukin                                         const ocsd_trc_index_t index,
23117f65170SRuslan Bukin                                         const uint32_t dataBlockSize,
23217f65170SRuslan Bukin                                         const uint8_t *pDataBlock,
23317f65170SRuslan Bukin                                         uint32_t *numBytesProcessed
23417f65170SRuslan Bukin                                         )
23517f65170SRuslan Bukin {
23617f65170SRuslan Bukin     try {
23717f65170SRuslan Bukin 
23817f65170SRuslan Bukin         if(!m_first_data)  // is this the initial data block?
23917f65170SRuslan Bukin         {
24017f65170SRuslan Bukin             m_trc_curr_idx = index;
24117f65170SRuslan Bukin         }
24217f65170SRuslan Bukin         else
24317f65170SRuslan Bukin         {
24417f65170SRuslan Bukin             if(m_trc_curr_idx != index) // none continuous trace data - throw an error.
24517f65170SRuslan Bukin                 throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_DFMTR_NOTCONTTRACE,index);
24617f65170SRuslan Bukin         }
24717f65170SRuslan Bukin 
24817f65170SRuslan Bukin         if(dataBlockSize % m_alignment) // must be correctly aligned data
24917f65170SRuslan Bukin         {
25017f65170SRuslan Bukin             ocsdError err(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PARAM_VAL);
25117f65170SRuslan Bukin             char msg_buffer[64];
25217f65170SRuslan Bukin             sprintf(msg_buffer,"Input block incorrect size, must be %d byte multiple", m_alignment);
25317f65170SRuslan Bukin             err.setMessage(msg_buffer);
25417f65170SRuslan Bukin             throw ocsdError(&err);
25517f65170SRuslan Bukin         }
25617f65170SRuslan Bukin 
25717f65170SRuslan Bukin         // record the incoming block for extraction routines to use.
25817f65170SRuslan Bukin         m_in_block_base = pDataBlock;
25917f65170SRuslan Bukin         m_in_block_size = dataBlockSize;
26017f65170SRuslan Bukin         m_in_block_processed = 0;
26117f65170SRuslan Bukin 
26217f65170SRuslan Bukin         // processing loop...
26317f65170SRuslan Bukin         if(checkForSync())
26417f65170SRuslan Bukin         {
26517f65170SRuslan Bukin             bool bProcessing = true;
26617f65170SRuslan Bukin             while(bProcessing)
26717f65170SRuslan Bukin             {
26817f65170SRuslan Bukin                 bProcessing = extractFrame();   // will stop on end of input data.
26917f65170SRuslan Bukin                 if(bProcessing)
27017f65170SRuslan Bukin                     bProcessing = unpackFrame();
27117f65170SRuslan Bukin                 if(bProcessing)
27217f65170SRuslan Bukin                     bProcessing = outputFrame(); // will stop on data path halt.
27317f65170SRuslan Bukin             }
27417f65170SRuslan Bukin         }
27517f65170SRuslan Bukin     }
27617f65170SRuslan Bukin     catch(const ocsdError &err) {
27717f65170SRuslan Bukin         LogError(err);
27817f65170SRuslan Bukin         CollateDataPathResp(OCSD_RESP_FATAL_INVALID_DATA);
27917f65170SRuslan Bukin     }
28017f65170SRuslan Bukin     catch(...) {
28117f65170SRuslan Bukin         LogError(ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_FAIL));
28217f65170SRuslan Bukin         CollateDataPathResp(OCSD_RESP_FATAL_SYS_ERR);
28317f65170SRuslan Bukin     }
28417f65170SRuslan Bukin 
28517f65170SRuslan Bukin     if(!m_first_data)
28617f65170SRuslan Bukin         m_first_data = true;
28717f65170SRuslan Bukin 
28817f65170SRuslan Bukin     // update the outputs.
28917f65170SRuslan Bukin     *numBytesProcessed = m_in_block_processed;
29017f65170SRuslan Bukin 
29117f65170SRuslan Bukin     return highestDataPathResp();
29217f65170SRuslan Bukin }
29317f65170SRuslan Bukin 
DecodeConfigure(uint32_t flags)29417f65170SRuslan Bukin ocsd_err_t  TraceFmtDcdImpl::DecodeConfigure(uint32_t flags)
29517f65170SRuslan Bukin {
29617f65170SRuslan Bukin     const char *pszErrMsg = "";
29717f65170SRuslan Bukin     ocsd_err_t err = OCSD_OK;
29817f65170SRuslan Bukin 
29917f65170SRuslan Bukin     if((flags & ~OCSD_DFRMTR_VALID_MASK) != 0)
30017f65170SRuslan Bukin     {
30117f65170SRuslan Bukin         err = OCSD_ERR_INVALID_PARAM_VAL;
30217f65170SRuslan Bukin         pszErrMsg = "Unknown Config Flags";
30317f65170SRuslan Bukin     }
30417f65170SRuslan Bukin 
30517f65170SRuslan Bukin     if((flags & OCSD_DFRMTR_VALID_MASK) == 0)
30617f65170SRuslan Bukin     {
30717f65170SRuslan Bukin         err = OCSD_ERR_INVALID_PARAM_VAL;
30817f65170SRuslan Bukin         pszErrMsg = "No Config Flags Set";
30917f65170SRuslan Bukin     }
31017f65170SRuslan Bukin 
31117f65170SRuslan Bukin     if((flags & (OCSD_DFRMTR_HAS_FSYNCS | OCSD_DFRMTR_HAS_HSYNCS)) &&
31217f65170SRuslan Bukin        (flags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
31317f65170SRuslan Bukin        )
31417f65170SRuslan Bukin     {
31517f65170SRuslan Bukin         err = OCSD_ERR_INVALID_PARAM_VAL;
31617f65170SRuslan Bukin         pszErrMsg = "Invalid Config Flag Combination Set";
31717f65170SRuslan Bukin     }
31817f65170SRuslan Bukin 
31917f65170SRuslan Bukin     if(err != OCSD_OK)
32017f65170SRuslan Bukin     {
32117f65170SRuslan Bukin         ocsdError errObj(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL);
32217f65170SRuslan Bukin         errObj.setMessage(pszErrMsg);
32317f65170SRuslan Bukin         LogError(errObj);
32417f65170SRuslan Bukin     }
32517f65170SRuslan Bukin     else
32617f65170SRuslan Bukin     {
32717f65170SRuslan Bukin         m_cfgFlags = flags;
32817f65170SRuslan Bukin         m_alignment = 16;
32917f65170SRuslan Bukin         if(flags & OCSD_DFRMTR_HAS_FSYNCS)
33017f65170SRuslan Bukin             m_alignment = 4;
33117f65170SRuslan Bukin         else if(flags & OCSD_DFRMTR_HAS_HSYNCS)
33217f65170SRuslan Bukin             m_alignment = 2;
33317f65170SRuslan Bukin     }
33417f65170SRuslan Bukin     return err;
33517f65170SRuslan Bukin }
33617f65170SRuslan Bukin 
resetStateParams()33717f65170SRuslan Bukin void TraceFmtDcdImpl::resetStateParams()
33817f65170SRuslan Bukin {
33917f65170SRuslan Bukin     // overall dynamic state - intra frame
34017f65170SRuslan Bukin     m_trc_curr_idx = OCSD_BAD_TRC_INDEX;    /* source index of current trace data */
34117f65170SRuslan Bukin     m_frame_synced = false;
34217f65170SRuslan Bukin     m_first_data = false;
34317f65170SRuslan Bukin     m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
34417f65170SRuslan Bukin 
34517f65170SRuslan Bukin     // current frame processing
34617f65170SRuslan Bukin     m_ex_frm_n_bytes = 0;
34717f65170SRuslan Bukin     m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
34817f65170SRuslan Bukin }
34917f65170SRuslan Bukin 
checkForSync()35017f65170SRuslan Bukin bool TraceFmtDcdImpl::checkForSync()
35117f65170SRuslan Bukin {
35217f65170SRuslan Bukin     // we can sync on:-
35317f65170SRuslan Bukin     // 16 byte alignment - standard input buffers such as ETB
35417f65170SRuslan Bukin     // FSYNC packets in the stream
35517f65170SRuslan Bukin     // forced index programmed into the object.
35617f65170SRuslan Bukin     uint32_t unsynced_bytes = 0;
35717f65170SRuslan Bukin 
35817f65170SRuslan Bukin     if(!m_frame_synced)
35917f65170SRuslan Bukin     {
36017f65170SRuslan Bukin         if(m_use_force_sync)
36117f65170SRuslan Bukin         {
36217f65170SRuslan Bukin             // is the force sync point in this block?
36317f65170SRuslan Bukin             if((m_force_sync_idx >= m_trc_curr_idx) && (m_force_sync_idx < (m_trc_curr_idx + m_in_block_size)))
36417f65170SRuslan Bukin             {
36517f65170SRuslan Bukin                 unsynced_bytes = m_force_sync_idx - m_trc_curr_idx;
36617f65170SRuslan Bukin                 m_frame_synced = true;
36717f65170SRuslan Bukin             }
36817f65170SRuslan Bukin             else
36917f65170SRuslan Bukin             {
37017f65170SRuslan Bukin                 unsynced_bytes = m_in_block_size;
37117f65170SRuslan Bukin             }
37217f65170SRuslan Bukin         }
37317f65170SRuslan Bukin         else if( m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS)   // memory aligned data
37417f65170SRuslan Bukin         {
37517f65170SRuslan Bukin              unsynced_bytes = findfirstFSync();
37617f65170SRuslan Bukin 
37717f65170SRuslan Bukin         }
37817f65170SRuslan Bukin         else
37917f65170SRuslan Bukin         {
38017f65170SRuslan Bukin             // OCSD_DFRMTR_FRAME_MEM_ALIGN - this has guaranteed 16 byte frame size and alignment.
38117f65170SRuslan Bukin             m_frame_synced = true;
38217f65170SRuslan Bukin         }
38317f65170SRuslan Bukin 
38417f65170SRuslan Bukin         if(unsynced_bytes)
38517f65170SRuslan Bukin         {
38617f65170SRuslan Bukin             outputUnsyncedBytes(unsynced_bytes);
38717f65170SRuslan Bukin             m_in_block_processed = unsynced_bytes;
38817f65170SRuslan Bukin             m_trc_curr_idx += unsynced_bytes;
38917f65170SRuslan Bukin         }
39017f65170SRuslan Bukin     }
39117f65170SRuslan Bukin     return m_frame_synced;
39217f65170SRuslan Bukin }
39317f65170SRuslan Bukin 
findfirstFSync()39417f65170SRuslan Bukin uint32_t TraceFmtDcdImpl::findfirstFSync()
39517f65170SRuslan Bukin {
396*fc502085SRuslan Bukin     uint32_t processed = 0;
397*fc502085SRuslan Bukin     const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
398*fc502085SRuslan Bukin     const uint8_t *dataPtr = m_in_block_base;
399*fc502085SRuslan Bukin 
400*fc502085SRuslan Bukin     while (processed < (m_in_block_size - 3))
401*fc502085SRuslan Bukin     {
402*fc502085SRuslan Bukin         if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
403*fc502085SRuslan Bukin         {
404*fc502085SRuslan Bukin             m_frame_synced = true;
405*fc502085SRuslan Bukin             break;
406*fc502085SRuslan Bukin         }
407*fc502085SRuslan Bukin         processed++;
408*fc502085SRuslan Bukin         dataPtr++;
409*fc502085SRuslan Bukin     }
410*fc502085SRuslan Bukin     return processed;
41117f65170SRuslan Bukin }
41217f65170SRuslan Bukin 
outputUnsyncedBytes(uint32_t)41317f65170SRuslan Bukin void TraceFmtDcdImpl::outputUnsyncedBytes(uint32_t /*num_bytes*/)
41417f65170SRuslan Bukin {
41517f65170SRuslan Bukin     //**TBD:
41617f65170SRuslan Bukin }
41717f65170SRuslan Bukin 
checkForResetFSyncPatterns()41817f65170SRuslan Bukin int TraceFmtDcdImpl::checkForResetFSyncPatterns()
41917f65170SRuslan Bukin {
42017f65170SRuslan Bukin 	const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
42117f65170SRuslan Bukin 	bool check_for_fsync = true;
42217f65170SRuslan Bukin 	int num_fsyncs = 0;
42317f65170SRuslan Bukin 	const uint8_t *dataPtr = m_in_block_base + m_in_block_processed;
42417f65170SRuslan Bukin 
42517f65170SRuslan Bukin 	while (check_for_fsync && (m_in_block_processed < m_in_block_size))
42617f65170SRuslan Bukin 	{
42717f65170SRuslan Bukin 		// look for consecutive fsyncs as padding or for reset downstream - both cases will reset downstream....
42817f65170SRuslan Bukin 		if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
42917f65170SRuslan Bukin 		{
43017f65170SRuslan Bukin 			dataPtr += sizeof(uint32_t);
43117f65170SRuslan Bukin 			num_fsyncs++;
43217f65170SRuslan Bukin 		}
43317f65170SRuslan Bukin 		else
43417f65170SRuslan Bukin 			check_for_fsync = false;
43517f65170SRuslan Bukin 	}
43617f65170SRuslan Bukin 
43717f65170SRuslan Bukin 	if (num_fsyncs)
43817f65170SRuslan Bukin 	{
43917f65170SRuslan Bukin         printf("Frame deformatter: Found %d FSYNCS\n",num_fsyncs);
44017f65170SRuslan Bukin 		if ((num_fsyncs % 4) == 0)
44117f65170SRuslan Bukin         {
44217f65170SRuslan Bukin             // reset the upstream decoders
44317f65170SRuslan Bukin 			executeNoneDataOpAllIDs(OCSD_OP_RESET,m_trc_curr_idx);
44417f65170SRuslan Bukin 
44517f65170SRuslan Bukin             // reset the intra frame parameters
44617f65170SRuslan Bukin             m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
44717f65170SRuslan Bukin             m_ex_frm_n_bytes = 0;
44817f65170SRuslan Bukin             m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
44917f65170SRuslan Bukin         }
45017f65170SRuslan Bukin 		else
45117f65170SRuslan Bukin 		{
45217f65170SRuslan Bukin 			// TBD: throw processing error, none frame size block of fsyncs
45317f65170SRuslan Bukin 		}
45417f65170SRuslan Bukin 	}
45517f65170SRuslan Bukin     return num_fsyncs * 4;
45617f65170SRuslan Bukin }
45717f65170SRuslan Bukin 
45817f65170SRuslan Bukin 
extractFrame()45917f65170SRuslan Bukin bool TraceFmtDcdImpl::extractFrame()
46017f65170SRuslan Bukin {
46117f65170SRuslan Bukin 	const uint32_t FSYNC_PATTERN = 0x7FFFFFFF;    // LE host pattern for FSYNC
46217f65170SRuslan Bukin 	const uint16_t HSYNC_PATTERN = 0x7FFF;        // LE host pattern for HSYNC
46317f65170SRuslan Bukin 
46417f65170SRuslan Bukin 
46517f65170SRuslan Bukin 	bool cont_process = true;   // continue processing after extraction.
46617f65170SRuslan Bukin     uint32_t f_sync_bytes = 0; // skipped f sync bytes
46717f65170SRuslan Bukin     uint32_t h_sync_bytes = 0; // skipped h sync bytes
468*fc502085SRuslan Bukin     uint32_t ex_bytes = 0;  // extracted this pass (may be filling out part frame)
46917f65170SRuslan Bukin 
47017f65170SRuslan Bukin     // memory aligned sources are always multiples of frames, aligned to start.
47117f65170SRuslan Bukin     if( m_cfgFlags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
47217f65170SRuslan Bukin     {
47317f65170SRuslan Bukin 		// some linux drivers (e.g. for perf) will insert FSYNCS to pad or differentiate
47417f65170SRuslan Bukin         // between blocks of aligned data, always in frame aligned complete 16 byte frames.
47517f65170SRuslan Bukin         if (m_cfgFlags & OCSD_DFRMTR_RESET_ON_4X_FSYNC)
47617f65170SRuslan Bukin         {
47717f65170SRuslan Bukin             f_sync_bytes = checkForResetFSyncPatterns();
47817f65170SRuslan Bukin 
47917f65170SRuslan Bukin             /* in this case the FSYNC pattern is output on both packed and unpacked cases */
48017f65170SRuslan Bukin             if (f_sync_bytes && (m_b_output_packed_raw || m_b_output_unpacked_raw))
48117f65170SRuslan Bukin             {
48217f65170SRuslan Bukin                 outputRawMonBytes(OCSD_OP_DATA,
48317f65170SRuslan Bukin                     m_trc_curr_idx,
48417f65170SRuslan Bukin                     OCSD_FRM_FSYNC,
48517f65170SRuslan Bukin                     f_sync_bytes,
48617f65170SRuslan Bukin                     m_in_block_base + m_in_block_processed,
48717f65170SRuslan Bukin                     0);
48817f65170SRuslan Bukin             }
48917f65170SRuslan Bukin         }
49017f65170SRuslan Bukin 
49117f65170SRuslan Bukin         if((m_in_block_processed+f_sync_bytes) == m_in_block_size)
49217f65170SRuslan Bukin         {
49317f65170SRuslan Bukin             m_ex_frm_n_bytes = 0;
49417f65170SRuslan Bukin             cont_process = false;   // end of input data.
49517f65170SRuslan Bukin         }
49617f65170SRuslan Bukin 		else
49717f65170SRuslan Bukin 		{
49817f65170SRuslan Bukin 			// always a complete frame.
49917f65170SRuslan Bukin 			m_ex_frm_n_bytes = OCSD_DFRMTR_FRAME_SIZE;
50017f65170SRuslan Bukin 			memcpy(m_ex_frm_data, m_in_block_base + m_in_block_processed + f_sync_bytes, m_ex_frm_n_bytes);
50117f65170SRuslan Bukin 			m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
50217f65170SRuslan Bukin 			ex_bytes = OCSD_DFRMTR_FRAME_SIZE;
50317f65170SRuslan Bukin         }
50417f65170SRuslan Bukin     }
50517f65170SRuslan Bukin     else
50617f65170SRuslan Bukin     {
50717f65170SRuslan Bukin         // extract data accounting for frame syncs and hsyncs if present.
50817f65170SRuslan Bukin         // we know we are aligned at this point - could be FSYNC or HSYNCs here.
50917f65170SRuslan Bukin 
51017f65170SRuslan Bukin         // check what we a looking for
51117f65170SRuslan Bukin         bool hasFSyncs =  ((m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) == OCSD_DFRMTR_HAS_FSYNCS);
51217f65170SRuslan Bukin         bool hasHSyncs =  ((m_cfgFlags & OCSD_DFRMTR_HAS_HSYNCS) == OCSD_DFRMTR_HAS_HSYNCS);
51317f65170SRuslan Bukin 
51417f65170SRuslan Bukin         const uint8_t *dataPtr = m_in_block_base+m_in_block_processed;
51517f65170SRuslan Bukin         const uint8_t *eodPtr = m_in_block_base+m_in_block_size;
51617f65170SRuslan Bukin 
51717f65170SRuslan Bukin         cont_process = (bool)(dataPtr < eodPtr);
51817f65170SRuslan Bukin 
51917f65170SRuslan Bukin         // can have FSYNCS at start of frame (in middle is an error).
52017f65170SRuslan Bukin         if(hasFSyncs && cont_process && (m_ex_frm_n_bytes == 0))
52117f65170SRuslan Bukin         {
52217f65170SRuslan Bukin             while((*((uint32_t *)(dataPtr)) == FSYNC_PATTERN) && cont_process)
52317f65170SRuslan Bukin             {
52417f65170SRuslan Bukin                 f_sync_bytes += 4;
52517f65170SRuslan Bukin                 dataPtr += 4;
52617f65170SRuslan Bukin                 cont_process = (bool)(dataPtr < eodPtr);
52717f65170SRuslan Bukin             }
52817f65170SRuslan Bukin         }
52917f65170SRuslan Bukin 
53017f65170SRuslan Bukin         // not an FSYNC
53117f65170SRuslan Bukin         while((m_ex_frm_n_bytes < OCSD_DFRMTR_FRAME_SIZE) && cont_process)
53217f65170SRuslan Bukin         {
53317f65170SRuslan Bukin             // check for illegal out of sequence FSYNC
53417f65170SRuslan Bukin             if((m_ex_frm_n_bytes % 4) == 0)
53517f65170SRuslan Bukin             {
53617f65170SRuslan Bukin                 if(*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
53717f65170SRuslan Bukin                 {
53817f65170SRuslan Bukin                     // throw an illegal FSYNC error
539*fc502085SRuslan Bukin                     throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad FSYNC in frame.");
54017f65170SRuslan Bukin                 }
54117f65170SRuslan Bukin             }
54217f65170SRuslan Bukin 
54317f65170SRuslan Bukin             // mark start of frame after FSyncs
54417f65170SRuslan Bukin             if(m_ex_frm_n_bytes == 0)
54517f65170SRuslan Bukin                 m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
54617f65170SRuslan Bukin 
54717f65170SRuslan Bukin             m_ex_frm_data[m_ex_frm_n_bytes] = dataPtr[0];
54817f65170SRuslan Bukin             m_ex_frm_data[m_ex_frm_n_bytes+1] = dataPtr[1];
54917f65170SRuslan Bukin             m_ex_frm_n_bytes+=2;
55017f65170SRuslan Bukin             ex_bytes +=2;
55117f65170SRuslan Bukin 
55217f65170SRuslan Bukin             // check pair is not HSYNC
55317f65170SRuslan Bukin             if(*((uint16_t *)(dataPtr)) == HSYNC_PATTERN)
55417f65170SRuslan Bukin             {
55517f65170SRuslan Bukin                 if(hasHSyncs)
55617f65170SRuslan Bukin                 {
55717f65170SRuslan Bukin                     m_ex_frm_n_bytes-=2;
55817f65170SRuslan Bukin                     ex_bytes -= 2;
55917f65170SRuslan Bukin                     h_sync_bytes+=2;
56017f65170SRuslan Bukin                 }
56117f65170SRuslan Bukin                 else
56217f65170SRuslan Bukin                 {
56317f65170SRuslan Bukin                     // throw illegal HSYNC error.
564*fc502085SRuslan Bukin                     throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad HSYNC in frame.");
56517f65170SRuslan Bukin                 }
56617f65170SRuslan Bukin             }
56717f65170SRuslan Bukin 
56817f65170SRuslan Bukin             dataPtr += 2;
56917f65170SRuslan Bukin             cont_process = (bool)(dataPtr < eodPtr);
57017f65170SRuslan Bukin         }
57117f65170SRuslan Bukin 
57217f65170SRuslan Bukin         // if we hit the end of data but still have a complete frame waiting,
57317f65170SRuslan Bukin         // need to continue processing to allow it to be used.
57417f65170SRuslan Bukin         if(!cont_process && (m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE))
57517f65170SRuslan Bukin             cont_process = true;
57617f65170SRuslan Bukin     }
57717f65170SRuslan Bukin 
578*fc502085SRuslan Bukin     // total bytes processed this pass
579*fc502085SRuslan Bukin     uint32_t total_processed = ex_bytes + f_sync_bytes + h_sync_bytes;
580*fc502085SRuslan Bukin 
58117f65170SRuslan Bukin     // output raw data on raw frame channel - packed raw.
582*fc502085SRuslan Bukin     if (((m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE) || !cont_process) && m_b_output_packed_raw)
58317f65170SRuslan Bukin     {
58417f65170SRuslan Bukin         outputRawMonBytes(  OCSD_OP_DATA,
58517f65170SRuslan Bukin                             m_trc_curr_idx,
58617f65170SRuslan Bukin                             OCSD_FRM_PACKED,
587*fc502085SRuslan Bukin                             total_processed,
58817f65170SRuslan Bukin                             m_in_block_base+m_in_block_processed,
58917f65170SRuslan Bukin                             0);
59017f65170SRuslan Bukin     }
59117f65170SRuslan Bukin 
59217f65170SRuslan Bukin     // update the processed count for the buffer
593*fc502085SRuslan Bukin     m_in_block_processed += total_processed;
59417f65170SRuslan Bukin 
59517f65170SRuslan Bukin     // update index past the processed data
596*fc502085SRuslan Bukin     m_trc_curr_idx += total_processed;
59717f65170SRuslan Bukin 
59817f65170SRuslan Bukin     return cont_process;
59917f65170SRuslan Bukin }
60017f65170SRuslan Bukin 
unpackFrame()60117f65170SRuslan Bukin bool TraceFmtDcdImpl::unpackFrame()
60217f65170SRuslan Bukin {
60317f65170SRuslan Bukin     // unpack cannot fail as never called on incomplete frame.
60417f65170SRuslan Bukin     uint8_t frameFlagBit = 0x1;
60517f65170SRuslan Bukin     uint8_t newSrcID = OCSD_BAD_CS_SRC_ID;
60617f65170SRuslan Bukin     bool PrevIDandIDChange = false;
60717f65170SRuslan Bukin 
60817f65170SRuslan Bukin     // init output processing
60917f65170SRuslan Bukin     m_out_data_idx = 0;
61017f65170SRuslan Bukin     m_out_processed = 0;
61117f65170SRuslan Bukin 
61217f65170SRuslan Bukin     // set up first out data packet...
61317f65170SRuslan Bukin     m_out_data[m_out_data_idx].id = m_curr_src_ID;
61417f65170SRuslan Bukin     m_out_data[m_out_data_idx].valid = 0;
61517f65170SRuslan Bukin     m_out_data[m_out_data_idx].index =  m_trc_curr_idx_sof;
61617f65170SRuslan Bukin     m_out_data[m_out_data_idx].used = 0;
61717f65170SRuslan Bukin 
61817f65170SRuslan Bukin     // work on byte pairs - bytes 0 - 13.
61917f65170SRuslan Bukin     for(int i = 0; i < 14; i+=2)
62017f65170SRuslan Bukin     {
62117f65170SRuslan Bukin         PrevIDandIDChange = false;
62217f65170SRuslan Bukin 
62317f65170SRuslan Bukin         // it's an ID + data
62417f65170SRuslan Bukin         if(m_ex_frm_data[i] & 0x1)
62517f65170SRuslan Bukin         {
62617f65170SRuslan Bukin             newSrcID = (m_ex_frm_data[i] >> 1) & 0x7f;
62717f65170SRuslan Bukin             if(newSrcID != m_curr_src_ID)   // ID change
62817f65170SRuslan Bukin             {
62917f65170SRuslan Bukin                 PrevIDandIDChange = ((frameFlagBit & m_ex_frm_data[15]) != 0);
63017f65170SRuslan Bukin 
63117f65170SRuslan Bukin                 // following byte for old id?
63217f65170SRuslan Bukin                 if(PrevIDandIDChange)
63317f65170SRuslan Bukin                     // 2nd byte always data
63417f65170SRuslan Bukin                     m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
63517f65170SRuslan Bukin 
63617f65170SRuslan Bukin                 // change ID
63717f65170SRuslan Bukin                 m_curr_src_ID = newSrcID;
63817f65170SRuslan Bukin 
63917f65170SRuslan Bukin                 // if we already have data in this buffer
64017f65170SRuslan Bukin                 if(m_out_data[m_out_data_idx].valid > 0)
64117f65170SRuslan Bukin                 {
64217f65170SRuslan Bukin                     m_out_data_idx++; // move to next buffer
64317f65170SRuslan Bukin                     m_out_data[m_out_data_idx].valid = 0;
64417f65170SRuslan Bukin                     m_out_data[m_out_data_idx].used = 0;
64517f65170SRuslan Bukin                     m_out_data[m_out_data_idx].index = m_trc_curr_idx_sof + i;
64617f65170SRuslan Bukin                 }
64717f65170SRuslan Bukin 
64817f65170SRuslan Bukin                 // set new ID on buffer
64917f65170SRuslan Bukin                 m_out_data[m_out_data_idx].id = m_curr_src_ID;
65017f65170SRuslan Bukin 
65117f65170SRuslan Bukin                 /// TBD - ID indexing in here.
65217f65170SRuslan Bukin             }
65317f65170SRuslan Bukin         }
65417f65170SRuslan Bukin         else
65517f65170SRuslan Bukin         // it's just data
65617f65170SRuslan Bukin         {
65717f65170SRuslan 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);
65817f65170SRuslan Bukin         }
65917f65170SRuslan Bukin 
66017f65170SRuslan Bukin         // 2nd byte always data
66117f65170SRuslan Bukin         if(!PrevIDandIDChange) // output only if we didn't for an ID change + prev ID.
66217f65170SRuslan Bukin             m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
66317f65170SRuslan Bukin 
66417f65170SRuslan Bukin         frameFlagBit <<= 1;
66517f65170SRuslan Bukin     }
66617f65170SRuslan Bukin 
66717f65170SRuslan Bukin     // unpack byte 14;
66817f65170SRuslan Bukin 
66917f65170SRuslan Bukin     // it's an ID
67017f65170SRuslan Bukin     if(m_ex_frm_data[14] & 0x1)
67117f65170SRuslan Bukin     {
67217f65170SRuslan Bukin         // no matter if change or not, no associated data in byte 15 anyway so just set.
67317f65170SRuslan Bukin         m_curr_src_ID = (m_ex_frm_data[14] >> 1) & 0x7f;
67417f65170SRuslan Bukin     }
67517f65170SRuslan Bukin     // it's data
67617f65170SRuslan Bukin     else
67717f65170SRuslan Bukin     {
67817f65170SRuslan 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);
67917f65170SRuslan Bukin     }
68017f65170SRuslan Bukin     m_ex_frm_n_bytes = 0;   // mark frame as empty;
68117f65170SRuslan Bukin     return true;
68217f65170SRuslan Bukin }
68317f65170SRuslan Bukin 
68417f65170SRuslan Bukin // output data to channels.
outputFrame()68517f65170SRuslan Bukin bool TraceFmtDcdImpl::outputFrame()
68617f65170SRuslan Bukin {
68717f65170SRuslan Bukin     bool cont_processing = true;
68817f65170SRuslan Bukin     ITrcDataIn *pDataIn = 0;
68917f65170SRuslan Bukin     uint32_t bytes_used;
69017f65170SRuslan Bukin 
69117f65170SRuslan Bukin     // output each valid ID within the frame - stopping if we get a wait or error
69217f65170SRuslan Bukin     while((m_out_processed < (m_out_data_idx + 1)) && cont_processing)
69317f65170SRuslan Bukin     {
69417f65170SRuslan Bukin 
69517f65170SRuslan Bukin         // may have data prior to a valid ID appearing
69617f65170SRuslan Bukin         if(m_out_data[m_out_processed].id != OCSD_BAD_CS_SRC_ID)
69717f65170SRuslan Bukin         {
69817f65170SRuslan Bukin             if((pDataIn = m_IDStreams[m_out_data[m_out_processed].id].first()) != 0)
69917f65170SRuslan Bukin             {
70017f65170SRuslan Bukin                 // log the stuff we are about to put out early so as to make it visible before interpretation
70117f65170SRuslan Bukin                 // however, don't re-output if only part used first time round.
70217f65170SRuslan Bukin                 if(m_b_output_unpacked_raw && (m_out_data[m_out_processed].used == 0) && rawChanEnabled( m_out_data[m_out_processed].id))
70317f65170SRuslan Bukin                 {
70417f65170SRuslan Bukin                     outputRawMonBytes( OCSD_OP_DATA,
70517f65170SRuslan Bukin                             m_out_data[m_out_processed].index,
70617f65170SRuslan Bukin                             OCSD_FRM_ID_DATA,
70717f65170SRuslan Bukin                             m_out_data[m_out_processed].valid,
70817f65170SRuslan Bukin                             m_out_data[m_out_processed].data,
70917f65170SRuslan Bukin                             m_out_data[m_out_processed].id);
71017f65170SRuslan Bukin                 }
71117f65170SRuslan Bukin 
71217f65170SRuslan Bukin                 // output to the connected packet process
71317f65170SRuslan Bukin                 CollateDataPathResp(pDataIn->TraceDataIn(OCSD_OP_DATA,
71417f65170SRuslan Bukin                     m_out_data[m_out_processed].index + m_out_data[m_out_processed].used,
71517f65170SRuslan Bukin                     m_out_data[m_out_processed].valid - m_out_data[m_out_processed].used,
71617f65170SRuslan Bukin                     m_out_data[m_out_processed].data + m_out_data[m_out_processed].used,
71717f65170SRuslan Bukin                     &bytes_used));
71817f65170SRuslan Bukin 
71917f65170SRuslan Bukin                 if(!dataPathCont())
72017f65170SRuslan Bukin                 {
72117f65170SRuslan Bukin                     cont_processing = false;
72217f65170SRuslan Bukin                     m_out_data[m_out_processed].used += bytes_used;
72317f65170SRuslan Bukin                     if(m_out_data[m_out_processed].used == m_out_data[m_out_processed].valid)
72417f65170SRuslan Bukin                         m_out_processed++; // we have used up all this data.
72517f65170SRuslan Bukin                 }
72617f65170SRuslan Bukin                 else
72717f65170SRuslan Bukin                 {
72817f65170SRuslan Bukin                     m_out_processed++; // we have sent this data;
72917f65170SRuslan Bukin                 }
73017f65170SRuslan Bukin             }
73117f65170SRuslan Bukin             else
73217f65170SRuslan Bukin             {
73317f65170SRuslan Bukin                 // optional raw output for debugging / monitor tools
73417f65170SRuslan Bukin                 if(m_b_output_unpacked_raw && rawChanEnabled( m_out_data[m_out_processed].id))
73517f65170SRuslan Bukin                 {
73617f65170SRuslan Bukin                     outputRawMonBytes(  OCSD_OP_DATA,
73717f65170SRuslan Bukin                         m_out_data[m_out_processed].index,
73817f65170SRuslan Bukin                         OCSD_FRM_ID_DATA,
73917f65170SRuslan Bukin                         m_out_data[m_out_processed].valid,
74017f65170SRuslan Bukin                         m_out_data[m_out_processed].data,
74117f65170SRuslan Bukin                         m_out_data[m_out_processed].id);
74217f65170SRuslan Bukin                 }
74317f65170SRuslan Bukin                 m_out_processed++; // skip past this data.
74417f65170SRuslan Bukin             }
74517f65170SRuslan Bukin         }
74617f65170SRuslan Bukin         else
74717f65170SRuslan Bukin         {
74817f65170SRuslan Bukin             // optional raw output for debugging / monitor tools of unknown src ID data
74917f65170SRuslan Bukin             if(m_b_output_unpacked_raw)
75017f65170SRuslan Bukin             {
75117f65170SRuslan Bukin                 outputRawMonBytes(  OCSD_OP_DATA,
75217f65170SRuslan Bukin                     m_out_data[m_out_processed].index,
75317f65170SRuslan Bukin                     OCSD_FRM_ID_DATA,
75417f65170SRuslan Bukin                     m_out_data[m_out_processed].valid,
75517f65170SRuslan Bukin                     m_out_data[m_out_processed].data,
75617f65170SRuslan Bukin                     m_out_data[m_out_processed].id);
75717f65170SRuslan Bukin             }
75817f65170SRuslan Bukin             m_out_processed++; // skip past this data.
75917f65170SRuslan Bukin         }
76017f65170SRuslan Bukin     }
76117f65170SRuslan Bukin     return cont_processing;
76217f65170SRuslan Bukin }
76317f65170SRuslan Bukin 
76417f65170SRuslan Bukin /***************************************************************/
76517f65170SRuslan Bukin /* interface */
76617f65170SRuslan Bukin /***************************************************************/
TraceFormatterFrameDecoder()76717f65170SRuslan Bukin TraceFormatterFrameDecoder::TraceFormatterFrameDecoder() : m_pDecoder(0)
76817f65170SRuslan Bukin {
76917f65170SRuslan Bukin     m_instNum = -1;
77017f65170SRuslan Bukin }
77117f65170SRuslan Bukin 
TraceFormatterFrameDecoder(int instNum)77217f65170SRuslan Bukin TraceFormatterFrameDecoder::TraceFormatterFrameDecoder(int instNum) : m_pDecoder(0)
77317f65170SRuslan Bukin {
77417f65170SRuslan Bukin     m_instNum = instNum;
77517f65170SRuslan Bukin }
77617f65170SRuslan Bukin 
~TraceFormatterFrameDecoder()77717f65170SRuslan Bukin TraceFormatterFrameDecoder::~TraceFormatterFrameDecoder()
77817f65170SRuslan Bukin {
77917f65170SRuslan Bukin     if(m_pDecoder)
78017f65170SRuslan Bukin     {
78117f65170SRuslan Bukin         delete m_pDecoder;
78217f65170SRuslan Bukin         m_pDecoder = 0;
78317f65170SRuslan Bukin     }
78417f65170SRuslan Bukin }
78517f65170SRuslan Bukin 
78617f65170SRuslan 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)78717f65170SRuslan Bukin ocsd_datapath_resp_t TraceFormatterFrameDecoder::TraceDataIn(  const ocsd_datapath_op_t op,
78817f65170SRuslan Bukin                                                                 const ocsd_trc_index_t index,
78917f65170SRuslan Bukin                                                                 const uint32_t dataBlockSize,
79017f65170SRuslan Bukin                                                                 const uint8_t *pDataBlock,
79117f65170SRuslan Bukin                                                                 uint32_t *numBytesProcessed)
79217f65170SRuslan Bukin {
79317f65170SRuslan Bukin     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
79417f65170SRuslan Bukin }
79517f65170SRuslan Bukin 
79617f65170SRuslan Bukin /* attach a data processor to a stream ID output */
getIDStreamAttachPt(uint8_t ID)79717f65170SRuslan Bukin componentAttachPt<ITrcDataIn> *TraceFormatterFrameDecoder::getIDStreamAttachPt(uint8_t ID)
79817f65170SRuslan Bukin {
79917f65170SRuslan Bukin     componentAttachPt<ITrcDataIn> *pAttachPt = 0;
80017f65170SRuslan Bukin     if((ID < 128) && (m_pDecoder != 0))
80117f65170SRuslan Bukin         pAttachPt = &(m_pDecoder->m_IDStreams[ID]);
80217f65170SRuslan Bukin     return pAttachPt;
80317f65170SRuslan Bukin }
80417f65170SRuslan Bukin 
80517f65170SRuslan Bukin /* attach a data processor to the raw frame output */
getTrcRawFrameAttachPt()80617f65170SRuslan Bukin componentAttachPt<ITrcRawFrameIn> *TraceFormatterFrameDecoder::getTrcRawFrameAttachPt()
80717f65170SRuslan Bukin {
80817f65170SRuslan Bukin     return (m_pDecoder != 0) ? &m_pDecoder->m_RawTraceFrame : 0;
80917f65170SRuslan Bukin }
81017f65170SRuslan Bukin 
81117f65170SRuslan Bukin 
getTrcSrcIndexAttachPt()81217f65170SRuslan Bukin componentAttachPt<ITrcSrcIndexCreator> *TraceFormatterFrameDecoder::getTrcSrcIndexAttachPt()
81317f65170SRuslan Bukin {
81417f65170SRuslan Bukin     return (m_pDecoder != 0) ? &m_pDecoder->m_SrcIndexer : 0;
81517f65170SRuslan Bukin }
81617f65170SRuslan Bukin 
getErrLogAttachPt()81717f65170SRuslan Bukin componentAttachPt<ITraceErrorLog> *TraceFormatterFrameDecoder::getErrLogAttachPt()
81817f65170SRuslan Bukin {
81917f65170SRuslan Bukin     return (m_pDecoder != 0) ? m_pDecoder->getErrorLogAttachPt() : 0;
82017f65170SRuslan Bukin }
82117f65170SRuslan Bukin 
82217f65170SRuslan Bukin /* configuration - set operational mode for incoming stream (has FSYNCS etc) */
Configure(uint32_t cfg_flags)82317f65170SRuslan Bukin ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags)
82417f65170SRuslan Bukin {
82517f65170SRuslan Bukin     if(!m_pDecoder)
82617f65170SRuslan Bukin     {
82717f65170SRuslan Bukin         if(m_instNum >= 0)
82817f65170SRuslan Bukin             m_pDecoder = new (std::nothrow) TraceFmtDcdImpl(m_instNum);
82917f65170SRuslan Bukin         else
83017f65170SRuslan Bukin             m_pDecoder = new (std::nothrow) TraceFmtDcdImpl();
83117f65170SRuslan Bukin         if(!m_pDecoder) return OCSD_ERR_MEM;
83217f65170SRuslan Bukin     }
833*fc502085SRuslan Bukin     m_pDecoder->DecodeConfigure(cfg_flags);
83417f65170SRuslan Bukin     return OCSD_OK;
83517f65170SRuslan Bukin }
83617f65170SRuslan Bukin 
getConfigFlags() const83717f65170SRuslan Bukin const uint32_t TraceFormatterFrameDecoder::getConfigFlags() const
83817f65170SRuslan Bukin {
83917f65170SRuslan Bukin     uint32_t flags = 0;
84017f65170SRuslan Bukin     if(m_pDecoder)
84117f65170SRuslan Bukin         flags = m_pDecoder->m_cfgFlags;
84217f65170SRuslan Bukin     return flags;
84317f65170SRuslan Bukin }
84417f65170SRuslan Bukin 
84517f65170SRuslan Bukin 
84617f65170SRuslan Bukin /* enable / disable ID streams - default as all enabled */
OutputFilterIDs(std::vector<uint8_t> & id_list,bool bEnable)84717f65170SRuslan Bukin ocsd_err_t TraceFormatterFrameDecoder::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
84817f65170SRuslan Bukin {
84917f65170SRuslan Bukin     return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterIDs(id_list,bEnable);
85017f65170SRuslan Bukin }
85117f65170SRuslan Bukin 
OutputFilterAllIDs(bool bEnable)85217f65170SRuslan Bukin ocsd_err_t TraceFormatterFrameDecoder::OutputFilterAllIDs(bool bEnable)
85317f65170SRuslan Bukin {
85417f65170SRuslan Bukin     return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterAllIDs(bEnable);
85517f65170SRuslan Bukin }
85617f65170SRuslan Bukin 
85717f65170SRuslan Bukin /* decode control */
Reset()85817f65170SRuslan Bukin ocsd_datapath_resp_t TraceFormatterFrameDecoder::Reset()
85917f65170SRuslan Bukin {
86017f65170SRuslan Bukin     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Reset();
86117f65170SRuslan Bukin }
86217f65170SRuslan Bukin 
Flush()86317f65170SRuslan Bukin ocsd_datapath_resp_t TraceFormatterFrameDecoder::Flush()
86417f65170SRuslan Bukin {
86517f65170SRuslan Bukin     return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Flush();
86617f65170SRuslan Bukin }
86717f65170SRuslan Bukin 
86817f65170SRuslan Bukin 
86917f65170SRuslan Bukin /* End of File trc_frame_deformatter.cpp */
870