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 44template <class P, class Pt, class Pc> 45class DecoderMngrBase : public IDecoderMngr 46{ 47public: 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 82private: 83 const ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type. 84}; 85 86template <class P, class Pt, class Pc> 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 95template <class P, class Pt, class Pc> 96ocsd_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 163template <class P, class Pt, class Pc> 164ocsd_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 172template <class P, class Pt, class Pc> 173ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog) 174{ 175 return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog); 176} 177 178template <class P, class Pt, class Pc> 179ocsd_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 196template <class P, class Pt, class Pc> 197ocsd_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 214template <class P, class Pt, class Pc> 215ocsd_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 231template <class P, class Pt, class Pc> 232ocsd_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 248template <class P, class Pt, class Pc> 249ocsd_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 269template <class P, class Pt, class Pc> 270ocsd_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 290template <class P, class Pt, class Pc> 291ocsd_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 311template <class P, class Pt, class Pc> 312ocsd_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 325template< 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. 331class DecodeMngrFullDcd : public DecoderMngrBase<P,Pt,Pc> 332{ 333public: 334 DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol) 335 : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {}; 336 337 virtual ~DecodeMngrFullDcd() {}; 338 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 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 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. */ 366template< 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{ 375public: 376 DecodeMngrFullDcdExCfg(const std::string &name, ocsd_trace_protocol_t builtInProtocol) 377 : DecoderMngrBase<P, Pt, Pc>(name, builtInProtocol) {}; 378 379 virtual ~DecodeMngrFullDcdExCfg() {}; 380 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 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 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 412template< 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. 417class DecodeMngrPktProc : public DecoderMngrBase<P,Pt,Pc> 418{ 419public: 420 DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol) 421 : DecoderMngrBase<P,Pt,Pc>(name,builtInProtocol) {}; 422 423 virtual ~DecodeMngrPktProc() {}; 424 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 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