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