]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - decoder/source/ocsd_dcd_tree.cpp
Import OpenCSD v0.14.2
[FreeBSD/FreeBSD.git] / decoder / source / ocsd_dcd_tree.cpp
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 */