1/* 2 * \file ocsd_dcd_tree.cpp 3 * \brief OpenCSD : 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 8 9/* 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation 18 * and/or other materials provided with the distribution. 19 * 20 * 3. Neither the name of the copyright holder nor the names of its contributors 21 * may be used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36#include "common/ocsd_dcd_tree.h" 37#include "common/ocsd_lib_dcd_register.h" 38#include "mem_acc/trc_mem_acc_mapper.h" 39 40/***************************************************************/ 41ITraceErrorLog *DecodeTree::s_i_error_logger = &DecodeTree::s_error_logger; 42std::list<DecodeTree *> DecodeTree::s_trace_dcd_trees; /**< list of pointers to decode tree objects */ 43ocsdDefaultErrorLogger DecodeTree::s_error_logger; /**< The library default error logger */ 44TrcIDecode DecodeTree::s_instruction_decoder; /**< default instruction decode library */ 45 46DecodeTree *DecodeTree::CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, uint32_t formatterCfgFlags) 47{ 48 DecodeTree *dcd_tree = new (std::nothrow) DecodeTree(); 49 if(dcd_tree != 0) 50 { 51 if(dcd_tree->initialise(src_type, formatterCfgFlags)) 52 { 53 s_trace_dcd_trees.push_back(dcd_tree); 54 } 55 else 56 { 57 delete dcd_tree; 58 dcd_tree = 0; 59 } 60 } 61 return dcd_tree; 62} 63 64void DecodeTree::DestroyDecodeTree(DecodeTree *p_dcd_tree) 65{ 66 std::list<DecodeTree *>::iterator it; 67 bool bDestroyed = false; 68 it = s_trace_dcd_trees.begin(); 69 while(!bDestroyed && (it != s_trace_dcd_trees.end())) 70 { 71 if(*it == p_dcd_tree) 72 { 73 s_trace_dcd_trees.erase(it); 74 delete p_dcd_tree; 75 bDestroyed = true; 76 } 77 else 78 it++; 79 } 80} 81 82void DecodeTree::setAlternateErrorLogger(ITraceErrorLog *p_error_logger) 83{ 84 if(p_error_logger) 85 s_i_error_logger = p_error_logger; 86 else 87 s_i_error_logger = &s_error_logger; 88} 89 90/***************************************************************/ 91 92DecodeTree::DecodeTree() : 93 m_i_instr_decode(&s_instruction_decoder), 94 m_i_mem_access(0), 95 m_i_gen_elem_out(0), 96 m_i_decoder_root(0), 97 m_frame_deformatter_root(0), 98 m_decode_elem_iter(0), 99 m_default_mapper(0), 100 m_created_mapper(false) 101{ 102 for(int i = 0; i < 0x80; i++) 103 m_decode_elements[i] = 0; 104 105 // reset the global demux stats. 106 m_demux_stats.frame_bytes = 0; 107 m_demux_stats.no_id_bytes = 0; 108 m_demux_stats.valid_id_bytes = 0; 109 m_demux_stats.unknown_id_bytes = 0; 110 m_demux_stats.reserved_id_bytes = 0; 111} 112 113DecodeTree::~DecodeTree() 114{ 115 destroyMemAccMapper(); 116 for(uint8_t i = 0; i < 0x80; i++) 117 { 118 destroyDecodeElement(i); 119 } 120 PktPrinterFact::destroyAllPrinters(m_printer_list); 121 delete m_frame_deformatter_root; 122} 123 124 125 126ocsd_datapath_resp_t DecodeTree::TraceDataIn( const ocsd_datapath_op_t op, 127 const ocsd_trc_index_t index, 128 const uint32_t dataBlockSize, 129 const uint8_t *pDataBlock, 130 uint32_t *numBytesProcessed) 131{ 132 if(m_i_decoder_root) 133 return m_i_decoder_root->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed); 134 *numBytesProcessed = 0; 135 return OCSD_RESP_FATAL_NOT_INIT; 136} 137 138/* set key interfaces - attach / replace on any existing tree components */ 139void DecodeTree::setInstrDecoder(IInstrDecode *i_instr_decode) 140{ 141 uint8_t elemID; 142 DecodeTreeElement *pElem = 0; 143 144 pElem = getFirstElement(elemID); 145 while(pElem != 0) 146 { 147 pElem->getDecoderMngr()->attachInstrDecoder(pElem->getDecoderHandle(),i_instr_decode); 148 pElem = getNextElement(elemID); 149 } 150} 151 152void DecodeTree::setMemAccessI(ITargetMemAccess *i_mem_access) 153{ 154 uint8_t elemID; 155 DecodeTreeElement *pElem = 0; 156 157 pElem = getFirstElement(elemID); 158 while(pElem != 0) 159 { 160 pElem->getDecoderMngr()->attachMemAccessor(pElem->getDecoderHandle(),i_mem_access); 161 pElem = getNextElement(elemID); 162 } 163 m_i_mem_access = i_mem_access; 164} 165 166void DecodeTree::setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem) 167{ 168 uint8_t elemID; 169 DecodeTreeElement *pElem = 0; 170 171 pElem = getFirstElement(elemID); 172 while(pElem != 0) 173 { 174 pElem->getDecoderMngr()->attachOutputSink(pElem->getDecoderHandle(),i_gen_trace_elem); 175 pElem = getNextElement(elemID); 176 } 177} 178 179ocsd_err_t DecodeTree::createMemAccMapper(memacc_mapper_t type /* = MEMACC_MAP_GLOBAL*/ ) 180{ 181 // clean up any old one 182 destroyMemAccMapper(); 183 184 // make a new one 185 switch(type) 186 { 187 default: 188 case MEMACC_MAP_GLOBAL: 189 m_default_mapper = new (std::nothrow) TrcMemAccMapGlobalSpace(); 190 break; 191 } 192 193 // set the access interface 194 if(m_default_mapper) 195 { 196 m_created_mapper = true; 197 setMemAccessI(m_default_mapper); 198 m_default_mapper->setErrorLog(s_i_error_logger); 199 } 200 201 return (m_default_mapper != 0) ? OCSD_OK : OCSD_ERR_MEM; 202} 203 204void DecodeTree::setExternMemAccMapper(TrcMemAccMapper* pMapper) 205{ 206 destroyMemAccMapper(); // destroy any existing mapper - if decode tree created it. 207 m_default_mapper = pMapper; 208} 209 210void DecodeTree::destroyMemAccMapper() 211{ 212 if(m_default_mapper && m_created_mapper) 213 { 214 m_default_mapper->RemoveAllAccessors(); 215 delete m_default_mapper; 216 m_default_mapper = 0; 217 m_created_mapper = false; 218 } 219} 220 221void DecodeTree::logMappedRanges() 222{ 223 if(m_default_mapper) 224 m_default_mapper->logMappedRanges(); 225} 226 227/* Memory accessor creation - all on default mem accessor using the 0 CSID for global core space. */ 228ocsd_err_t DecodeTree::addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length) 229{ 230 if(!hasMemAccMapper()) 231 return OCSD_ERR_NOT_INIT; 232 233 // need a valid memory buffer, and a least enough bytes for one opcode. 234 if((p_mem_buffer == 0) || (mem_length < 4)) 235 return OCSD_ERR_INVALID_PARAM_VAL; 236 237 TrcMemAccessorBase *p_accessor; 238 ocsd_err_t err = TrcMemAccFactory::CreateBufferAccessor(&p_accessor, address, p_mem_buffer, mem_length); 239 if(err == OCSD_OK) 240 { 241 TrcMemAccBufPtr *pMBuffAcc = dynamic_cast<TrcMemAccBufPtr *>(p_accessor); 242 if(pMBuffAcc) 243 { 244 pMBuffAcc->setMemSpace(mem_space); 245 err = m_default_mapper->AddAccessor(p_accessor,0); 246 } 247 else 248 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 249 250 if(err != OCSD_OK) 251 TrcMemAccFactory::DestroyAccessor(p_accessor); 252 } 253 return err; 254} 255 256ocsd_err_t DecodeTree::addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 257{ 258 if(!hasMemAccMapper()) 259 return OCSD_ERR_NOT_INIT; 260 261 if(filepath.length() == 0) 262 return OCSD_ERR_INVALID_PARAM_VAL; 263 264 TrcMemAccessorBase *p_accessor; 265 ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,address); 266 267 if(err == OCSD_OK) 268 { 269 TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 270 if(pAcc) 271 { 272 pAcc->setMemSpace(mem_space); 273 err = m_default_mapper->AddAccessor(pAcc,0); 274 } 275 else 276 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 277 278 if(err != OCSD_OK) 279 TrcMemAccFactory::DestroyAccessor(p_accessor); 280 } 281 return err; 282 283} 284 285ocsd_err_t DecodeTree::addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 286{ 287 if(!hasMemAccMapper()) 288 return OCSD_ERR_NOT_INIT; 289 290 if((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 291 return OCSD_ERR_INVALID_PARAM_VAL; 292 293 TrcMemAccessorBase *p_accessor; 294 int curr_region_idx = 0; 295 296 // add first region during the creation of the file accessor. 297 ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,region_array[curr_region_idx].start_address,region_array[curr_region_idx].file_offset, region_array[curr_region_idx].region_size); 298 if(err == OCSD_OK) 299 { 300 TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 301 if(pAcc) 302 { 303 // add additional regions to the file accessor. 304 curr_region_idx++; 305 while(curr_region_idx < num_regions) 306 { 307 pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 308 region_array[curr_region_idx].region_size, 309 region_array[curr_region_idx].file_offset); 310 curr_region_idx++; 311 } 312 pAcc->setMemSpace(mem_space); 313 314 // add the accessor to the map. 315 err = m_default_mapper->AddAccessor(pAcc,0); 316 } 317 else 318 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 319 320 if(err != OCSD_OK) 321 TrcMemAccFactory::DestroyAccessor(p_accessor); 322 } 323 return err; 324} 325 326ocsd_err_t DecodeTree::updateBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 327{ 328 if (!hasMemAccMapper()) 329 return OCSD_ERR_NOT_INIT; 330 331 if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 332 return OCSD_ERR_INVALID_PARAM_VAL; 333 334 TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath); 335 if (!pAcc) 336 return OCSD_ERR_INVALID_PARAM_VAL; 337 338 int curr_region_idx = 0; 339 while (curr_region_idx < num_regions) 340 { 341 // check "new" range 342 if (!pAcc->addrStartOfRange(region_array[curr_region_idx].start_address)) 343 { 344 // ensure adds cleanly 345 if (!pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 346 region_array[curr_region_idx].region_size, 347 region_array[curr_region_idx].file_offset)) 348 return OCSD_ERR_INVALID_PARAM_VAL; // otherwise bail out 349 } 350 curr_region_idx++; 351 } 352 return OCSD_OK; 353} 354ocsd_err_t DecodeTree::initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, 355 const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context) 356{ 357 if(!hasMemAccMapper()) 358 return OCSD_ERR_NOT_INIT; 359 360 if(p_cb_func == 0) 361 return OCSD_ERR_INVALID_PARAM_VAL; 362 363 TrcMemAccessorBase *p_accessor; 364 ocsd_err_t err = TrcMemAccFactory::CreateCBAccessor(&p_accessor, st_address, en_address, mem_space); 365 if(err == OCSD_OK) 366 { 367 TrcMemAccCB *pCBAcc = dynamic_cast<TrcMemAccCB *>(p_accessor); 368 if(pCBAcc) 369 { 370 if (IDfn) 371 pCBAcc->setCBIDIfFn((Fn_MemAccID_CB)p_cb_func, p_context); 372 else 373 pCBAcc->setCBIfFn((Fn_MemAcc_CB)p_cb_func, p_context); 374 375 err = m_default_mapper->AddAccessor(p_accessor,0); 376 } 377 else 378 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 379 380 if(err != OCSD_OK) 381 TrcMemAccFactory::DestroyAccessor(p_accessor); 382 } 383 return err; 384} 385 386ocsd_err_t DecodeTree::addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context) 387{ 388 return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, false, p_context); 389} 390 391ocsd_err_t DecodeTree::addCallbackIDMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAccID_CB p_cb_func, const void *p_context) 392{ 393 return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, true, p_context); 394} 395 396ocsd_err_t DecodeTree::removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space) 397{ 398 if(!hasMemAccMapper()) 399 return OCSD_ERR_NOT_INIT; 400 return m_default_mapper->RemoveAccessorByAddress(address,mem_space,0); 401} 402 403ocsd_err_t DecodeTree::createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig) 404{ 405 ocsd_err_t err = OCSD_OK; 406 IDecoderMngr *pDecoderMngr = 0; 407 TraceComponent *pTraceComp = 0; 408 int crtFlags = createFlags; 409 410 uint8_t CSID = 0; // default for single stream decoder (no deformatter) - we ignore the ID 411 if(usingFormatter()) 412 { 413 CSID = pConfig->getTraceID(); 414 crtFlags |= OCSD_CREATE_FLG_INST_ID; 415 } 416 417 // create the decode element to attach to the channel. 418 if((err = createDecodeElement(CSID)) != OCSD_OK) 419 return err; 420 421 // get the libary decoder register. 422 OcsdLibDcdRegister * lib_reg = OcsdLibDcdRegister::getDecoderRegister(); 423 if(lib_reg == 0) 424 return OCSD_ERR_NOT_INIT; 425 426 // find the named decoder 427 if((err = lib_reg->getDecoderMngrByName(decoderName,&pDecoderMngr)) != OCSD_OK) 428 return err; 429 430 // got the decoder... 431 if((err = pDecoderMngr->createDecoder(crtFlags,(int)CSID,pConfig,&pTraceComp)) != OCSD_OK) 432 return err; 433 434 m_decode_elements[CSID]->SetDecoderElement(decoderName, pDecoderMngr, pTraceComp, true); 435 436 // always attach an error logger 437 if(err == OCSD_OK) 438 err = pDecoderMngr->attachErrorLogger(pTraceComp,DecodeTree::s_i_error_logger); 439 440 // if we created a packet decoder it may need additional components. 441 if(crtFlags & OCSD_CREATE_FLG_FULL_DECODER) 442 { 443 if(m_i_instr_decode && (err == OCSD_OK)) 444 err = pDecoderMngr->attachInstrDecoder(pTraceComp,m_i_instr_decode); 445 446 if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if instruction decoder refused 447 err = OCSD_OK; 448 449 if(m_i_mem_access && (err == OCSD_OK)) 450 err = pDecoderMngr->attachMemAccessor(pTraceComp,m_i_mem_access); 451 452 if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if mem accessor refused 453 err = OCSD_OK; 454 455 if( m_i_gen_elem_out && (err == OCSD_OK)) 456 err = pDecoderMngr->attachOutputSink(pTraceComp,m_i_gen_elem_out); 457 } 458 459 // finally attach the packet processor input to the demux output channel 460 if(err == OCSD_OK) 461 { 462 ITrcDataIn *pDataIn = 0; 463 if((err = pDecoderMngr->getDataInputI(pTraceComp,&pDataIn)) == OCSD_OK) 464 { 465 // got the interface -> attach to demux, or direct to input of decode tree 466 if(usingFormatter()) 467 err = m_frame_deformatter_root->getIDStreamAttachPt(CSID)->attach(pDataIn); 468 else 469 m_i_decoder_root = pDataIn; 470 } 471 } 472 473 if(err != OCSD_OK) 474 { 475 destroyDecodeElement(CSID); // will destroy decoder as well. 476 } 477 return err; 478} 479 480ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID) 481{ 482 ocsd_err_t err = OCSD_OK; 483 uint8_t localID = CSID; 484 if(!usingFormatter()) 485 localID = 0; 486 487 if(usingFormatter() && !OCSD_IS_VALID_CS_SRC_ID(CSID)) 488 err = OCSD_ERR_INVALID_ID; 489 else 490 { 491 destroyDecodeElement(localID); 492 } 493 return err; 494} 495 496ocsd_err_t DecodeTree::getDecoderStats(const uint8_t CSID, ocsd_decode_stats_t **p_stats_block) 497{ 498 ocsd_err_t err = OCSD_OK; 499 TrcPktProcI *pPktProc = getPktProcI(CSID); 500 if (!pPktProc) 501 return OCSD_ERR_INVALID_PARAM_VAL; 502 err = pPktProc->getStatsBlock(p_stats_block); 503 if (err == OCSD_OK) { 504 // copy in the global demux stats. 505 (*p_stats_block)->demux.frame_bytes = m_demux_stats.frame_bytes; 506 (*p_stats_block)->demux.no_id_bytes = m_demux_stats.no_id_bytes; 507 (*p_stats_block)->demux.valid_id_bytes = m_demux_stats.valid_id_bytes; 508 (*p_stats_block)->demux.unknown_id_bytes = m_demux_stats.unknown_id_bytes; 509 (*p_stats_block)->demux.reserved_id_bytes = m_demux_stats.reserved_id_bytes; 510 } 511 return err; 512} 513 514ocsd_err_t DecodeTree::resetDecoderStats(const uint8_t CSID) 515{ 516 TrcPktProcI *pPktProc = getPktProcI(CSID); 517 if (!pPktProc) 518 return OCSD_ERR_INVALID_PARAM_VAL; 519 pPktProc->resetStats(); 520 521 // reset the global demux stats. 522 m_demux_stats.frame_bytes = 0; 523 m_demux_stats.no_id_bytes = 0; 524 m_demux_stats.valid_id_bytes = 0; 525 m_demux_stats.unknown_id_bytes = 0; 526 m_demux_stats.reserved_id_bytes = 0; 527 return OCSD_OK; 528} 529 530TrcPktProcI *DecodeTree::getPktProcI(const uint8_t CSID) 531{ 532 TrcPktProcI *pPktProc = 0; 533 TraceComponent *pComp, *pAssoc; 534 DecodeTreeElement *pElem = getDecoderElement(CSID); 535 536 if (pElem) 537 { 538 pComp = pElem->getDecoderHandle(); 539 if (pComp) 540 { 541 /* if this is a full decoder then the associated component is the packet processor */ 542 pAssoc = pComp->getAssocComponent(); 543 if (pAssoc) 544 pPktProc = dynamic_cast<TrcPktProcI *>(pAssoc); 545 else 546 pPktProc = dynamic_cast<TrcPktProcI *>(pComp); 547 } 548 } 549 return pPktProc; 550} 551 552DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const 553{ 554 DecodeTreeElement *ret_elem = 0; 555 if(usingFormatter() && OCSD_IS_VALID_CS_SRC_ID(CSID)) 556 { 557 ret_elem = m_decode_elements[CSID]; 558 } 559 else 560 ret_elem = m_decode_elements[0]; // ID 0 is used if single leaf tree. 561 return ret_elem; 562} 563 564DecodeTreeElement *DecodeTree::getFirstElement(uint8_t &elemID) 565{ 566 m_decode_elem_iter = 0; 567 return getNextElement(elemID); 568} 569 570DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID) 571{ 572 DecodeTreeElement *ret_elem = 0; 573 574 if(m_decode_elem_iter < 0x80) 575 { 576 // find a none zero entry or end of range 577 while((m_decode_elem_iter < 0x80) && (m_decode_elements[m_decode_elem_iter] == 0)) 578 m_decode_elem_iter++; 579 580 // return entry unless end of range 581 if(m_decode_elem_iter < 0x80) 582 { 583 ret_elem = m_decode_elements[m_decode_elem_iter]; 584 elemID = m_decode_elem_iter; 585 m_decode_elem_iter++; 586 } 587 } 588 return ret_elem; 589} 590 591bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags) 592{ 593 ocsd_err_t err; 594 m_dcd_tree_type = type; 595 if(type == OCSD_TRC_SRC_FRAME_FORMATTED) 596 { 597 // frame formatted - we want to create the deformatter and hook it up 598 m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder(); 599 if(m_frame_deformatter_root) 600 { 601 if (m_frame_deformatter_root->Init() != OCSD_OK) 602 return false; 603 m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger); 604 err = m_frame_deformatter_root->Configure(formatterCfgFlags); 605 if (err != OCSD_OK) 606 return false; 607 m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root); 608 m_frame_deformatter_root->SetDemuxStatsBlock(&m_demux_stats); 609 } 610 else 611 return false; 612 } 613 return true; 614} 615 616void DecodeTree::setSingleRoot(TrcPktProcI *pComp) 617{ 618 m_i_decoder_root = static_cast<ITrcDataIn*>(pComp); 619} 620 621ocsd_err_t DecodeTree::createDecodeElement(const uint8_t CSID) 622{ 623 ocsd_err_t err = OCSD_ERR_INVALID_ID; 624 if(CSID < 0x80) 625 { 626 if(m_decode_elements[CSID] == 0) 627 { 628 m_decode_elements[CSID] = new (std::nothrow) DecodeTreeElement(); 629 if(m_decode_elements[CSID] == 0) 630 err = OCSD_ERR_MEM; 631 else 632 err = OCSD_OK; 633 } 634 else 635 err = OCSD_ERR_ATTACH_TOO_MANY; 636 } 637 return err; 638} 639 640void DecodeTree::destroyDecodeElement(const uint8_t CSID) 641{ 642 if(CSID < 0x80) 643 { 644 if(m_decode_elements[CSID] != 0) 645 { 646 m_decode_elements[CSID]->DestroyElem(); 647 delete m_decode_elements[CSID]; 648 m_decode_elements[CSID] = 0; 649 } 650 } 651} 652 653ocsd_err_t DecodeTree::setIDFilter(std::vector<uint8_t> &ids) 654{ 655 ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 656 if(usingFormatter()) 657 { 658 err = m_frame_deformatter_root->OutputFilterAllIDs(false); 659 if(err == OCSD_OK) 660 err = m_frame_deformatter_root->OutputFilterIDs(ids,true); 661 } 662 return err; 663} 664 665ocsd_err_t DecodeTree::clearIDFilter() 666{ 667 ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 668 if(usingFormatter()) 669 { 670 err = m_frame_deformatter_root->OutputFilterAllIDs(true); 671 } 672 return err; 673} 674 675/** add a protocol packet printer */ 676ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter) 677{ 678 ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL; 679 DecodeTreeElement *pElement = getDecoderElement(CSID); 680 if (pElement) 681 { 682 ocsd_trace_protocol_t protocol = pElement->getProtocol(); 683 ItemPrinter *pPrinter; 684 685 pPrinter = PktPrinterFact::createProtocolPrinter(getPrinterList(), protocol, CSID); 686 if (pPrinter) 687 { 688 pPrinter->setMessageLogger(getCurrentErrorLogI()->getOutputLogger()); 689 switch (protocol) 690 { 691 case OCSD_PROTOCOL_ETMV4I: 692 case OCSD_PROTOCOL_ETE: 693 { 694 PacketPrinter<EtmV4ITrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV4ITrcPacket> *>(pPrinter); 695 if (bMonitor) 696 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV4ITrcPacket> *)pTPrinter); 697 else 698 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV4ITrcPacket> *)pTPrinter); 699 } 700 break; 701 702 case OCSD_PROTOCOL_ETMV3: 703 { 704 PacketPrinter<EtmV3TrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV3TrcPacket> *>(pPrinter); 705 if (bMonitor) 706 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV3TrcPacket> *)pTPrinter); 707 else 708 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV3TrcPacket> *)pTPrinter); 709 } 710 break; 711 712 case OCSD_PROTOCOL_PTM: 713 { 714 PacketPrinter<PtmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<PtmTrcPacket> *>(pPrinter); 715 if (bMonitor) 716 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<PtmTrcPacket> *)pTPrinter); 717 else 718 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<PtmTrcPacket> *)pTPrinter); 719 } 720 break; 721 722 case OCSD_PROTOCOL_STM: 723 { 724 PacketPrinter<StmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<StmTrcPacket> *>(pPrinter); 725 if (bMonitor) 726 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<StmTrcPacket> *)pTPrinter); 727 else 728 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<StmTrcPacket> *)pTPrinter); 729 } 730 break; 731 732 default: 733 err = OCSD_ERR_NO_PROTOCOL; 734 break; 735 } 736 737 if (err == OCSD_OK) 738 { 739 if (ppPrinter) 740 *ppPrinter = pPrinter; 741 } 742 else 743 PktPrinterFact::destroyPrinter(getPrinterList(), pPrinter); 744 } 745 } 746 return err; 747} 748 749/** add a raw frame printer */ 750ocsd_err_t DecodeTree::addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags) 751{ 752 ocsd_err_t err = OCSD_ERR_MEM; 753 RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(getPrinterList()); 754 if (pPrinter) 755 { 756 pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 757 TraceFormatterFrameDecoder *pFrameDecoder = getFrameDeformatter(); 758 uint32_t cfgFlags = pFrameDecoder->getConfigFlags(); 759 cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT)); 760 pFrameDecoder->Configure(cfgFlags); 761 err = pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter); 762 if (ppPrinter && (err==OCSD_OK)) 763 *ppPrinter = pPrinter; 764 } 765 return err; 766} 767 768/** add a generic element output printer */ 769ocsd_err_t DecodeTree::addGenElemPrinter(TrcGenericElementPrinter **ppPrinter) 770{ 771 ocsd_err_t err = OCSD_ERR_MEM; 772 TrcGenericElementPrinter *pPrinter = PktPrinterFact::createGenElemPrinter(getPrinterList()); 773 if (pPrinter) 774 { 775 pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 776 setGenTraceElemOutI(pPrinter); 777 err = OCSD_OK; 778 if (ppPrinter) 779 *ppPrinter = pPrinter; 780 } 781 return err; 782 783} 784 785/* End of File ocsd_dcd_tree.cpp */ 786