xref: /freebsd/contrib/opencsd/decoder/include/common/ocsd_dcd_mngr.h (revision 46e6e290975f19ea62d03f90ac3e523af4dae557)
1  /*
2   * \file       ocsd_dcd_mngr.h
3   * \brief      OpenCSD : Decoder manager base class.
4   *
5   * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
6   */
7  
8  /*
9   * Redistribution and use in source and binary forms, with or without modification,
10   * are permitted provided that the following conditions are met:
11   *
12   * 1. Redistributions of source code must retain the above copyright notice,
13   * this list of conditions and the following disclaimer.
14   *
15   * 2. Redistributions in binary form must reproduce the above copyright notice,
16   * this list of conditions and the following disclaimer in the documentation
17   * and/or other materials provided with the distribution.
18   *
19   * 3. Neither the name of the copyright holder nor the names of its contributors
20   * may be used to endorse or promote products derived from this software without
21   * specific prior written permission.
22   *
23   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   */
34  
35  #ifndef ARM_OCSD_DCD_MNGR_H_INCLUDED
36  #define ARM_OCSD_DCD_MNGR_H_INCLUDED
37  
38  #include "opencsd/ocsd_if_types.h"
39  #include "common/ocsd_dcd_mngr_i.h"
40  #include "common/ocsd_lib_dcd_register.h"
41  #include "common/trc_pkt_decode_base.h"
42  #include "common/trc_pkt_proc_base.h"
43  
44  template <class P, class Pt, class Pc>
45  class DecoderMngrBase : public IDecoderMngr
46  {
47  public:
48      DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol);
~DecoderMngrBase()49      virtual ~DecoderMngrBase() {};
50  
51      // create decoder interface.
52      virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config,  TraceComponent **p_component);
53      virtual ocsd_err_t destroyDecoder(TraceComponent *p_component);
54  
getProtocolType()55      virtual const ocsd_trace_protocol_t getProtocolType() const { return m_builtInProtocol; }
56  
57  // common
58      virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog);
59  
60  // pkt decoder
61      virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec);
62      virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor);
63      virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink);
64  
65  // pkt processor
66      virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon);
67      virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer);
68      virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink);
69  
70  // data input connection interface
71      virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn);
72  
73  // generate a Config object from opaque config struct pointer.
74      virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct);
75  
76  // implemented by decoder handler derived classes
77      virtual TraceComponent *createPktProc(const bool useInstID, const int instID) = 0;
createPktDecode(const bool useInstID,const int instID)78      virtual TraceComponent *createPktDecode(const bool useInstID, const int instID) { return 0; };
79      virtual CSConfig *createConfig(const void *pDataStruct) = 0;
80  
81  
82  private:
83      const ocsd_trace_protocol_t m_builtInProtocol;    //!< Protocol ID if built in type.
84  };
85  
86  template <class P, class Pt, class Pc>
DecoderMngrBase(const std::string & decoderTypeName,ocsd_trace_protocol_t builtInProtocol)87      DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol) :
88          m_builtInProtocol(builtInProtocol)
89  {
90      OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
91      if(pDcdReg)
92          pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
93  }
94  
95  template <class P, class Pt, class Pc>
createDecoder(const int create_flags,const int instID,const CSConfig * pConfig,TraceComponent ** ppTrcComp)96  ocsd_err_t  DecoderMngrBase<P,Pt,Pc>::createDecoder(const int create_flags, const int instID, const CSConfig *pConfig,  TraceComponent **ppTrcComp)
97  {
98      TraceComponent *pkt_proc = 0;
99      TraceComponent *pkt_dcd = 0;
100      bool bUseInstID =  (create_flags & OCSD_CREATE_FLG_INST_ID) != 0;
101      bool bDecoder = (create_flags & OCSD_CREATE_FLG_FULL_DECODER) != 0;
102      bool bUnConfigured = (pConfig == 0);
103  
104      const Pc *pConf = dynamic_cast< const Pc * >(pConfig);
105  
106      // check inputs valid...
107      if((pConf == 0) && !bUnConfigured)
108          return OCSD_ERR_INVALID_PARAM_TYPE;
109  
110       if((create_flags & (OCSD_CREATE_FLG_PACKET_PROC | OCSD_CREATE_FLG_FULL_DECODER)) == 0)
111          return OCSD_ERR_INVALID_PARAM_VAL;
112  
113      // always need a packet processor
114      pkt_proc = createPktProc(bUseInstID, instID);
115      if(!pkt_proc)
116          return OCSD_ERR_MEM;
117  
118      // set the op mode flags
119      pkt_proc->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTPROC_COMMON));
120  
121      // set the configuration
122      TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);
123      if(pProcBase == 0)
124          return OCSD_ERR_INVALID_PARAM_TYPE;
125  
126      if(!bUnConfigured)
127          pProcBase->setProtocolConfig(pConf);
128  
129      *ppTrcComp = pkt_proc;
130  
131      // may need a packet decoder
132      if(bDecoder)
133      {
134          // create the decoder
135          pkt_dcd = createPktDecode(bUseInstID, instID);
136          if(!pkt_dcd)
137              return OCSD_ERR_MEM;
138  
139          // set the op mode flags
140          pkt_dcd->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTDEC_COMMON));
141  
142          // get the decoder base
143          TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);
144          if(pBase == 0)
145              return OCSD_ERR_INVALID_PARAM_TYPE;
146  
147          if(!bUnConfigured)
148              pBase->setProtocolConfig(pConf);
149  
150          // associate decoder with packet processor
151          // -> this means a TraceComponent with an associated component is a packet decoder.
152          //    the associated component is the connected packet processor.
153          pkt_dcd->setAssocComponent(pkt_proc);
154  
155          // connect packet processor and decoder
156          pProcBase->getPacketOutAttachPt()->attach(pBase);
157  
158          *ppTrcComp = pkt_dcd;
159      }
160      return OCSD_OK;
161  }
162  
163  template <class P, class Pt, class Pc>
destroyDecoder(TraceComponent * pComponent)164  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::destroyDecoder(TraceComponent *pComponent)
165  {
166      if(pComponent->getAssocComponent() != 0)
167          delete pComponent->getAssocComponent();
168      delete pComponent;
169      return OCSD_OK;
170  }
171  
172  template <class P, class Pt, class Pc>
attachErrorLogger(TraceComponent * pComponent,ITraceErrorLog * pIErrorLog)173  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
174  {
175      return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog);
176  }
177  
178  template <class P, class Pt, class Pc>
attachInstrDecoder(TraceComponent * pComponent,IInstrDecode * pIInstrDec)179  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec)
180  {
181      ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
182  
183      if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
184          return OCSD_ERR_INVALID_PARAM_TYPE;
185  
186      TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
187      if(pDcdI == 0)
188          return OCSD_ERR_INVALID_PARAM_TYPE;
189  
190      if(pDcdI->getUsesIDecode())
191          err = pDcdI->getInstrDecodeAttachPt()->replace_first(pIInstrDec);
192  
193      return err;
194  }
195  
196  template <class P, class Pt, class Pc>
attachMemAccessor(TraceComponent * pComponent,ITargetMemAccess * pMemAccessor)197  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor)
198  {
199      ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
200  
201      if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
202          return OCSD_ERR_INVALID_PARAM_TYPE;
203  
204      TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
205      if(pDcdI == 0)
206          return OCSD_ERR_INVALID_PARAM_TYPE;
207  
208      if(pDcdI->getUsesMemAccess())
209          err = pDcdI->getMemoryAccessAttachPt()->replace_first(pMemAccessor);
210  
211      return err;
212  }
213  
214  template <class P, class Pt, class Pc>
attachOutputSink(TraceComponent * pComponent,ITrcGenElemIn * pOutSink)215  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink)
216  {
217      ocsd_err_t err = OCSD_ERR_INVALID_PARAM_TYPE;
218  
219      if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
220          return err;
221  
222      TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
223      if(pDcdI == 0)
224          return OCSD_ERR_INVALID_PARAM_TYPE;
225  
226      err = pDcdI->getTraceElemOutAttachPt()->replace_first(pOutSink);
227  
228      return err;
229  }
230  
231  template <class P, class Pt, class Pc>
getDataInputI(TraceComponent * pComponent,ITrcDataIn ** ppDataIn)232  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn)
233  {
234      // find the packet processor
235      TraceComponent *pPktProc = pComponent;
236      if(pComponent->getAssocComponent() != 0)
237          pPktProc = pComponent->getAssocComponent();
238  
239      TrcPktProcI *pPPI = dynamic_cast< TrcPktProcI * >(pPktProc);
240      if(pPPI == 0)
241          return OCSD_ERR_INVALID_PARAM_TYPE;
242  
243      *ppDataIn = pPPI;
244  
245      return OCSD_OK;
246  }
247  
248  template <class P, class Pt, class Pc>
attachPktMonitor(TraceComponent * pComponent,ITrcTypedBase * pPktRawDataMon)249  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
250  {
251      // find the packet processor
252      TraceComponent *pPktProc = pComponent;
253      if(pComponent->getAssocComponent() != 0)
254          pPktProc = pComponent->getAssocComponent();
255  
256      // get the packet processor
257      TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
258      if(pPktProcBase == 0)
259          return OCSD_ERR_INVALID_PARAM_TYPE;
260  
261      // get the interface
262      IPktRawDataMon<P> *p_If =  dynamic_cast< IPktRawDataMon<P> * >(pPktRawDataMon);
263      if(p_If == 0)
264          return  OCSD_ERR_INVALID_PARAM_TYPE;
265  
266      return pPktProcBase->getRawPacketMonAttachPt()->replace_first(p_If);
267  }
268  
269  template <class P, class Pt, class Pc>
attachPktIndexer(TraceComponent * pComponent,ITrcTypedBase * pPktIndexer)270  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
271  {
272      // find the packet processor
273      TraceComponent *pPktProc = pComponent;
274      if(pComponent->getAssocComponent() != 0)
275          pPktProc = pComponent->getAssocComponent();
276  
277      // get the packet processor
278      TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
279      if(pPktProcBase == 0)
280          return OCSD_ERR_INVALID_PARAM_TYPE;
281  
282      // get the interface
283      ITrcPktIndexer<Pt> *p_If =  dynamic_cast< ITrcPktIndexer<Pt> * >(pPktIndexer);
284      if(p_If == 0)
285          return  OCSD_ERR_INVALID_PARAM_TYPE;
286  
287      return pPktProcBase->getTraceIDIndexerAttachPt()->replace_first(p_If);
288  }
289  
290  template <class P, class Pt, class Pc>
attachPktSink(TraceComponent * pComponent,ITrcTypedBase * pPktDataInSink)291  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink)
292  {
293      // must be solo packet processor
294      if(pComponent->getAssocComponent() != 0)
295          return OCSD_ERR_INVALID_PARAM_TYPE;
296  
297      // interface must be the correct one.
298      IPktDataIn<P> *pkt_in_i = dynamic_cast< IPktDataIn<P> * >(pPktDataInSink);
299      if(pkt_in_i == 0)
300          return OCSD_ERR_INVALID_PARAM_TYPE;
301  
302      // get the packet processor
303      TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pComponent);
304      if(pPktProcBase == 0)
305          return OCSD_ERR_INVALID_PARAM_TYPE;
306  
307      // attach
308      return  pPktProcBase->getPacketOutAttachPt()->replace_first(pkt_in_i);
309  }
310  
311  template <class P, class Pt, class Pc>
createConfigFromDataStruct(CSConfig ** pConfigBase,const void * pDataStruct)312  ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct)
313  {
314      CSConfig *pConfig = createConfig(pDataStruct);
315      if(!pConfig)
316          return OCSD_ERR_MEM;
317      *pConfigBase = pConfig;
318      return OCSD_OK;
319  }
320  
321  /****************************************************************************************************/
322  /* Full decoder / packet process pair, templated base for creating decoder objects                  */
323  /****************************************************************************************************/
324  
325  template<   class P,            // Packet class.
326              class Pt,           // Packet enum type ID.
327              class Pc,           // Processor config class.
328              class PcSt,         // Processor config struct type
329              class PktProc,      // Packet processor class.
330              class PktDcd>       // Packet decoder class.
331  class DecodeMngrFullDcd : public DecoderMngrBase<P,Pt,Pc>
332  {
333  public:
DecodeMngrFullDcd(const std::string & name,ocsd_trace_protocol_t builtInProtocol)334      DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
335          : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
336  
~DecodeMngrFullDcd()337      virtual ~DecodeMngrFullDcd() {};
338  
createPktProc(const bool useInstID,const int instID)339      virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
340      {
341          TraceComponent *pComp;
342          if(useInstID)
343              pComp = new (std::nothrow) PktProc(instID);
344          else
345              pComp = new (std::nothrow) PktProc();
346          return pComp;
347      }
348  
createPktDecode(const bool useInstID,const int instID)349      virtual TraceComponent *createPktDecode(const bool useInstID, const int instID)
350      {
351          TraceComponent *pComp;
352          if(useInstID)
353              pComp = new (std::nothrow)PktDcd(instID);
354          else
355              pComp = new (std::nothrow)PktDcd();
356          return pComp;
357      }
358  
createConfig(const void * pDataStruct)359      virtual CSConfig *createConfig(const void *pDataStruct)
360      {
361         return new (std::nothrow) Pc((PcSt *)pDataStruct);
362      }
363  };
364  
365  /* full decode - extended config object - base + derived. */
366  template<   class P,            // Packet class.
367              class Pt,           // Packet enum type ID.
368              class Pc,           // Processor config base class.
369              class PcEx,         // Processor config derived class
370              class PcSt,         // Processor config struct type
371              class PktProc,      // Packet processor class.
372              class PktDcd>       // Packet decoder class.
373              class DecodeMngrFullDcdExCfg : public DecoderMngrBase<P, Pt, Pc>
374  {
375  public:
DecodeMngrFullDcdExCfg(const std::string & name,ocsd_trace_protocol_t builtInProtocol)376      DecodeMngrFullDcdExCfg(const std::string &name, ocsd_trace_protocol_t builtInProtocol)
377          : DecoderMngrBase<P, Pt, Pc>(name, builtInProtocol) {};
378  
~DecodeMngrFullDcdExCfg()379      virtual ~DecodeMngrFullDcdExCfg() {};
380  
createPktProc(const bool useInstID,const int instID)381      virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
382      {
383          TraceComponent *pComp;
384          if (useInstID)
385              pComp = new (std::nothrow) PktProc(instID);
386          else
387              pComp = new (std::nothrow) PktProc();
388          return pComp;
389      }
390  
createPktDecode(const bool useInstID,const int instID)391      virtual TraceComponent *createPktDecode(const bool useInstID, const int instID)
392      {
393          TraceComponent *pComp;
394          if (useInstID)
395              pComp = new (std::nothrow)PktDcd(instID);
396          else
397              pComp = new (std::nothrow)PktDcd();
398          return pComp;
399      }
400  
createConfig(const void * pDataStruct)401      virtual CSConfig *createConfig(const void *pDataStruct)
402      {
403          return new (std::nothrow) PcEx((PcSt *)pDataStruct);
404      }
405  };
406  
407  
408  /****************************************************************************************************/
409  /* Packet processor only, templated base for creating decoder objects                               */
410  /****************************************************************************************************/
411  
412  template<   class P,            // Packet class.
413              class Pt,           // Packet enum type ID.
414              class Pc,           // Processor config class.
415              class PcSt,         // Processor config struct type
416              class PktProc>      // Packet processor class.
417  class DecodeMngrPktProc : public DecoderMngrBase<P,Pt,Pc>
418  {
419  public:
DecodeMngrPktProc(const std::string & name,ocsd_trace_protocol_t builtInProtocol)420      DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
421          : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
422  
~DecodeMngrPktProc()423      virtual ~DecodeMngrPktProc() {};
424  
createPktProc(const bool useInstID,const int instID)425      virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
426      {
427          TraceComponent *pComp;
428          if(useInstID)
429              pComp = new (std::nothrow) PktProc(instID);
430          else
431              pComp = new (std::nothrow) PktProc();
432          return pComp;
433      }
434  
createConfig(const void * pDataStruct)435      virtual CSConfig *createConfig(const void *pDataStruct)
436      {
437         return new (std::nothrow) Pc((PcSt *)pDataStruct);
438      }
439  };
440  
441  
442  
443  #endif // ARM_OCSD_DCD_MNGR_H_INCLUDED
444  
445  /* End of File ocsd_dcd_mngr.h */
446