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 m_pStatsBlock(0)
5917f65170SRuslan Bukin
6017f65170SRuslan Bukin {
6117f65170SRuslan Bukin resetStateParams();
6217f65170SRuslan Bukin setRawChanFilterAll(true);
6317f65170SRuslan Bukin }
6417f65170SRuslan Bukin
TraceFmtDcdImpl(int instNum)6517f65170SRuslan Bukin TraceFmtDcdImpl::TraceFmtDcdImpl(int instNum) : TraceComponent(DEFORMATTER_NAME, instNum),
6617f65170SRuslan Bukin m_cfgFlags(0),
6717f65170SRuslan Bukin m_force_sync_idx(0),
6817f65170SRuslan Bukin m_use_force_sync(false),
6917f65170SRuslan Bukin m_alignment(16)
7017f65170SRuslan Bukin {
7117f65170SRuslan Bukin resetStateParams();
7217f65170SRuslan Bukin setRawChanFilterAll(true);
7317f65170SRuslan Bukin }
7417f65170SRuslan Bukin
~TraceFmtDcdImpl()7517f65170SRuslan Bukin TraceFmtDcdImpl::~TraceFmtDcdImpl()
7617f65170SRuslan Bukin {
7717f65170SRuslan Bukin }
7817f65170SRuslan 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)7917f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::TraceDataIn(
8017f65170SRuslan Bukin const ocsd_datapath_op_t op,
8117f65170SRuslan Bukin const ocsd_trc_index_t index,
8217f65170SRuslan Bukin const uint32_t dataBlockSize,
8317f65170SRuslan Bukin const uint8_t *pDataBlock,
8417f65170SRuslan Bukin uint32_t *numBytesProcessed)
8517f65170SRuslan Bukin {
8617f65170SRuslan Bukin ocsd_datapath_resp_t resp = OCSD_RESP_FATAL_INVALID_OP;
8717f65170SRuslan Bukin InitCollateDataPathResp();
8817f65170SRuslan Bukin
8917f65170SRuslan Bukin m_b_output_packed_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_PACKED_RAW_OUT) != 0);
9017f65170SRuslan Bukin m_b_output_unpacked_raw = m_RawTraceFrame.num_attached() && ((m_cfgFlags & OCSD_DFRMTR_UNPACKED_RAW_OUT) != 0);
9117f65170SRuslan Bukin
9217f65170SRuslan Bukin switch(op)
9317f65170SRuslan Bukin {
9417f65170SRuslan Bukin case OCSD_OP_RESET:
9517f65170SRuslan Bukin resp = Reset();
9617f65170SRuslan Bukin break;
9717f65170SRuslan Bukin
9817f65170SRuslan Bukin case OCSD_OP_FLUSH:
9917f65170SRuslan Bukin resp = Flush();
10017f65170SRuslan Bukin break;
10117f65170SRuslan Bukin
10217f65170SRuslan Bukin case OCSD_OP_EOT:
10317f65170SRuslan Bukin // local 'flush' here?
10417f65170SRuslan Bukin // pass on EOT to connected ID streams
10517f65170SRuslan Bukin resp = executeNoneDataOpAllIDs(OCSD_OP_EOT);
10617f65170SRuslan Bukin break;
10717f65170SRuslan Bukin
10817f65170SRuslan Bukin case OCSD_OP_DATA:
10917f65170SRuslan Bukin if((dataBlockSize <= 0) || ( pDataBlock == 0) || (numBytesProcessed == 0))
11017f65170SRuslan Bukin resp = OCSD_RESP_FATAL_INVALID_PARAM;
11117f65170SRuslan Bukin else
11217f65170SRuslan Bukin resp = processTraceData(index,dataBlockSize, pDataBlock, numBytesProcessed);
11317f65170SRuslan Bukin break;
11417f65170SRuslan Bukin
11517f65170SRuslan Bukin default:
11617f65170SRuslan Bukin break;
11717f65170SRuslan Bukin }
11817f65170SRuslan Bukin
11917f65170SRuslan Bukin return resp;
12017f65170SRuslan Bukin }
12117f65170SRuslan Bukin
12217f65170SRuslan Bukin /* enable / disable ID streams - default as all enabled */
OutputFilterIDs(std::vector<uint8_t> & id_list,bool bEnable)12317f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
12417f65170SRuslan Bukin {
12517f65170SRuslan Bukin ocsd_err_t err = OCSD_OK;
12617f65170SRuslan Bukin std::vector<uint8_t>::iterator iter = id_list.begin();
12717f65170SRuslan Bukin uint8_t id = 0;
12817f65170SRuslan Bukin
12917f65170SRuslan Bukin while((iter < id_list.end()) && (err == OCSD_OK))
13017f65170SRuslan Bukin {
13117f65170SRuslan Bukin id = *iter;
13217f65170SRuslan Bukin if(id > 128)
13317f65170SRuslan Bukin err = OCSD_ERR_INVALID_ID;
13417f65170SRuslan Bukin else
13517f65170SRuslan Bukin {
13617f65170SRuslan Bukin m_IDStreams[id].set_enabled(bEnable);
13717f65170SRuslan Bukin m_raw_chan_enable[id] = bEnable;
13817f65170SRuslan Bukin }
13917f65170SRuslan Bukin iter++;
14017f65170SRuslan Bukin }
14117f65170SRuslan Bukin return err;
14217f65170SRuslan Bukin }
14317f65170SRuslan Bukin
OutputFilterAllIDs(bool bEnable)14417f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::OutputFilterAllIDs(bool bEnable)
14517f65170SRuslan Bukin {
14617f65170SRuslan Bukin for(uint8_t id = 0; id < 128; id++)
14717f65170SRuslan Bukin {
14817f65170SRuslan Bukin m_IDStreams[id].set_enabled(bEnable);
14917f65170SRuslan Bukin }
15017f65170SRuslan Bukin setRawChanFilterAll(bEnable);
15117f65170SRuslan Bukin return OCSD_OK;
15217f65170SRuslan Bukin }
15317f65170SRuslan Bukin
setRawChanFilterAll(bool bEnable)15417f65170SRuslan Bukin void TraceFmtDcdImpl::setRawChanFilterAll(bool bEnable)
15517f65170SRuslan Bukin {
15617f65170SRuslan Bukin for(int i=0; i<128; i++)
15717f65170SRuslan Bukin {
15817f65170SRuslan Bukin m_raw_chan_enable[i] = bEnable;
15917f65170SRuslan Bukin }
16017f65170SRuslan Bukin }
16117f65170SRuslan Bukin
rawChanEnabled(const uint8_t id) const16217f65170SRuslan Bukin const bool TraceFmtDcdImpl::rawChanEnabled(const uint8_t id) const
16317f65170SRuslan Bukin {
16417f65170SRuslan Bukin if(id < 128)
16517f65170SRuslan Bukin return m_raw_chan_enable[id];
16617f65170SRuslan Bukin return false;
16717f65170SRuslan Bukin }
16817f65170SRuslan Bukin
16917f65170SRuslan Bukin /* decode control */
Reset()17017f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::Reset()
17117f65170SRuslan Bukin {
17217f65170SRuslan Bukin resetStateParams();
17317f65170SRuslan Bukin InitCollateDataPathResp();
17417f65170SRuslan Bukin return executeNoneDataOpAllIDs(OCSD_OP_RESET);
17517f65170SRuslan Bukin }
17617f65170SRuslan Bukin
Flush()17717f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::Flush()
17817f65170SRuslan Bukin {
17917f65170SRuslan Bukin executeNoneDataOpAllIDs(OCSD_OP_FLUSH); // flush any upstream data.
18017f65170SRuslan Bukin if(dataPathCont())
18117f65170SRuslan Bukin outputFrame(); // try to flush any partial frame data remaining
18217f65170SRuslan Bukin return highestDataPathResp();
18317f65170SRuslan Bukin }
18417f65170SRuslan Bukin
executeNoneDataOpAllIDs(ocsd_datapath_op_t op,const ocsd_trc_index_t index)18517f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::executeNoneDataOpAllIDs(ocsd_datapath_op_t op,
18617f65170SRuslan Bukin const ocsd_trc_index_t index /* = 0*/)
18717f65170SRuslan Bukin {
18817f65170SRuslan Bukin ITrcDataIn *pTrcComp = 0;
18917f65170SRuslan Bukin for(uint8_t id = 0; id < 128; id++)
19017f65170SRuslan Bukin {
19117f65170SRuslan Bukin if(m_IDStreams[id].num_attached())
19217f65170SRuslan Bukin {
19317f65170SRuslan Bukin pTrcComp = m_IDStreams[id].first();
19417f65170SRuslan Bukin while(pTrcComp)
19517f65170SRuslan Bukin {
19617f65170SRuslan Bukin CollateDataPathResp(pTrcComp->TraceDataIn(op,index,0,0,0));
19717f65170SRuslan Bukin pTrcComp = m_IDStreams[id].next();
19817f65170SRuslan Bukin }
19917f65170SRuslan Bukin }
20017f65170SRuslan Bukin }
20117f65170SRuslan Bukin
20217f65170SRuslan Bukin if( m_RawTraceFrame.num_attached())
20317f65170SRuslan Bukin {
20417f65170SRuslan Bukin if(m_RawTraceFrame.first())
20517f65170SRuslan Bukin m_RawTraceFrame.first()->TraceRawFrameIn(op,0,OCSD_FRM_NONE,0,0,0);
20617f65170SRuslan Bukin }
20717f65170SRuslan Bukin return highestDataPathResp();
20817f65170SRuslan Bukin }
20917f65170SRuslan 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)21017f65170SRuslan Bukin void TraceFmtDcdImpl::outputRawMonBytes(const ocsd_datapath_op_t op,
21117f65170SRuslan Bukin const ocsd_trc_index_t index,
21217f65170SRuslan Bukin const ocsd_rawframe_elem_t frame_element,
21317f65170SRuslan Bukin const int dataBlockSize,
21417f65170SRuslan Bukin const uint8_t *pDataBlock,
21517f65170SRuslan Bukin const uint8_t traceID)
21617f65170SRuslan Bukin {
21717f65170SRuslan Bukin if( m_RawTraceFrame.num_attached())
21817f65170SRuslan Bukin {
21917f65170SRuslan Bukin if(m_RawTraceFrame.first())
22017f65170SRuslan Bukin m_RawTraceFrame.first()->TraceRawFrameIn(op,index,frame_element,dataBlockSize, pDataBlock,traceID);
22117f65170SRuslan Bukin }
22217f65170SRuslan Bukin }
22317f65170SRuslan Bukin
CollateDataPathResp(const ocsd_datapath_resp_t resp)22417f65170SRuslan Bukin void TraceFmtDcdImpl::CollateDataPathResp(const ocsd_datapath_resp_t resp)
22517f65170SRuslan Bukin {
22617f65170SRuslan Bukin // simple most severe error across multiple IDs.
22717f65170SRuslan Bukin if(resp > m_highestResp) m_highestResp = resp;
22817f65170SRuslan Bukin }
22917f65170SRuslan Bukin
processTraceData(const ocsd_trc_index_t index,const uint32_t dataBlockSize,const uint8_t * pDataBlock,uint32_t * numBytesProcessed)23017f65170SRuslan Bukin ocsd_datapath_resp_t TraceFmtDcdImpl::processTraceData(
23117f65170SRuslan Bukin const ocsd_trc_index_t index,
23217f65170SRuslan Bukin const uint32_t dataBlockSize,
23317f65170SRuslan Bukin const uint8_t *pDataBlock,
23417f65170SRuslan Bukin uint32_t *numBytesProcessed
23517f65170SRuslan Bukin )
23617f65170SRuslan Bukin {
23717f65170SRuslan Bukin try {
23817f65170SRuslan Bukin
23917f65170SRuslan Bukin if(!m_first_data) // is this the initial data block?
24017f65170SRuslan Bukin {
24117f65170SRuslan Bukin m_trc_curr_idx = index;
24217f65170SRuslan Bukin }
24317f65170SRuslan Bukin else
24417f65170SRuslan Bukin {
24517f65170SRuslan Bukin if(m_trc_curr_idx != index) // none continuous trace data - throw an error.
24617f65170SRuslan Bukin throw ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_DFMTR_NOTCONTTRACE,index);
24717f65170SRuslan Bukin }
24817f65170SRuslan Bukin
24917f65170SRuslan Bukin // record the incoming block for extraction routines to use.
25017f65170SRuslan Bukin m_in_block_base = pDataBlock;
25117f65170SRuslan Bukin m_in_block_size = dataBlockSize;
25217f65170SRuslan Bukin m_in_block_processed = 0;
25317f65170SRuslan Bukin
25417f65170SRuslan Bukin if(dataBlockSize % m_alignment) // must be correctly aligned data
25517f65170SRuslan Bukin {
25617f65170SRuslan Bukin ocsdError err(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PARAM_VAL);
25717f65170SRuslan Bukin char msg_buffer[64];
25817f65170SRuslan Bukin sprintf(msg_buffer,"Input block incorrect size, must be %d byte multiple", m_alignment);
25917f65170SRuslan Bukin err.setMessage(msg_buffer);
26017f65170SRuslan Bukin throw ocsdError(&err);
26117f65170SRuslan Bukin }
26217f65170SRuslan Bukin
26317f65170SRuslan Bukin // processing loop...
26417f65170SRuslan Bukin if(checkForSync())
26517f65170SRuslan Bukin {
26617f65170SRuslan Bukin bool bProcessing = true;
26717f65170SRuslan Bukin while(bProcessing)
26817f65170SRuslan Bukin {
26917f65170SRuslan Bukin bProcessing = extractFrame(); // will stop on end of input data.
27017f65170SRuslan Bukin if(bProcessing)
27117f65170SRuslan Bukin bProcessing = unpackFrame();
27217f65170SRuslan Bukin if(bProcessing)
27317f65170SRuslan Bukin bProcessing = outputFrame(); // will stop on data path halt.
27417f65170SRuslan Bukin }
27517f65170SRuslan Bukin }
27617f65170SRuslan Bukin }
27717f65170SRuslan Bukin catch(const ocsdError &err) {
27817f65170SRuslan Bukin LogError(err);
27917f65170SRuslan Bukin CollateDataPathResp(OCSD_RESP_FATAL_INVALID_DATA);
28017f65170SRuslan Bukin }
28117f65170SRuslan Bukin catch(...) {
28217f65170SRuslan Bukin LogError(ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_FAIL));
28317f65170SRuslan Bukin CollateDataPathResp(OCSD_RESP_FATAL_SYS_ERR);
28417f65170SRuslan Bukin }
28517f65170SRuslan Bukin
28617f65170SRuslan Bukin if(!m_first_data)
28717f65170SRuslan Bukin m_first_data = true;
28817f65170SRuslan Bukin
28917f65170SRuslan Bukin // update the outputs.
29017f65170SRuslan Bukin *numBytesProcessed = m_in_block_processed;
29117f65170SRuslan Bukin
29217f65170SRuslan Bukin return highestDataPathResp();
29317f65170SRuslan Bukin }
29417f65170SRuslan Bukin
DecodeConfigure(uint32_t flags)29517f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::DecodeConfigure(uint32_t flags)
29617f65170SRuslan Bukin {
29717f65170SRuslan Bukin const char *pszErrMsg = "";
29817f65170SRuslan Bukin ocsd_err_t err = OCSD_OK;
29917f65170SRuslan Bukin
30017f65170SRuslan Bukin if((flags & ~OCSD_DFRMTR_VALID_MASK) != 0)
30117f65170SRuslan Bukin {
30217f65170SRuslan Bukin err = OCSD_ERR_INVALID_PARAM_VAL;
30317f65170SRuslan Bukin pszErrMsg = "Unknown Config Flags";
30417f65170SRuslan Bukin }
30517f65170SRuslan Bukin
30617f65170SRuslan Bukin if((flags & OCSD_DFRMTR_VALID_MASK) == 0)
30717f65170SRuslan Bukin {
30817f65170SRuslan Bukin err = OCSD_ERR_INVALID_PARAM_VAL;
30917f65170SRuslan Bukin pszErrMsg = "No Config Flags Set";
31017f65170SRuslan Bukin }
31117f65170SRuslan Bukin
31217f65170SRuslan Bukin if((flags & (OCSD_DFRMTR_HAS_FSYNCS | OCSD_DFRMTR_HAS_HSYNCS)) &&
31317f65170SRuslan Bukin (flags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
31417f65170SRuslan Bukin )
31517f65170SRuslan Bukin {
31617f65170SRuslan Bukin err = OCSD_ERR_INVALID_PARAM_VAL;
31717f65170SRuslan Bukin pszErrMsg = "Invalid Config Flag Combination Set";
31817f65170SRuslan Bukin }
31917f65170SRuslan Bukin
32017f65170SRuslan Bukin if(err != OCSD_OK)
32117f65170SRuslan Bukin {
32217f65170SRuslan Bukin ocsdError errObj(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL);
32317f65170SRuslan Bukin errObj.setMessage(pszErrMsg);
32417f65170SRuslan Bukin LogError(errObj);
32517f65170SRuslan Bukin }
32617f65170SRuslan Bukin else
32717f65170SRuslan Bukin {
32817f65170SRuslan Bukin // alightment is the multiple of bytes the buffer size must be.
32917f65170SRuslan Bukin m_cfgFlags = flags;
33017f65170SRuslan Bukin
33117f65170SRuslan Bukin // using memory aligned buffers, the formatter always outputs 16 byte frames so enforce
33217f65170SRuslan Bukin // this on the input
33317f65170SRuslan Bukin m_alignment = 16;
33417f65170SRuslan Bukin // if we have HSYNCS then always align to 2 byte buffers
33517f65170SRuslan Bukin if(flags & OCSD_DFRMTR_HAS_HSYNCS)
33617f65170SRuslan Bukin m_alignment = 2;
33717f65170SRuslan Bukin // otherwise FSYNCS only can have 4 byte aligned buffers.
33817f65170SRuslan Bukin else if(flags & OCSD_DFRMTR_HAS_FSYNCS)
33917f65170SRuslan Bukin m_alignment = 4;
34017f65170SRuslan Bukin }
34117f65170SRuslan Bukin return err;
34217f65170SRuslan Bukin }
34317f65170SRuslan Bukin
resetStateParams()34417f65170SRuslan Bukin void TraceFmtDcdImpl::resetStateParams()
34517f65170SRuslan Bukin {
34617f65170SRuslan Bukin // overall dynamic state - intra frame
34717f65170SRuslan Bukin m_trc_curr_idx = OCSD_BAD_TRC_INDEX; /* source index of current trace data */
34817f65170SRuslan Bukin m_frame_synced = false;
34917f65170SRuslan Bukin m_first_data = false;
35017f65170SRuslan Bukin m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
35117f65170SRuslan Bukin
35217f65170SRuslan Bukin // current frame processing
35317f65170SRuslan Bukin m_ex_frm_n_bytes = 0;
35417f65170SRuslan Bukin m_b_fsync_start_eob = false;
35517f65170SRuslan Bukin m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
35617f65170SRuslan Bukin }
35717f65170SRuslan Bukin
checkForSync()35817f65170SRuslan Bukin bool TraceFmtDcdImpl::checkForSync()
35917f65170SRuslan Bukin {
36017f65170SRuslan Bukin // we can sync on:-
36117f65170SRuslan Bukin // 16 byte alignment - standard input buffers such as ETB
36217f65170SRuslan Bukin // FSYNC packets in the stream
36317f65170SRuslan Bukin // forced index programmed into the object.
36417f65170SRuslan Bukin uint32_t unsynced_bytes = 0;
36517f65170SRuslan Bukin
36617f65170SRuslan Bukin if(!m_frame_synced)
36717f65170SRuslan Bukin {
36817f65170SRuslan Bukin if(m_use_force_sync)
36917f65170SRuslan Bukin {
37017f65170SRuslan Bukin // is the force sync point in this block?
37117f65170SRuslan Bukin if((m_force_sync_idx >= m_trc_curr_idx) && (m_force_sync_idx < (m_trc_curr_idx + m_in_block_size)))
37217f65170SRuslan Bukin {
37317f65170SRuslan Bukin unsynced_bytes = m_force_sync_idx - m_trc_curr_idx;
37417f65170SRuslan Bukin m_frame_synced = true;
37517f65170SRuslan Bukin }
37617f65170SRuslan Bukin else
37717f65170SRuslan Bukin {
37817f65170SRuslan Bukin unsynced_bytes = m_in_block_size;
37917f65170SRuslan Bukin }
38017f65170SRuslan Bukin }
38117f65170SRuslan Bukin else if( m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) // memory aligned data
38217f65170SRuslan Bukin {
38317f65170SRuslan Bukin unsynced_bytes = findfirstFSync();
38417f65170SRuslan Bukin
38517f65170SRuslan Bukin }
38617f65170SRuslan Bukin else
38717f65170SRuslan Bukin {
38817f65170SRuslan Bukin // OCSD_DFRMTR_FRAME_MEM_ALIGN - this has guaranteed 16 byte frame size and alignment.
38917f65170SRuslan Bukin m_frame_synced = true;
39017f65170SRuslan Bukin }
39117f65170SRuslan Bukin
39217f65170SRuslan Bukin if(unsynced_bytes)
39317f65170SRuslan Bukin {
39417f65170SRuslan Bukin outputUnsyncedBytes(unsynced_bytes);
39517f65170SRuslan Bukin m_in_block_processed = unsynced_bytes;
396*fc502085SRuslan Bukin m_trc_curr_idx += unsynced_bytes;
397*fc502085SRuslan Bukin }
398*fc502085SRuslan Bukin }
399*fc502085SRuslan Bukin return m_frame_synced;
400*fc502085SRuslan Bukin }
401*fc502085SRuslan Bukin
findfirstFSync()402*fc502085SRuslan Bukin uint32_t TraceFmtDcdImpl::findfirstFSync()
403*fc502085SRuslan Bukin {
404*fc502085SRuslan Bukin uint32_t processed = 0;
405*fc502085SRuslan Bukin const uint32_t FSYNC_PATTERN = 0x7FFFFFFF; // LE host pattern for FSYNC
406*fc502085SRuslan Bukin const uint8_t *dataPtr = m_in_block_base;
407*fc502085SRuslan Bukin
408*fc502085SRuslan Bukin while (processed < (m_in_block_size - 3))
409*fc502085SRuslan Bukin {
410*fc502085SRuslan Bukin if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
41117f65170SRuslan Bukin {
41217f65170SRuslan Bukin m_frame_synced = true;
41317f65170SRuslan Bukin break;
41417f65170SRuslan Bukin }
41517f65170SRuslan Bukin processed++;
41617f65170SRuslan Bukin dataPtr++;
41717f65170SRuslan Bukin }
41817f65170SRuslan Bukin return processed;
41917f65170SRuslan Bukin }
42017f65170SRuslan Bukin
outputUnsyncedBytes(uint32_t)42117f65170SRuslan Bukin void TraceFmtDcdImpl::outputUnsyncedBytes(uint32_t /*num_bytes*/)
42217f65170SRuslan Bukin {
42317f65170SRuslan Bukin //**TBD:
42417f65170SRuslan Bukin }
42517f65170SRuslan Bukin
checkForResetFSyncPatterns(uint32_t & f_sync_bytes)42617f65170SRuslan Bukin ocsd_err_t TraceFmtDcdImpl::checkForResetFSyncPatterns(uint32_t &f_sync_bytes)
42717f65170SRuslan Bukin {
42817f65170SRuslan Bukin const uint32_t FSYNC_PATTERN = 0x7FFFFFFF; // LE host pattern for FSYNC
42917f65170SRuslan Bukin bool check_for_fsync = true;
43017f65170SRuslan Bukin int num_fsyncs = 0;
43117f65170SRuslan Bukin uint32_t bytes_processed = m_in_block_processed;
43217f65170SRuslan Bukin const uint8_t *dataPtr = m_in_block_base + bytes_processed;
43317f65170SRuslan Bukin ocsd_err_t err = OCSD_OK;
43417f65170SRuslan Bukin
43517f65170SRuslan Bukin while (check_for_fsync && (bytes_processed < m_in_block_size))
43617f65170SRuslan Bukin {
43717f65170SRuslan Bukin // look for consecutive fsyncs as padding or for reset downstream - both cases will reset downstream....
43817f65170SRuslan Bukin if (*((uint32_t *)(dataPtr)) == FSYNC_PATTERN)
43917f65170SRuslan Bukin {
44017f65170SRuslan Bukin dataPtr += sizeof(uint32_t);
44117f65170SRuslan Bukin num_fsyncs++;
44217f65170SRuslan Bukin bytes_processed += sizeof(uint32_t);
44317f65170SRuslan Bukin }
44417f65170SRuslan Bukin else
44517f65170SRuslan Bukin check_for_fsync = false;
44617f65170SRuslan Bukin }
44717f65170SRuslan Bukin
44817f65170SRuslan Bukin if (num_fsyncs)
44917f65170SRuslan Bukin {
45017f65170SRuslan Bukin if ((num_fsyncs % 4) == 0)
45117f65170SRuslan Bukin {
45217f65170SRuslan Bukin // reset the upstream decoders
45317f65170SRuslan Bukin executeNoneDataOpAllIDs(OCSD_OP_RESET,m_trc_curr_idx);
45417f65170SRuslan Bukin
45517f65170SRuslan Bukin // reset the intra frame parameters
45617f65170SRuslan Bukin m_curr_src_ID = OCSD_BAD_CS_SRC_ID;
45717f65170SRuslan Bukin m_ex_frm_n_bytes = 0;
45817f65170SRuslan Bukin m_trc_curr_idx_sof = OCSD_BAD_TRC_INDEX;
45917f65170SRuslan Bukin }
46017f65170SRuslan Bukin else
46117f65170SRuslan Bukin {
46217f65170SRuslan Bukin err = OCSD_ERR_DFMTR_BAD_FHSYNC;
46317f65170SRuslan Bukin }
46417f65170SRuslan Bukin }
46517f65170SRuslan Bukin f_sync_bytes += num_fsyncs * 4;
46617f65170SRuslan Bukin return err;
46717f65170SRuslan Bukin }
468*fc502085SRuslan Bukin
46917f65170SRuslan Bukin /* Extract a single frame from the input buffer. */
extractFrame()47017f65170SRuslan Bukin bool TraceFmtDcdImpl::extractFrame()
47117f65170SRuslan Bukin {
47217f65170SRuslan Bukin const uint32_t FSYNC_PATTERN = 0x7FFFFFFF; // LE host pattern for FSYNC
47317f65170SRuslan Bukin const uint16_t HSYNC_PATTERN = 0x7FFF; // LE host pattern for HSYNC
47417f65170SRuslan Bukin const uint16_t FSYNC_START = 0xFFFF; // LE host pattern for start 2 bytes of fsync
47517f65170SRuslan Bukin
47617f65170SRuslan Bukin ocsd_err_t err;
47717f65170SRuslan Bukin uint32_t f_sync_bytes = 0; // skipped f sync bytes
47817f65170SRuslan Bukin uint32_t h_sync_bytes = 0; // skipped h sync bytes
47917f65170SRuslan Bukin uint32_t ex_bytes = 0; // extracted this pass (may be filling out part frame)
48017f65170SRuslan Bukin uint32_t buf_left = m_in_block_size - m_in_block_processed; // bytes remaining in buffer this pass.
48117f65170SRuslan Bukin
48217f65170SRuslan Bukin // last call was end of input block - but carried on to process full frame.
48317f65170SRuslan Bukin // exit early here.
48417f65170SRuslan Bukin if (!buf_left)
48517f65170SRuslan Bukin return false;
48617f65170SRuslan Bukin
48717f65170SRuslan Bukin // memory aligned input data is forced to be always multiples of 16 byte frames, aligned to start.
48817f65170SRuslan Bukin if( m_cfgFlags & OCSD_DFRMTR_FRAME_MEM_ALIGN)
48917f65170SRuslan Bukin {
49017f65170SRuslan Bukin // some linux drivers (e.g. for perf) will insert FSYNCS to pad or differentiate
49117f65170SRuslan Bukin // between blocks of aligned data, always in frame aligned complete 16 byte frames.
49217f65170SRuslan Bukin // we need to skip past these frames, resetting as we go.
49317f65170SRuslan Bukin if (m_cfgFlags & OCSD_DFRMTR_RESET_ON_4X_FSYNC)
49417f65170SRuslan Bukin {
49517f65170SRuslan Bukin err = checkForResetFSyncPatterns(f_sync_bytes);
49617f65170SRuslan Bukin
49717f65170SRuslan Bukin /* in this case the FSYNC pattern is output on both packed and unpacked cases */
49817f65170SRuslan Bukin if (f_sync_bytes && (m_b_output_packed_raw || m_b_output_unpacked_raw))
49917f65170SRuslan Bukin {
50017f65170SRuslan Bukin outputRawMonBytes(OCSD_OP_DATA,
50117f65170SRuslan Bukin m_trc_curr_idx,
50217f65170SRuslan Bukin OCSD_FRM_FSYNC,
50317f65170SRuslan Bukin f_sync_bytes,
50417f65170SRuslan Bukin m_in_block_base + m_in_block_processed,
50517f65170SRuslan Bukin 0);
50617f65170SRuslan Bukin }
50717f65170SRuslan Bukin
50817f65170SRuslan Bukin // throw processing error, none frame size block of fsyncs
50917f65170SRuslan Bukin if (err)
51017f65170SRuslan Bukin throw ocsdError(OCSD_ERR_SEV_ERROR, err, m_trc_curr_idx, "Incorrect FSYNC frame reset pattern");
51117f65170SRuslan Bukin
51217f65170SRuslan Bukin buf_left -= f_sync_bytes;
51317f65170SRuslan Bukin }
51417f65170SRuslan Bukin
51517f65170SRuslan Bukin if (buf_left)
51617f65170SRuslan Bukin {
51717f65170SRuslan Bukin // always a complete frame - the input data has to be 16 byte multiple alignment.
51817f65170SRuslan Bukin m_ex_frm_n_bytes = OCSD_DFRMTR_FRAME_SIZE;
51917f65170SRuslan Bukin memcpy(m_ex_frm_data, m_in_block_base + m_in_block_processed + f_sync_bytes, m_ex_frm_n_bytes);
52017f65170SRuslan Bukin m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
52117f65170SRuslan Bukin ex_bytes = OCSD_DFRMTR_FRAME_SIZE;
52217f65170SRuslan Bukin }
52317f65170SRuslan Bukin }
52417f65170SRuslan Bukin else
52517f65170SRuslan Bukin {
52617f65170SRuslan Bukin // extract data accounting for frame syncs and hsyncs if present.
52717f65170SRuslan Bukin // we know we are aligned at this point - could be FSYNC or HSYNCs here.
52817f65170SRuslan Bukin // HSYNC present, library forces input to be aligned 2 byte multiples
52917f65170SRuslan Bukin // FSYNC - w/o HSYNCs, forces input to be aligned 4 byte multiples.
53017f65170SRuslan Bukin
53117f65170SRuslan Bukin // check what we a looking for
53217f65170SRuslan Bukin bool hasFSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_FSYNCS) == OCSD_DFRMTR_HAS_FSYNCS);
53317f65170SRuslan Bukin bool hasHSyncs = ((m_cfgFlags & OCSD_DFRMTR_HAS_HSYNCS) == OCSD_DFRMTR_HAS_HSYNCS);
53417f65170SRuslan Bukin
53517f65170SRuslan Bukin const uint8_t* dataPtr = m_in_block_base + m_in_block_processed;
53617f65170SRuslan Bukin uint16_t data_pair_val;
53717f65170SRuslan Bukin
53817f65170SRuslan Bukin // can have FSYNCS at start of frame (in middle is an error).
539*fc502085SRuslan Bukin if (hasFSyncs && (m_ex_frm_n_bytes == 0))
54017f65170SRuslan Bukin {
54117f65170SRuslan Bukin // was there an fsync start at the end of the last buffer?
54217f65170SRuslan Bukin if (m_b_fsync_start_eob) {
54317f65170SRuslan Bukin // last 2 of FSYNC look like HSYNC
54417f65170SRuslan Bukin if (*(uint16_t*)(dataPtr) != HSYNC_PATTERN)
54517f65170SRuslan Bukin {
54617f65170SRuslan Bukin // this means 0xFFFF followed by something else - invalid ID + ????
54717f65170SRuslan 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)");
54817f65170SRuslan Bukin }
54917f65170SRuslan Bukin else
55017f65170SRuslan Bukin {
55117f65170SRuslan Bukin f_sync_bytes += 2;
55217f65170SRuslan Bukin buf_left -= 2;
55317f65170SRuslan Bukin dataPtr += 2;
55417f65170SRuslan Bukin }
55517f65170SRuslan Bukin m_b_fsync_start_eob = false;
55617f65170SRuslan Bukin }
55717f65170SRuslan Bukin
55817f65170SRuslan Bukin // regular fsync checks
55917f65170SRuslan Bukin while ((buf_left >= 4) && (*((uint32_t*)(dataPtr)) == FSYNC_PATTERN))
56017f65170SRuslan Bukin {
56117f65170SRuslan Bukin f_sync_bytes += 4;
56217f65170SRuslan Bukin dataPtr += 4;
56317f65170SRuslan Bukin buf_left -= 4;
564*fc502085SRuslan Bukin }
56517f65170SRuslan Bukin
56617f65170SRuslan Bukin // handle possible part fsync at the end of a buffer
56717f65170SRuslan Bukin if (buf_left == 2)
56817f65170SRuslan Bukin {
56917f65170SRuslan Bukin if (*(uint16_t*)(dataPtr) == FSYNC_START)
57017f65170SRuslan Bukin {
57117f65170SRuslan Bukin f_sync_bytes += 2;
57217f65170SRuslan Bukin buf_left -= 2;
57317f65170SRuslan Bukin dataPtr += 2;
57417f65170SRuslan Bukin m_b_fsync_start_eob = true;
57517f65170SRuslan Bukin }
57617f65170SRuslan Bukin }
57717f65170SRuslan Bukin }
578*fc502085SRuslan Bukin
579*fc502085SRuslan Bukin // process remaining data in pairs of bytes
580*fc502085SRuslan Bukin while ((m_ex_frm_n_bytes < OCSD_DFRMTR_FRAME_SIZE) && buf_left)
58117f65170SRuslan Bukin {
582*fc502085SRuslan Bukin // mark start of frame after FSyncs
58317f65170SRuslan Bukin if (m_ex_frm_n_bytes == 0)
58417f65170SRuslan Bukin m_trc_curr_idx_sof = m_trc_curr_idx + f_sync_bytes;
58517f65170SRuslan Bukin
58617f65170SRuslan Bukin m_ex_frm_data[m_ex_frm_n_bytes] = dataPtr[0];
587*fc502085SRuslan Bukin m_ex_frm_data[m_ex_frm_n_bytes + 1] = dataPtr[1];
58817f65170SRuslan Bukin
58917f65170SRuslan Bukin data_pair_val = *((uint16_t*)(dataPtr));
59017f65170SRuslan Bukin
59117f65170SRuslan Bukin // check pair is not HSYNC
59217f65170SRuslan Bukin if (data_pair_val == HSYNC_PATTERN)
593*fc502085SRuslan Bukin {
59417f65170SRuslan Bukin if (hasHSyncs)
59517f65170SRuslan Bukin {
596*fc502085SRuslan Bukin h_sync_bytes += 2;
59717f65170SRuslan Bukin }
59817f65170SRuslan Bukin else
59917f65170SRuslan Bukin {
60017f65170SRuslan Bukin // throw illegal HSYNC error.
60117f65170SRuslan Bukin throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_DFMTR_BAD_FHSYNC, m_trc_curr_idx, "Bad HSYNC in frame.");
60217f65170SRuslan Bukin }
60317f65170SRuslan Bukin }
60417f65170SRuslan Bukin // can't have a start of FSYNC here / illegal trace ID
60517f65170SRuslan Bukin else if (data_pair_val == FSYNC_START)
60617f65170SRuslan Bukin {
60717f65170SRuslan 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).");
60817f65170SRuslan Bukin }
60917f65170SRuslan Bukin else
61017f65170SRuslan Bukin {
61117f65170SRuslan Bukin m_ex_frm_n_bytes += 2;
61217f65170SRuslan Bukin ex_bytes += 2;
61317f65170SRuslan Bukin }
61417f65170SRuslan Bukin
61517f65170SRuslan Bukin buf_left -= 2;
61617f65170SRuslan Bukin dataPtr += 2;
61717f65170SRuslan Bukin }
61817f65170SRuslan Bukin }
61917f65170SRuslan Bukin
62017f65170SRuslan Bukin // total bytes processed this pass
62117f65170SRuslan Bukin uint32_t total_processed = ex_bytes + f_sync_bytes + h_sync_bytes;
62217f65170SRuslan Bukin
62317f65170SRuslan Bukin // output raw data on raw frame channel - packed raw.
62417f65170SRuslan Bukin if (((m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE) || (buf_left == 0)) && m_b_output_packed_raw)
62517f65170SRuslan Bukin {
62617f65170SRuslan Bukin outputRawMonBytes( OCSD_OP_DATA,
62717f65170SRuslan Bukin m_trc_curr_idx,
62817f65170SRuslan Bukin OCSD_FRM_PACKED,
62917f65170SRuslan Bukin total_processed,
63017f65170SRuslan Bukin m_in_block_base+m_in_block_processed,
63117f65170SRuslan Bukin 0);
63217f65170SRuslan Bukin }
63317f65170SRuslan Bukin
63417f65170SRuslan Bukin // update the processed count for the buffer
63517f65170SRuslan Bukin m_in_block_processed += total_processed;
63617f65170SRuslan Bukin
63717f65170SRuslan Bukin // update index past the processed data
63817f65170SRuslan Bukin m_trc_curr_idx += total_processed;
63917f65170SRuslan Bukin
64017f65170SRuslan Bukin // update any none trace data byte stats
64117f65170SRuslan Bukin addToFrameStats((uint64_t)(f_sync_bytes + h_sync_bytes));
64217f65170SRuslan Bukin
64317f65170SRuslan Bukin // if we are exiting with a full frame then signal processing to continue
64417f65170SRuslan Bukin return (bool)(m_ex_frm_n_bytes == OCSD_DFRMTR_FRAME_SIZE);
64517f65170SRuslan Bukin }
64617f65170SRuslan Bukin
unpackFrame()64717f65170SRuslan Bukin bool TraceFmtDcdImpl::unpackFrame()
64817f65170SRuslan Bukin {
64917f65170SRuslan Bukin // unpack cannot fail as never called on incomplete frame.
65017f65170SRuslan Bukin uint8_t frameFlagBit = 0x1;
65117f65170SRuslan Bukin uint8_t newSrcID = OCSD_BAD_CS_SRC_ID;
65217f65170SRuslan Bukin bool PrevIDandIDChange = false;
65317f65170SRuslan Bukin uint64_t noneDataBytes = 0;
65417f65170SRuslan Bukin
65517f65170SRuslan Bukin // init output processing
65617f65170SRuslan Bukin m_out_data_idx = 0;
65717f65170SRuslan Bukin m_out_processed = 0;
65817f65170SRuslan Bukin
65917f65170SRuslan Bukin // set up first out data packet...
66017f65170SRuslan Bukin m_out_data[m_out_data_idx].id = m_curr_src_ID;
66117f65170SRuslan Bukin m_out_data[m_out_data_idx].valid = 0;
66217f65170SRuslan Bukin m_out_data[m_out_data_idx].index = m_trc_curr_idx_sof;
66317f65170SRuslan Bukin m_out_data[m_out_data_idx].used = 0;
66417f65170SRuslan Bukin
66517f65170SRuslan Bukin // work on byte pairs - bytes 0 - 13.
66617f65170SRuslan Bukin for(int i = 0; i < 14; i+=2)
66717f65170SRuslan Bukin {
66817f65170SRuslan Bukin PrevIDandIDChange = false;
66917f65170SRuslan Bukin
67017f65170SRuslan Bukin // it's an ID + data
67117f65170SRuslan Bukin if(m_ex_frm_data[i] & 0x1)
67217f65170SRuslan Bukin {
67317f65170SRuslan Bukin newSrcID = (m_ex_frm_data[i] >> 1) & 0x7f;
67417f65170SRuslan Bukin if(newSrcID != m_curr_src_ID) // ID change
67517f65170SRuslan Bukin {
67617f65170SRuslan Bukin PrevIDandIDChange = ((frameFlagBit & m_ex_frm_data[15]) != 0);
67717f65170SRuslan Bukin
67817f65170SRuslan Bukin // following byte for old id?
67917f65170SRuslan Bukin if(PrevIDandIDChange)
68017f65170SRuslan Bukin // 2nd byte always data
68117f65170SRuslan Bukin m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
68217f65170SRuslan Bukin
68317f65170SRuslan Bukin // change ID
68417f65170SRuslan Bukin m_curr_src_ID = newSrcID;
68517f65170SRuslan Bukin
68617f65170SRuslan Bukin // if we already have data in this buffer
68717f65170SRuslan Bukin if(m_out_data[m_out_data_idx].valid > 0)
68817f65170SRuslan Bukin {
68917f65170SRuslan Bukin m_out_data_idx++; // move to next buffer
69017f65170SRuslan Bukin m_out_data[m_out_data_idx].valid = 0;
69117f65170SRuslan Bukin m_out_data[m_out_data_idx].used = 0;
69217f65170SRuslan Bukin m_out_data[m_out_data_idx].index = m_trc_curr_idx_sof + i;
69317f65170SRuslan Bukin }
69417f65170SRuslan Bukin
69517f65170SRuslan Bukin // set new ID on buffer
69617f65170SRuslan Bukin m_out_data[m_out_data_idx].id = m_curr_src_ID;
69717f65170SRuslan Bukin
69817f65170SRuslan Bukin /// TBD - ID indexing in here.
69917f65170SRuslan Bukin }
70017f65170SRuslan Bukin noneDataBytes++;
70117f65170SRuslan Bukin }
70217f65170SRuslan Bukin else
70317f65170SRuslan Bukin // it's just data
70417f65170SRuslan Bukin {
70517f65170SRuslan 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);
70617f65170SRuslan Bukin }
70717f65170SRuslan Bukin
70817f65170SRuslan Bukin // 2nd byte always data
70917f65170SRuslan Bukin if(!PrevIDandIDChange) // output only if we didn't for an ID change + prev ID.
71017f65170SRuslan Bukin m_out_data[m_out_data_idx].data[m_out_data[m_out_data_idx].valid++] = m_ex_frm_data[i+1];
71117f65170SRuslan Bukin
71217f65170SRuslan Bukin frameFlagBit <<= 1;
71317f65170SRuslan Bukin }
71417f65170SRuslan Bukin
71517f65170SRuslan Bukin // unpack byte 14;
71617f65170SRuslan Bukin
71717f65170SRuslan Bukin // it's an ID
71817f65170SRuslan Bukin if(m_ex_frm_data[14] & 0x1)
71917f65170SRuslan Bukin {
72017f65170SRuslan Bukin // no matter if change or not, no associated data in byte 15 anyway so just set.
72117f65170SRuslan Bukin m_curr_src_ID = (m_ex_frm_data[14] >> 1) & 0x7f;
72217f65170SRuslan Bukin noneDataBytes++;
72317f65170SRuslan Bukin }
72417f65170SRuslan Bukin // it's data
72517f65170SRuslan Bukin else
72617f65170SRuslan Bukin {
72717f65170SRuslan 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);
72817f65170SRuslan Bukin }
72917f65170SRuslan Bukin m_ex_frm_n_bytes = 0; // mark frame as empty;
73017f65170SRuslan Bukin
73117f65170SRuslan Bukin noneDataBytes++; // byte 15 is always non-data.
73217f65170SRuslan Bukin addToFrameStats(noneDataBytes); // update the non data byte stats.
73317f65170SRuslan Bukin return true;
73417f65170SRuslan Bukin }
73517f65170SRuslan Bukin
73617f65170SRuslan Bukin // output data to channels.
outputFrame()73717f65170SRuslan Bukin bool TraceFmtDcdImpl::outputFrame()
73817f65170SRuslan Bukin {
73917f65170SRuslan Bukin bool cont_processing = true;
74017f65170SRuslan Bukin ITrcDataIn *pDataIn = 0;
74117f65170SRuslan Bukin uint32_t bytes_used;
74217f65170SRuslan Bukin
74317f65170SRuslan Bukin // output each valid ID within the frame - stopping if we get a wait or error
74417f65170SRuslan Bukin while((m_out_processed < (m_out_data_idx + 1)) && cont_processing)
74517f65170SRuslan Bukin {
74617f65170SRuslan Bukin
74717f65170SRuslan Bukin // may have data prior to a valid ID appearing
74817f65170SRuslan Bukin if(m_out_data[m_out_processed].id != OCSD_BAD_CS_SRC_ID)
74917f65170SRuslan Bukin {
75017f65170SRuslan Bukin if((pDataIn = m_IDStreams[m_out_data[m_out_processed].id].first()) != 0)
75117f65170SRuslan Bukin {
75217f65170SRuslan Bukin // log the stuff we are about to put out early so as to make it visible before interpretation
75317f65170SRuslan Bukin // however, don't re-output if only part used first time round.
75417f65170SRuslan Bukin if(m_b_output_unpacked_raw && (m_out_data[m_out_processed].used == 0) && rawChanEnabled( m_out_data[m_out_processed].id))
75517f65170SRuslan Bukin {
75617f65170SRuslan Bukin outputRawMonBytes( OCSD_OP_DATA,
75717f65170SRuslan Bukin m_out_data[m_out_processed].index,
75817f65170SRuslan Bukin OCSD_FRM_ID_DATA,
75917f65170SRuslan Bukin m_out_data[m_out_processed].valid,
76017f65170SRuslan Bukin m_out_data[m_out_processed].data,
76117f65170SRuslan Bukin m_out_data[m_out_processed].id);
76217f65170SRuslan Bukin }
76317f65170SRuslan Bukin
76417f65170SRuslan Bukin // output to the connected packet process
76517f65170SRuslan Bukin CollateDataPathResp(pDataIn->TraceDataIn(OCSD_OP_DATA,
76617f65170SRuslan Bukin m_out_data[m_out_processed].index + m_out_data[m_out_processed].used,
76717f65170SRuslan Bukin m_out_data[m_out_processed].valid - m_out_data[m_out_processed].used,
76817f65170SRuslan Bukin m_out_data[m_out_processed].data + m_out_data[m_out_processed].used,
76917f65170SRuslan Bukin &bytes_used));
77017f65170SRuslan Bukin
77117f65170SRuslan Bukin addToIDStats((uint64_t)bytes_used);
77217f65170SRuslan Bukin
77317f65170SRuslan Bukin if(!dataPathCont())
77417f65170SRuslan Bukin {
77517f65170SRuslan Bukin cont_processing = false;
77617f65170SRuslan Bukin m_out_data[m_out_processed].used += bytes_used;
77717f65170SRuslan Bukin if(m_out_data[m_out_processed].used == m_out_data[m_out_processed].valid)
77817f65170SRuslan Bukin m_out_processed++; // we have used up all this data.
77917f65170SRuslan Bukin }
78017f65170SRuslan Bukin else
78117f65170SRuslan Bukin {
78217f65170SRuslan Bukin m_out_processed++; // we have sent this data;
78317f65170SRuslan Bukin }
78417f65170SRuslan Bukin }
78517f65170SRuslan Bukin else
78617f65170SRuslan Bukin {
78717f65170SRuslan Bukin // optional raw output for debugging / monitor tools
78817f65170SRuslan Bukin if(m_b_output_unpacked_raw && rawChanEnabled( m_out_data[m_out_processed].id))
78917f65170SRuslan Bukin {
79017f65170SRuslan Bukin outputRawMonBytes( OCSD_OP_DATA,
79117f65170SRuslan Bukin m_out_data[m_out_processed].index,
79217f65170SRuslan Bukin OCSD_FRM_ID_DATA,
79317f65170SRuslan Bukin m_out_data[m_out_processed].valid,
79417f65170SRuslan Bukin m_out_data[m_out_processed].data,
79517f65170SRuslan Bukin m_out_data[m_out_processed].id);
79617f65170SRuslan Bukin }
79717f65170SRuslan Bukin
79817f65170SRuslan Bukin if (isReservedID(m_out_data[m_out_processed].id))
79917f65170SRuslan Bukin addToReservedIDStats((uint64_t)m_out_data[m_out_processed].valid);
80017f65170SRuslan Bukin else
80117f65170SRuslan Bukin addToNoIDStats((uint64_t)m_out_data[m_out_processed].valid);
80217f65170SRuslan Bukin m_out_processed++; // skip past this data.
80317f65170SRuslan Bukin }
80417f65170SRuslan Bukin }
80517f65170SRuslan Bukin else
80617f65170SRuslan Bukin {
80717f65170SRuslan Bukin // optional raw output for debugging / monitor tools of unknown src ID data
80817f65170SRuslan Bukin if(m_b_output_unpacked_raw)
80917f65170SRuslan Bukin {
81017f65170SRuslan Bukin outputRawMonBytes( OCSD_OP_DATA,
81117f65170SRuslan Bukin m_out_data[m_out_processed].index,
81217f65170SRuslan Bukin OCSD_FRM_ID_DATA,
81317f65170SRuslan Bukin m_out_data[m_out_processed].valid,
81417f65170SRuslan Bukin m_out_data[m_out_processed].data,
81517f65170SRuslan Bukin m_out_data[m_out_processed].id);
81617f65170SRuslan Bukin }
81717f65170SRuslan Bukin addToUnknownIDStats((uint64_t)m_out_data[m_out_processed].valid);
81817f65170SRuslan Bukin m_out_processed++; // skip past this data.
81917f65170SRuslan Bukin }
82017f65170SRuslan Bukin }
82117f65170SRuslan Bukin return cont_processing;
82217f65170SRuslan Bukin }
82317f65170SRuslan Bukin
addToIDStats(uint64_t val)82417f65170SRuslan Bukin void TraceFmtDcdImpl::addToIDStats(uint64_t val)
82517f65170SRuslan Bukin {
82617f65170SRuslan Bukin if (m_pStatsBlock)
82717f65170SRuslan Bukin m_pStatsBlock->valid_id_bytes += val;
82817f65170SRuslan Bukin }
82917f65170SRuslan Bukin
addToNoIDStats(uint64_t val)83017f65170SRuslan Bukin void TraceFmtDcdImpl::addToNoIDStats(uint64_t val)
83117f65170SRuslan Bukin {
83217f65170SRuslan Bukin if (m_pStatsBlock)
833*fc502085SRuslan Bukin m_pStatsBlock->no_id_bytes += val;
83417f65170SRuslan Bukin }
83517f65170SRuslan Bukin
addToFrameStats(uint64_t val)83617f65170SRuslan Bukin void TraceFmtDcdImpl::addToFrameStats(uint64_t val)
83717f65170SRuslan Bukin {
83817f65170SRuslan Bukin if (m_pStatsBlock)
83917f65170SRuslan Bukin m_pStatsBlock->frame_bytes += val;
84017f65170SRuslan Bukin }
84117f65170SRuslan Bukin
addToUnknownIDStats(uint64_t val)84217f65170SRuslan Bukin void TraceFmtDcdImpl::addToUnknownIDStats(uint64_t val)
84317f65170SRuslan Bukin {
84417f65170SRuslan Bukin if (m_pStatsBlock)
84517f65170SRuslan Bukin m_pStatsBlock->unknown_id_bytes += val;
84617f65170SRuslan Bukin }
84717f65170SRuslan Bukin
addToReservedIDStats(uint64_t val)84817f65170SRuslan Bukin void TraceFmtDcdImpl::addToReservedIDStats(uint64_t val)
84917f65170SRuslan Bukin {
85017f65170SRuslan Bukin if (m_pStatsBlock)
85117f65170SRuslan Bukin m_pStatsBlock->reserved_id_bytes += val;
85217f65170SRuslan Bukin }
85317f65170SRuslan Bukin
85417f65170SRuslan Bukin /***************************************************************/
85517f65170SRuslan Bukin /* interface */
85617f65170SRuslan Bukin /***************************************************************/
TraceFormatterFrameDecoder()85717f65170SRuslan Bukin TraceFormatterFrameDecoder::TraceFormatterFrameDecoder() : m_pDecoder(0)
85817f65170SRuslan Bukin {
85917f65170SRuslan Bukin m_instNum = -1;
86017f65170SRuslan Bukin }
86117f65170SRuslan Bukin
TraceFormatterFrameDecoder(int instNum)86217f65170SRuslan Bukin TraceFormatterFrameDecoder::TraceFormatterFrameDecoder(int instNum) : m_pDecoder(0)
86317f65170SRuslan Bukin {
86417f65170SRuslan Bukin m_instNum = instNum;
86517f65170SRuslan Bukin }
86617f65170SRuslan Bukin
~TraceFormatterFrameDecoder()86717f65170SRuslan Bukin TraceFormatterFrameDecoder::~TraceFormatterFrameDecoder()
86817f65170SRuslan Bukin {
86917f65170SRuslan Bukin if(m_pDecoder)
870 {
871 delete m_pDecoder;
872 m_pDecoder = 0;
873 }
874 }
875
876 /* 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)877 ocsd_datapath_resp_t TraceFormatterFrameDecoder::TraceDataIn( const ocsd_datapath_op_t op,
878 const ocsd_trc_index_t index,
879 const uint32_t dataBlockSize,
880 const uint8_t *pDataBlock,
881 uint32_t *numBytesProcessed)
882 {
883 return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
884 }
885
886 /* attach a data processor to a stream ID output */
getIDStreamAttachPt(uint8_t ID)887 componentAttachPt<ITrcDataIn> *TraceFormatterFrameDecoder::getIDStreamAttachPt(uint8_t ID)
888 {
889 componentAttachPt<ITrcDataIn> *pAttachPt = 0;
890 if((ID < 128) && (m_pDecoder != 0))
891 pAttachPt = &(m_pDecoder->m_IDStreams[ID]);
892 return pAttachPt;
893 }
894
895 /* attach a data processor to the raw frame output */
getTrcRawFrameAttachPt()896 componentAttachPt<ITrcRawFrameIn> *TraceFormatterFrameDecoder::getTrcRawFrameAttachPt()
897 {
898 return (m_pDecoder != 0) ? &m_pDecoder->m_RawTraceFrame : 0;
899 }
900
901
getTrcSrcIndexAttachPt()902 componentAttachPt<ITrcSrcIndexCreator> *TraceFormatterFrameDecoder::getTrcSrcIndexAttachPt()
903 {
904 return (m_pDecoder != 0) ? &m_pDecoder->m_SrcIndexer : 0;
905 }
906
getErrLogAttachPt()907 componentAttachPt<ITraceErrorLog> *TraceFormatterFrameDecoder::getErrLogAttachPt()
908 {
909 return (m_pDecoder != 0) ? m_pDecoder->getErrorLogAttachPt() : 0;
910 }
911
Init()912 ocsd_err_t TraceFormatterFrameDecoder::Init()
913 {
914 if (!m_pDecoder)
915 {
916 if (m_instNum >= 0)
917 m_pDecoder = new (std::nothrow) TraceFmtDcdImpl(m_instNum);
918 else
919 m_pDecoder = new (std::nothrow) TraceFmtDcdImpl();
920 if (!m_pDecoder) return OCSD_ERR_MEM;
921 }
922 return OCSD_OK;
923 }
924
925 /* configuration - set operational mode for incoming stream (has FSYNCS etc) */
Configure(uint32_t cfg_flags)926 ocsd_err_t TraceFormatterFrameDecoder::Configure(uint32_t cfg_flags)
927 {
928 if (!m_pDecoder)
929 return OCSD_ERR_NOT_INIT;
930 return m_pDecoder->DecodeConfigure(cfg_flags);
931 }
932
getConfigFlags() const933 const uint32_t TraceFormatterFrameDecoder::getConfigFlags() const
934 {
935 uint32_t flags = 0;
936 if(m_pDecoder)
937 flags = m_pDecoder->m_cfgFlags;
938 return flags;
939 }
940
941
942 /* enable / disable ID streams - default as all enabled */
OutputFilterIDs(std::vector<uint8_t> & id_list,bool bEnable)943 ocsd_err_t TraceFormatterFrameDecoder::OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable)
944 {
945 return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterIDs(id_list,bEnable);
946 }
947
OutputFilterAllIDs(bool bEnable)948 ocsd_err_t TraceFormatterFrameDecoder::OutputFilterAllIDs(bool bEnable)
949 {
950 return (m_pDecoder == 0) ? OCSD_ERR_NOT_INIT : m_pDecoder->OutputFilterAllIDs(bEnable);
951 }
952
953 /* decode control */
Reset()954 ocsd_datapath_resp_t TraceFormatterFrameDecoder::Reset()
955 {
956 return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Reset();
957 }
958
Flush()959 ocsd_datapath_resp_t TraceFormatterFrameDecoder::Flush()
960 {
961 return (m_pDecoder == 0) ? OCSD_RESP_FATAL_NOT_INIT : m_pDecoder->Flush();
962 }
963
SetDemuxStatsBlock(ocsd_demux_stats_t * pStatsBlock)964 void TraceFormatterFrameDecoder::SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock)
965 {
966 if (m_pDecoder)
967 m_pDecoder->SetDemuxStatsBlock(pStatsBlock);
968 }
969
970 /* End of File trc_frame_deformatter.cpp */
971