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