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