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 */ 397