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