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 const 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 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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: 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. */ 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: 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 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: 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