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