]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/opencsd/decoder/include/common/ocsd_dcd_mngr.h
Re-add opencsd as a vendor import from the dist directory
[FreeBSD/FreeBSD.git] / contrib / opencsd / decoder / include / common / ocsd_dcd_mngr.h
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);
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
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;
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     ocsd_trace_protocol_t m_builtInProtocol;    //!< Protocol ID if built in type.
84 };
85
86 template <class P, class Pt, class Pc>
87 DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol)
88 {
89     OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
90     if(pDcdReg)
91         pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
92     m_builtInProtocol = builtInProtocol;
93 }
94
95 template <class P, class Pt, class Pc>
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 configuration
119     TrcPktProcBase<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(pkt_proc);       
120     if(pProcBase == 0)
121         return OCSD_ERR_INVALID_PARAM_TYPE;
122
123     if(!bUnConfigured)
124         pProcBase->setProtocolConfig(pConf);
125
126     *ppTrcComp = pkt_proc;
127
128     // may need a packet decoder
129     if(bDecoder)
130     {
131         // create the decoder
132         pkt_dcd = createPktDecode(bUseInstID, instID);
133         if(!pkt_dcd)
134             return OCSD_ERR_MEM;
135
136         // get the decoder base
137         TrcPktDecodeBase<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(pkt_dcd);       
138         if(pBase == 0)
139             return OCSD_ERR_INVALID_PARAM_TYPE;
140
141         if(!bUnConfigured)
142             pBase->setProtocolConfig(pConf);
143
144         // associate decoder with packet processor
145         // -> this means a TraceComponent with an associated component is a packet decoder.
146         //    the associated component is the connected packet processor.
147         pkt_dcd->setAssocComponent(pkt_proc);
148
149         // connect packet processor and decoder
150         pProcBase->getPacketOutAttachPt()->attach(pBase);
151
152         *ppTrcComp = pkt_dcd;
153     }
154     return OCSD_OK;
155 }
156
157 template <class P, class Pt, class Pc>
158 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::destroyDecoder(TraceComponent *pComponent)
159 {
160     if(pComponent->getAssocComponent() != 0)
161         delete pComponent->getAssocComponent();
162     delete pComponent;
163     return OCSD_OK;
164 }
165
166 template <class P, class Pt, class Pc>
167 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
168 {
169     return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog);
170 }
171
172 template <class P, class Pt, class Pc>
173 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec)
174 {
175     ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
176
177     if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
178         return OCSD_ERR_INVALID_PARAM_TYPE;
179
180     TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
181     if(pDcdI == 0)
182         return OCSD_ERR_INVALID_PARAM_TYPE;
183
184     if(pDcdI->getUsesIDecode())
185         err = pDcdI->getInstrDecodeAttachPt()->replace_first(pIInstrDec);
186
187     return err;
188 }
189
190 template <class P, class Pt, class Pc>
191 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor)
192 {
193     ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED;
194
195     if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
196         return OCSD_ERR_INVALID_PARAM_TYPE;
197
198     TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
199     if(pDcdI == 0)
200         return OCSD_ERR_INVALID_PARAM_TYPE;
201
202     if(pDcdI->getUsesMemAccess())
203         err = pDcdI->getMemoryAccessAttachPt()->replace_first(pMemAccessor);        
204
205     return err;
206 }
207
208 template <class P, class Pt, class Pc>
209 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink)
210 {
211     ocsd_err_t err = OCSD_ERR_INVALID_PARAM_TYPE;
212
213     if(pComponent->getAssocComponent() == 0)    // no associated component - so this is a packet processor
214         return err;
215
216     TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent);
217     if(pDcdI == 0)
218         return OCSD_ERR_INVALID_PARAM_TYPE;
219
220     err = pDcdI->getTraceElemOutAttachPt()->replace_first(pOutSink);
221
222     return err;
223 }
224
225 template <class P, class Pt, class Pc>
226 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn)
227 {
228     // find the packet processor
229     TraceComponent *pPktProc = pComponent;
230     if(pComponent->getAssocComponent() != 0)
231         pPktProc = pComponent->getAssocComponent();
232
233     TrcPktProcI *pPPI = dynamic_cast< TrcPktProcI * >(pPktProc);
234     if(pPPI == 0)
235         return OCSD_ERR_INVALID_PARAM_TYPE;
236
237     *ppDataIn = pPPI;
238
239     return OCSD_OK;
240 }
241
242 template <class P, class Pt, class Pc>
243 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
244 {
245     // find the packet processor
246     TraceComponent *pPktProc = pComponent;
247     if(pComponent->getAssocComponent() != 0)
248         pPktProc = pComponent->getAssocComponent();
249
250     // get the packet processor
251     TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
252     if(pPktProcBase == 0)
253         return OCSD_ERR_INVALID_PARAM_TYPE;
254
255     // get the interface
256     IPktRawDataMon<P> *p_If =  dynamic_cast< IPktRawDataMon<P> * >(pPktRawDataMon);
257     if(p_If == 0)
258         return  OCSD_ERR_INVALID_PARAM_TYPE;
259
260     return pPktProcBase->getRawPacketMonAttachPt()->replace_first(p_If);
261 }
262
263 template <class P, class Pt, class Pc>
264 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
265 {
266     // find the packet processor
267     TraceComponent *pPktProc = pComponent;
268     if(pComponent->getAssocComponent() != 0)
269         pPktProc = pComponent->getAssocComponent();
270
271     // get the packet processor
272     TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
273     if(pPktProcBase == 0)
274         return OCSD_ERR_INVALID_PARAM_TYPE;
275
276     // get the interface
277     ITrcPktIndexer<Pt> *p_If =  dynamic_cast< ITrcPktIndexer<Pt> * >(pPktIndexer);
278     if(p_If == 0)
279         return  OCSD_ERR_INVALID_PARAM_TYPE;
280
281     return pPktProcBase->getTraceIDIndexerAttachPt()->replace_first(p_If);
282 }
283
284 template <class P, class Pt, class Pc>
285 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink)
286 {
287     // must be solo packet processor
288     if(pComponent->getAssocComponent() != 0)
289         return OCSD_ERR_INVALID_PARAM_TYPE;
290
291     // interface must be the correct one.
292     IPktDataIn<P> *pkt_in_i = dynamic_cast< IPktDataIn<P> * >(pPktDataInSink);
293     if(pkt_in_i == 0)
294         return OCSD_ERR_INVALID_PARAM_TYPE;
295
296     // get the packet processor
297     TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pComponent);
298     if(pPktProcBase == 0)
299         return OCSD_ERR_INVALID_PARAM_TYPE;
300
301     // attach
302     return  pPktProcBase->getPacketOutAttachPt()->replace_first(pkt_in_i);
303 }
304
305 template <class P, class Pt, class Pc>
306 ocsd_err_t DecoderMngrBase<P,Pt,Pc>::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct)
307 {
308     CSConfig *pConfig = createConfig(pDataStruct);
309     if(!pConfig)
310         return OCSD_ERR_MEM;
311     *pConfigBase = pConfig;
312     return OCSD_OK;
313 }
314
315 /****************************************************************************************************/
316 /* Full decoder / packet process pair, templated base for creating decoder objects                  */
317 /****************************************************************************************************/
318
319 template<   class P,            // Packet class.
320             class Pt,           // Packet enum type ID.
321             class Pc,           // Processor config class.
322             class PcSt,         // Processor config struct type
323             class PktProc,      // Packet processor class.
324             class PktDcd>       // Packet decoder class.
325 class DecodeMngrFullDcd : public DecoderMngrBase<P,Pt,Pc>
326 {
327 public:
328     DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol) 
329         : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
330
331     virtual ~DecodeMngrFullDcd() {};
332
333     virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
334     {
335         TraceComponent *pComp;
336         if(useInstID)
337             pComp = new (std::nothrow) PktProc(instID);
338         else
339             pComp = new (std::nothrow) PktProc();
340         return pComp;
341     }
342
343     virtual TraceComponent *createPktDecode(const bool useInstID, const int instID)
344     {
345         TraceComponent *pComp;
346         if(useInstID)
347             pComp = new (std::nothrow)PktDcd(instID);
348         else
349             pComp = new (std::nothrow)PktDcd();
350         return pComp;
351     }
352
353     virtual CSConfig *createConfig(const void *pDataStruct)
354     {
355        return new (std::nothrow) Pc((PcSt *)pDataStruct);
356     }
357 };
358
359 /****************************************************************************************************/
360 /* Packet processor only, templated base for creating decoder objects                               */
361 /****************************************************************************************************/
362
363 template<   class P,            // Packet class.
364             class Pt,           // Packet enum type ID.
365             class Pc,           // Processor config class.
366             class PcSt,         // Processor config struct type
367             class PktProc>      // Packet processor class.
368 class DecodeMngrPktProc : public DecoderMngrBase<P,Pt,Pc>
369 {
370 public:
371     DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol) 
372         : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {};
373
374     virtual ~DecodeMngrPktProc() {};
375
376     virtual TraceComponent *createPktProc(const bool useInstID, const int instID)
377     {
378         TraceComponent *pComp;
379         if(useInstID)
380             pComp = new (std::nothrow) PktProc(instID);
381         else
382             pComp = new (std::nothrow) PktProc();
383         return pComp;
384     }
385
386     virtual CSConfig *createConfig(const void *pDataStruct)
387     {
388        return new (std::nothrow) Pc((PcSt *)pDataStruct);
389     }
390 };
391
392
393
394 #endif // ARM_OCSD_DCD_MNGR_H_INCLUDED
395
396 /* End of File ocsd_dcd_mngr.h */