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 /***************************************************************/ 41 ITraceErrorLog *DecodeTree::s_i_error_logger = &DecodeTree::s_error_logger; 42 std::list<DecodeTree *> DecodeTree::s_trace_dcd_trees; /**< list of pointers to decode tree objects */ 43 ocsdDefaultErrorLogger DecodeTree::s_error_logger; /**< The library default error logger */ 44 TrcIDecode DecodeTree::s_instruction_decoder; /**< default instruction decode library */ 45 46 DecodeTree *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 64 void 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 82 void 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 92 DecodeTree::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 106 DecodeTree::~DecodeTree() 107 { 108 destroyMemAccMapper(); 109 for(uint8_t i = 0; i < 0x80; i++) 110 { 111 destroyDecodeElement(i); 112 } 113 PktPrinterFact::destroyAllPrinters(m_printer_list); 114 delete m_frame_deformatter_root; 115 } 116 117 118 119 ocsd_datapath_resp_t DecodeTree::TraceDataIn( const ocsd_datapath_op_t op, 120 const ocsd_trc_index_t index, 121 const uint32_t dataBlockSize, 122 const uint8_t *pDataBlock, 123 uint32_t *numBytesProcessed) 124 { 125 if(m_i_decoder_root) 126 return m_i_decoder_root->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed); 127 *numBytesProcessed = 0; 128 return OCSD_RESP_FATAL_NOT_INIT; 129 } 130 131 /* set key interfaces - attach / replace on any existing tree components */ 132 void DecodeTree::setInstrDecoder(IInstrDecode *i_instr_decode) 133 { 134 uint8_t elemID; 135 DecodeTreeElement *pElem = 0; 136 137 pElem = getFirstElement(elemID); 138 while(pElem != 0) 139 { 140 pElem->getDecoderMngr()->attachInstrDecoder(pElem->getDecoderHandle(),i_instr_decode); 141 pElem = getNextElement(elemID); 142 } 143 } 144 145 void DecodeTree::setMemAccessI(ITargetMemAccess *i_mem_access) 146 { 147 uint8_t elemID; 148 DecodeTreeElement *pElem = 0; 149 150 pElem = getFirstElement(elemID); 151 while(pElem != 0) 152 { 153 pElem->getDecoderMngr()->attachMemAccessor(pElem->getDecoderHandle(),i_mem_access); 154 pElem = getNextElement(elemID); 155 } 156 m_i_mem_access = i_mem_access; 157 } 158 159 void DecodeTree::setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem) 160 { 161 uint8_t elemID; 162 DecodeTreeElement *pElem = 0; 163 164 pElem = getFirstElement(elemID); 165 while(pElem != 0) 166 { 167 pElem->getDecoderMngr()->attachOutputSink(pElem->getDecoderHandle(),i_gen_trace_elem); 168 pElem = getNextElement(elemID); 169 } 170 } 171 172 ocsd_err_t DecodeTree::createMemAccMapper(memacc_mapper_t type /* = MEMACC_MAP_GLOBAL*/ ) 173 { 174 // clean up any old one 175 destroyMemAccMapper(); 176 177 // make a new one 178 switch(type) 179 { 180 default: 181 case MEMACC_MAP_GLOBAL: 182 m_default_mapper = new (std::nothrow) TrcMemAccMapGlobalSpace(); 183 break; 184 } 185 186 // set the access interface 187 if(m_default_mapper) 188 { 189 m_created_mapper = true; 190 setMemAccessI(m_default_mapper); 191 m_default_mapper->setErrorLog(s_i_error_logger); 192 } 193 194 return (m_default_mapper != 0) ? OCSD_OK : OCSD_ERR_MEM; 195 } 196 197 void DecodeTree::setExternMemAccMapper(TrcMemAccMapper* pMapper) 198 { 199 destroyMemAccMapper(); // destroy any existing mapper - if decode tree created it. 200 m_default_mapper = pMapper; 201 } 202 203 void DecodeTree::destroyMemAccMapper() 204 { 205 if(m_default_mapper && m_created_mapper) 206 { 207 m_default_mapper->RemoveAllAccessors(); 208 delete m_default_mapper; 209 m_default_mapper = 0; 210 m_created_mapper = false; 211 } 212 } 213 214 void DecodeTree::logMappedRanges() 215 { 216 if(m_default_mapper) 217 m_default_mapper->logMappedRanges(); 218 } 219 220 /* Memory accessor creation - all on default mem accessor using the 0 CSID for global core space. */ 221 ocsd_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) 222 { 223 if(!hasMemAccMapper()) 224 return OCSD_ERR_NOT_INIT; 225 226 // need a valid memory buffer, and a least enough bytes for one opcode. 227 if((p_mem_buffer == 0) || (mem_length < 4)) 228 return OCSD_ERR_INVALID_PARAM_VAL; 229 230 TrcMemAccessorBase *p_accessor; 231 ocsd_err_t err = TrcMemAccFactory::CreateBufferAccessor(&p_accessor, address, p_mem_buffer, mem_length); 232 if(err == OCSD_OK) 233 { 234 TrcMemAccBufPtr *pMBuffAcc = dynamic_cast<TrcMemAccBufPtr *>(p_accessor); 235 if(pMBuffAcc) 236 { 237 pMBuffAcc->setMemSpace(mem_space); 238 err = m_default_mapper->AddAccessor(p_accessor,0); 239 } 240 else 241 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 242 243 if(err != OCSD_OK) 244 TrcMemAccFactory::DestroyAccessor(p_accessor); 245 } 246 return err; 247 } 248 249 ocsd_err_t DecodeTree::addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath) 250 { 251 if(!hasMemAccMapper()) 252 return OCSD_ERR_NOT_INIT; 253 254 if(filepath.length() == 0) 255 return OCSD_ERR_INVALID_PARAM_VAL; 256 257 TrcMemAccessorBase *p_accessor; 258 ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,address); 259 260 if(err == OCSD_OK) 261 { 262 TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 263 if(pAcc) 264 { 265 pAcc->setMemSpace(mem_space); 266 err = m_default_mapper->AddAccessor(pAcc,0); 267 } 268 else 269 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 270 271 if(err != OCSD_OK) 272 TrcMemAccFactory::DestroyAccessor(p_accessor); 273 } 274 return err; 275 276 } 277 278 ocsd_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) 279 { 280 if(!hasMemAccMapper()) 281 return OCSD_ERR_NOT_INIT; 282 283 if((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 284 return OCSD_ERR_INVALID_PARAM_VAL; 285 286 TrcMemAccessorBase *p_accessor; 287 int curr_region_idx = 0; 288 289 // add first region during the creation of the file accessor. 290 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); 291 if(err == OCSD_OK) 292 { 293 TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor); 294 if(pAcc) 295 { 296 // add additional regions to the file accessor. 297 curr_region_idx++; 298 while(curr_region_idx < num_regions) 299 { 300 pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 301 region_array[curr_region_idx].region_size, 302 region_array[curr_region_idx].file_offset); 303 curr_region_idx++; 304 } 305 pAcc->setMemSpace(mem_space); 306 307 // add the accessor to the map. 308 err = m_default_mapper->AddAccessor(pAcc,0); 309 } 310 else 311 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 312 313 if(err != OCSD_OK) 314 TrcMemAccFactory::DestroyAccessor(p_accessor); 315 } 316 return err; 317 } 318 319 ocsd_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) 320 { 321 if (!hasMemAccMapper()) 322 return OCSD_ERR_NOT_INIT; 323 324 if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) 325 return OCSD_ERR_INVALID_PARAM_VAL; 326 327 TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath); 328 if (!pAcc) 329 return OCSD_ERR_INVALID_PARAM_VAL; 330 331 int curr_region_idx = 0; 332 while (curr_region_idx < num_regions) 333 { 334 // check "new" range 335 if (!pAcc->addrStartOfRange(region_array[curr_region_idx].start_address)) 336 { 337 // ensure adds cleanly 338 if (!pAcc->AddOffsetRange(region_array[curr_region_idx].start_address, 339 region_array[curr_region_idx].region_size, 340 region_array[curr_region_idx].file_offset)) 341 return OCSD_ERR_INVALID_PARAM_VAL; // otherwise bail out 342 } 343 curr_region_idx++; 344 } 345 return OCSD_OK; 346 } 347 ocsd_err_t DecodeTree::initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, 348 const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context) 349 { 350 if(!hasMemAccMapper()) 351 return OCSD_ERR_NOT_INIT; 352 353 if(p_cb_func == 0) 354 return OCSD_ERR_INVALID_PARAM_VAL; 355 356 TrcMemAccessorBase *p_accessor; 357 ocsd_err_t err = TrcMemAccFactory::CreateCBAccessor(&p_accessor, st_address, en_address, mem_space); 358 if(err == OCSD_OK) 359 { 360 TrcMemAccCB *pCBAcc = dynamic_cast<TrcMemAccCB *>(p_accessor); 361 if(pCBAcc) 362 { 363 if (IDfn) 364 pCBAcc->setCBIDIfFn((Fn_MemAccID_CB)p_cb_func, p_context); 365 else 366 pCBAcc->setCBIfFn((Fn_MemAcc_CB)p_cb_func, p_context); 367 368 err = m_default_mapper->AddAccessor(p_accessor,0); 369 } 370 else 371 err = OCSD_ERR_MEM; // wrong type of object - treat as mem error 372 373 if(err != OCSD_OK) 374 TrcMemAccFactory::DestroyAccessor(p_accessor); 375 } 376 return err; 377 } 378 379 ocsd_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) 380 { 381 return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, false, p_context); 382 } 383 384 ocsd_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) 385 { 386 return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, true, p_context); 387 } 388 389 ocsd_err_t DecodeTree::removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space) 390 { 391 if(!hasMemAccMapper()) 392 return OCSD_ERR_NOT_INIT; 393 return m_default_mapper->RemoveAccessorByAddress(address,mem_space,0); 394 } 395 396 ocsd_err_t DecodeTree::createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig) 397 { 398 ocsd_err_t err = OCSD_OK; 399 IDecoderMngr *pDecoderMngr = 0; 400 TraceComponent *pTraceComp = 0; 401 int crtFlags = createFlags; 402 403 uint8_t CSID = 0; // default for single stream decoder (no deformatter) - we ignore the ID 404 if(usingFormatter()) 405 { 406 CSID = pConfig->getTraceID(); 407 crtFlags |= OCSD_CREATE_FLG_INST_ID; 408 } 409 410 // create the decode element to attach to the channel. 411 if((err = createDecodeElement(CSID)) != OCSD_OK) 412 return err; 413 414 // get the libary decoder register. 415 OcsdLibDcdRegister * lib_reg = OcsdLibDcdRegister::getDecoderRegister(); 416 if(lib_reg == 0) 417 return OCSD_ERR_NOT_INIT; 418 419 // find the named decoder 420 if((err = lib_reg->getDecoderMngrByName(decoderName,&pDecoderMngr)) != OCSD_OK) 421 return err; 422 423 // got the decoder... 424 if((err = pDecoderMngr->createDecoder(crtFlags,(int)CSID,pConfig,&pTraceComp)) != OCSD_OK) 425 return err; 426 427 m_decode_elements[CSID]->SetDecoderElement(decoderName, pDecoderMngr, pTraceComp, true); 428 429 // always attach an error logger 430 if(err == OCSD_OK) 431 err = pDecoderMngr->attachErrorLogger(pTraceComp,DecodeTree::s_i_error_logger); 432 433 // if we created a packet decoder it may need additional components. 434 if(crtFlags & OCSD_CREATE_FLG_FULL_DECODER) 435 { 436 if(m_i_instr_decode && (err == OCSD_OK)) 437 err = pDecoderMngr->attachInstrDecoder(pTraceComp,m_i_instr_decode); 438 439 if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if instruction decoder refused 440 err = OCSD_OK; 441 442 if(m_i_mem_access && (err == OCSD_OK)) 443 err = pDecoderMngr->attachMemAccessor(pTraceComp,m_i_mem_access); 444 445 if(err == OCSD_ERR_DCD_INTERFACE_UNUSED) // ignore if mem accessor refused 446 err = OCSD_OK; 447 448 if( m_i_gen_elem_out && (err == OCSD_OK)) 449 err = pDecoderMngr->attachOutputSink(pTraceComp,m_i_gen_elem_out); 450 } 451 452 // finally attach the packet processor input to the demux output channel 453 if(err == OCSD_OK) 454 { 455 ITrcDataIn *pDataIn = 0; 456 if((err = pDecoderMngr->getDataInputI(pTraceComp,&pDataIn)) == OCSD_OK) 457 { 458 // got the interface -> attach to demux, or direct to input of decode tree 459 if(usingFormatter()) 460 err = m_frame_deformatter_root->getIDStreamAttachPt(CSID)->attach(pDataIn); 461 else 462 m_i_decoder_root = pDataIn; 463 } 464 } 465 466 if(err != OCSD_OK) 467 { 468 destroyDecodeElement(CSID); // will destroy decoder as well. 469 } 470 return err; 471 } 472 473 ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID) 474 { 475 ocsd_err_t err = OCSD_OK; 476 uint8_t localID = CSID; 477 if(!usingFormatter()) 478 localID = 0; 479 480 if(usingFormatter() && !OCSD_IS_VALID_CS_SRC_ID(CSID)) 481 err = OCSD_ERR_INVALID_ID; 482 else 483 { 484 destroyDecodeElement(localID); 485 } 486 return err; 487 } 488 489 DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const 490 { 491 DecodeTreeElement *ret_elem = 0; 492 if(usingFormatter() && OCSD_IS_VALID_CS_SRC_ID(CSID)) 493 { 494 ret_elem = m_decode_elements[CSID]; 495 } 496 else 497 ret_elem = m_decode_elements[0]; // ID 0 is used if single leaf tree. 498 return ret_elem; 499 } 500 501 DecodeTreeElement *DecodeTree::getFirstElement(uint8_t &elemID) 502 { 503 m_decode_elem_iter = 0; 504 return getNextElement(elemID); 505 } 506 507 DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID) 508 { 509 DecodeTreeElement *ret_elem = 0; 510 511 if(m_decode_elem_iter < 0x80) 512 { 513 // find a none zero entry or end of range 514 while((m_decode_elements[m_decode_elem_iter] == 0) && (m_decode_elem_iter < 0x80)) 515 m_decode_elem_iter++; 516 517 // return entry unless end of range 518 if(m_decode_elem_iter < 0x80) 519 { 520 ret_elem = m_decode_elements[m_decode_elem_iter]; 521 elemID = m_decode_elem_iter; 522 m_decode_elem_iter++; 523 } 524 } 525 return ret_elem; 526 } 527 528 bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags) 529 { 530 bool initOK = true; 531 m_dcd_tree_type = type; 532 if(type == OCSD_TRC_SRC_FRAME_FORMATTED) 533 { 534 // frame formatted - we want to create the deformatter and hook it up 535 m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder(); 536 if(m_frame_deformatter_root) 537 { 538 m_frame_deformatter_root->Configure(formatterCfgFlags); 539 m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger); 540 m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root); 541 } 542 else 543 initOK = false; 544 } 545 return initOK; 546 } 547 548 void DecodeTree::setSingleRoot(TrcPktProcI *pComp) 549 { 550 m_i_decoder_root = static_cast<ITrcDataIn*>(pComp); 551 } 552 553 ocsd_err_t DecodeTree::createDecodeElement(const uint8_t CSID) 554 { 555 ocsd_err_t err = OCSD_ERR_INVALID_ID; 556 if(CSID < 0x80) 557 { 558 if(m_decode_elements[CSID] == 0) 559 { 560 m_decode_elements[CSID] = new (std::nothrow) DecodeTreeElement(); 561 if(m_decode_elements[CSID] == 0) 562 err = OCSD_ERR_MEM; 563 else 564 err = OCSD_OK; 565 } 566 else 567 err = OCSD_ERR_ATTACH_TOO_MANY; 568 } 569 return err; 570 } 571 572 void DecodeTree::destroyDecodeElement(const uint8_t CSID) 573 { 574 if(CSID < 0x80) 575 { 576 if(m_decode_elements[CSID] != 0) 577 { 578 m_decode_elements[CSID]->DestroyElem(); 579 delete m_decode_elements[CSID]; 580 m_decode_elements[CSID] = 0; 581 } 582 } 583 } 584 585 ocsd_err_t DecodeTree::setIDFilter(std::vector<uint8_t> &ids) 586 { 587 ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 588 if(usingFormatter()) 589 { 590 err = m_frame_deformatter_root->OutputFilterAllIDs(false); 591 if(err == OCSD_OK) 592 err = m_frame_deformatter_root->OutputFilterIDs(ids,true); 593 } 594 return err; 595 } 596 597 ocsd_err_t DecodeTree::clearIDFilter() 598 { 599 ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER; 600 if(usingFormatter()) 601 { 602 err = m_frame_deformatter_root->OutputFilterAllIDs(true); 603 } 604 return err; 605 } 606 607 /** add a protocol packet printer */ 608 ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter) 609 { 610 ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL; 611 DecodeTreeElement *pElement = getDecoderElement(CSID); 612 if (pElement) 613 { 614 ocsd_trace_protocol_t protocol = pElement->getProtocol(); 615 ItemPrinter *pPrinter; 616 617 pPrinter = PktPrinterFact::createProtocolPrinter(getPrinterList(), protocol, CSID); 618 if (pPrinter) 619 { 620 pPrinter->setMessageLogger(getCurrentErrorLogI()->getOutputLogger()); 621 switch (protocol) 622 { 623 case OCSD_PROTOCOL_ETMV4I: 624 { 625 PacketPrinter<EtmV4ITrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV4ITrcPacket> *>(pPrinter); 626 if (bMonitor) 627 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV4ITrcPacket> *)pTPrinter); 628 else 629 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV4ITrcPacket> *)pTPrinter); 630 } 631 break; 632 633 case OCSD_PROTOCOL_ETMV3: 634 { 635 PacketPrinter<EtmV3TrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV3TrcPacket> *>(pPrinter); 636 if (bMonitor) 637 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV3TrcPacket> *)pTPrinter); 638 else 639 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV3TrcPacket> *)pTPrinter); 640 } 641 break; 642 643 case OCSD_PROTOCOL_PTM: 644 { 645 PacketPrinter<PtmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<PtmTrcPacket> *>(pPrinter); 646 if (bMonitor) 647 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<PtmTrcPacket> *)pTPrinter); 648 else 649 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<PtmTrcPacket> *)pTPrinter); 650 } 651 break; 652 653 case OCSD_PROTOCOL_STM: 654 { 655 PacketPrinter<StmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<StmTrcPacket> *>(pPrinter); 656 if (bMonitor) 657 err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<StmTrcPacket> *)pTPrinter); 658 else 659 err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<StmTrcPacket> *)pTPrinter); 660 } 661 break; 662 663 default: 664 err = OCSD_ERR_NO_PROTOCOL; 665 break; 666 } 667 668 if (err == OCSD_OK) 669 { 670 if (ppPrinter) 671 *ppPrinter = pPrinter; 672 } 673 else 674 PktPrinterFact::destroyPrinter(getPrinterList(), pPrinter); 675 } 676 } 677 return err; 678 } 679 680 /** add a raw frame printer */ 681 ocsd_err_t DecodeTree::addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags) 682 { 683 ocsd_err_t err = OCSD_ERR_MEM; 684 RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(getPrinterList()); 685 if (pPrinter) 686 { 687 pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 688 TraceFormatterFrameDecoder *pFrameDecoder = getFrameDeformatter(); 689 uint32_t cfgFlags = pFrameDecoder->getConfigFlags(); 690 cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT)); 691 pFrameDecoder->Configure(cfgFlags); 692 err = pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter); 693 if (ppPrinter && (err==OCSD_OK)) 694 *ppPrinter = pPrinter; 695 } 696 return err; 697 } 698 699 /** add a generic element output printer */ 700 ocsd_err_t DecodeTree::addGenElemPrinter(TrcGenericElementPrinter **ppPrinter) 701 { 702 ocsd_err_t err = OCSD_ERR_MEM; 703 TrcGenericElementPrinter *pPrinter = PktPrinterFact::createGenElemPrinter(getPrinterList()); 704 if (pPrinter) 705 { 706 pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger())); 707 setGenTraceElemOutI(pPrinter); 708 err = OCSD_OK; 709 if (ppPrinter) 710 *ppPrinter = pPrinter; 711 } 712 return err; 713 714 } 715 716 /* End of File ocsd_dcd_tree.cpp */ 717