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