2 * \file ocsd_c_api_custom_obj.cpp
5 * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
35 /* pull in the C++ decode library */
38 #include "opencsd/c_api/opencsd_c_api.h"
39 #include "ocsd_c_api_custom_obj.h"
40 #include "common/ocsd_lib_dcd_register.h"
42 /***************** C-API functions ********************************/
44 /** register a custom decoder with the library */
45 OCSD_C_API ocsd_err_t ocsd_register_custom_decoder(const char *name, ocsd_extern_dcd_fact_t *p_dcd_fact)
47 ocsd_err_t err = OCSD_OK;
48 OcsdLibDcdRegister *pRegister = OcsdLibDcdRegister::getDecoderRegister();
50 // check not already registered
51 if(pRegister->isRegisteredDecoder(name))
52 return OCSD_ERR_DCDREG_NAME_REPEAT;
54 // validate the factory interface structure
55 if((p_dcd_fact->createDecoder == 0) ||
56 (p_dcd_fact->destroyDecoder == 0) ||
57 (p_dcd_fact->csidFromConfig == 0)
59 return OCSD_ERR_INVALID_PARAM_VAL;
62 CustomDcdMngrWrapper *pWrapper = new (std::nothrow) CustomDcdMngrWrapper();
66 p_dcd_fact->protocol_id = OcsdLibDcdRegister::getNextCustomProtocolID();
67 if(p_dcd_fact->protocol_id < OCSD_PROTOCOL_END)
69 // fill out the wrapper and register it
70 pWrapper->setAPIDcdFact(p_dcd_fact);
71 err = pRegister->registerDecoderTypeByName(name,pWrapper);
73 OcsdLibDcdRegister::releaseLastCustomProtocolID();
76 err = OCSD_ERR_DCDREG_TOOMANY; // too many decoders
84 OCSD_C_API ocsd_err_t ocsd_deregister_decoders()
86 // destroys all builtin and custom decoders & library registration object.
87 OcsdLibDcdRegister::deregisterAllDecoders();
91 OCSD_C_API ocsd_err_t ocsd_cust_protocol_to_str(const ocsd_trace_protocol_t pkt_protocol, const void *trc_pkt, char *buffer, const int buflen)
93 OcsdLibDcdRegister *pRegister = OcsdLibDcdRegister::getDecoderRegister();
94 IDecoderMngr *p_mngr = 0;
95 if (OCSD_PROTOCOL_IS_CUSTOM(pkt_protocol) && (pRegister->getDecoderMngrByType(pkt_protocol, &p_mngr) == OCSD_OK))
97 CustomDcdMngrWrapper *pWrapper = static_cast<CustomDcdMngrWrapper *>(p_mngr);
98 pWrapper->pktToString(trc_pkt, buffer, buflen);
101 return OCSD_ERR_NO_PROTOCOL;
104 /***************** Decode Manager Wrapper *****************************/
106 CustomDcdMngrWrapper::CustomDcdMngrWrapper()
108 m_dcd_fact.protocol_id = OCSD_PROTOCOL_END;
112 // set the C-API decoder factory interface
113 void CustomDcdMngrWrapper::setAPIDcdFact(ocsd_extern_dcd_fact_t *p_dcd_fact)
115 m_dcd_fact = *p_dcd_fact;
118 // create and destroy decoders
119 ocsd_err_t CustomDcdMngrWrapper::createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **ppComponent)
121 ocsd_err_t err = OCSD_OK;
122 if(m_dcd_fact.protocol_id == OCSD_PROTOCOL_END)
123 return OCSD_ERR_NOT_INIT;
125 CustomDecoderWrapper *pComp = new (std::nothrow) CustomDecoderWrapper();
126 *ppComponent = pComp;
130 ocsd_extern_dcd_cb_fns lib_callbacks;
131 CustomDecoderWrapper::SetCallbacks(lib_callbacks);
132 lib_callbacks.lib_context = pComp;
133 lib_callbacks.packetCBFlags = 0;
135 ocsd_extern_dcd_inst_t *pDecodeInst = pComp->getDecoderInstInfo();
137 err = m_dcd_fact.createDecoder( create_flags,
138 ((CustomConfigWrapper *)p_config)->getConfig(),
144 // validate the decoder
145 if ((pDecodeInst->fn_data_in == 0) ||
146 (pDecodeInst->fn_update_pkt_mon == 0) ||
147 (pDecodeInst->cs_id == 0) ||
148 (pDecodeInst->decoder_handle == 0) ||
149 (pDecodeInst->p_decoder_name == 0)
152 err = OCSD_ERR_INVALID_PARAM_VAL;
159 pComp->updateNameFromDcdInst();
163 ocsd_err_t CustomDcdMngrWrapper::destroyDecoder(TraceComponent *pComponent)
165 CustomDecoderWrapper *pCustWrap = dynamic_cast<CustomDecoderWrapper *>(pComponent);
166 if(m_dcd_fact.protocol_id != OCSD_PROTOCOL_END)
167 m_dcd_fact.destroyDecoder(pCustWrap->getDecoderInstInfo()->decoder_handle);
172 const ocsd_trace_protocol_t CustomDcdMngrWrapper::getProtocolType() const
174 return m_dcd_fact.protocol_id;
177 ocsd_err_t CustomDcdMngrWrapper::createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct)
179 ocsd_err_t err = OCSD_OK;
180 CustomConfigWrapper *pConfig = new (std::nothrow) CustomConfigWrapper(pDataStruct);
184 if(m_dcd_fact.csidFromConfig == 0)
185 return OCSD_ERR_NOT_INIT;
188 err = m_dcd_fact.csidFromConfig(pDataStruct,&csid);
191 pConfig->setCSID(csid);
192 *pConfigBase = pConfig;
197 ocsd_err_t CustomDcdMngrWrapper::getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn)
199 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
201 return OCSD_ERR_INVALID_PARAM_TYPE;
203 *ppDataIn = pDecoder;
207 // component connections
209 ocsd_err_t CustomDcdMngrWrapper::attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog)
211 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
213 return OCSD_ERR_INVALID_PARAM_TYPE;
214 pDecoder->getErrorLogAttachPt()->replace_first(pIErrorLog);
219 ocsd_err_t CustomDcdMngrWrapper::attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec)
221 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
223 return OCSD_ERR_INVALID_PARAM_TYPE;
224 pDecoder->attachInstrDecI(pIInstrDec);
228 ocsd_err_t CustomDcdMngrWrapper::attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor)
230 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
232 return OCSD_ERR_INVALID_PARAM_TYPE;
233 pDecoder->attachMemAccI(pMemAccessor);
237 ocsd_err_t CustomDcdMngrWrapper::attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink)
239 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
241 return OCSD_ERR_INVALID_PARAM_TYPE;
242 pDecoder->attachGenElemI(pOutSink);
246 // pkt processor only
247 ocsd_err_t CustomDcdMngrWrapper::attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon)
249 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
251 return OCSD_ERR_INVALID_PARAM_TYPE;
252 IPktRawDataMon<void> *pIF = 0;
255 pIF = dynamic_cast<IPktRawDataMon<void> *>(pPktRawDataMon);
257 return OCSD_ERR_INVALID_PARAM_TYPE;
259 pDecoder->attachPtkMonI(pIF);
263 ocsd_err_t CustomDcdMngrWrapper::attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer)
265 // indexers for external custom will also be external and custom.
266 return OCSD_ERR_DCD_INTERFACE_UNUSED;
269 ocsd_err_t CustomDcdMngrWrapper::attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink)
271 CustomDecoderWrapper *pDecoder = dynamic_cast<CustomDecoderWrapper *>(pComponent);
273 return OCSD_ERR_INVALID_PARAM_TYPE;
274 IPktDataIn<void> *pIF = 0;
277 pIF = dynamic_cast<IPktDataIn<void> *>(pPktDataInSink);
279 return OCSD_ERR_INVALID_PARAM_TYPE;
281 pDecoder->attachPtkSinkI(pIF);
285 void CustomDcdMngrWrapper::pktToString(const void *pkt, char *pStrBuffer, int bufSize)
287 if (m_dcd_fact.pktToString)
288 m_dcd_fact.pktToString(pkt, pStrBuffer, bufSize);
290 snprintf(pStrBuffer, bufSize, "CUSTOM_PKT[]: print unsupported; protocol(%d).",m_dcd_fact.protocol_id);
293 /************************** Decoder instance wrapper **************************************/
295 /* callback functions */
296 ocsd_datapath_resp_t GenElemOpCB( const void *lib_context,
297 const ocsd_trc_index_t index_sop,
298 const uint8_t trc_chan_id,
299 const ocsd_generic_trace_elem *elem)
301 if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn)
302 return ((CustomDecoderWrapper *)lib_context)->m_pGenElemIn->TraceElemIn(index_sop,trc_chan_id,*(OcsdTraceElement *)elem);
303 return OCSD_RESP_FATAL_NOT_INIT;
306 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)
311 ((CustomDecoderWrapper *)lib_context)->LogError(ocsdError(filter_level, code, idx, chan_id, std::string(pMsg)));
313 ((CustomDecoderWrapper *)lib_context)->LogError(ocsdError(filter_level, code, idx, chan_id));
317 void LogMsgCB(const void *lib_context, const ocsd_err_severity_t filter_level, const char *msg)
319 if (lib_context && msg)
320 ((CustomDecoderWrapper *)lib_context)->LogMessage(filter_level, std::string(msg));
323 ocsd_err_t DecodeArmInstCB(const void *lib_context, ocsd_instr_info *instr_info)
325 if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec)
326 return ((CustomDecoderWrapper *)lib_context)->m_pIInstrDec->DecodeInstruction(instr_info);
327 return OCSD_ERR_ATTACH_INVALID_PARAM;
330 ocsd_err_t MemAccessCB(const void *lib_context,
331 const ocsd_vaddr_t address,
332 const uint8_t cs_trace_id,
333 const ocsd_mem_space_acc_t mem_space,
337 if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor)
338 return ((CustomDecoderWrapper *)lib_context)->m_pMemAccessor->ReadTargetMemory(address, cs_trace_id, mem_space, num_bytes, p_buffer);
339 return OCSD_ERR_INVALID_PARAM_VAL;
342 void PktMonCB(const void *lib_context,
343 const ocsd_datapath_op_t op,
344 const ocsd_trc_index_t index_sop,
347 const uint8_t *p_data)
349 if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktMon)
350 ((CustomDecoderWrapper *)lib_context)->m_pPktMon->RawPacketDataMon(op, index_sop, pkt, size, p_data);
353 ocsd_datapath_resp_t PktDataSinkCB(const void *lib_context,
354 const ocsd_datapath_op_t op,
355 const ocsd_trc_index_t index_sop,
358 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
359 if (lib_context && ((CustomDecoderWrapper *)lib_context)->m_pPktIn)
360 resp = ((CustomDecoderWrapper *)lib_context)->m_pPktIn->PacketDataIn(op, index_sop, pkt);
366 /** decoder instance object */
367 CustomDecoderWrapper::CustomDecoderWrapper() : TraceComponent("extern_wrapper"),
376 CustomDecoderWrapper::~CustomDecoderWrapper()
380 ocsd_datapath_resp_t CustomDecoderWrapper::TraceDataIn( const ocsd_datapath_op_t op,
381 const ocsd_trc_index_t index,
382 const uint32_t dataBlockSize,
383 const uint8_t *pDataBlock,
384 uint32_t *numBytesProcessed)
386 if(m_decoder_inst.fn_data_in)
387 return m_decoder_inst.fn_data_in( m_decoder_inst.decoder_handle,
393 return OCSD_RESP_FATAL_NOT_INIT;
396 void CustomDecoderWrapper::attachPtkMonI(IPktRawDataMon<void>* pIF)
399 int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0);
400 m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags);
403 void CustomDecoderWrapper::attachPtkSinkI(IPktDataIn<void>* pIF)
406 int flags = (m_pPktMon ? OCSD_CUST_DCD_PKT_CB_USE_MON : 0) | (m_pPktIn ? OCSD_CUST_DCD_PKT_CB_USE_SINK : 0);
407 m_decoder_inst.fn_update_pkt_mon(m_decoder_inst.decoder_handle, flags);
410 void CustomDecoderWrapper::updateNameFromDcdInst()
412 // create a unique component name from the decoder name + cs-id.
413 std::string name_combined = m_decoder_inst.p_decoder_name;
415 sprintf(num_buffer, "_%04d", m_decoder_inst.cs_id);
416 name_combined += (std::string)num_buffer;
417 setComponentName(name_combined);
420 void CustomDecoderWrapper::SetCallbacks(ocsd_extern_dcd_cb_fns & callbacks)
422 callbacks.fn_arm_instruction_decode = DecodeArmInstCB;
423 callbacks.fn_gen_elem_out = GenElemOpCB;
424 callbacks.fn_log_error = LogErrorCB;
425 callbacks.fn_log_msg = LogMsgCB;
426 callbacks.fn_memory_access = MemAccessCB;
427 callbacks.fn_packet_data_sink = PktDataSinkCB;
428 callbacks.fn_packet_mon = PktMonCB;
431 /* End of File ocsd_c_api_custom_obj.cpp */