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 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 {
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>
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