You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
446 lines
16 KiB
446 lines
16 KiB
/*
|
|
* \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 P, class Pt, class Pc>
|
|
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 <class P, class Pt, class Pc>
|
|
DecoderMngrBase<P,Pt,Pc>::DecoderMngrBase(const std::string &decoderTypeName, ocsd_trace_protocol_t builtInProtocol)
|
|
{
|
|
OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
|
|
if(pDcdReg)
|
|
pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
|
|
m_builtInProtocol = builtInProtocol;
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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<P,Pt,Pc> *pProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> *>(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<P,Pc> *pBase = dynamic_cast< TrcPktDecodeBase<P,Pc> *>(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 <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::destroyDecoder(TraceComponent *pComponent)
|
|
{
|
|
if(pComponent->getAssocComponent() != 0)
|
|
delete pComponent->getAssocComponent();
|
|
delete pComponent;
|
|
return OCSD_OK;
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
|
|
{
|
|
return pComponent->getErrorLogAttachPt()->replace_first(pIErrorLog);
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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 <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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 <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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 <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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 <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
|
|
{
|
|
// find the packet processor
|
|
TraceComponent *pPktProc = pComponent;
|
|
if(pComponent->getAssocComponent() != 0)
|
|
pPktProc = pComponent->getAssocComponent();
|
|
|
|
// get the packet processor
|
|
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
|
|
if(pPktProcBase == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
// get the interface
|
|
IPktRawDataMon<P> *p_If = dynamic_cast< IPktRawDataMon<P> * >(pPktRawDataMon);
|
|
if(p_If == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
return pPktProcBase->getRawPacketMonAttachPt()->replace_first(p_If);
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
|
|
{
|
|
// find the packet processor
|
|
TraceComponent *pPktProc = pComponent;
|
|
if(pComponent->getAssocComponent() != 0)
|
|
pPktProc = pComponent->getAssocComponent();
|
|
|
|
// get the packet processor
|
|
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pPktProc);
|
|
if(pPktProcBase == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
// get the interface
|
|
ITrcPktIndexer<Pt> *p_If = dynamic_cast< ITrcPktIndexer<Pt> * >(pPktIndexer);
|
|
if(p_If == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
return pPktProcBase->getTraceIDIndexerAttachPt()->replace_first(p_If);
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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<P> *pkt_in_i = dynamic_cast< IPktDataIn<P> * >(pPktDataInSink);
|
|
if(pkt_in_i == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
// get the packet processor
|
|
TrcPktProcBase<P,Pt,Pc> *pPktProcBase = dynamic_cast< TrcPktProcBase<P,Pt,Pc> * >(pComponent);
|
|
if(pPktProcBase == 0)
|
|
return OCSD_ERR_INVALID_PARAM_TYPE;
|
|
|
|
// attach
|
|
return pPktProcBase->getPacketOutAttachPt()->replace_first(pkt_in_i);
|
|
}
|
|
|
|
template <class P, class Pt, class Pc>
|
|
ocsd_err_t DecoderMngrBase<P,Pt,Pc>::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<P,Pt,Pc>
|
|
{
|
|
public:
|
|
DecodeMngrFullDcd (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
|
|
: DecoderMngrBase<P,Pt,Pc>(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);
|
|
}
|
|
};
|
|
|
|
/* full decode - extended config object - base + derived. */
|
|
template< class P, // Packet class.
|
|
class Pt, // Packet enum type ID.
|
|
class Pc, // Processor config base class.
|
|
class PcEx, // Processor config derived class
|
|
class PcSt, // Processor config struct type
|
|
class PktProc, // Packet processor class.
|
|
class PktDcd> // Packet decoder class.
|
|
class DecodeMngrFullDcdExCfg : public DecoderMngrBase<P, Pt, Pc>
|
|
{
|
|
public:
|
|
DecodeMngrFullDcdExCfg(const std::string &name, ocsd_trace_protocol_t builtInProtocol)
|
|
: DecoderMngrBase<P, Pt, Pc>(name, builtInProtocol) {};
|
|
|
|
virtual ~DecodeMngrFullDcdExCfg() {};
|
|
|
|
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) PcEx((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<P,Pt,Pc>
|
|
{
|
|
public:
|
|
DecodeMngrPktProc (const std::string &name, ocsd_trace_protocol_t builtInProtocol)
|
|
: DecoderMngrBase<P,Pt,Pc>(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 */
|