/* * \file ocsd_dcd_mngr.h * \brief OpenCSD : Decoder manager base class. * * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved. */ /* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ARM_OCSD_DCD_MNGR_H_INCLUDED #define ARM_OCSD_DCD_MNGR_H_INCLUDED #include "opencsd/ocsd_if_types.h" #include "common/ocsd_dcd_mngr_i.h" #include "common/ocsd_lib_dcd_register.h" #include "common/trc_pkt_decode_base.h" #include "common/trc_pkt_proc_base.h" template class DecoderMngrBase : public IDecoderMngr { public: DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol); virtual ~DecoderMngrBase() {}; // create decoder interface. virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **p_component); virtual ocsd_err_t destroyDecoder(TraceComponent *p_component); virtual const ocsd_trace_protocol_t getProtocolType() const { return m_builtInProtocol; } // common virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog); // pkt decoder virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec); virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor); virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink); // pkt processor virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon); virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer); virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink); // data input connection interface virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn); // generate a Config object from opaque config struct pointer. virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct); // implemented by decoder handler derived classes virtual TraceComponent *createPktProc(const bool useInstID, const int instID) = 0; virtual TraceComponent *createPktDecode(const bool useInstID, const int instID) { return 0; }; virtual CSConfig *createConfig(const void *pDataStruct) = 0; private: ocsd_trace_protocol_t m_builtInProtocol; //!< Protocol ID if built in type. }; template DecoderMngrBase::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol) { OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister(); if(pDcdReg) pDcdReg->registerDecoderTypeByName(decoderTypeName,this); m_builtInProtocol = builtInProtocol; } template ocsd_err_t DecoderMngrBase::createDecoder(const int create_flags, const int instID, const CSConfig *pConfig, TraceComponent **ppTrcComp) { TraceComponent *pkt_proc = 0; TraceComponent *pkt_dcd = 0; bool bUseInstID = (create_flags & OCSD_CREATE_FLG_INST_ID) != 0; bool bDecoder = (create_flags & OCSD_CREATE_FLG_FULL_DECODER) != 0; bool bUnConfigured = (pConfig == 0); const Pc *pConf = dynamic_cast< const Pc * >(pConfig); // check inputs valid... if((pConf == 0) && !bUnConfigured) return OCSD_ERR_INVALID_PARAM_TYPE; if((create_flags & (OCSD_CREATE_FLG_PACKET_PROC | OCSD_CREATE_FLG_FULL_DECODER)) == 0) return OCSD_ERR_INVALID_PARAM_VAL; // always need a packet processor pkt_proc = createPktProc(bUseInstID, instID); if(!pkt_proc) return OCSD_ERR_MEM; // set the op mode flags pkt_proc->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTPROC_COMMON)); // set the configuration TrcPktProcBase *pProcBase = dynamic_cast< TrcPktProcBase *>(pkt_proc); if(pProcBase == 0) return OCSD_ERR_INVALID_PARAM_TYPE; if(!bUnConfigured) pProcBase->setProtocolConfig(pConf); *ppTrcComp = pkt_proc; // may need a packet decoder if(bDecoder) { // create the decoder pkt_dcd = createPktDecode(bUseInstID, instID); if(!pkt_dcd) return OCSD_ERR_MEM; // set the op mode flags pkt_dcd->setComponentOpMode(create_flags & (OCSD_OPFLG_COMP_MODE_MASK | OCSD_OPFLG_PKTDEC_COMMON)); // get the decoder base TrcPktDecodeBase *pBase = dynamic_cast< TrcPktDecodeBase *>(pkt_dcd); if(pBase == 0) return OCSD_ERR_INVALID_PARAM_TYPE; if(!bUnConfigured) pBase->setProtocolConfig(pConf); // associate decoder with packet processor // -> this means a TraceComponent with an associated component is a packet decoder. // the associated component is the connected packet processor. pkt_dcd->setAssocComponent(pkt_proc); // connect packet processor and decoder pProcBase->getPacketOutAttachPt()->attach(pBase); *ppTrcComp = pkt_dcd; } return OCSD_OK; } template ocsd_err_t DecoderMngrBase::destroyDecoder(TraceComponent *pComponent) { if(pComponent->getAssocComponent() != 0) delete pComponent->getAssocComponent(); delete pComponent; return OCSD_OK; } template ocsd_err_t DecoderMngrBase::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog) { return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog); } template ocsd_err_t DecoderMngrBase::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec) { ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED; if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor return OCSD_ERR_INVALID_PARAM_TYPE; TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent); if(pDcdI == 0) return OCSD_ERR_INVALID_PARAM_TYPE; if(pDcdI->getUsesIDecode()) err = pDcdI->getInstrDecodeAttachPt()->replace_first(pIInstrDec); return err; } template ocsd_err_t DecoderMngrBase::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor) { ocsd_err_t err = OCSD_ERR_DCD_INTERFACE_UNUSED; if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor return OCSD_ERR_INVALID_PARAM_TYPE; TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent); if(pDcdI == 0) return OCSD_ERR_INVALID_PARAM_TYPE; if(pDcdI->getUsesMemAccess()) err = pDcdI->getMemoryAccessAttachPt()->replace_first(pMemAccessor); return err; } template ocsd_err_t DecoderMngrBase::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink) { ocsd_err_t err = OCSD_ERR_INVALID_PARAM_TYPE; if(pComponent->getAssocComponent() == 0) // no associated component - so this is a packet processor return err; TrcPktDecodeI *pDcdI = dynamic_cast< TrcPktDecodeI * >(pComponent); if(pDcdI == 0) return OCSD_ERR_INVALID_PARAM_TYPE; err = pDcdI->getTraceElemOutAttachPt()->replace_first(pOutSink); return err; } template ocsd_err_t DecoderMngrBase::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn) { // find the packet processor TraceComponent *pPktProc = pComponent; if(pComponent->getAssocComponent() != 0) pPktProc = pComponent->getAssocComponent(); TrcPktProcI *pPPI = dynamic_cast< TrcPktProcI * >(pPktProc); if(pPPI == 0) return OCSD_ERR_INVALID_PARAM_TYPE; *ppDataIn = pPPI; return OCSD_OK; } template ocsd_err_t DecoderMngrBase::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon) { // find the packet processor TraceComponent *pPktProc = pComponent; if(pComponent->getAssocComponent() != 0) pPktProc = pComponent->getAssocComponent(); // get the packet processor TrcPktProcBase *pPktProcBase = dynamic_cast< TrcPktProcBase * >(pPktProc); if(pPktProcBase == 0) return OCSD_ERR_INVALID_PARAM_TYPE; // get the interface IPktRawDataMon

*p_If = dynamic_cast< IPktRawDataMon

* >(pPktRawDataMon); if(p_If == 0) return OCSD_ERR_INVALID_PARAM_TYPE; return pPktProcBase->getRawPacketMonAttachPt()->replace_first(p_If); } template ocsd_err_t DecoderMngrBase::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer) { // find the packet processor TraceComponent *pPktProc = pComponent; if(pComponent->getAssocComponent() != 0) pPktProc = pComponent->getAssocComponent(); // get the packet processor TrcPktProcBase *pPktProcBase = dynamic_cast< TrcPktProcBase * >(pPktProc); if(pPktProcBase == 0) return OCSD_ERR_INVALID_PARAM_TYPE; // get the interface ITrcPktIndexer *p_If = dynamic_cast< ITrcPktIndexer * >(pPktIndexer); if(p_If == 0) return OCSD_ERR_INVALID_PARAM_TYPE; return pPktProcBase->getTraceIDIndexerAttachPt()->replace_first(p_If); } template ocsd_err_t DecoderMngrBase::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink) { // must be solo packet processor if(pComponent->getAssocComponent() != 0) return OCSD_ERR_INVALID_PARAM_TYPE; // interface must be the correct one. IPktDataIn

*pkt_in_i = dynamic_cast< IPktDataIn

* >(pPktDataInSink); if(pkt_in_i == 0) return OCSD_ERR_INVALID_PARAM_TYPE; // get the packet processor TrcPktProcBase *pPktProcBase = dynamic_cast< TrcPktProcBase * >(pComponent); if(pPktProcBase == 0) return OCSD_ERR_INVALID_PARAM_TYPE; // attach return pPktProcBase->getPacketOutAttachPt()->replace_first(pkt_in_i); } template ocsd_err_t DecoderMngrBase::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct) { CSConfig *pConfig = createConfig(pDataStruct); if(!pConfig) return OCSD_ERR_MEM; *pConfigBase = pConfig; return OCSD_OK; } /****************************************************************************************************/ /* Full decoder / packet process pair, templated base for creating decoder objects */ /****************************************************************************************************/ template< class P, // Packet class. class Pt, // Packet enum type ID. class Pc, // Processor config class. class PcSt, // Processor config struct type class PktProc, // Packet processor class. class PktDcd> // Packet decoder class. class DecodeMngrFullDcd : public DecoderMngrBase { public: DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol) : DecoderMngrBase(name,builtInProtocol) {}; virtual ~DecodeMngrFullDcd() {}; virtual TraceComponent *createPktProc(const bool useInstID, const int instID) { TraceComponent *pComp; if(useInstID) pComp = new (std::nothrow) PktProc(instID); else pComp = new (std::nothrow) PktProc(); return pComp; } virtual TraceComponent *createPktDecode(const bool useInstID, const int instID) { TraceComponent *pComp; if(useInstID) pComp = new (std::nothrow)PktDcd(instID); else pComp = new (std::nothrow)PktDcd(); return pComp; } virtual CSConfig *createConfig(const void *pDataStruct) { return new (std::nothrow) Pc((PcSt *)pDataStruct); } }; /****************************************************************************************************/ /* Packet processor only, templated base for creating decoder objects */ /****************************************************************************************************/ template< class P, // Packet class. class Pt, // Packet enum type ID. class Pc, // Processor config class. class PcSt, // Processor config struct type class PktProc> // Packet processor class. class DecodeMngrPktProc : public DecoderMngrBase { public: DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol) : DecoderMngrBase(name,builtInProtocol) {}; virtual ~DecodeMngrPktProc() {}; virtual TraceComponent *createPktProc(const bool useInstID, const int instID) { TraceComponent *pComp; if(useInstID) pComp = new (std::nothrow) PktProc(instID); else pComp = new (std::nothrow) PktProc(); return pComp; } virtual CSConfig *createConfig(const void *pDataStruct) { return new (std::nothrow) Pc((PcSt *)pDataStruct); } }; #endif // ARM_OCSD_DCD_MNGR_H_INCLUDED /* End of File ocsd_dcd_mngr.h */