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