Adds callback handling for the packet monitor and packet processor sink interfaces for the custom decoder objects.
Adds "custom packet to string" function.
Adds C-API generic trace element initialisation function.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/c_api/ocsd_c_api_custom.h | 3 + decoder/include/c_api/opencsd_c_api.h | 6 ++ decoder/include/common/ocsd_lib_dcd_register.h | 5 ++ decoder/source/c_api/ocsd_c_api.cpp | 27 +++++++-- decoder/source/c_api/ocsd_c_api_custom_obj.cpp | 82 ++++++++++++++++++++++---- decoder/source/c_api/ocsd_c_api_custom_obj.h | 25 ++++++-- decoder/source/c_api/ocsd_c_api_obj.h | 51 ++++++++++++++++ decoder/source/ocsd_lib_dcd_register.cpp | 16 +++-- 8 files changed, 193 insertions(+), 22 deletions(-)
diff --git a/decoder/include/c_api/ocsd_c_api_custom.h b/decoder/include/c_api/ocsd_c_api_custom.h index 0594acd..7d396ca 100644 --- a/decoder/include/c_api/ocsd_c_api_custom.h +++ b/decoder/include/c_api/ocsd_c_api_custom.h @@ -140,6 +140,9 @@ typedef struct _ocsd_extern_dcd_fact { ocsd_trace_protocol_t protocol_id; /**< protocol ID assigned during registration. */ } ocsd_extern_dcd_fact_t;
+ +ocsd_err_t ocsd_cust_protocol_to_str(const ocsd_trace_protocol_t pkt_protocol, const void *trc_pkt, char *buffer, const int buflen); + #endif // ARM_OCSD_C_API_CUSTOM_H_INCLUDED
/* End of File ocsd_c_api_custom.h */ diff --git a/decoder/include/c_api/opencsd_c_api.h b/decoder/include/c_api/opencsd_c_api.h index 66927a7..adb3609 100644 --- a/decoder/include/c_api/opencsd_c_api.h +++ b/decoder/include/c_api/opencsd_c_api.h @@ -378,6 +378,12 @@ OCSD_C_API ocsd_err_t ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol, con */ OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, char *buffer, const int buffer_size);
+ +/*! + * Init a generic element with type, clearing any flags etc. + */ +OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type); + /** @}*/
/** register a custom decoder with the library */ diff --git a/decoder/include/common/ocsd_lib_dcd_register.h b/decoder/include/common/ocsd_lib_dcd_register.h index 15dfc03..efb2d21 100644 --- a/decoder/include/common/ocsd_lib_dcd_register.h +++ b/decoder/include/common/ocsd_lib_dcd_register.h @@ -79,6 +79,11 @@ private:
std::map<const ocsd_trace_protocol_t, IDecoderMngr *> m_typed_decoder_mngrs; //!< map linking decoder managers to protocol type ID
+ // cache last found by type to speed up repeated quries on same object. + IDecoderMngr *m_pLastTypedDecoderMngr; //!< last manager we found by type + + + // singleton pattern - need just one of these in the library - ensure all default constructors are private. OcsdLibDcdRegister(); OcsdLibDcdRegister(OcsdLibDcdRegister const &) {}; diff --git a/decoder/source/c_api/ocsd_c_api.cpp b/decoder/source/c_api/ocsd_c_api.cpp index dbb7049..da3e557 100644 --- a/decoder/source/c_api/ocsd_c_api.cpp +++ b/decoder/source/c_api/ocsd_c_api.cpp @@ -304,7 +304,10 @@ OCSD_C_API ocsd_err_t ocsd_pkt_str(const ocsd_trace_protocol_t pkt_protocol, con break;
default: - err = OCSD_ERR_NO_PROTOCOL; + if ((pkt_protocol >= OCSD_PROTOCOL_CUSTOM_0) && (pkt_protocol < OCSD_PROTOCOL_END)) + err = ocsd_cust_protocol_to_str(pkt_protocol, p_pkt, buffer, buffer_size); + else + err = OCSD_ERR_NO_PROTOCOL; break; }
@@ -331,7 +334,6 @@ OCSD_C_API ocsd_err_t ocsd_gen_elem_str(const ocsd_generic_trace_elem *p_pkt, ch return err; }
- /*** Decode tree -- memory accessor control */
OCSD_C_API ocsd_err_t ocsd_dt_add_binfile_mem_acc(const dcd_tree_handle_t handle, const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const char *filepath) @@ -397,6 +399,13 @@ OCSD_C_API void ocsd_tl_log_mapped_mem_ranges(const dcd_tree_handle_t handle) } }
+OCSD_C_API void ocsd_gen_elem_init(ocsd_generic_trace_elem *p_pkt, const ocsd_gen_trc_elem_t elem_type) +{ + p_pkt->elem_type = elem_type; + p_pkt->flag_bits = 0; + p_pkt->ptr_extended_data = 0; +} + /*******************************************************************************/ /* C API local fns */ /*******************************************************************************/ @@ -424,7 +433,12 @@ static ocsd_err_t ocsd_create_pkt_sink_cb(ocsd_trace_protocol_t protocol, FnDef break;
default: - err = OCSD_ERR_NO_PROTOCOL; + if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END)) + { + *ppCBObj = new (std::nothrow) PktCBObj<void>(pPktInFn, p_context); + } + else + err = OCSD_ERR_NO_PROTOCOL; break; }
@@ -458,7 +472,12 @@ static ocsd_err_t ocsd_create_pkt_mon_cb(ocsd_trace_protocol_t protocol, FnDefPk break;
default: - err = OCSD_ERR_NO_PROTOCOL; + if ((protocol >= OCSD_PROTOCOL_CUSTOM_0) && (protocol < OCSD_PROTOCOL_END)) + { + *ppCBObj = new (std::nothrow) PktMonCBObj<void>(pPktInFn, p_context); + } + else + err = OCSD_ERR_NO_PROTOCOL; break; }
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 283fad2..a8d5aea 100644 --- a/decoder/source/c_api/ocsd_c_api_custom_obj.cpp +++ b/decoder/source/c_api/ocsd_c_api_custom_obj.cpp @@ -88,6 +88,21 @@ OCSD_C_API ocsd_err_t ocsd_deregister_decoders() return OCSD_OK; }
+ + +ocsd_err_t ocsd_cust_protocol_to_str(const ocsd_trace_protocol_t pkt_protocol, const void *trc_pkt, char *buffer, const int buflen) +{ + OcsdLibDcdRegister *pRegister = OcsdLibDcdRegister::getDecoderRegister(); + IDecoderMngr *p_mngr = 0; + if (pRegister->getDecoderMngrByType(pkt_protocol, &p_mngr) == OCSD_OK) + { + CustomDcdMngrWrapper *pWrapper = static_cast<CustomDcdMngrWrapper *>(p_mngr); + pWrapper->pktToString(trc_pkt, buffer, buflen); + return OCSD_OK; + } + return OCSD_ERR_NO_PROTOCOL; +} + /***************** Decode Manager Wrapper *****************************/
CustomDcdMngrWrapper::CustomDcdMngrWrapper() @@ -217,7 +232,7 @@ 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); + pDecoder->attachMemAccI(pMemAccessor); return OCSD_OK; }
@@ -236,7 +251,14 @@ ocsd_err_t CustomDcdMngrWrapper::attachPktMonitor(TraceComponent *pComponent, IT CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent); if(pDecoder == 0) return OCSD_ERR_INVALID_PARAM_TYPE; - // TBD: + IPktRawDataMon<void> *pIF = 0; + if (pPktRawDataMon) + { + pIF = dynamic_cast<IPktRawDataMon<void> *>(pPktRawDataMon); + if (!pIF) + return OCSD_ERR_INVALID_PARAM_TYPE; + } + pDecoder->attachPtkMonI(pIF); return OCSD_OK; }
@@ -255,13 +277,14 @@ ocsd_err_t CustomDcdMngrWrapper::attachPktSink(TraceComponent *pComponent, ITrcT return OCSD_OK; }
-void CustomDcdMngrWrapper::pktToString(void *pkt, char *pStrBuffer, int bufSize) +void CustomDcdMngrWrapper::pktToString(const void *pkt, char *pStrBuffer, int bufSize) { - if(m_dcd_fact.pktToString) - m_dcd_fact.pktToString(pkt,pStrBuffer,bufSize); + if (m_dcd_fact.pktToString) + m_dcd_fact.pktToString(pkt, pStrBuffer, bufSize); + else + snprintf(pStrBuffer, bufSize, "CUSTOM_PKT[]: print unsupported; protocol(%d).",m_dcd_fact.protocol_id); }
- /************************** Decoder instance wrapper **************************************/
/* callback functions */ @@ -311,11 +334,37 @@ ocsd_err_t MemAccessCB(const void *lib_context, return OCSD_ERR_INVALID_PARAM_VAL; }
+void PktMonCB(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) +{ + if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktMon) + ((CustomDecoderWrapper *)lib_context)->m_pPktMon->RawPacketDataMon(op, index_sop, pkt, size, p_data); +} + +ocsd_datapath_resp_t PktDataSinkCB(const void *lib_context, + const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *pkt) +{ + ocsd_datapath_resp_t resp = OCSD_RESP_CONT; + if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktIn) + resp = ((CustomDecoderWrapper *)lib_context)->m_pPktIn->PacketDataIn(op, index_sop, pkt); + return resp; +} + + + /** decoder instance object */ CustomDecoderWrapper::CustomDecoderWrapper() : TraceComponent("extern_wrapper"), m_pGenElemIn(0), m_pIInstrDec(0), - m_pMemAccessor(0) + m_pMemAccessor(0), + m_pPktMon(0), + m_pPktIn(0) { }
@@ -339,6 +388,20 @@ ocsd_datapath_resp_t CustomDecoderWrapper::TraceDataIn( const ocsd_datapath_op_t return OCSD_RESP_FATAL_NOT_INIT; }
+void CustomDecoderWrapper::attachPtkMonI(IPktRawDataMon<void>* pIF) +{ + m_pPktMon = pIF; + int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0); + m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags); +} + +void CustomDecoderWrapper::attachPtkSinkI(IPktDataIn<void>* pIF) +{ + m_pPktIn = pIF; + int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0); + m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags); +} + void CustomDecoderWrapper::updateNameFromDcdInst() { // create a unique component name from the decoder name + cs-id. @@ -356,9 +419,8 @@ void CustomDecoderWrapper::SetCallbacks(ocsd_extern_dcd_cb_fns & callbacks) 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; + callbacks.fn_packet_data_sink = PktDataSinkCB; + callbacks.fn_packet_mon = PktMonCB; }
- /* 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 27b19f7..25b212c 100644 --- a/decoder/source/c_api/ocsd_c_api_custom_obj.h +++ b/decoder/source/c_api/ocsd_c_api_custom_obj.h @@ -88,7 +88,8 @@ public: // create configuration from data structure virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct);
- void pktToString(void *pkt, char *pStrBuffer, int bufSize); +// custom packet to string interface. + void pktToString(const void *pkt, char *pStrBuffer, int bufSize);
private:
@@ -111,7 +112,10 @@ public:
void attachGenElemI(ITrcGenElemIn *pIF) { m_pGenElemIn = pIF; }; void attachInstrDecI(IInstrDecode *pIF) { m_pIInstrDec = pIF; }; - void attchMemAccI(ITargetMemAccess *pIF) { m_pMemAccessor = pIF; }; + void attachMemAccI(ITargetMemAccess *pIF) { m_pMemAccessor = pIF; }; + + void attachPtkMonI(IPktRawDataMon<void> *pIF); + void attachPtkSinkI(IPktDataIn<void> *pIF);
void updateNameFromDcdInst();
@@ -144,13 +148,26 @@ private: uint32_t *num_bytes, uint8_t *p_buffer);
+ friend void PktMonCB(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); + + friend ocsd_datapath_resp_t PktDataSinkCB(const void *lib_context, + const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *pkt); + private: 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. + IPktRawDataMon<void> *m_pPktMon; //!< interface to packet monitor (full or packet only decode). + IPktDataIn<void> *m_pPktIn; //!< interface to packet sink (decode packets only).
- ocsd_extern_dcd_inst_t m_decoder_inst; - + ocsd_extern_dcd_inst_t m_decoder_inst; };
/**** Decoder configuration wrapper - implements CSConfig base class interface ***/ diff --git a/decoder/source/c_api/ocsd_c_api_obj.h b/decoder/source/c_api/ocsd_c_api_obj.h index e375784..617aa5c 100644 --- a/decoder/source/c_api/ocsd_c_api_obj.h +++ b/decoder/source/c_api/ocsd_c_api_obj.h @@ -63,6 +63,31 @@ private: const void *m_p_context; };
+// void specialisation for custom decoders that pass packets as const void * pointers +template<> +class PktCBObj<void> : public IPktDataIn<void> +{ +public: + PktCBObj(FnDefPktDataIn pCBFunc, const void *p_context) + { + m_c_api_cb_fn = pCBFunc; + m_p_context = p_context; + }; + + virtual ~PktCBObj() {}; + + virtual ocsd_datapath_resp_t PacketDataIn(const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *p_packet_in) + { + return m_c_api_cb_fn(m_p_context, op, index_sop, p_packet_in); + }; + +private: + FnDefPktDataIn m_c_api_cb_fn; + const void *m_p_context; +}; +
template<class TrcPkt> class PktMonCBObj : public IPktRawDataMon<TrcPkt> @@ -93,6 +118,32 @@ private: const void *m_p_context; };
+// void specialisation for custom decoders that pass packets as const void * pointers +template<> +class PktMonCBObj<void> : public IPktRawDataMon<void> +{ +public: + PktMonCBObj(FnDefPktDataMon pCBFunc, const void *p_context) + { + m_c_api_cb_fn = pCBFunc; + m_p_context = p_context; + }; + + virtual ~PktMonCBObj() {}; + virtual void RawPacketDataMon(const ocsd_datapath_op_t op, + const ocsd_trc_index_t index_sop, + const void *p_packet_in, + const uint32_t size, + const uint8_t *p_data) + { + m_c_api_cb_fn(m_p_context, op, index_sop, p_packet_in, size, p_data); + }; + +private: + FnDefPktDataMon m_c_api_cb_fn; + const void *m_p_context; +}; + #endif // ARM_OCSD_C_API_OBJ_H_INCLUDED
/* End of File ocsd_c_api_obj.h */ diff --git a/decoder/source/ocsd_lib_dcd_register.cpp b/decoder/source/ocsd_lib_dcd_register.cpp index bc562cc..650b532 100644 --- a/decoder/source/ocsd_lib_dcd_register.cpp +++ b/decoder/source/ocsd_lib_dcd_register.cpp @@ -80,12 +80,14 @@ void OcsdLibDcdRegister::releaseLastCustomProtocolID() OcsdLibDcdRegister::OcsdLibDcdRegister() { m_iter = m_decoder_mngrs.begin(); + m_pLastTypedDecoderMngr = 0; }
OcsdLibDcdRegister::~OcsdLibDcdRegister() { m_decoder_mngrs.clear(); m_typed_decoder_mngrs.clear(); + m_pLastTypedDecoderMngr = 0; }
@@ -166,10 +168,16 @@ const ocsd_err_t OcsdLibDcdRegister::getDecoderMngrByType(const ocsd_trace_proto if(!m_b_registeredBuiltins) return OCSD_ERR_MEM; } - std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType); - if(iter != m_typed_decoder_mngrs.end()) - return OCSD_ERR_DCDREG_NAME_UNKNOWN; - *p_decoder_mngr = iter->second; + + if (m_pLastTypedDecoderMngr && (m_pLastTypedDecoderMngr->getProtocolType() == decoderType)) + *p_decoder_mngr = m_pLastTypedDecoderMngr; + else + { + std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType); + if (iter != m_typed_decoder_mngrs.end()) + return OCSD_ERR_DCDREG_NAME_UNKNOWN; + *p_decoder_mngr = m_pLastTypedDecoderMngr = iter->second; + } return OCSD_OK; }