Adds a custom factory API for registering named decoders with the library and creating new instances of the decoder types.
Updates to the decoder manager and decoder instance wrapper C++ objects that interface with the C-API
Added in LogMessage to TraceComponent base class to allow derived classes to easily call logging interface without deref pointers etc.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/c_api/ocsd_c_api_cust_fact.h | 54 ++++++++++ decoder/include/c_api/ocsd_c_api_cust_impl.h | 133 +++++++++++++++++++++++++ decoder/include/c_api/ocsd_c_api_custom.h | 84 ++++++++-------- decoder/include/common/trc_component.h | 1 + decoder/source/c_api/ocsd_c_api_custom_obj.cpp | 131 ++++++++++++++++++++---- decoder/source/c_api/ocsd_c_api_custom_obj.h | 46 +++++++-- decoder/source/trc_component.cpp | 13 ++- 7 files changed, 392 insertions(+), 70 deletions(-) create mode 100644 decoder/include/c_api/ocsd_c_api_cust_fact.h create mode 100644 decoder/include/c_api/ocsd_c_api_cust_impl.h
diff --git a/decoder/include/c_api/ocsd_c_api_cust_fact.h b/decoder/include/c_api/ocsd_c_api_cust_fact.h new file mode 100644 index 0000000..f9e6a95 --- /dev/null +++ b/decoder/include/c_api/ocsd_c_api_cust_fact.h @@ -0,0 +1,54 @@ +/* +* \file ocsd_c_api_cust_fact.h +* \brief OpenCSD : Custom decoder factory API functions +* +* \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_C_API_CUST_FACT_H_INCLUDED +#define ARM_OCSD_C_API_CUST_FACT_H_INCLUDED + +#include "ocsd_c_api_types.h" +#include "ocsd_c_api_custom.h" + +/* Declarations for the functions implemented in the custom decoder factory. */ + +/** Required function to create a decoder instance - fills in the decoder struct supplied. */ +ocsd_err_t CreateCustomDecoder(const int create_flags, const void *decoder_cfg, ocsd_extern_dcd_inst_t *p_decoder_inst); + +/** Required Function to destroy a decoder instance - indicated by decoder handle */ +ocsd_err_t DestroyCustomDecoder(const void *decoder_handle); + +/** Required Function to extract the CoreSight Trace ID from the configuration structure */ +ocsd_err_t GetCSIDFromConfig(const void *decoder_cfg, unsigned char *p_csid); + +/** Optional Function to convert a protocol specific trace packet to human readable string */ +ocsd_err_t PacketToString(const void *trc_pkt, char *buffer, const int buflen); + +#endif /* ARM_OCSD_C_API_CUST_FACT_H_INCLUDED */ diff --git a/decoder/include/c_api/ocsd_c_api_cust_impl.h b/decoder/include/c_api/ocsd_c_api_cust_impl.h new file mode 100644 index 0000000..084610f --- /dev/null +++ b/decoder/include/c_api/ocsd_c_api_cust_impl.h @@ -0,0 +1,133 @@ +/* +* \file ocsd_c_api_cust_impl.h +* \brief OpenCSD : Custom decoder implementation common API definitions +* +* \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_C_API_CUST_IMPL_H_INCLUDED +#define ARM_OCSD_C_API_CUST_IMPL_H_INCLUDED + +#include "c_api/ocsd_c_api_types.h" +#include "c_api/ocsd_c_api_custom.h" + +/* inline functions to call the various CB functionality */ + +inline ocsd_datapath_resp_t lib_cb_GenElemOp(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_trc_index_t index_sop, + const uint8_t trc_chan_id, + const ocsd_generic_trace_elem *elem) +{ + if (callbacks->fn_gen_elem_out) + return callbacks->fn_gen_elem_out(callbacks->lib_context, index_sop, trc_chan_id, elem); + return OCSD_RESP_FATAL_NOT_INIT; +} + +inline void lib_cb_LogError(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_err_severity_t filter_level, + const ocsd_err_t code, + const ocsd_trc_index_t idx, + const uint8_t chan_id, + const char *pMsg) +{ + if (callbacks->fn_log_error) + callbacks->fn_log_error(callbacks->lib_context, filter_level, code, idx, chan_id, pMsg); +} + +inline void lib_cb_LogMsg(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_err_severity_t filter_level, + const char *pMsg) +{ + if (callbacks->fn_log_msg) + callbacks->fn_log_msg(callbacks->lib_context, filter_level, pMsg); +} + +inline ocsd_err_t lib_cb_DecodeArmInst(const ocsd_extern_dcd_cb_fns *callbacks, + ocsd_instr_info *instr_info) +{ + if (callbacks->fn_arm_instruction_decode) + return callbacks->fn_arm_instruction_decode(callbacks->lib_context, instr_info); + return OCSD_ERR_NOT_INIT; +} + +inline ocsd_err_t lib_cb_MemAccess(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_vaddr_t address, + const uint8_t cs_trace_id, + const ocsd_mem_space_acc_t mem_space, + uint32_t *num_bytes, + uint8_t *p_buffer) +{ + if (callbacks->fn_memory_access) + return callbacks->fn_memory_access(callbacks->lib_context, address, cs_trace_id, mem_space, num_bytes, p_buffer); + return OCSD_ERR_NOT_INIT; +} + +inline void lib_cb_PktMon(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *pkt, + const uint32_t size, + const uint8_t *p_data) +{ + if (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_MON) + { + if (callbacks->fn_packet_mon) + callbacks->fn_packet_mon(callbacks->lib_context, op, index_sop, pkt, size, p_data); + } +} + +inline int lib_cb_usePktMon(const ocsd_extern_dcd_cb_fns *callbacks) +{ + return (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_MON); +} + + +/* callback function to connect to the packet sink interface, on the main decode +data path - used if decoder created as packet processor only */ +inline ocsd_datapath_resp_t lib_cb_PktDataSink(const ocsd_extern_dcd_cb_fns *callbacks, + const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *pkt) +{ + if (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_SINK) + { + if (callbacks->fn_packet_data_sink) + return callbacks->fn_packet_data_sink(callbacks->lib_context, op, index_sop, pkt); + else + return OCSD_RESP_FATAL_NOT_INIT; + } + return OCSD_RESP_CONT; +} + +inline int lib_cb_usePktSink(const ocsd_extern_dcd_cb_fns *callbacks) +{ + return (callbacks->packetCBFlags & OCSD_CUST_DCD_PKT_CB_USE_SINK); +} + +#endif /* ARM_OCSD_C_API_CUST_IMPL_H_INCLUDED */ diff --git a/decoder/include/c_api/ocsd_c_api_custom.h b/decoder/include/c_api/ocsd_c_api_custom.h index 607e023..0594acd 100644 --- a/decoder/include/c_api/ocsd_c_api_custom.h +++ b/decoder/include/c_api/ocsd_c_api_custom.h @@ -1,6 +1,6 @@ /* * \file ocsd_c_api_custom.h - * \brief Reference CoreSight Trace Decoder : + * \brief OpenCSD : Custom decoder interface types and structures * * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved. */ @@ -46,74 +46,77 @@ typedef ocsd_datapath_resp_t (* fnTraceDataIn)( const void *decoder_handle, const uint8_t *pDataBlock, uint32_t *numBytesProcessed);
+/* function to update the in-use flags for the packet sinks - must be implemented in the decoder */ +typedef void (* fnUpdatePktMonFlags)(const void *decoder_handle, const int flags);
-/* callback and registration function to connect a generic element output point */ -typedef ocsd_datapath_resp_t (* fnGenElemOpCB)( const void *cb_context, + +/* callback function to connect into the generic element output point */ +typedef ocsd_datapath_resp_t (* fnGenElemOpCB)( const void *lib_context, const ocsd_trc_index_t index_sop, const uint8_t trc_chan_id, const ocsd_generic_trace_elem *elem); -typedef ocsd_err_t (* fnRegisterGenElemOpCB)(const void *decoder_handle, const void *cb_context, const fnGenElemOpCB pFnGenElemOut);
-/* callback and registration function to connect into the library error logging mechanism */ -typedef void (* fnLogErrorCB)(const void *cb_context, const ocsd_err_severity_t filter_level, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const char *pMsg); -typedef void (* fnLogMsgCB)(const void *cb_context, const ocsd_err_severity_t filter_level, const char *msg); -typedef void (* fnRegisterErrLogCB)(const void *decoder_handle, const void *cb_context, const fnLogErrorCB pFnErrLog, const fnLogMsgCB pFnMsgLog); +/* callback functions to connect into the library error logging mechanism */ +typedef void (* fnLogErrorCB)(const void *lib_context, const ocsd_err_severity_t filter_level, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const char *pMsg); +typedef void (* fnLogMsgCB)(const void *lib_context, const ocsd_err_severity_t filter_level, const char *msg);
-/* callback and registration function to connect an ARM instruction decoder */ -typedef ocsd_err_t (* fnDecodeArmInstCB)(const void *cb_context, ocsd_instr_info *instr_info); -typedef ocsd_err_t (* fnRegisterDecodeArmInstCB)(const void *decoder_handle, const void *cb_context, const fnDecodeArmInstCB pFnDecodeArmInstr); +/* callback function to connect an ARM instruction decoder */ +typedef ocsd_err_t (* fnDecodeArmInstCB)(const void *lib_context, ocsd_instr_info *instr_info);
-/* callback and registration function to connect the memory accessor interface */ -typedef ocsd_err_t (* fnMemAccessCB)(const void *cb_context, +/* callback function to connect the memory accessor interface */ +typedef ocsd_err_t (* fnMemAccessCB)(const void *lib_context, const ocsd_vaddr_t address, const uint8_t cs_trace_id, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer); -typedef ocsd_err_t (* fnRegisterMemAccessCB)(const void *decoder_handle, const void *cb_context, const fnMemAccessCB pFnmemAcc);
-/* callback and registration function to connect to the packet monitor interface of the packet processor */ -typedef void (* fnPktMonCB)( const void *cb_context, +/* callback function to connect to the packet monitor interface of the packet processor */ +typedef void (* fnPktMonCB)( const void *lib_context, const ocsd_datapath_op_t op, const ocsd_trc_index_t index_sop, const void *pkt, const uint32_t size, const uint8_t *p_data); -typedef ocsd_err_t (* fnRegisterPktMonCB)(const void *decoder_handle, const void *cb_context, fnPktMonCB pFnPktMon);
-/* callback and registration function to connect to the packet sink interface, on the main decode +/* callback function to connect to the packet sink interface, on the main decode data path - use if decoder created as packet processor only */ -typedef ocsd_datapath_resp_t (* fnPktDataSinkCB)( const ocsd_datapath_op_t op, +typedef ocsd_datapath_resp_t (* fnPktDataSinkCB)( const void *lib_context, + const ocsd_datapath_op_t op, const ocsd_trc_index_t index_sop, - const void *p_packet_in); -typedef ocsd_err_t (* fnRegisterPktDataSinkCB)(const void *decoder_handle, const void *cb_context, fnPktDataSinkCB pFnPktData); - -/** This structure is filled in by the ocsd_extern_dcd_fact_t creation function with the exception of the - library context value. */ + const void *pkt); + +/** an instance of this is owned by the decoder, filled in by the library - allows the CB fns in the library decode tree to be called. */ +typedef struct _ocsd_extern_dcd_cb_fns { + fnGenElemOpCB fn_gen_elem_out; + fnLogErrorCB fn_log_error; + fnLogMsgCB fn_log_msg; + fnDecodeArmInstCB fn_arm_instruction_decode; + fnMemAccessCB fn_memory_access; + fnPktMonCB fn_packet_mon; + fnPktDataSinkCB fn_packet_data_sink; + const void *lib_context; + int packetCBFlags; /**< Flags to indicate if the packet sink / packet monitor callbacks are in use. */ +} ocsd_extern_dcd_cb_fns; + +#define OCSD_CUST_DCD_PKT_CB_USE_MON 0x1 +#define OCSD_CUST_DCD_PKT_CB_USE_SINK 0x2 + +/** Owned by the library instance object, this structure is filled in by the ocsd_extern_dcd_fact_t createDecoder() function. */ typedef struct _ocsd_extern_dcd_inst { - /* Mandatory decoder functions - library initialisation will fail without these. */ - fnTraceDataIn fn_data_in; /**< raw trace data input function to decoder */ - - /* Optional decoder functions - set to 0 if the decoder class does not require / support this functionality */ - fnRegisterGenElemOpCB fn_reg_gen_out_cb; /**< connect callback to get the generic element output of the decoder */ - fnRegisterErrLogCB fn_reg_error_log_cb; /**< connect callbacks for error logging */ - fnRegisterDecodeArmInstCB fn_reg_instr_dcd_cb; /**< connect callback to decode an arm instruction */ - fnRegisterMemAccessCB fn_reg_mem_acc_cb; /**< connect callback to access trace memory images */ - fnRegisterPktMonCB fn_reg_pkt_mon_cb; /**< connect to the packet monitor of the packet processing stage */ - fnRegisterPktDataSinkCB fn_reg_pkt_sink_cb; /**< connect to packet sink on main datapath if decoder in packe processing mode only */ + /* Mandatory decoder call back functions - library initialisation will fail without these. */ + fnTraceDataIn fn_data_in; /**< raw trace data input function to decoder */ + fnUpdatePktMonFlags fn_update_pkt_mon; /**< update the packet monitor / sink usage flags */
/* Decoder instance data */ - void *decoder_handle; /**< Instance handle for the decoder */ - unsigned char cs_id; /**< CS ID of the trace stream this decoder should be attached to */ + void *decoder_handle; /**< Instance handle for the decoder - used by library to call the decoder CB functions */ char *p_decoder_name; /**< type name of the decoder - may be used in logging */ + uint8_t cs_id; /**< Coresight ID for the instance - extracted from the config on creation. */
- /* opaque library context value */ - void *library_context; /**< Context information for this decoder used by the library */ } ocsd_extern_dcd_inst_t;
- /** function to create a decoder instance - fills in the decoder struct supplied. */ -typedef ocsd_err_t (* fnCreateCustomDecoder)(const int create_flags, const void *decoder_cfg, ocsd_extern_dcd_inst_t *p_decoder_inst); +typedef ocsd_err_t (* fnCreateCustomDecoder)(const int create_flags, const void *decoder_cfg, const ocsd_extern_dcd_cb_fns *p_lib_callbacks, ocsd_extern_dcd_inst_t *p_decoder_inst); /** Function to destroy a decoder instance - indicated by decoder handle */ typedef ocsd_err_t (* fnDestroyCustomDecoder)(const void *decoder_handle); /** Function to extract the CoreSight Trace ID from the configuration structure */ @@ -121,7 +124,6 @@ typedef ocsd_err_t (* fnGetCSIDFromConfig)(const void *decoder_cfg, unsigned cha /** Function to convert a protocol specific trace packet to human readable string */ typedef ocsd_err_t (* fnPacketToString)(const void *trc_pkt, char *buffer, const int buflen);
- /** set of functions and callbacks to create an extern custom decoder in the library via the C API interface. This structure is registered with the library by name and then decoders of the type can be created on the decode tree. diff --git a/decoder/include/common/trc_component.h b/decoder/include/common/trc_component.h index 49ad265..b786e96 100644 --- a/decoder/include/common/trc_component.h +++ b/decoder/include/common/trc_component.h @@ -114,6 +114,7 @@ protected: friend class errLogAttachMonitor;
void LogError(const ocsdError &Error); + void LogMessage(const ocsd_err_severity_t filter_level, const std::string &msg); const ocsd_err_severity_t getErrorLogLevel() const { return m_errVerbosity; }; const bool isLoggingErrorLevel(const ocsd_err_severity_t level) const { return level <= m_errVerbosity; }; void updateErrorLogLevel(); diff --git a/decoder/source/c_api/ocsd_c_api_custom_obj.cpp b/decoder/source/c_api/ocsd_c_api_custom_obj.cpp index 36db747..283fad2 100644 --- a/decoder/source/c_api/ocsd_c_api_custom_obj.cpp +++ b/decoder/source/c_api/ocsd_c_api_custom_obj.cpp @@ -109,17 +109,41 @@ ocsd_err_t CustomDcdMngrWrapper::createDecoder(const int create_flags, const int if(m_dcd_fact.protocol_id == OCSD_PROTOCOL_END) return OCSD_ERR_NOT_INIT;
- ocsd_extern_dcd_inst_t dcd_inst; + CustomDecoderWrapper *pComp = new (std::nothrow) CustomDecoderWrapper(); + *ppComponent = pComp; + if (pComp == 0) + return OCSD_ERR_MEM; + + ocsd_extern_dcd_cb_fns lib_callbacks; + CustomDecoderWrapper::SetCallbacks(lib_callbacks); + lib_callbacks.lib_context = pComp; + + + ocsd_extern_dcd_inst_t *pDecodeInst = pComp->getDecoderInstInfo(); + err = m_dcd_fact.createDecoder( create_flags, - ((CustomConfigWrapper *)p_config)->getConfig(), - &dcd_inst); - if(err == OCSD_OK) + ((CustomConfigWrapper *)p_config)->getConfig(), + &lib_callbacks, + pDecodeInst); + + if (err == OCSD_OK) { - CustomDecoderWrapper *pComp = new (std::nothrow) CustomDecoderWrapper(dcd_inst,dcd_inst.p_decoder_name,dcd_inst.cs_id); - *ppComponent = pComp; - if(pComp == 0) - err = OCSD_ERR_MEM; + // validate the decoder + if ((pDecodeInst->fn_data_in == 0) || + (pDecodeInst->fn_update_pkt_mon == 0) || + (pDecodeInst->cs_id == 0) || + (pDecodeInst->decoder_handle == 0) || + (pDecodeInst->p_decoder_name == 0) + ) + { + err = OCSD_ERR_INVALID_PARAM_VAL; + } } + + if (err != OCSD_OK) + delete pComp; + else + pComp->updateNameFromDcdInst(); return err; }
@@ -128,6 +152,7 @@ ocsd_err_t CustomDcdMngrWrapper::destroyDecoder(TraceComponent *pComponent) CustomDecoderWrapper *pCustWrap = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(m_dcd_fact.protocol_id != OCSD_PROTOCOL_END) m_dcd_fact.destroyDecoder(pCustWrap->getDecoderInstInfo()->decoder_handle); + delete pCustWrap; return OCSD_OK; }
@@ -171,8 +196,10 @@ ocsd_err_t CustomDcdMngrWrapper::getDataInputI(TraceComponent *pComponent, ITrcD ocsd_err_t CustomDcdMngrWrapper::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog) { CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); - if(pDecoder == 0) + if (pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; + pDecoder->getErrorLogAttachPt()->replace_first(pIErrorLog); + return OCSD_OK; }
// full decoder @@ -181,7 +208,7 @@ ocsd_err_t CustomDcdMngrWrapper::attachInstrDecoder(TraceComponent *pComponent, CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; - + pDecoder->attachInstrDecI(pIInstrDec); return OCSD_OK; }
@@ -190,6 +217,8 @@ ocsd_err_t CustomDcdMngrWrapper::attachMemAccessor(TraceComponent *pComponent, I CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; + pDecoder->attchMemAccI(pMemAccessor); + return OCSD_OK; }
ocsd_err_t CustomDcdMngrWrapper::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink) @@ -197,6 +226,8 @@ ocsd_err_t CustomDcdMngrWrapper::attachOutputSink(TraceComponent *pComponent, IT CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; + pDecoder->attachGenElemI(pOutSink); + return OCSD_OK; }
// pkt processor only @@ -205,6 +236,8 @@ ocsd_err_t CustomDcdMngrWrapper::attachPktMonitor(TraceComponent *pComponent, IT CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; + // TBD: + return OCSD_OK; }
ocsd_err_t CustomDcdMngrWrapper::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer) @@ -218,6 +251,8 @@ ocsd_err_t CustomDcdMngrWrapper::attachPktSink(TraceComponent *pComponent, ITrcT CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; + // TBD: + return OCSD_OK; }
void CustomDcdMngrWrapper::pktToString(void *pkt, char *pStrBuffer, int bufSize) @@ -229,23 +264,59 @@ void CustomDcdMngrWrapper::pktToString(void *pkt, char *pStrBuffer, int bufSize)
/************************** Decoder instance wrapper **************************************/
-ocsd_datapath_resp_t GenElemOpCB( const void *cb_context, +/* callback functions */ +ocsd_datapath_resp_t GenElemOpCB( const void *lib_context, const ocsd_trc_index_t index_sop, const uint8_t trc_chan_id, const ocsd_generic_trace_elem *elem) { - if(cb_context && ((CustomDecoderWrapper *)cb_context)->m_pGenElemIn) - return ((CustomDecoderWrapper *)cb_context)->m_pGenElemIn->TraceElemIn(index_sop,trc_chan_id,*(OcsdTraceElement *)elem); + if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn) + return ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn->TraceElemIn(index_sop,trc_chan_id,*(OcsdTraceElement *)elem); return OCSD_RESP_FATAL_NOT_INIT; }
-CustomDecoderWrapper::CustomDecoderWrapper( const ocsd_extern_dcd_inst_t &dcd_inst, - const std::string &name, - const int instID) - : TraceComponent(name,instID) +void LogErrorCB(const void *lib_context, const ocsd_err_severity_t filter_level, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const char *pMsg) +{ + if (lib_context) + { + if(pMsg) + ((CustomDecoderWrapper *)lib_context)->LogError(&ocsdError(filter_level, code, idx, chan_id, std::string(pMsg))); + else + ((CustomDecoderWrapper *)lib_context)->LogError(&ocsdError(filter_level, code, idx, chan_id)); + } +} + +void LogMsgCB(const void *lib_context, const ocsd_err_severity_t filter_level, const char *msg) +{ + if (lib_context && msg) + ((CustomDecoderWrapper *)lib_context)->LogMessage(filter_level, std::string(msg)); +} + +ocsd_err_t DecodeArmInstCB(const void *lib_context, ocsd_instr_info *instr_info) +{ + if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec) + return ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec->DecodeInstruction(instr_info); + return OCSD_ERR_ATTACH_INVALID_PARAM; +} + +ocsd_err_t MemAccessCB(const void *lib_context, + const ocsd_vaddr_t address, + const uint8_t cs_trace_id, + const ocsd_mem_space_acc_t mem_space, + uint32_t *num_bytes, + uint8_t *p_buffer) +{ + if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor) + return ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor->ReadTargetMemory(address, cs_trace_id, mem_space, num_bytes, p_buffer); + return OCSD_ERR_INVALID_PARAM_VAL; +} + +/** decoder instance object */ +CustomDecoderWrapper::CustomDecoderWrapper() : TraceComponent("extern_wrapper"), + m_pGenElemIn(0), + m_pIInstrDec(0), + m_pMemAccessor(0) { - m_pGenElemIn = 0; - m_decoder_inst = dcd_inst; }
CustomDecoderWrapper::~CustomDecoderWrapper() @@ -268,4 +339,26 @@ ocsd_datapath_resp_t CustomDecoderWrapper::TraceDataIn( const ocsd_datapath_op_t return OCSD_RESP_FATAL_NOT_INIT; }
+void CustomDecoderWrapper::updateNameFromDcdInst() +{ + // create a unique component name from the decoder name + cs-id. + std::string name_combined = m_decoder_inst.p_decoder_name; + char num_buffer[32]; + sprintf(num_buffer, "_%04d", m_decoder_inst.cs_id); + name_combined += (std::string)num_buffer; + setComponentName(name_combined); +} + +void CustomDecoderWrapper::SetCallbacks(ocsd_extern_dcd_cb_fns & callbacks) +{ + callbacks.fn_arm_instruction_decode = DecodeArmInstCB; + callbacks.fn_gen_elem_out = GenElemOpCB; + callbacks.fn_log_error = LogErrorCB; + callbacks.fn_log_msg = LogMsgCB; + callbacks.fn_memory_access = MemAccessCB; + callbacks.fn_packet_data_sink = 0; + callbacks.fn_packet_mon = 0; +} + + /* End of File ocsd_c_api_custom_obj.cpp */ diff --git a/decoder/source/c_api/ocsd_c_api_custom_obj.h b/decoder/source/c_api/ocsd_c_api_custom_obj.h index ec8cc03..27b19f7 100644 --- a/decoder/source/c_api/ocsd_c_api_custom_obj.h +++ b/decoder/source/c_api/ocsd_c_api_custom_obj.h @@ -99,9 +99,9 @@ private: class CustomDecoderWrapper : public TraceComponent, public ITrcDataIn { public: - CustomDecoderWrapper(const ocsd_extern_dcd_inst_t &dcd_inst, const std::string &name, const int instID); + CustomDecoderWrapper(); virtual ~CustomDecoderWrapper(); - const ocsd_extern_dcd_inst_t *getDecoderInstInfo() const { return &m_decoder_inst; } + ocsd_extern_dcd_inst_t *getDecoderInstInfo() { return &m_decoder_inst; }
virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op, const ocsd_trc_index_t index, @@ -109,20 +109,48 @@ public: const uint8_t *pDataBlock, uint32_t *numBytesProcessed);
+ void attachGenElemI(ITrcGenElemIn *pIF) { m_pGenElemIn = pIF; }; + void attachInstrDecI(IInstrDecode *pIF) { m_pIInstrDec = pIF; }; + void attchMemAccI(ITargetMemAccess *pIF) { m_pMemAccessor = pIF; }; + + void updateNameFromDcdInst(); + + static void SetCallbacks(ocsd_extern_dcd_cb_fns &callbacks); + +private: // declare the callback functions as friend functions. - friend ocsd_datapath_resp_t GenElemOpCB( const void *cb_context, + friend ocsd_datapath_resp_t GenElemOpCB( const void *lib_context, const ocsd_trc_index_t index_sop, const uint8_t trc_chan_id, const ocsd_generic_trace_elem *elem);
-private: - ITrcGenElemIn *m_pGenElemIn; //!< generic element sink interface - output from decdoer. - ITraceErrorLog *m_pErrorLog; //!< error log interface - IInstrDecode *m_pIInstrDec; //!< arm instruction decode interface. - ITargetMemAccess *m_pMemAccessor; + friend void LogErrorCB( const void *lib_context, + const ocsd_err_severity_t filter_level, + const ocsd_err_t code, + const ocsd_trc_index_t idx, + const uint8_t chan_id, + const char *pMsg); + + friend void LogMsgCB(const void *lib_context, + const ocsd_err_severity_t filter_level, + const char *msg); + + friend ocsd_err_t DecodeArmInstCB(const void *lib_context, ocsd_instr_info *instr_info); + + friend ocsd_err_t MemAccessCB(const void *lib_context, + const ocsd_vaddr_t address, + const uint8_t cs_trace_id, + const ocsd_mem_space_acc_t mem_space, + uint32_t *num_bytes, + uint8_t *p_buffer);
private: - ocsd_extern_dcd_inst_t m_decoder_inst; + ITrcGenElemIn *m_pGenElemIn; //!< generic element sink interface - output from decoder fed to common sink. + IInstrDecode *m_pIInstrDec; //!< arm instruction decode interface - decoder may want to use this. + ITargetMemAccess *m_pMemAccessor; //!< system memory accessor insterface - decoder may want to use this. + + ocsd_extern_dcd_inst_t m_decoder_inst; + };
/**** Decoder configuration wrapper - implements CSConfig base class interface ***/ diff --git a/decoder/source/trc_component.cpp b/decoder/source/trc_component.cpp index 3c201f8..47200a1 100644 --- a/decoder/source/trc_component.cpp +++ b/decoder/source/trc_component.cpp @@ -101,6 +101,18 @@ void TraceComponent::LogError(const ocsdError &Error) } }
+void TraceComponent::LogMessage(const ocsd_err_severity_t filter_level, const std::string &msg) +{ + if ((m_errLogHandle != OCSD_INVALID_HANDLE) && + isLoggingErrorLevel(filter_level)) + { + // ensure we have not disabled the attachPt + if (m_error_logger.first()) + m_error_logger.first()->LogMessage(this->m_errLogHandle, filter_level, msg); + } + +} + void TraceComponent::do_attach_notify(const int num_attached) { if(num_attached) @@ -134,5 +146,4 @@ ocsd_err_t TraceComponent::setComponentOpMode(uint32_t op_flags) return OCSD_OK; }
- /* End of File trc_component.cpp */