xref: /freebsd-src/contrib/opencsd/decoder/source/ocsd_dcd_tree.cpp (revision c120c5646da1a1d2c4d90fd069a7e2a8d559eb46)
1*c120c564SAndrew Turner /*
2*c120c564SAndrew Turner  * \file       ocsd_dcd_tree.cpp
3*c120c564SAndrew Turner  * \brief      OpenCSD :
4*c120c564SAndrew Turner  *
5*c120c564SAndrew Turner  * \copyright  Copyright (c) 2015, ARM Limited. All Rights Reserved.
6*c120c564SAndrew Turner  */
7*c120c564SAndrew Turner 
8*c120c564SAndrew Turner 
9*c120c564SAndrew Turner /*
10*c120c564SAndrew Turner  * Redistribution and use in source and binary forms, with or without modification,
11*c120c564SAndrew Turner  * are permitted provided that the following conditions are met:
12*c120c564SAndrew Turner  *
13*c120c564SAndrew Turner  * 1. Redistributions of source code must retain the above copyright notice,
14*c120c564SAndrew Turner  * this list of conditions and the following disclaimer.
15*c120c564SAndrew Turner  *
16*c120c564SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright notice,
17*c120c564SAndrew Turner  * this list of conditions and the following disclaimer in the documentation
18*c120c564SAndrew Turner  * and/or other materials provided with the distribution.
19*c120c564SAndrew Turner  *
20*c120c564SAndrew Turner  * 3. Neither the name of the copyright holder nor the names of its contributors
21*c120c564SAndrew Turner  * may be used to endorse or promote products derived from this software without
22*c120c564SAndrew Turner  * specific prior written permission.
23*c120c564SAndrew Turner  *
24*c120c564SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
25*c120c564SAndrew Turner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26*c120c564SAndrew Turner  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27*c120c564SAndrew Turner  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28*c120c564SAndrew Turner  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*c120c564SAndrew Turner  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*c120c564SAndrew Turner  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31*c120c564SAndrew Turner  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*c120c564SAndrew Turner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*c120c564SAndrew Turner  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*c120c564SAndrew Turner  */
35*c120c564SAndrew Turner 
36*c120c564SAndrew Turner #include "common/ocsd_dcd_tree.h"
37*c120c564SAndrew Turner #include "common/ocsd_lib_dcd_register.h"
38*c120c564SAndrew Turner #include "mem_acc/trc_mem_acc_mapper.h"
39*c120c564SAndrew Turner 
40*c120c564SAndrew Turner /***************************************************************/
41*c120c564SAndrew Turner ITraceErrorLog *DecodeTree::s_i_error_logger = &DecodeTree::s_error_logger;
42*c120c564SAndrew Turner std::list<DecodeTree *> DecodeTree::s_trace_dcd_trees;  /**< list of pointers to decode tree objects */
43*c120c564SAndrew Turner ocsdDefaultErrorLogger DecodeTree::s_error_logger;     /**< The library default error logger */
44*c120c564SAndrew Turner TrcIDecode DecodeTree::s_instruction_decoder;           /**< default instruction decode library */
45*c120c564SAndrew Turner 
46*c120c564SAndrew Turner DecodeTree *DecodeTree::CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, uint32_t formatterCfgFlags)
47*c120c564SAndrew Turner {
48*c120c564SAndrew Turner     DecodeTree *dcd_tree = new (std::nothrow) DecodeTree();
49*c120c564SAndrew Turner     if(dcd_tree != 0)
50*c120c564SAndrew Turner     {
51*c120c564SAndrew Turner         if(dcd_tree->initialise(src_type, formatterCfgFlags))
52*c120c564SAndrew Turner         {
53*c120c564SAndrew Turner             s_trace_dcd_trees.push_back(dcd_tree);
54*c120c564SAndrew Turner         }
55*c120c564SAndrew Turner         else
56*c120c564SAndrew Turner         {
57*c120c564SAndrew Turner             delete dcd_tree;
58*c120c564SAndrew Turner             dcd_tree = 0;
59*c120c564SAndrew Turner         }
60*c120c564SAndrew Turner     }
61*c120c564SAndrew Turner     return dcd_tree;
62*c120c564SAndrew Turner }
63*c120c564SAndrew Turner 
64*c120c564SAndrew Turner void DecodeTree::DestroyDecodeTree(DecodeTree *p_dcd_tree)
65*c120c564SAndrew Turner {
66*c120c564SAndrew Turner     std::list<DecodeTree *>::iterator it;
67*c120c564SAndrew Turner     bool bDestroyed = false;
68*c120c564SAndrew Turner     it = s_trace_dcd_trees.begin();
69*c120c564SAndrew Turner     while(!bDestroyed && (it != s_trace_dcd_trees.end()))
70*c120c564SAndrew Turner     {
71*c120c564SAndrew Turner         if(*it == p_dcd_tree)
72*c120c564SAndrew Turner         {
73*c120c564SAndrew Turner             s_trace_dcd_trees.erase(it);
74*c120c564SAndrew Turner             delete p_dcd_tree;
75*c120c564SAndrew Turner             bDestroyed = true;
76*c120c564SAndrew Turner         }
77*c120c564SAndrew Turner         else
78*c120c564SAndrew Turner             it++;
79*c120c564SAndrew Turner     }
80*c120c564SAndrew Turner }
81*c120c564SAndrew Turner 
82*c120c564SAndrew Turner void DecodeTree::setAlternateErrorLogger(ITraceErrorLog *p_error_logger)
83*c120c564SAndrew Turner {
84*c120c564SAndrew Turner     if(p_error_logger)
85*c120c564SAndrew Turner         s_i_error_logger = p_error_logger;
86*c120c564SAndrew Turner     else
87*c120c564SAndrew Turner         s_i_error_logger = &s_error_logger;
88*c120c564SAndrew Turner }
89*c120c564SAndrew Turner 
90*c120c564SAndrew Turner /***************************************************************/
91*c120c564SAndrew Turner 
92*c120c564SAndrew Turner DecodeTree::DecodeTree() :
93*c120c564SAndrew Turner     m_i_instr_decode(&s_instruction_decoder),
94*c120c564SAndrew Turner     m_i_mem_access(0),
95*c120c564SAndrew Turner     m_i_gen_elem_out(0),
96*c120c564SAndrew Turner     m_i_decoder_root(0),
97*c120c564SAndrew Turner     m_frame_deformatter_root(0),
98*c120c564SAndrew Turner     m_decode_elem_iter(0),
99*c120c564SAndrew Turner     m_default_mapper(0),
100*c120c564SAndrew Turner     m_created_mapper(false)
101*c120c564SAndrew Turner {
102*c120c564SAndrew Turner     for(int i = 0; i < 0x80; i++)
103*c120c564SAndrew Turner         m_decode_elements[i] = 0;
104*c120c564SAndrew Turner }
105*c120c564SAndrew Turner 
106*c120c564SAndrew Turner DecodeTree::~DecodeTree()
107*c120c564SAndrew Turner {
108*c120c564SAndrew Turner     destroyMemAccMapper();
109*c120c564SAndrew Turner     for(uint8_t i = 0; i < 0x80; i++)
110*c120c564SAndrew Turner     {
111*c120c564SAndrew Turner         destroyDecodeElement(i);
112*c120c564SAndrew Turner     }
113*c120c564SAndrew Turner     PktPrinterFact::destroyAllPrinters(m_printer_list);
114*c120c564SAndrew Turner }
115*c120c564SAndrew Turner 
116*c120c564SAndrew Turner 
117*c120c564SAndrew Turner 
118*c120c564SAndrew Turner ocsd_datapath_resp_t DecodeTree::TraceDataIn( const ocsd_datapath_op_t op,
119*c120c564SAndrew Turner                                                const ocsd_trc_index_t index,
120*c120c564SAndrew Turner                                                const uint32_t dataBlockSize,
121*c120c564SAndrew Turner                                                const uint8_t *pDataBlock,
122*c120c564SAndrew Turner                                                uint32_t *numBytesProcessed)
123*c120c564SAndrew Turner {
124*c120c564SAndrew Turner     if(m_i_decoder_root)
125*c120c564SAndrew Turner         return m_i_decoder_root->TraceDataIn(op,index,dataBlockSize,pDataBlock,numBytesProcessed);
126*c120c564SAndrew Turner     *numBytesProcessed = 0;
127*c120c564SAndrew Turner     return OCSD_RESP_FATAL_NOT_INIT;
128*c120c564SAndrew Turner }
129*c120c564SAndrew Turner 
130*c120c564SAndrew Turner /* set key interfaces - attach / replace on any existing tree components */
131*c120c564SAndrew Turner void DecodeTree::setInstrDecoder(IInstrDecode *i_instr_decode)
132*c120c564SAndrew Turner {
133*c120c564SAndrew Turner     uint8_t elemID;
134*c120c564SAndrew Turner     DecodeTreeElement *pElem = 0;
135*c120c564SAndrew Turner 
136*c120c564SAndrew Turner     pElem = getFirstElement(elemID);
137*c120c564SAndrew Turner     while(pElem != 0)
138*c120c564SAndrew Turner     {
139*c120c564SAndrew Turner         pElem->getDecoderMngr()->attachInstrDecoder(pElem->getDecoderHandle(),i_instr_decode);
140*c120c564SAndrew Turner         pElem = getNextElement(elemID);
141*c120c564SAndrew Turner     }
142*c120c564SAndrew Turner }
143*c120c564SAndrew Turner 
144*c120c564SAndrew Turner void DecodeTree::setMemAccessI(ITargetMemAccess *i_mem_access)
145*c120c564SAndrew Turner {
146*c120c564SAndrew Turner     uint8_t elemID;
147*c120c564SAndrew Turner     DecodeTreeElement *pElem = 0;
148*c120c564SAndrew Turner 
149*c120c564SAndrew Turner     pElem = getFirstElement(elemID);
150*c120c564SAndrew Turner     while(pElem != 0)
151*c120c564SAndrew Turner     {
152*c120c564SAndrew Turner         pElem->getDecoderMngr()->attachMemAccessor(pElem->getDecoderHandle(),i_mem_access);
153*c120c564SAndrew Turner         pElem = getNextElement(elemID);
154*c120c564SAndrew Turner     }
155*c120c564SAndrew Turner     m_i_mem_access = i_mem_access;
156*c120c564SAndrew Turner }
157*c120c564SAndrew Turner 
158*c120c564SAndrew Turner void DecodeTree::setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem)
159*c120c564SAndrew Turner {
160*c120c564SAndrew Turner     uint8_t elemID;
161*c120c564SAndrew Turner     DecodeTreeElement *pElem = 0;
162*c120c564SAndrew Turner 
163*c120c564SAndrew Turner     pElem = getFirstElement(elemID);
164*c120c564SAndrew Turner     while(pElem != 0)
165*c120c564SAndrew Turner     {
166*c120c564SAndrew Turner         pElem->getDecoderMngr()->attachOutputSink(pElem->getDecoderHandle(),i_gen_trace_elem);
167*c120c564SAndrew Turner         pElem = getNextElement(elemID);
168*c120c564SAndrew Turner     }
169*c120c564SAndrew Turner }
170*c120c564SAndrew Turner 
171*c120c564SAndrew Turner ocsd_err_t DecodeTree::createMemAccMapper(memacc_mapper_t type /* = MEMACC_MAP_GLOBAL*/ )
172*c120c564SAndrew Turner {
173*c120c564SAndrew Turner     // clean up any old one
174*c120c564SAndrew Turner     destroyMemAccMapper();
175*c120c564SAndrew Turner 
176*c120c564SAndrew Turner     // make a new one
177*c120c564SAndrew Turner     switch(type)
178*c120c564SAndrew Turner     {
179*c120c564SAndrew Turner     default:
180*c120c564SAndrew Turner     case MEMACC_MAP_GLOBAL:
181*c120c564SAndrew Turner         m_default_mapper = new (std::nothrow) TrcMemAccMapGlobalSpace();
182*c120c564SAndrew Turner         break;
183*c120c564SAndrew Turner     }
184*c120c564SAndrew Turner 
185*c120c564SAndrew Turner     // set the access interface
186*c120c564SAndrew Turner     if(m_default_mapper)
187*c120c564SAndrew Turner     {
188*c120c564SAndrew Turner         m_created_mapper = true;
189*c120c564SAndrew Turner         setMemAccessI(m_default_mapper);
190*c120c564SAndrew Turner         m_default_mapper->setErrorLog(s_i_error_logger);
191*c120c564SAndrew Turner     }
192*c120c564SAndrew Turner 
193*c120c564SAndrew Turner     return (m_default_mapper != 0) ? OCSD_OK : OCSD_ERR_MEM;
194*c120c564SAndrew Turner }
195*c120c564SAndrew Turner 
196*c120c564SAndrew Turner void DecodeTree::setExternMemAccMapper(TrcMemAccMapper* pMapper)
197*c120c564SAndrew Turner {
198*c120c564SAndrew Turner     destroyMemAccMapper();  // destroy any existing mapper - if decode tree created it.
199*c120c564SAndrew Turner     m_default_mapper = pMapper;
200*c120c564SAndrew Turner }
201*c120c564SAndrew Turner 
202*c120c564SAndrew Turner void DecodeTree::destroyMemAccMapper()
203*c120c564SAndrew Turner {
204*c120c564SAndrew Turner     if(m_default_mapper && m_created_mapper)
205*c120c564SAndrew Turner     {
206*c120c564SAndrew Turner         m_default_mapper->RemoveAllAccessors();
207*c120c564SAndrew Turner         delete m_default_mapper;
208*c120c564SAndrew Turner         m_default_mapper = 0;
209*c120c564SAndrew Turner         m_created_mapper = false;
210*c120c564SAndrew Turner     }
211*c120c564SAndrew Turner }
212*c120c564SAndrew Turner 
213*c120c564SAndrew Turner void DecodeTree::logMappedRanges()
214*c120c564SAndrew Turner {
215*c120c564SAndrew Turner     if(m_default_mapper)
216*c120c564SAndrew Turner         m_default_mapper->logMappedRanges();
217*c120c564SAndrew Turner }
218*c120c564SAndrew Turner 
219*c120c564SAndrew Turner /* Memory accessor creation - all on default mem accessor using the 0 CSID for global core space. */
220*c120c564SAndrew Turner 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)
221*c120c564SAndrew Turner {
222*c120c564SAndrew Turner     if(!hasMemAccMapper())
223*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
224*c120c564SAndrew Turner 
225*c120c564SAndrew Turner     // need a valid memory buffer, and a least enough bytes for one opcode.
226*c120c564SAndrew Turner     if((p_mem_buffer == 0) || (mem_length < 4))
227*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
228*c120c564SAndrew Turner 
229*c120c564SAndrew Turner     TrcMemAccessorBase *p_accessor;
230*c120c564SAndrew Turner     ocsd_err_t err = TrcMemAccFactory::CreateBufferAccessor(&p_accessor, address, p_mem_buffer, mem_length);
231*c120c564SAndrew Turner     if(err == OCSD_OK)
232*c120c564SAndrew Turner     {
233*c120c564SAndrew Turner         TrcMemAccBufPtr *pMBuffAcc = dynamic_cast<TrcMemAccBufPtr *>(p_accessor);
234*c120c564SAndrew Turner         if(pMBuffAcc)
235*c120c564SAndrew Turner         {
236*c120c564SAndrew Turner             pMBuffAcc->setMemSpace(mem_space);
237*c120c564SAndrew Turner             err = m_default_mapper->AddAccessor(p_accessor,0);
238*c120c564SAndrew Turner         }
239*c120c564SAndrew Turner         else
240*c120c564SAndrew Turner             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
241*c120c564SAndrew Turner 
242*c120c564SAndrew Turner         if(err != OCSD_OK)
243*c120c564SAndrew Turner             TrcMemAccFactory::DestroyAccessor(p_accessor);
244*c120c564SAndrew Turner     }
245*c120c564SAndrew Turner     return err;
246*c120c564SAndrew Turner }
247*c120c564SAndrew Turner 
248*c120c564SAndrew Turner ocsd_err_t DecodeTree::addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath)
249*c120c564SAndrew Turner {
250*c120c564SAndrew Turner     if(!hasMemAccMapper())
251*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
252*c120c564SAndrew Turner 
253*c120c564SAndrew Turner     if(filepath.length() == 0)
254*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
255*c120c564SAndrew Turner 
256*c120c564SAndrew Turner     TrcMemAccessorBase *p_accessor;
257*c120c564SAndrew Turner     ocsd_err_t err = TrcMemAccFactory::CreateFileAccessor(&p_accessor,filepath,address);
258*c120c564SAndrew Turner 
259*c120c564SAndrew Turner     if(err == OCSD_OK)
260*c120c564SAndrew Turner     {
261*c120c564SAndrew Turner         TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor);
262*c120c564SAndrew Turner         if(pAcc)
263*c120c564SAndrew Turner         {
264*c120c564SAndrew Turner             pAcc->setMemSpace(mem_space);
265*c120c564SAndrew Turner             err = m_default_mapper->AddAccessor(pAcc,0);
266*c120c564SAndrew Turner         }
267*c120c564SAndrew Turner         else
268*c120c564SAndrew Turner             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
269*c120c564SAndrew Turner 
270*c120c564SAndrew Turner         if(err != OCSD_OK)
271*c120c564SAndrew Turner             TrcMemAccFactory::DestroyAccessor(p_accessor);
272*c120c564SAndrew Turner     }
273*c120c564SAndrew Turner     return err;
274*c120c564SAndrew Turner 
275*c120c564SAndrew Turner }
276*c120c564SAndrew Turner 
277*c120c564SAndrew Turner 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)
278*c120c564SAndrew Turner {
279*c120c564SAndrew Turner     if(!hasMemAccMapper())
280*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
281*c120c564SAndrew Turner 
282*c120c564SAndrew Turner     if((region_array == 0) || (num_regions == 0) || (filepath.length() == 0))
283*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
284*c120c564SAndrew Turner 
285*c120c564SAndrew Turner     TrcMemAccessorBase *p_accessor;
286*c120c564SAndrew Turner     int curr_region_idx = 0;
287*c120c564SAndrew Turner 
288*c120c564SAndrew Turner     // add first region during the creation of the file accessor.
289*c120c564SAndrew Turner     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);
290*c120c564SAndrew Turner     if(err == OCSD_OK)
291*c120c564SAndrew Turner     {
292*c120c564SAndrew Turner         TrcMemAccessorFile *pAcc = dynamic_cast<TrcMemAccessorFile *>(p_accessor);
293*c120c564SAndrew Turner         if(pAcc)
294*c120c564SAndrew Turner         {
295*c120c564SAndrew Turner             // add additional regions to the file accessor.
296*c120c564SAndrew Turner             curr_region_idx++;
297*c120c564SAndrew Turner             while(curr_region_idx < num_regions)
298*c120c564SAndrew Turner             {
299*c120c564SAndrew Turner                 pAcc->AddOffsetRange(region_array[curr_region_idx].start_address,
300*c120c564SAndrew Turner                                         region_array[curr_region_idx].region_size,
301*c120c564SAndrew Turner                                         region_array[curr_region_idx].file_offset);
302*c120c564SAndrew Turner                 curr_region_idx++;
303*c120c564SAndrew Turner             }
304*c120c564SAndrew Turner             pAcc->setMemSpace(mem_space);
305*c120c564SAndrew Turner 
306*c120c564SAndrew Turner             // add the accessor to the map.
307*c120c564SAndrew Turner             err = m_default_mapper->AddAccessor(pAcc,0);
308*c120c564SAndrew Turner         }
309*c120c564SAndrew Turner         else
310*c120c564SAndrew Turner             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
311*c120c564SAndrew Turner 
312*c120c564SAndrew Turner         if(err != OCSD_OK)
313*c120c564SAndrew Turner             TrcMemAccFactory::DestroyAccessor(p_accessor);
314*c120c564SAndrew Turner     }
315*c120c564SAndrew Turner     return err;
316*c120c564SAndrew Turner }
317*c120c564SAndrew Turner 
318*c120c564SAndrew Turner 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)
319*c120c564SAndrew Turner {
320*c120c564SAndrew Turner     if (!hasMemAccMapper())
321*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
322*c120c564SAndrew Turner 
323*c120c564SAndrew Turner     if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0))
324*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
325*c120c564SAndrew Turner 
326*c120c564SAndrew Turner     TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath);
327*c120c564SAndrew Turner     if (!pAcc)
328*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
329*c120c564SAndrew Turner 
330*c120c564SAndrew Turner     int curr_region_idx = 0;
331*c120c564SAndrew Turner     while (curr_region_idx < num_regions)
332*c120c564SAndrew Turner     {
333*c120c564SAndrew Turner         // check "new" range
334*c120c564SAndrew Turner         if (!pAcc->addrStartOfRange(region_array[curr_region_idx].start_address))
335*c120c564SAndrew Turner         {
336*c120c564SAndrew Turner             // ensure adds cleanly
337*c120c564SAndrew Turner             if (!pAcc->AddOffsetRange(region_array[curr_region_idx].start_address,
338*c120c564SAndrew Turner                 region_array[curr_region_idx].region_size,
339*c120c564SAndrew Turner                 region_array[curr_region_idx].file_offset))
340*c120c564SAndrew Turner                 return OCSD_ERR_INVALID_PARAM_VAL;  // otherwise bail out
341*c120c564SAndrew Turner         }
342*c120c564SAndrew Turner         curr_region_idx++;
343*c120c564SAndrew Turner     }
344*c120c564SAndrew Turner     return OCSD_OK;
345*c120c564SAndrew Turner }
346*c120c564SAndrew Turner ocsd_err_t DecodeTree::initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address,
347*c120c564SAndrew Turner     const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context)
348*c120c564SAndrew Turner {
349*c120c564SAndrew Turner     if(!hasMemAccMapper())
350*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
351*c120c564SAndrew Turner 
352*c120c564SAndrew Turner     if(p_cb_func == 0)
353*c120c564SAndrew Turner         return OCSD_ERR_INVALID_PARAM_VAL;
354*c120c564SAndrew Turner 
355*c120c564SAndrew Turner     TrcMemAccessorBase *p_accessor;
356*c120c564SAndrew Turner     ocsd_err_t err = TrcMemAccFactory::CreateCBAccessor(&p_accessor, st_address, en_address, mem_space);
357*c120c564SAndrew Turner     if(err == OCSD_OK)
358*c120c564SAndrew Turner     {
359*c120c564SAndrew Turner         TrcMemAccCB *pCBAcc = dynamic_cast<TrcMemAccCB *>(p_accessor);
360*c120c564SAndrew Turner         if(pCBAcc)
361*c120c564SAndrew Turner         {
362*c120c564SAndrew Turner             if (IDfn)
363*c120c564SAndrew Turner                 pCBAcc->setCBIDIfFn((Fn_MemAccID_CB)p_cb_func, p_context);
364*c120c564SAndrew Turner             else
365*c120c564SAndrew Turner                 pCBAcc->setCBIfFn((Fn_MemAcc_CB)p_cb_func, p_context);
366*c120c564SAndrew Turner 
367*c120c564SAndrew Turner             err = m_default_mapper->AddAccessor(p_accessor,0);
368*c120c564SAndrew Turner         }
369*c120c564SAndrew Turner         else
370*c120c564SAndrew Turner             err = OCSD_ERR_MEM;    // wrong type of object - treat as mem error
371*c120c564SAndrew Turner 
372*c120c564SAndrew Turner         if(err != OCSD_OK)
373*c120c564SAndrew Turner             TrcMemAccFactory::DestroyAccessor(p_accessor);
374*c120c564SAndrew Turner     }
375*c120c564SAndrew Turner     return err;
376*c120c564SAndrew Turner }
377*c120c564SAndrew Turner 
378*c120c564SAndrew Turner 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)
379*c120c564SAndrew Turner {
380*c120c564SAndrew Turner     return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, false, p_context);
381*c120c564SAndrew Turner }
382*c120c564SAndrew Turner 
383*c120c564SAndrew Turner 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)
384*c120c564SAndrew Turner {
385*c120c564SAndrew Turner     return initCallbackMemAcc(st_address, en_address, mem_space, (void *)p_cb_func, true, p_context);
386*c120c564SAndrew Turner }
387*c120c564SAndrew Turner 
388*c120c564SAndrew Turner ocsd_err_t DecodeTree::removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space)
389*c120c564SAndrew Turner {
390*c120c564SAndrew Turner     if(!hasMemAccMapper())
391*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
392*c120c564SAndrew Turner     return m_default_mapper->RemoveAccessorByAddress(address,mem_space,0);
393*c120c564SAndrew Turner }
394*c120c564SAndrew Turner 
395*c120c564SAndrew Turner ocsd_err_t DecodeTree::createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig)
396*c120c564SAndrew Turner {
397*c120c564SAndrew Turner     ocsd_err_t err = OCSD_OK;
398*c120c564SAndrew Turner     IDecoderMngr *pDecoderMngr = 0;
399*c120c564SAndrew Turner     TraceComponent *pTraceComp = 0;
400*c120c564SAndrew Turner     int crtFlags = createFlags;
401*c120c564SAndrew Turner 
402*c120c564SAndrew Turner     uint8_t CSID = 0;   // default for single stream decoder (no deformatter) - we ignore the ID
403*c120c564SAndrew Turner     if(usingFormatter())
404*c120c564SAndrew Turner     {
405*c120c564SAndrew Turner         CSID = pConfig->getTraceID();
406*c120c564SAndrew Turner         crtFlags |= OCSD_CREATE_FLG_INST_ID;
407*c120c564SAndrew Turner     }
408*c120c564SAndrew Turner 
409*c120c564SAndrew Turner     // create the decode element to attach to the channel.
410*c120c564SAndrew Turner     if((err = createDecodeElement(CSID)) != OCSD_OK)
411*c120c564SAndrew Turner         return err;
412*c120c564SAndrew Turner 
413*c120c564SAndrew Turner     // get the libary decoder register.
414*c120c564SAndrew Turner     OcsdLibDcdRegister * lib_reg = OcsdLibDcdRegister::getDecoderRegister();
415*c120c564SAndrew Turner     if(lib_reg == 0)
416*c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
417*c120c564SAndrew Turner 
418*c120c564SAndrew Turner     // find the named decoder
419*c120c564SAndrew Turner     if((err = lib_reg->getDecoderMngrByName(decoderName,&pDecoderMngr)) != OCSD_OK)
420*c120c564SAndrew Turner         return err;
421*c120c564SAndrew Turner 
422*c120c564SAndrew Turner     // got the decoder...
423*c120c564SAndrew Turner     if((err = pDecoderMngr->createDecoder(crtFlags,(int)CSID,pConfig,&pTraceComp)) != OCSD_OK)
424*c120c564SAndrew Turner         return err;
425*c120c564SAndrew Turner 
426*c120c564SAndrew Turner     m_decode_elements[CSID]->SetDecoderElement(decoderName, pDecoderMngr, pTraceComp, true);
427*c120c564SAndrew Turner 
428*c120c564SAndrew Turner     // always attach an error logger
429*c120c564SAndrew Turner     if(err == OCSD_OK)
430*c120c564SAndrew Turner         err = pDecoderMngr->attachErrorLogger(pTraceComp,DecodeTree::s_i_error_logger);
431*c120c564SAndrew Turner 
432*c120c564SAndrew Turner     // if we created a packet decoder it may need additional components.
433*c120c564SAndrew Turner     if(crtFlags &  OCSD_CREATE_FLG_FULL_DECODER)
434*c120c564SAndrew Turner     {
435*c120c564SAndrew Turner         if(m_i_instr_decode && (err == OCSD_OK))
436*c120c564SAndrew Turner             err = pDecoderMngr->attachInstrDecoder(pTraceComp,m_i_instr_decode);
437*c120c564SAndrew Turner 
438*c120c564SAndrew Turner         if(err == OCSD_ERR_DCD_INTERFACE_UNUSED)    // ignore if instruction decoder refused
439*c120c564SAndrew Turner             err = OCSD_OK;
440*c120c564SAndrew Turner 
441*c120c564SAndrew Turner         if(m_i_mem_access && (err == OCSD_OK))
442*c120c564SAndrew Turner             err = pDecoderMngr->attachMemAccessor(pTraceComp,m_i_mem_access);
443*c120c564SAndrew Turner 
444*c120c564SAndrew Turner         if(err == OCSD_ERR_DCD_INTERFACE_UNUSED)    // ignore if mem accessor refused
445*c120c564SAndrew Turner             err = OCSD_OK;
446*c120c564SAndrew Turner 
447*c120c564SAndrew Turner         if( m_i_gen_elem_out && (err == OCSD_OK))
448*c120c564SAndrew Turner             err = pDecoderMngr->attachOutputSink(pTraceComp,m_i_gen_elem_out);
449*c120c564SAndrew Turner     }
450*c120c564SAndrew Turner 
451*c120c564SAndrew Turner     // finally attach the packet processor input to the demux output channel
452*c120c564SAndrew Turner     if(err == OCSD_OK)
453*c120c564SAndrew Turner     {
454*c120c564SAndrew Turner         ITrcDataIn *pDataIn = 0;
455*c120c564SAndrew Turner         if((err = pDecoderMngr->getDataInputI(pTraceComp,&pDataIn)) == OCSD_OK)
456*c120c564SAndrew Turner         {
457*c120c564SAndrew Turner             // got the interface -> attach to demux, or direct to input of decode tree
458*c120c564SAndrew Turner             if(usingFormatter())
459*c120c564SAndrew Turner                 err = m_frame_deformatter_root->getIDStreamAttachPt(CSID)->attach(pDataIn);
460*c120c564SAndrew Turner             else
461*c120c564SAndrew Turner                 m_i_decoder_root = pDataIn;
462*c120c564SAndrew Turner         }
463*c120c564SAndrew Turner     }
464*c120c564SAndrew Turner 
465*c120c564SAndrew Turner     if(err != OCSD_OK)
466*c120c564SAndrew Turner     {
467*c120c564SAndrew Turner         destroyDecodeElement(CSID); // will destroy decoder as well.
468*c120c564SAndrew Turner     }
469*c120c564SAndrew Turner     return err;
470*c120c564SAndrew Turner }
471*c120c564SAndrew Turner 
472*c120c564SAndrew Turner ocsd_err_t DecodeTree::removeDecoder(const uint8_t CSID)
473*c120c564SAndrew Turner {
474*c120c564SAndrew Turner     ocsd_err_t err = OCSD_OK;
475*c120c564SAndrew Turner     uint8_t localID = CSID;
476*c120c564SAndrew Turner     if(!usingFormatter())
477*c120c564SAndrew Turner         localID = 0;
478*c120c564SAndrew Turner 
479*c120c564SAndrew Turner     if(usingFormatter() && !OCSD_IS_VALID_CS_SRC_ID(CSID))
480*c120c564SAndrew Turner         err = OCSD_ERR_INVALID_ID;
481*c120c564SAndrew Turner     else
482*c120c564SAndrew Turner     {
483*c120c564SAndrew Turner         destroyDecodeElement(localID);
484*c120c564SAndrew Turner     }
485*c120c564SAndrew Turner     return err;
486*c120c564SAndrew Turner }
487*c120c564SAndrew Turner 
488*c120c564SAndrew Turner DecodeTreeElement * DecodeTree::getDecoderElement(const uint8_t CSID) const
489*c120c564SAndrew Turner {
490*c120c564SAndrew Turner     DecodeTreeElement *ret_elem = 0;
491*c120c564SAndrew Turner     if(usingFormatter() && OCSD_IS_VALID_CS_SRC_ID(CSID))
492*c120c564SAndrew Turner     {
493*c120c564SAndrew Turner         ret_elem = m_decode_elements[CSID];
494*c120c564SAndrew Turner     }
495*c120c564SAndrew Turner     else
496*c120c564SAndrew Turner         ret_elem = m_decode_elements[0];    // ID 0 is used if single leaf tree.
497*c120c564SAndrew Turner     return ret_elem;
498*c120c564SAndrew Turner }
499*c120c564SAndrew Turner 
500*c120c564SAndrew Turner DecodeTreeElement *DecodeTree::getFirstElement(uint8_t &elemID)
501*c120c564SAndrew Turner {
502*c120c564SAndrew Turner     m_decode_elem_iter = 0;
503*c120c564SAndrew Turner     return getNextElement(elemID);
504*c120c564SAndrew Turner }
505*c120c564SAndrew Turner 
506*c120c564SAndrew Turner DecodeTreeElement *DecodeTree::getNextElement(uint8_t &elemID)
507*c120c564SAndrew Turner {
508*c120c564SAndrew Turner     DecodeTreeElement *ret_elem = 0;
509*c120c564SAndrew Turner 
510*c120c564SAndrew Turner     if(m_decode_elem_iter < 0x80)
511*c120c564SAndrew Turner     {
512*c120c564SAndrew Turner         // find a none zero entry or end of range
513*c120c564SAndrew Turner         while((m_decode_elements[m_decode_elem_iter] == 0) && (m_decode_elem_iter < 0x80))
514*c120c564SAndrew Turner             m_decode_elem_iter++;
515*c120c564SAndrew Turner 
516*c120c564SAndrew Turner         // return entry unless end of range
517*c120c564SAndrew Turner         if(m_decode_elem_iter < 0x80)
518*c120c564SAndrew Turner         {
519*c120c564SAndrew Turner             ret_elem = m_decode_elements[m_decode_elem_iter];
520*c120c564SAndrew Turner             elemID = m_decode_elem_iter;
521*c120c564SAndrew Turner             m_decode_elem_iter++;
522*c120c564SAndrew Turner         }
523*c120c564SAndrew Turner     }
524*c120c564SAndrew Turner     return ret_elem;
525*c120c564SAndrew Turner }
526*c120c564SAndrew Turner 
527*c120c564SAndrew Turner bool DecodeTree::initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags)
528*c120c564SAndrew Turner {
529*c120c564SAndrew Turner     bool initOK = true;
530*c120c564SAndrew Turner     m_dcd_tree_type = type;
531*c120c564SAndrew Turner     if(type ==  OCSD_TRC_SRC_FRAME_FORMATTED)
532*c120c564SAndrew Turner     {
533*c120c564SAndrew Turner         // frame formatted - we want to create the deformatter and hook it up
534*c120c564SAndrew Turner         m_frame_deformatter_root = new (std::nothrow) TraceFormatterFrameDecoder();
535*c120c564SAndrew Turner         if(m_frame_deformatter_root)
536*c120c564SAndrew Turner         {
537*c120c564SAndrew Turner             m_frame_deformatter_root->Configure(formatterCfgFlags);
538*c120c564SAndrew Turner             m_frame_deformatter_root->getErrLogAttachPt()->attach(DecodeTree::s_i_error_logger);
539*c120c564SAndrew Turner             m_i_decoder_root = dynamic_cast<ITrcDataIn*>(m_frame_deformatter_root);
540*c120c564SAndrew Turner         }
541*c120c564SAndrew Turner         else
542*c120c564SAndrew Turner             initOK = false;
543*c120c564SAndrew Turner     }
544*c120c564SAndrew Turner     return initOK;
545*c120c564SAndrew Turner }
546*c120c564SAndrew Turner 
547*c120c564SAndrew Turner void DecodeTree::setSingleRoot(TrcPktProcI *pComp)
548*c120c564SAndrew Turner {
549*c120c564SAndrew Turner     m_i_decoder_root = static_cast<ITrcDataIn*>(pComp);
550*c120c564SAndrew Turner }
551*c120c564SAndrew Turner 
552*c120c564SAndrew Turner ocsd_err_t DecodeTree::createDecodeElement(const uint8_t CSID)
553*c120c564SAndrew Turner {
554*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_INVALID_ID;
555*c120c564SAndrew Turner     if(CSID < 0x80)
556*c120c564SAndrew Turner     {
557*c120c564SAndrew Turner         if(m_decode_elements[CSID] == 0)
558*c120c564SAndrew Turner         {
559*c120c564SAndrew Turner             m_decode_elements[CSID] = new (std::nothrow) DecodeTreeElement();
560*c120c564SAndrew Turner             if(m_decode_elements[CSID] == 0)
561*c120c564SAndrew Turner                 err = OCSD_ERR_MEM;
562*c120c564SAndrew Turner             else
563*c120c564SAndrew Turner                 err = OCSD_OK;
564*c120c564SAndrew Turner         }
565*c120c564SAndrew Turner         else
566*c120c564SAndrew Turner             err = OCSD_ERR_ATTACH_TOO_MANY;
567*c120c564SAndrew Turner     }
568*c120c564SAndrew Turner     return err;
569*c120c564SAndrew Turner }
570*c120c564SAndrew Turner 
571*c120c564SAndrew Turner void DecodeTree::destroyDecodeElement(const uint8_t CSID)
572*c120c564SAndrew Turner {
573*c120c564SAndrew Turner     if(CSID < 0x80)
574*c120c564SAndrew Turner     {
575*c120c564SAndrew Turner         if(m_decode_elements[CSID] != 0)
576*c120c564SAndrew Turner         {
577*c120c564SAndrew Turner             m_decode_elements[CSID]->DestroyElem();
578*c120c564SAndrew Turner             delete m_decode_elements[CSID];
579*c120c564SAndrew Turner             m_decode_elements[CSID] = 0;
580*c120c564SAndrew Turner         }
581*c120c564SAndrew Turner     }
582*c120c564SAndrew Turner }
583*c120c564SAndrew Turner 
584*c120c564SAndrew Turner ocsd_err_t DecodeTree::setIDFilter(std::vector<uint8_t> &ids)
585*c120c564SAndrew Turner {
586*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER;
587*c120c564SAndrew Turner     if(usingFormatter())
588*c120c564SAndrew Turner     {
589*c120c564SAndrew Turner         err = m_frame_deformatter_root->OutputFilterAllIDs(false);
590*c120c564SAndrew Turner         if(err == OCSD_OK)
591*c120c564SAndrew Turner             err = m_frame_deformatter_root->OutputFilterIDs(ids,true);
592*c120c564SAndrew Turner     }
593*c120c564SAndrew Turner     return err;
594*c120c564SAndrew Turner }
595*c120c564SAndrew Turner 
596*c120c564SAndrew Turner ocsd_err_t DecodeTree::clearIDFilter()
597*c120c564SAndrew Turner {
598*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_DCDT_NO_FORMATTER;
599*c120c564SAndrew Turner     if(usingFormatter())
600*c120c564SAndrew Turner     {
601*c120c564SAndrew Turner         err = m_frame_deformatter_root->OutputFilterAllIDs(true);
602*c120c564SAndrew Turner     }
603*c120c564SAndrew Turner     return err;
604*c120c564SAndrew Turner }
605*c120c564SAndrew Turner 
606*c120c564SAndrew Turner /** add a protocol packet printer */
607*c120c564SAndrew Turner ocsd_err_t DecodeTree::addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter)
608*c120c564SAndrew Turner {
609*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
610*c120c564SAndrew Turner     DecodeTreeElement *pElement = getDecoderElement(CSID);
611*c120c564SAndrew Turner     if (pElement)
612*c120c564SAndrew Turner     {
613*c120c564SAndrew Turner         ocsd_trace_protocol_t protocol = pElement->getProtocol();
614*c120c564SAndrew Turner         ItemPrinter *pPrinter;
615*c120c564SAndrew Turner 
616*c120c564SAndrew Turner         pPrinter = PktPrinterFact::createProtocolPrinter(getPrinterList(), protocol, CSID);
617*c120c564SAndrew Turner         if (pPrinter)
618*c120c564SAndrew Turner         {
619*c120c564SAndrew Turner             pPrinter->setMessageLogger(getCurrentErrorLogI()->getOutputLogger());
620*c120c564SAndrew Turner             switch (protocol)
621*c120c564SAndrew Turner             {
622*c120c564SAndrew Turner             case  OCSD_PROTOCOL_ETMV4I:
623*c120c564SAndrew Turner             {
624*c120c564SAndrew Turner                 PacketPrinter<EtmV4ITrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV4ITrcPacket> *>(pPrinter);
625*c120c564SAndrew Turner                 if (bMonitor)
626*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV4ITrcPacket> *)pTPrinter);
627*c120c564SAndrew Turner                 else
628*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV4ITrcPacket> *)pTPrinter);
629*c120c564SAndrew Turner             }
630*c120c564SAndrew Turner             break;
631*c120c564SAndrew Turner 
632*c120c564SAndrew Turner             case  OCSD_PROTOCOL_ETMV3:
633*c120c564SAndrew Turner             {
634*c120c564SAndrew Turner                 PacketPrinter<EtmV3TrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<EtmV3TrcPacket> *>(pPrinter);
635*c120c564SAndrew Turner                 if (bMonitor)
636*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<EtmV3TrcPacket> *)pTPrinter);
637*c120c564SAndrew Turner                 else
638*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<EtmV3TrcPacket> *)pTPrinter);
639*c120c564SAndrew Turner             }
640*c120c564SAndrew Turner             break;
641*c120c564SAndrew Turner 
642*c120c564SAndrew Turner             case  OCSD_PROTOCOL_PTM:
643*c120c564SAndrew Turner             {
644*c120c564SAndrew Turner                 PacketPrinter<PtmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<PtmTrcPacket> *>(pPrinter);
645*c120c564SAndrew Turner                 if (bMonitor)
646*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<PtmTrcPacket> *)pTPrinter);
647*c120c564SAndrew Turner                 else
648*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<PtmTrcPacket> *)pTPrinter);
649*c120c564SAndrew Turner             }
650*c120c564SAndrew Turner             break;
651*c120c564SAndrew Turner 
652*c120c564SAndrew Turner             case OCSD_PROTOCOL_STM:
653*c120c564SAndrew Turner             {
654*c120c564SAndrew Turner                 PacketPrinter<StmTrcPacket> *pTPrinter = dynamic_cast<PacketPrinter<StmTrcPacket> *>(pPrinter);
655*c120c564SAndrew Turner                 if (bMonitor)
656*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktMonitor(pElement->getDecoderHandle(), (IPktRawDataMon<StmTrcPacket> *)pTPrinter);
657*c120c564SAndrew Turner                 else
658*c120c564SAndrew Turner                     err = pElement->getDecoderMngr()->attachPktSink(pElement->getDecoderHandle(), (IPktDataIn<StmTrcPacket> *)pTPrinter);
659*c120c564SAndrew Turner             }
660*c120c564SAndrew Turner             break;
661*c120c564SAndrew Turner 
662*c120c564SAndrew Turner             default:
663*c120c564SAndrew Turner                 err = OCSD_ERR_NO_PROTOCOL;
664*c120c564SAndrew Turner                 break;
665*c120c564SAndrew Turner             }
666*c120c564SAndrew Turner 
667*c120c564SAndrew Turner             if (err == OCSD_OK)
668*c120c564SAndrew Turner             {
669*c120c564SAndrew Turner                 if (ppPrinter)
670*c120c564SAndrew Turner                     *ppPrinter = pPrinter;
671*c120c564SAndrew Turner             }
672*c120c564SAndrew Turner             else
673*c120c564SAndrew Turner                 PktPrinterFact::destroyPrinter(getPrinterList(), pPrinter);
674*c120c564SAndrew Turner         }
675*c120c564SAndrew Turner     }
676*c120c564SAndrew Turner     return err;
677*c120c564SAndrew Turner }
678*c120c564SAndrew Turner 
679*c120c564SAndrew Turner /** add a raw frame printer */
680*c120c564SAndrew Turner ocsd_err_t DecodeTree::addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags)
681*c120c564SAndrew Turner {
682*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_MEM;
683*c120c564SAndrew Turner     RawFramePrinter *pPrinter = PktPrinterFact::createRawFramePrinter(getPrinterList());
684*c120c564SAndrew Turner     if (pPrinter)
685*c120c564SAndrew Turner     {
686*c120c564SAndrew Turner         pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger()));
687*c120c564SAndrew Turner         TraceFormatterFrameDecoder *pFrameDecoder = getFrameDeformatter();
688*c120c564SAndrew Turner         uint32_t cfgFlags = pFrameDecoder->getConfigFlags();
689*c120c564SAndrew Turner         cfgFlags |= ((uint32_t)flags & (OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT));
690*c120c564SAndrew Turner         pFrameDecoder->Configure(cfgFlags);
691*c120c564SAndrew Turner         err = pFrameDecoder->getTrcRawFrameAttachPt()->attach(pPrinter);
692*c120c564SAndrew Turner         if (ppPrinter && (err==OCSD_OK))
693*c120c564SAndrew Turner             *ppPrinter = pPrinter;
694*c120c564SAndrew Turner     }
695*c120c564SAndrew Turner     return err;
696*c120c564SAndrew Turner }
697*c120c564SAndrew Turner 
698*c120c564SAndrew Turner /** add a generic element output printer */
699*c120c564SAndrew Turner ocsd_err_t DecodeTree::addGenElemPrinter(TrcGenericElementPrinter **ppPrinter)
700*c120c564SAndrew Turner {
701*c120c564SAndrew Turner     ocsd_err_t err = OCSD_ERR_MEM;
702*c120c564SAndrew Turner     TrcGenericElementPrinter *pPrinter = PktPrinterFact::createGenElemPrinter(getPrinterList());
703*c120c564SAndrew Turner     if (pPrinter)
704*c120c564SAndrew Turner     {
705*c120c564SAndrew Turner         pPrinter->setMessageLogger((DecodeTree::getCurrentErrorLogI()->getOutputLogger()));
706*c120c564SAndrew Turner         setGenTraceElemOutI(pPrinter);
707*c120c564SAndrew Turner         err = OCSD_OK;
708*c120c564SAndrew Turner         if (ppPrinter)
709*c120c564SAndrew Turner             *ppPrinter = pPrinter;
710*c120c564SAndrew Turner     }
711*c120c564SAndrew Turner     return err;
712*c120c564SAndrew Turner 
713*c120c564SAndrew Turner }
714*c120c564SAndrew Turner 
715*c120c564SAndrew Turner /* End of File ocsd_dcd_tree.cpp */
716