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