summaryrefslogtreecommitdiffstats
path: root/decoder/include/common
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:24:57 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:24:57 +0000
commit070852d8604cece0c31f28ff3eb8d21d9ba415fb (patch)
tree9097175a6a5b8b7e37af9a96269ac0b61a0189cd /decoder/include/common
parentInitial commit. (diff)
downloadlibopencsd-upstream.tar.xz
libopencsd-upstream.zip
Adding upstream version 1.3.3.upstream/1.3.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decoder/include/common')
-rw-r--r--decoder/include/common/comp_attach_notifier_i.h63
-rw-r--r--decoder/include/common/comp_attach_pt_t.h240
-rw-r--r--decoder/include/common/ocsd_code_follower.h237
-rw-r--r--decoder/include/common/ocsd_dcd_mngr.h445
-rw-r--r--decoder/include/common/ocsd_dcd_mngr_i.h98
-rw-r--r--decoder/include/common/ocsd_dcd_tree.h453
-rw-r--r--decoder/include/common/ocsd_dcd_tree_elem.h112
-rw-r--r--decoder/include/common/ocsd_error.h127
-rw-r--r--decoder/include/common/ocsd_error_logger.h89
-rw-r--r--decoder/include/common/ocsd_gen_elem_list.h153
-rw-r--r--decoder/include/common/ocsd_gen_elem_stack.h109
-rw-r--r--decoder/include/common/ocsd_lib_dcd_register.h131
-rw-r--r--decoder/include/common/ocsd_msg_logger.h87
-rw-r--r--decoder/include/common/ocsd_pe_context.h116
-rw-r--r--decoder/include/common/ocsd_version.h46
-rw-r--r--decoder/include/common/trc_component.h149
-rw-r--r--decoder/include/common/trc_core_arch_map.h77
-rw-r--r--decoder/include/common/trc_cs_config.h62
-rw-r--r--decoder/include/common/trc_frame_deformatter.h104
-rw-r--r--decoder/include/common/trc_gen_elem.h228
-rw-r--r--decoder/include/common/trc_pkt_decode_base.h317
-rw-r--r--decoder/include/common/trc_pkt_elem_base.h49
-rw-r--r--decoder/include/common/trc_pkt_proc_base.h456
-rw-r--r--decoder/include/common/trc_printable_elem.h91
-rw-r--r--decoder/include/common/trc_raw_buffer.h96
-rw-r--r--decoder/include/common/trc_ret_stack.h114
26 files changed, 4249 insertions, 0 deletions
diff --git a/decoder/include/common/comp_attach_notifier_i.h b/decoder/include/common/comp_attach_notifier_i.h
new file mode 100644
index 0000000..e0062ef
--- /dev/null
+++ b/decoder/include/common/comp_attach_notifier_i.h
@@ -0,0 +1,63 @@
+/*!
+ * \file comp_attach_notifier_i.h
+ * \brief OpenCSD : Component attach point notifier interface.
+ *
+ * \copyright Copyright (c) 2015, 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_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
+#define ARM_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
+
+/*!
+ * @class IComponentAttachNotifier
+ * @addtogroup ocsd_infrastructure
+ * @brief Notification interface for attachment.
+ *
+ * Interface to the componentAttachPt classes that allow notification on component
+ * connect and disconnect.
+ */
+class IComponentAttachNotifier {
+public:
+ IComponentAttachNotifier() {}; /**< Default interface constructor */
+ virtual ~IComponentAttachNotifier() {}; /**< Default interface destructor */
+
+ /*!
+ * Callback called by the componentAttachPt() classes when a component is attached
+ * to or detached from the attach point.
+ *
+ * @param num_attached : number of remaining components attached to the point after the
+ * operation that triggered the notification.
+ */
+ virtual void attachNotify(const int num_attached) = 0;
+};
+
+#endif // ARM_COMP_ATTACH_NOTIFIER_I_H_INCLUDED
+
+/* End of File comp_attach_notifier_i.h */
diff --git a/decoder/include/common/comp_attach_pt_t.h b/decoder/include/common/comp_attach_pt_t.h
new file mode 100644
index 0000000..71f4c84
--- /dev/null
+++ b/decoder/include/common/comp_attach_pt_t.h
@@ -0,0 +1,240 @@
+/*!
+ * \file comp_attach_pt_t.h
+ * \brief OpenCSD : Component attachment point interface class.
+ *
+ * \copyright Copyright (c) 2015, 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_COMP_ATTACH_PT_T_H_INCLUDED
+#define ARM_COMP_ATTACH_PT_T_H_INCLUDED
+
+#include <vector>
+#include "opencsd/ocsd_if_types.h"
+
+/** @defgroup ocsd_infrastructure OpenCSD Library : Library Component Infrastructure
+
+ @brief Classes providing library infrastructure and auxilary functionality
+@{*/
+
+#include "comp_attach_notifier_i.h"
+
+/*!
+ * @class componentAttachPt
+ * @brief Single component interface pointer attachment point.
+ *
+ * This is a class template to standardise the connections between decode components.
+ *
+ * An attachment point connects a component interface pointer to the component providing the
+ * attachment point.
+ *
+ * This attachment point implementation allows a single interface to be connected.
+ *
+ */
+template <class T>
+class componentAttachPt {
+public:
+ componentAttachPt(); /**< Default constructor */
+ virtual ~componentAttachPt(); /**< Default destructor */
+
+ /*!
+ * Attach an interface of type T to the attachment point.
+ *
+ * @param component : interface to attach.
+ *
+ * @return ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_TOO_MANY if too many connections.
+ */
+ virtual ocsd_err_t attach(T* component);
+
+ /*!
+ * Detach component from the attachment point.
+ *
+ * @param component : Component to detach.
+ *
+ * @return virtual ocsd_err_t : OCSD_OK if successful, OCSD_ERR_ATTACH_COMP_NOT_FOUND if no match to component.
+ */
+ virtual ocsd_err_t detach(T* component);
+
+
+ // detach current first if anything attached, connect supplied pointer, remain unattached if pointer 0
+ virtual ocsd_err_t replace_first(T* component);
+
+ /*!
+ * Detach all components.
+ */
+ virtual void detach_all();
+
+ /*!
+ * Return the current (first) attached interface pointer.
+ * Will return 0 if nothing attached or the attachment point is disabled.
+ *
+ * @return T* : Current Interface pointer of type T or 0.
+ */
+ virtual T* first();
+
+ /*!
+ * Return the next attached interface.
+ * The componentAttachPt base implmentation will always return 0 as only a single attachment is possible
+ *
+ * @return T* : Always returns 0.
+ */
+ virtual T* next();
+
+ /*!
+ * Returns the number of interface pointers attached to this attachment point.
+ *
+ * @return int : number of component interfaces attached.
+ */
+ virtual int num_attached();
+
+ /*!
+ * Attach a notifier interface to the attachment point. Will call back on this interface whenever
+ * a component is attached or detached.
+ *
+ * @param *notifier : pointer to the IComponentAttachNotifier interface.
+ */
+ void set_notifier(IComponentAttachNotifier *notifier);
+
+ /* enable state does not affect attach / detach, but can be used to filter access to interfaces */
+ const bool enabled() const; /**< return the enabled flag. */
+ void set_enabled(const bool enable);
+
+
+ /*!
+ * Check to see if any attachements. Will return attach state independent of enable state.
+ *
+ * @return const bool : true if attachment.
+ */
+ const bool hasAttached() const { return m_hasAttached; };
+
+
+ /*!
+ * Return both the attachment and enabled state.
+ *
+ * @return const bool : true if both has attachment and is enabled.
+ */
+ const bool hasAttachedAndEnabled() const { return m_hasAttached && m_enabled; };
+
+protected:
+ bool m_enabled; /**< Flag to indicate if the attachment point is enabled. */
+ bool m_hasAttached; /**< Flag indicating at least one attached interface */
+ IComponentAttachNotifier *m_notifier; /**< Optional attachement notifier interface. */
+ T *m_comp; /**< pointer to the single attached interface */
+};
+
+
+
+template<class T> componentAttachPt<T>::componentAttachPt()
+{
+ m_comp = 0;
+ m_notifier = 0;
+ m_enabled = true;
+ m_hasAttached = false;
+}
+
+template<class T> componentAttachPt<T>::~componentAttachPt()
+{
+ detach_all();
+}
+
+
+template<class T> ocsd_err_t componentAttachPt<T>::attach(T* component)
+{
+ if(m_comp != 0)
+ return OCSD_ERR_ATTACH_TOO_MANY;
+ m_comp = component;
+ if(m_notifier) m_notifier->attachNotify(1);
+ m_hasAttached = true;
+ return OCSD_OK;
+}
+
+template<class T> ocsd_err_t componentAttachPt<T>::replace_first(T* component)
+{
+ if(m_hasAttached)
+ detach(m_comp);
+
+ if(component == 0)
+ return OCSD_OK;
+
+ return attach(component);
+}
+
+template<class T> ocsd_err_t componentAttachPt<T>::detach(T* component)
+{
+ if(m_comp != component)
+ return OCSD_ERR_ATTACH_COMP_NOT_FOUND;
+ m_comp = 0;
+ m_hasAttached = false;
+ if(m_notifier) m_notifier->attachNotify(0);
+ return OCSD_OK;
+}
+
+template<class T> T* componentAttachPt<T>::first()
+{
+ return (m_enabled) ? m_comp : 0;
+}
+
+template<class T> T* componentAttachPt<T>::next()
+{
+ return 0;
+}
+
+template<class T> int componentAttachPt<T>::num_attached()
+{
+ return ((m_comp != 0) ? 1 : 0);
+}
+
+template<class T> void componentAttachPt<T>::detach_all()
+{
+ m_comp = 0;
+ m_hasAttached = false;
+ if(m_notifier) m_notifier->attachNotify(0);
+}
+
+template<class T> void componentAttachPt<T>::set_notifier(IComponentAttachNotifier *notifier)
+{
+ m_notifier = notifier;
+}
+
+template<class T> const bool componentAttachPt<T>::enabled() const
+{
+ return m_enabled;
+}
+
+template<class T> void componentAttachPt<T>::set_enabled(const bool enable)
+{
+ m_enabled = enable;
+}
+
+
+/** @}*/
+
+#endif // ARM_COMP_ATTACH_PT_T_H_INCLUDED
+
+/* End of File comp_attach_pt_t.h */
diff --git a/decoder/include/common/ocsd_code_follower.h b/decoder/include/common/ocsd_code_follower.h
new file mode 100644
index 0000000..b024aa0
--- /dev/null
+++ b/decoder/include/common/ocsd_code_follower.h
@@ -0,0 +1,237 @@
+/*
+ * \file ocsd_code_follower.h
+ * \brief OpenCSD : Code follower for instruction trace decode
+ *
+ * \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_CODE_FOLLOWER_H_INCLUDED
+#define ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+#include "opencsd/trc_pkt_types.h"
+#include "comp_attach_pt_t.h"
+#include "interfaces/trc_tgt_mem_access_i.h"
+#include "interfaces/trc_instr_decode_i.h"
+
+/*!
+ * @class OcsdCodeFollower
+ * @brief The code follower looks for waypoints or addresses.
+ *
+ * Code follower used to determine the trace ranges for Atom or other waypoint
+ * elements. Uses memory accessor and I decoder to follow the code path.
+ *
+ */
+class OcsdCodeFollower
+{
+public:
+ OcsdCodeFollower();
+ ~OcsdCodeFollower();
+
+//*********** setup API
+ void initInterfaces(componentAttachPt<ITargetMemAccess> *pMemAccess, componentAttachPt<IInstrDecode> *pIDecode);
+
+// set information for decode operation - static or occasionally changing settings
+// per decode values are passed as parameters into the decode API calls.
+ void setArchProfile(const ocsd_arch_profile_t profile); //!< core profile
+ void setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule); //!< memory space to use for access (filtered by S/NS, EL etc).
+ void setMemSpaceCSID(const uint8_t csid); //!< memory spaces might be partitioned by CSID
+ void setISA(const ocsd_isa isa); //!< set the ISA for the decode.
+ void setDSBDMBasWP(); //!< DSB and DMB can be treated as WP in some archs.
+
+//********** code following API
+
+ // standard WP search - for program flow trace
+ //ocsd_err_t followToAtomWP(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
+
+ // PTM exception code may require follow to an address
+ //ocsd_err_t followToAddress(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A, const ocsd_vaddr_t addrMatch);
+
+ // single instruction atom format such as ETMv3
+ ocsd_err_t followSingleAtom(const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
+
+ // follow N instructions
+ // ocsd_err_t followNInstructions(idec_res_t &op_result) // ETMv4 Q elements
+
+//*********************** results API
+ const ocsd_vaddr_t getRangeSt() const; //!< inclusive start address of decoded range (value passed in)
+ const ocsd_vaddr_t getRangeEn() const; //!< exclusive end address of decoded range (first instruction _not_ executed / potential next instruction).
+ const bool hasRange() const; //!< we have a valid range executed (may be false if nacc).
+
+ const bool hasNextAddr() const; //!< we have calulated the next address - otherwise this is needed from trace packets.
+ const ocsd_vaddr_t getNextAddr() const; //!< next address - valid if hasNextAddr() true.
+
+ // information on last instruction executed in range.
+ const ocsd_instr_type getInstrType() const; //!< last instruction type
+ const ocsd_instr_subtype getInstrSubType() const; //!< last instruction sub-type
+ const bool isCondInstr() const; //!< is a conditional instruction
+ const bool isLink() const; //!< is a link (branch with link etc)
+ const bool ISAChanged() const; //!< next ISA different from input ISA.
+ const ocsd_isa nextISA() const; //!< ISA for next instruction
+ const uint8_t getInstrSize() const; //!< Get the last instruction size.
+
+ // information on error conditions
+ const bool isNacc() const; //!< true if Memory Not Accessible (nacc) error occurred
+ void clearNacc(); //!< clear the nacc error flag
+ const ocsd_vaddr_t getNaccAddr() const; //!< get the nacc error address.
+
+private:
+ bool initFollowerState(); //!< clear all the o/p data and flags, check init valid.
+
+ ocsd_err_t decodeSingleOpCode(); //!< decode single opcode address from current m_inst_info packet
+
+ ocsd_instr_info m_instr_info;
+
+ ocsd_vaddr_t m_st_range_addr; //!< start of excuted range - inclusive address.
+ ocsd_vaddr_t m_en_range_addr; //!< end of executed range - exclusive address.
+ ocsd_vaddr_t m_next_addr; //!< calcuated next address (could be eo range of branch address, not set for indirect branches)
+ bool m_b_next_valid; //!< true if next address valid, false if need address from trace packets.
+
+ //! memory space rule to use when accessing memory.
+ ocsd_mem_space_acc_t m_mem_acc_rule;
+ //! memory space csid to use when accessing memory.
+ uint8_t m_mem_space_csid;
+
+ ocsd_vaddr_t m_nacc_address; //!< memory address that was inaccessible - failed read @ start, or during follow operation
+ bool m_b_nacc_err; //!< memory NACC error - required address was unavailable.
+
+ //! pointers to the memory access and i decode interfaces.
+ componentAttachPt<ITargetMemAccess> *m_pMemAccess;
+ componentAttachPt<IInstrDecode> *m_pIDecode;
+
+};
+
+#endif // ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
+
+//*********** setup API
+inline void OcsdCodeFollower::setArchProfile(const ocsd_arch_profile_t profile)
+{
+ m_instr_info.pe_type = profile;
+}
+
+inline void OcsdCodeFollower::setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule)
+{
+ m_mem_acc_rule = mem_acc_rule;
+}
+
+inline void OcsdCodeFollower::setMemSpaceCSID(const uint8_t csid)
+{
+ m_mem_space_csid = csid;
+}
+
+inline void OcsdCodeFollower::setISA(const ocsd_isa isa)
+{
+ m_instr_info.isa = isa;
+}
+
+inline void OcsdCodeFollower::setDSBDMBasWP()
+{
+ m_instr_info.dsb_dmb_waypoints = 1;
+}
+
+//**************************************** results API
+inline const ocsd_vaddr_t OcsdCodeFollower::getRangeSt() const
+{
+ return m_st_range_addr;
+}
+
+inline const ocsd_vaddr_t OcsdCodeFollower::getRangeEn() const
+{
+ return m_en_range_addr;
+}
+
+inline const bool OcsdCodeFollower::hasRange() const
+{
+ return m_st_range_addr < m_en_range_addr;
+}
+
+inline const bool OcsdCodeFollower::hasNextAddr() const
+{
+ return m_b_next_valid;
+}
+
+inline const ocsd_vaddr_t OcsdCodeFollower::getNextAddr() const
+{
+ return m_next_addr;
+}
+
+// information on last instruction executed in range.
+inline const ocsd_instr_type OcsdCodeFollower::getInstrType() const
+{
+ return m_instr_info.type;
+}
+
+inline const ocsd_instr_subtype OcsdCodeFollower::getInstrSubType() const
+{
+ return m_instr_info.sub_type;
+}
+
+inline const uint8_t OcsdCodeFollower::getInstrSize() const
+{
+ return m_instr_info.instr_size;
+}
+
+inline const bool OcsdCodeFollower::isCondInstr() const
+{
+ return (bool)(m_instr_info.is_conditional == 1);
+}
+
+inline const bool OcsdCodeFollower::isLink() const
+{
+ return (bool)(m_instr_info.is_link == 1);
+}
+
+inline const bool OcsdCodeFollower::ISAChanged() const
+{
+ return (bool)(m_instr_info.isa != m_instr_info.next_isa);
+}
+
+inline const ocsd_isa OcsdCodeFollower::nextISA() const
+{
+ return m_instr_info.next_isa;
+}
+
+// information on error conditions
+inline const bool OcsdCodeFollower::isNacc() const
+{
+ return m_b_nacc_err;
+}
+
+inline void OcsdCodeFollower::clearNacc()
+{
+ m_b_nacc_err = false;
+}
+
+inline const ocsd_vaddr_t OcsdCodeFollower::getNaccAddr() const
+{
+ return m_nacc_address;
+}
+
+/* End of File ocsd_code_follower.h */
diff --git a/decoder/include/common/ocsd_dcd_mngr.h b/decoder/include/common/ocsd_dcd_mngr.h
new file mode 100644
index 0000000..34c4ef1
--- /dev/null
+++ b/decoder/include/common/ocsd_dcd_mngr.h
@@ -0,0 +1,445 @@
+/*
+ * \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:
+ const 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) :
+ m_builtInProtocol(builtInProtocol)
+{
+ OcsdLibDcdRegister *pDcdReg = OcsdLibDcdRegister::getDecoderRegister();
+ if(pDcdReg)
+ pDcdReg->registerDecoderTypeByName(decoderTypeName,this);
+}
+
+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 */
diff --git a/decoder/include/common/ocsd_dcd_mngr_i.h b/decoder/include/common/ocsd_dcd_mngr_i.h
new file mode 100644
index 0000000..5ecbe31
--- /dev/null
+++ b/decoder/include/common/ocsd_dcd_mngr_i.h
@@ -0,0 +1,98 @@
+/*
+ * \file ocsd_dcd_mngr_i.h
+ * \brief OpenCSD : Decoder manager interface.
+ *
+ * \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_I_H_INCLUDED
+#define ARM_OCSD_DCD_MNGR_I_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+#include "common/trc_cs_config.h"
+#include "common/trc_component.h"
+
+#include "interfaces/trc_error_log_i.h"
+#include "interfaces/trc_data_raw_in_i.h"
+#include "interfaces/trc_instr_decode_i.h"
+#include "interfaces/trc_tgt_mem_access_i.h"
+#include "interfaces/trc_gen_elem_in_i.h"
+#include "interfaces/trc_abs_typed_base_i.h"
+
+class IDecoderMngr
+{
+public:
+ IDecoderMngr() {};
+ virtual ~IDecoderMngr() {};
+
+// create and destroy decoders
+ virtual ocsd_err_t createDecoder(const int create_flags, const int instID, const CSConfig *p_config, TraceComponent **ppComponent) = 0;
+ virtual ocsd_err_t destroyDecoder(TraceComponent *pComponent) = 0;
+
+ //! Get the built in protocol type ID managed by this instance - extern for custom decoders
+ virtual const ocsd_trace_protocol_t getProtocolType() const = 0;
+
+// connect decoders to other components - (replace current / 0 pointer value to detach );
+// compatible with all decoders
+ //!attach error logger to ptk-processor, or both of pkt processor and pkt decoder pair
+ virtual ocsd_err_t attachErrorLogger(TraceComponent *pComponent, ITraceErrorLog *pIErrorLog) = 0;
+
+// pkt decoder only
+ //! attach instruction decoder to pkt decoder
+ virtual ocsd_err_t attachInstrDecoder(TraceComponent *pComponent, IInstrDecode *pIInstrDec) = 0;
+
+ //! attach memory accessor to pkt decoder
+ virtual ocsd_err_t attachMemAccessor(TraceComponent *pComponent, ITargetMemAccess *pMemAccessor) = 0;
+
+ //! attach generic output interface to pkt decoder
+ virtual ocsd_err_t attachOutputSink(TraceComponent *pComponent, ITrcGenElemIn *pOutSink) = 0;
+
+// pkt processor only
+ //! attach a raw packet monitor to pkt processor (solo pkt processor, or pkt processor part of pair)
+ virtual ocsd_err_t attachPktMonitor(TraceComponent *pComponent, ITrcTypedBase *pPktRawDataMon) = 0;
+
+ //! attach a packet indexer to pkt processor (solo pkt processor, or pkt processor part of pair)
+ virtual ocsd_err_t attachPktIndexer(TraceComponent *pComponent, ITrcTypedBase *pPktIndexer) = 0;
+
+ //! attach a packet data sink to pkt processor output (solo pkt processor only - instead of decoder when pkt processor only created.)
+ virtual ocsd_err_t attachPktSink(TraceComponent *pComponent, ITrcTypedBase *pPktDataInSink) = 0;
+
+// data input connection interface
+ //! get raw data input interface from packet processor
+ virtual ocsd_err_t getDataInputI(TraceComponent *pComponent, ITrcDataIn **ppDataIn) = 0;
+
+// create configuration from data structure
+ virtual ocsd_err_t createConfigFromDataStruct(CSConfig **pConfigBase, const void *pDataStruct) = 0;
+
+};
+
+#endif // ARM_OCSD_DCD_MNGR_I_H_INCLUDED
+
+/* End of File ocsd_dcd_mngr.h */ \ No newline at end of file
diff --git a/decoder/include/common/ocsd_dcd_tree.h b/decoder/include/common/ocsd_dcd_tree.h
new file mode 100644
index 0000000..b1c3dc6
--- /dev/null
+++ b/decoder/include/common/ocsd_dcd_tree.h
@@ -0,0 +1,453 @@
+/*!
+ * \file ocsd_dcd_tree.h
+ * \brief OpenCSD : Trace Decode Tree.
+ *
+ * \copyright Copyright (c) 2015, 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_TREE_H_INCLUDED
+#define ARM_OCSD_DCD_TREE_H_INCLUDED
+
+#include <vector>
+#include <list>
+
+#include "opencsd.h"
+#include "ocsd_dcd_tree_elem.h"
+
+/** @defgroup dcd_tree OpenCSD Library : Trace Decode Tree.
+ @brief Create a multi source decode tree for a single trace capture buffer.
+
+ Use to create a connected set of decoder objects to decode a trace buffer.
+ There may be multiple trace sources within the capture buffer.
+
+@{*/
+
+/*!
+ * @class DecodeTree
+ * @brief Class to manage the decoding of data from a single trace sink .
+ *
+ * Provides functionality to build a tree of decode objects capable of decoding
+ * multiple trace sources within a single trace sink (capture buffer).
+ *
+ */
+class DecodeTree : public ITrcDataIn
+{
+public:
+/** @name Creation and Destruction
+@{*/
+ DecodeTree(); //!< default constructor
+ ~DecodeTree(); //!< default destructor
+
+ /*!
+ * @brief Create a decode tree.
+ * Automatically creates a trace frame deformatter if required and a default error log component.
+ *
+ * @param src_type : Data stream source type, can be CoreSight frame formatted trace, or single demuxed trace data stream,
+ * @param formatterCfgFlags : Configuration flags for trace de-formatter.
+ *
+ * @return DecodeTree * : pointer to the decode tree, 0 if creation failed.
+ */
+ static DecodeTree *CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, const uint32_t formatterCfgFlags);
+
+ /** @brief Destroy a decode tree */
+ static void DestroyDecodeTree(DecodeTree *p_dcd_tree);
+
+/** @}*/
+
+
+/** @name Error and element Logging
+@{*/
+ /** @brief The library default error logger */
+ static ocsdDefaultErrorLogger* getDefaultErrorLogger() { return &s_error_logger; };
+
+ /** the current error logging interface in use */
+ static ITraceErrorLog *getCurrentErrorLogI() { return s_i_error_logger; };
+
+ /** set an alternate error logging interface. */
+ static void setAlternateErrorLogger(ITraceErrorLog *p_error_logger);
+
+ /** get the list of packet printers for this decode tree */
+ std::vector<ItemPrinter *> &getPrinterList() { return m_printer_list; };
+
+ /** add a protocol packet printer */
+ ocsd_err_t addPacketPrinter(uint8_t CSID, bool bMonitor, ItemPrinter **ppPrinter);
+
+ /** add a raw frame printer */
+ ocsd_err_t addRawFramePrinter(RawFramePrinter **ppPrinter, uint32_t flags);
+
+ /** add a generic element output printer */
+ ocsd_err_t addGenElemPrinter(TrcGenericElementPrinter **ppPrinter);
+
+
+
+/** @}*/
+
+
+/** @name Trace Data Path
+@{*/
+ /** @brief Trace Data input interface (ITrcDataIn)
+
+ Decode tree implements the data in interface : ITrcDataIn .
+ Captured raw trace data is passed into the deformatter and decoders via this method.
+ */
+ virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed);
+
+ /*!
+ * @brief Decoded Trace output.
+ *
+ * Client trace analysis program attaches a generic trace element interface to
+ * receive the output from the trace decode operations.
+ *
+ * @param *i_gen_trace_elem : Pointer to the interface.
+ */
+ void setGenTraceElemOutI(ITrcGenElemIn *i_gen_trace_elem);
+
+ /*! @brief Return the connected generic element interface */
+ ITrcGenElemIn *getGenTraceElemOutI() const { return m_i_gen_elem_out; };
+
+/** @}*/
+
+/** @name Decoder Management
+@{*/
+
+ /*!
+ * Creates a decoder that is registered with the library under the supplied name.
+ * createFlags determine if a full packet processor / packet decoder pair or
+ * packet processor only is created.
+ * Uses the supplied configuration structure.
+ *
+ * @param &decoderName : registered name of decoder
+ * @param createFlags : Decoder creation options.
+ * @param *pConfig : Pointer to a valid configuration structure for the named decoder.
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t createDecoder(const std::string &decoderName, const int createFlags, const CSConfig *pConfig);
+
+ /* */
+ /*!
+ * Remove a decoder / packet processor attached to an Trace ID output on the frame de-mux.
+ *
+ * Once removed another decoder can be created that has a CSConfig using that ID.
+ *
+ * @param CSID : Trace ID to remove.
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t removeDecoder(const uint8_t CSID);
+
+ /*!
+ * Get the stats block for the channel indicated.
+ * Caller must check p_stats_block->version to esure that the block
+ * is filled in a compatible manner.
+ *
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ * @param p_stats_block: block pointer to set to reference the stats block.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if valid block pointer returned,
+ * OCSD_ERR_NOTINIT if decoder does not support stats counting.
+ */
+ ocsd_err_t getDecoderStats(const uint8_t CSID, ocsd_decode_stats_t **p_stats_block);
+
+ /*!
+ * Reset the stats block for the chosens decode channel.
+ * stats block is reset independently of the decoder reset to allow counts across
+ * multiple decode runs.
+ *
+ * @param handle : Handle to decode tree.
+ * @param CSID : Configured CoreSight trace ID for the decoder.
+ *
+ * @return ocsd_err_t : Library error code - OCSD_OK if successful.
+ */
+ ocsd_err_t resetDecoderStats(const uint8_t CSID);
+
+/* get decoder elements currently in use */
+
+ /*!
+ * Find a decode tree element associated with a specific CoreSight trace ID. *
+ */
+ DecodeTreeElement *getDecoderElement(const uint8_t CSID) const;
+ /* iterate decoder elements */
+
+ /*!
+ * Decode tree iteration. Return the first tree element 0 if no elements avaiable.
+ *
+ * @param &elemID : CoreSight Trace ID associated with this element
+ */
+ DecodeTreeElement *getFirstElement(uint8_t &elemID);
+ /*!
+ * Return the next tree element - or 0 if no futher elements avaiable.
+ *
+ * @param &elemID : CoreSight Trace ID associated with this element
+ */
+ DecodeTreeElement *getNextElement(uint8_t &elemID);
+
+/* set key interfaces - attach / replace on any existing tree components */
+
+ /*!
+ * Set an ARM instruction opcode decoder.
+ *
+ * @param *i_instr_decode : Pointer to the interface.
+ */
+ void setInstrDecoder(IInstrDecode *i_instr_decode);
+ /*!
+ * Set a target memory access interface - used to access program image memory for instruction
+ * trace decode.
+ *
+ * @param *i_mem_access : Pointer to the interface.
+ */
+ void setMemAccessI(ITargetMemAccess *i_mem_access);
+
+
+/** @}*/
+
+/** @name Memory Access Mapper
+
+ A memory mapper is used to organise a collection of memory accessor objects that contain the
+ memory images for different areas of traced instruction memory. These areas could be the executed
+ program and a set of loaded .so libraries for example - each of which would have code sections in
+ different memory locations.
+
+ A memory accessor represents a snapshot of an area of memory as it appeared during trace capture,
+ for a given memory space. Memory spaces are described by the ocsd_mem_space_acc_t enum. The most
+ general memory space is OCSD_MEM_SPACE_ANY. This represents memory that can be secure or none-secure,
+ available at any exception level.
+
+ The memory mapper will not allow two accessors to overlap in the same memory space.
+
+ The trace decdoer will access memory with a memory space parameter that represents the current core
+ state - the mapper will find the closest memory space match for the address.
+
+ e.g. if the core is accessing secure EL3, then the most specialised matching space will be accessed.
+ If an EL3 space matches that will be used, otherwise the any secure, and finally _ANY.
+
+ It is no necessary for clients to register memory accessors for all spaces - _ANY will be sufficient
+ in many cases.
+
+
+@{*/
+
+ /* */
+ /*!
+ * This creates a memory mapper within the decode tree.
+ *
+ * @param type : defaults to MEMACC_MAP_GLOBAL (only type available at present)
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t createMemAccMapper(memacc_mapper_t type = MEMACC_MAP_GLOBAL);
+
+ /*!
+ * Get a pointer to the memory mapper. Allows a client to add memory accessors directly to the mapper.
+ * @return TrcMemAccMapper : Pointer to the mapper.
+ */
+ TrcMemAccMapper *getMemAccMapper() const { return m_default_mapper; };
+
+ /*!
+ * Set an external mapper rather than create a mapper in the decode tree.
+ * Setting this will also destroy any internal mapper that was previously created.
+ *
+ * @param pMapper : pointer to the mapper to add.
+ */
+ void setExternMemAccMapper(TrcMemAccMapper * pMapper);
+
+ /*!
+ * Return true if a mapper has been set (internal or external
+ */
+ const bool hasMemAccMapper() const { return (bool)(m_default_mapper != 0); };
+
+ void logMappedRanges(); //!< Log the mapped memory ranges to the default message logger.
+
+/** @}*/
+
+/** @name Memory Accessors
+ A memory accessor represents a snapshot of an area of memory as it appeared during trace capture.
+
+ Memory spaces represent either common global memory, or Secure / none-secure and EL specific spaces.
+
+@{*/
+
+ /*!
+ * Creates a memory accessor for a memory block in the supplied buffer and adds to the current mapper.
+ *
+ * @param address : Start address for the memory block in the memory map.
+ * @param mem_space : Memory space
+ * @param *p_mem_buffer : start of the buffer.
+ * @param mem_length : length of the buffer.
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t addBufferMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const uint8_t *p_mem_buffer, const uint32_t mem_length);
+
+ /*!
+ * Creates a memory accessor for a memory block supplied as a contiguous binary data file, and adds to the current mapper.
+ *
+ * @param address : Start address for the memory block in the memory map.
+ * @param mem_space : Memory space
+ * @param &filepath : Path to the binary data file
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t addBinFileMemAcc(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
+
+ /*!
+ * Creates a memory accessor for a memory block supplied as a one or more memory regions in a binary file.
+ * Region structures are created that describe the memory start address, the offset within the binary file
+ * for that address, and the length of the region. This accessor can be used to point to the code section
+ * in a program file for example.
+ *
+ * @param *region_array : array of valid memory regions in the file.
+ * @param num_regions : number of regions
+ * @param mem_space : Memory space
+ * @param &filepath : Path to the binary data file
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t addBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
+
+
+ /*!
+ * Updates/adds to a memory accessor for a memory block supplied as a one or more memory regions in a binary file.
+ * Region structures are created that describe the memory start address, the offset within the binary file
+ * for that address, and the length of the region. This accessor can be used to point to the code section
+ * in a program file for example.
+ *
+ * @param *region_array : array of valid memory regions in the file.
+ * @param num_regions : number of regions
+ * @param mem_space : Memory space
+ * @param &filepath : Path to the binary data file
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t updateBinFileRegionMemAcc(const ocsd_file_mem_region_t *region_array, const int num_regions, const ocsd_mem_space_acc_t mem_space, const std::string &filepath);
+
+ /*!
+ * This memory accessor allows the client to supply a callback function for the region
+ * defined by the start and end addresses. This can be used to supply a custom memory accessor,
+ * or to directly access memory if the decode is running live on a target system.
+ *
+ * @param st_address : start address of region.
+ * @param en_address : end address of region.
+ * @param mem_space : Memory space
+ * @param p_cb_func : Callback function
+ * @param *p_context : client supplied context information
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t addCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAcc_CB p_cb_func, const void *p_context);
+ ocsd_err_t addCallbackIDMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address, const ocsd_mem_space_acc_t mem_space, Fn_MemAccID_CB p_cb_func, const void *p_context);
+
+ /*!
+ * Remove the memory accessor from the map, that begins at the given address, for the memory space provided.
+ *
+ * @param address : Start address of the memory accessor.
+ * @param mem_space : Memory space for the memory accessor.
+ *
+ * @return ocsd_err_t : Library error code or OCSD_OK if successful.
+ */
+ ocsd_err_t removeMemAccByAddress(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space);
+
+/** @}*/
+
+/** @name CoreSight Trace Frame De-mux
+@{*/
+
+ //! Get the Trace Frame de-mux.
+ TraceFormatterFrameDecoder *getFrameDeformatter() const { return m_frame_deformatter_root; };
+
+
+ /*! @brief ID filtering - sets the output filter on the trace deformatter.
+
+ Only supplied IDs will be decoded.
+
+ No effect if no decoder attached for the ID
+
+ @param ids : Vector of CS Trace IDs
+ */
+ ocsd_err_t setIDFilter(std::vector<uint8_t> &ids); // only supplied IDs will be decoded
+
+ ocsd_err_t clearIDFilter(); //!< remove filter, all IDs will be decoded
+
+/** @}*/
+
+private:
+ bool initialise(const ocsd_dcd_tree_src_t type, uint32_t formatterCfgFlags);
+ const bool usingFormatter() const { return (bool)(m_dcd_tree_type == OCSD_TRC_SRC_FRAME_FORMATTED); };
+ void setSingleRoot(TrcPktProcI *pComp);
+ ocsd_err_t createDecodeElement(const uint8_t CSID);
+ void destroyDecodeElement(const uint8_t CSID);
+ void destroyMemAccMapper();
+ ocsd_err_t initCallbackMemAcc(const ocsd_vaddr_t st_address, const ocsd_vaddr_t en_address,
+ const ocsd_mem_space_acc_t mem_space, void *p_cb_func, bool IDfn, const void *p_context);
+ TrcPktProcI *getPktProcI(const uint8_t CSID);
+
+ ocsd_dcd_tree_src_t m_dcd_tree_type;
+
+ IInstrDecode *m_i_instr_decode;
+ ITargetMemAccess *m_i_mem_access;
+ ITrcGenElemIn *m_i_gen_elem_out; //!< Output interface for generic elements from decoder.
+
+ ITrcDataIn* m_i_decoder_root; /*!< root decoder object interface - either deformatter or single packet processor */
+
+ TraceFormatterFrameDecoder *m_frame_deformatter_root;
+
+ DecodeTreeElement *m_decode_elements[0x80];
+
+ uint8_t m_decode_elem_iter;
+
+ TrcMemAccMapper *m_default_mapper; //!< the mem acc mapper to use
+ bool m_created_mapper; //!< true if created by decode tree object
+
+ std::vector<ItemPrinter *> m_printer_list; //!< list of packet printers.
+
+ /* global error logger - all sources */
+ static ITraceErrorLog *s_i_error_logger;
+ static std::list<DecodeTree *> s_trace_dcd_trees;
+
+ /**! default error logger */
+ static ocsdDefaultErrorLogger s_error_logger;
+
+ /**! default instruction decoder */
+ static TrcIDecode s_instruction_decoder;
+
+ /**! demux stats block */
+ ocsd_demux_stats_t m_demux_stats;
+};
+
+/** @}*/
+
+#endif // ARM_OCSD_DCD_TREE_H_INCLUDED
+
+/* End of File ocsd_dcd_tree.h */
diff --git a/decoder/include/common/ocsd_dcd_tree_elem.h b/decoder/include/common/ocsd_dcd_tree_elem.h
new file mode 100644
index 0000000..2b609fb
--- /dev/null
+++ b/decoder/include/common/ocsd_dcd_tree_elem.h
@@ -0,0 +1,112 @@
+/*!
+ * \file ocsd_dcd_tree_elem.h
+ * \brief OpenCSD : Decode tree element.
+ *
+ * \copyright Copyright (c) 2015, 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_TREE_ELEM_H_INCLUDED
+#define ARM_OCSD_DCD_TREE_ELEM_H_INCLUDED
+
+#include "common/ocsd_dcd_mngr_i.h"
+#include "common/trc_component.h"
+
+/** @addtogroup dcd_tree
+@{*/
+
+/*! @struct _decoder_elements
+ * @brief Decode tree element base structure.
+ *
+ * Element describes the protocol supported for this element and
+ * contains pointers to the decoder manager interface and component handle.
+ */
+typedef struct _decoder_elements
+{
+ std::string dcd_name; //!< Registered name of the decoder
+ TraceComponent *dcd_handle; //!< handle to the decoder object
+ IDecoderMngr *dcd_mngr; //!< pointer to the decoder manager interface for the decodcer
+ ocsd_trace_protocol_t protocol;//!< protocol type
+ bool created; /**< decode tree created this element (destroy it on tree destruction) */
+} decoder_element;
+
+/*!
+ * @class DecodeTreeElement
+ * @brief Decode tree element
+ *
+ * Decoder tree elements are references to individual decoders in the tree.
+ * These allow iteration of all decoders in the tree to perform common operations.
+ *
+ * The DecodeTree contains a list of elements.
+ */
+class DecodeTreeElement : protected decoder_element
+{
+public:
+ DecodeTreeElement();
+ ~DecodeTreeElement() {};
+
+ void SetDecoderElement(const std::string &name, IDecoderMngr *dcdMngr, TraceComponent *pHandle, bool bCreated);
+ void DestroyElem();
+
+ const std::string &getDecoderTypeName() { return dcd_name; };
+ IDecoderMngr *getDecoderMngr() { return dcd_mngr; };
+ ocsd_trace_protocol_t getProtocol() const { return protocol; };
+ TraceComponent *getDecoderHandle() { return dcd_handle; };
+};
+
+inline DecodeTreeElement::DecodeTreeElement()
+{
+ dcd_name = "unknown";
+ dcd_mngr = 0;
+ dcd_handle = 0;
+ protocol = OCSD_PROTOCOL_END;
+ created = false;
+}
+
+inline void DecodeTreeElement::SetDecoderElement(const std::string &name, IDecoderMngr *dcdMngr, TraceComponent *pHandle, bool bCreated)
+{
+ dcd_name = name;
+ dcd_mngr = dcdMngr;
+ dcd_handle = pHandle;
+ protocol = OCSD_PROTOCOL_UNKNOWN;
+ if(dcd_mngr)
+ protocol = dcd_mngr->getProtocolType();
+ created = bCreated;
+}
+
+inline void DecodeTreeElement::DestroyElem()
+{
+ if(created && (dcd_mngr != 0) && (dcd_handle != 0))
+ dcd_mngr->destroyDecoder(dcd_handle);
+}
+
+/** @}*/
+#endif // ARM_OCSD_DCD_TREE_ELEM_H_INCLUDED
+
+/* End of File ocsd_dcd_tree_elem.h */
diff --git a/decoder/include/common/ocsd_error.h b/decoder/include/common/ocsd_error.h
new file mode 100644
index 0000000..7c6ed3a
--- /dev/null
+++ b/decoder/include/common/ocsd_error.h
@@ -0,0 +1,127 @@
+/*!
+ * \file ocsd_error.h
+ * \brief OpenCSD : Library Error class
+ *
+ * \copyright Copyright (c) 2015, 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_ERROR_H_INCLUDED
+#define ARM_OCSD_ERROR_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+#include <string>
+/** @ingroup ocsd_infrastructure
+@{*/
+
+/*!
+ * @class ocsdError
+ *
+ * This class is the error object for the Ocsd.
+ *
+ * Errors are created with a severity (ocsd_err_severity_t) and a standard ocsd_err_t error code.
+ * Errors can optionally be created with a trace index (offset from start of capture buffer), and
+ * trace CoreSight source channel ID.
+ *
+ * A custom error message can be appended to the error.
+ *
+ * The ocsdError class contains a static function to output a formatted string representation of an error.
+ *
+ */
+class ocsdError {
+public:
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code); /**< Default error constructor with severity and error code. */
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx); /**< Constructor with optional trace index. */
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id); /**< Constructor with optional trace index and channel ID. */
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const std::string &msg); /**< Default error constructor with severity and error code - plus message. */
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const std::string &msg); /**< Constructor with optional trace index - plus message. */
+ ocsdError(const ocsd_err_severity_t sev_type, const ocsd_err_t code, const ocsd_trc_index_t idx, const uint8_t chan_id, const std::string &msg); /**< Constructor with optional trace index and channel ID - plus message. */
+
+ ocsdError(const ocsdError *pError); /**< Copy constructor */
+ ocsdError(const ocsdError &Error); /**< Copy constructor */
+ ~ocsdError(); /**< Destructor */
+
+ ocsdError& operator=(const ocsdError *p_err);
+ ocsdError& operator=(const ocsdError &err);
+
+ void setMessage(const std::string &msg) { m_err_message = msg; }; /**< Set custom error message */
+ const std::string &getMessage() const { return m_err_message; }; /**< Get custom error message */
+
+ const ocsd_err_t getErrorCode() const { return m_error_code; }; /**< Get error code. */
+ const ocsd_err_severity_t getErrorSeverity() const { return m_sev; }; /**< Get error severity. */
+ const ocsd_trc_index_t getErrorIndex() const { return m_idx; }; /**< Get trace index associated with the error. */
+ const uint8_t getErrorChanID() const { return m_chan_ID; }; /**< Get the trace source channel ID associated with the error. */
+
+ static const std::string getErrorString(const ocsdError &error); /**< Generate a formatted error string for the supplied error. */
+
+private:
+ static void appendErrorDetails(std::string &errStr, const ocsdError &error); /**< build the error string. */
+ ocsdError(); /**< Make no parameter default constructor inaccessible. */
+
+ ocsd_err_t m_error_code; /**< Error code for this error */
+ ocsd_err_severity_t m_sev; /**< severity for this error */
+ ocsd_trc_index_t m_idx; /**< Trace buffer index associated with this error (optional) */
+ uint8_t m_chan_ID; /**< trace source ID associated with this error (optional) */
+
+ std::string m_err_message; /**< Additional text associated with this error (optional) */
+};
+
+inline ocsdError& ocsdError::operator=(const ocsdError *p_err)
+{
+ this->m_error_code = p_err->getErrorCode();
+ this->m_sev = p_err->getErrorSeverity();
+ this->m_idx = p_err->getErrorIndex();
+ this->m_chan_ID = p_err->getErrorChanID();
+ this->m_err_message = p_err->getMessage();
+ return *this;
+}
+
+inline ocsdError& ocsdError::operator=(const ocsdError &err)
+{
+ return (*this = &err);
+}
+
+/* class to get data path response values as strings */
+class ocsdDataRespStr
+{
+public:
+ ocsdDataRespStr(ocsd_datapath_resp_t type) { m_type = type; }
+ ~ocsdDataRespStr() {};
+
+ const char* getStr();
+private:
+ ocsd_datapath_resp_t m_type;
+};
+
+/** @}*/
+
+#endif // ARM_OCSD_ERROR_H_INCLUDED
+
+/* End of File ocsd_error.h */
diff --git a/decoder/include/common/ocsd_error_logger.h b/decoder/include/common/ocsd_error_logger.h
new file mode 100644
index 0000000..3badd33
--- /dev/null
+++ b/decoder/include/common/ocsd_error_logger.h
@@ -0,0 +1,89 @@
+/*!
+ * \file ocsd_error_logger.h
+ * \brief OpenCSD : Library error logger.
+ *
+ * \copyright Copyright (c) 2015, 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_ERROR_LOGGER_H_INCLUDED
+#define ARM_OCSD_ERROR_LOGGER_H_INCLUDED
+
+#include <string>
+#include <vector>
+//#include <fstream>
+
+#include "interfaces/trc_error_log_i.h"
+#include "ocsd_error.h"
+#include "ocsd_msg_logger.h"
+
+class ocsdDefaultErrorLogger : public ITraceErrorLog
+{
+public:
+ ocsdDefaultErrorLogger();
+ virtual ~ocsdDefaultErrorLogger();
+
+ bool initErrorLogger(const ocsd_err_severity_t verbosity, bool bCreateOutputLogger = false); //!< Initialise the error logger with a severity filter, optionally create an output logger on stderr.
+
+ virtual ocsdMsgLogger *getOutputLogger() { return m_output_logger; };
+ virtual void setOutputLogger(ocsdMsgLogger *pLogger);
+
+ virtual const ocsd_hndl_err_log_t RegisterErrorSource(const std::string &component_name);
+
+ virtual void LogError(const ocsd_hndl_err_log_t handle, const ocsdError *Error);
+ virtual void LogMessage(const ocsd_hndl_err_log_t handle, const ocsd_err_severity_t filter_level, const std::string &msg );
+
+ virtual const ocsd_err_severity_t GetErrorLogVerbosity() const { return m_Verbosity; };
+
+ virtual ocsdError *GetLastError() { return m_lastErr; };
+ virtual ocsdError *GetLastIDError(const uint8_t chan_id)
+ {
+ if(OCSD_IS_VALID_CS_SRC_ID(chan_id))
+ return m_lastErrID[chan_id];
+ return 0;
+ };
+
+private:
+ void CreateErrorObj(ocsdError **ppErr, const ocsdError *p_from);
+
+ ocsdError *m_lastErr;
+ ocsdError *m_lastErrID[0x80];
+
+ ocsd_err_severity_t m_Verbosity;
+
+ ocsdMsgLogger *m_output_logger; // pointer to a standard message output logger;
+ bool m_created_output_logger; // true if this class created it's own logger;
+
+ std::vector<std::string> m_error_sources;
+};
+
+
+#endif // ARM_OCSD_ERROR_LOGGER_H_INCLUDED
+
+/* End of File ocsd_error_logger.h */
diff --git a/decoder/include/common/ocsd_gen_elem_list.h b/decoder/include/common/ocsd_gen_elem_list.h
new file mode 100644
index 0000000..2dab240
--- /dev/null
+++ b/decoder/include/common/ocsd_gen_elem_list.h
@@ -0,0 +1,153 @@
+/*
+ * \file ocsd_gen_elem_list.h
+ * \brief OpenCSD : Generic element output list.
+ *
+ * \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.
+ */
+
+#include <list>
+#include "trc_gen_elem.h"
+#include "comp_attach_pt_t.h"
+#include "interfaces/trc_gen_elem_in_i.h"
+
+/*!
+ * @class OcsdGenElemList
+ * @brief Maintain a list of elements to be output
+ *
+ * Each incoming packet can result in multiple output elements.
+ * These are stacked in this class prior to entering the output phase of processing.
+ *
+ * This should remove some of the requirement on the packet processing to be re-enterant,
+ * simplifying this code.
+ *
+ * Last element(s) on this list can be marked pending to allow for later cancellation.
+ * (This required for cancel element in ETMv3 exeception branch).
+ *
+ * The "list" is actually a ring buffer - maintaining pointers to indicate current valid elements.
+ * This buffer can increase on demand, but will only be released at the end of a decode session.
+ */
+class OcsdGenElemList
+{
+public:
+ OcsdGenElemList();
+ ~OcsdGenElemList();
+
+ void initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf);
+ void initCSID(const uint8_t CSID) { m_CSID = CSID; };
+
+ void reset(); //!< reset the element list.
+
+ OcsdTraceElement *getNextElem(const ocsd_trc_index_t trc_pkt_idx); //!< get next free element on the stack (add one to the output)
+ const int getNumElem() const; //!< return the total number of elements on the stack (inlcuding any pended ones).
+
+ const ocsd_gen_trc_elem_t getElemType(const int entryN) const; //!< get the type for the nth element in the stack (0 indexed)
+
+ void pendLastNElem(int numPend); //!< Last element to be pended prior to cancel/commit decision.
+ void commitAllPendElem(); //!< commit all pended elements.
+ void cancelPendElem(); //!< cancel the last pended element on the stack.
+ const int numPendElem() const; //!< return the number of pended elements.
+
+ /*! Send all of the none pended elements
+ Stop sending when all sent or _CONT response.
+ */
+ ocsd_datapath_resp_t sendElements();
+ const bool elemToSend() const; //!< true if any none-pending elements left to send.
+
+private:
+
+ void growArray();
+ const int getAdjustedIdx(int idxIn) const; //!< get adjusted index into circular buffer.
+
+
+ // list element contains pointer and byte index in trace stream
+ typedef struct _elemPtr {
+ OcsdTraceElement *pElem; //!< pointer to the listed trace element
+ ocsd_trc_index_t trc_pkt_idx; //!< packet index in the trace stream
+ } elemPtr_t;
+
+ elemPtr_t *m_pElemArray; //!< an array of pointers to elements.
+ int m_elemArraySize; //!< number of element pointers in the array
+
+ int m_firstElemIdx; //!< internal index in array of first element in use.
+ int m_numUsed; //!< number of elements in use
+ int m_numPend; //!< internal count of pended elements.
+
+ uint8_t m_CSID;
+
+ componentAttachPt<ITrcGenElemIn> *m_sendIf; //!< element send interface.
+};
+
+inline const int OcsdGenElemList::getAdjustedIdx(int idxIn) const
+{
+ if(idxIn >= m_elemArraySize)
+ idxIn -= m_elemArraySize;
+ return idxIn;
+}
+
+inline const int OcsdGenElemList::getNumElem() const
+{
+ return m_numUsed;
+}
+
+inline const int OcsdGenElemList::numPendElem() const
+{
+ return m_numPend;
+}
+
+inline void OcsdGenElemList::pendLastNElem(int numPend)
+{
+ if(numPend >= getNumElem())
+ m_numPend = numPend;
+}
+
+inline void OcsdGenElemList::commitAllPendElem()
+{
+ m_numPend = 0;
+}
+
+inline void OcsdGenElemList::cancelPendElem()
+{
+ if(m_numPend > 0)
+ {
+ m_numUsed -= m_numPend;
+ }
+}
+
+inline const bool OcsdGenElemList::elemToSend() const
+{
+ return ((getNumElem() - m_numPend) > 0);
+}
+
+inline void OcsdGenElemList::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf)
+{
+ m_sendIf = pGenElemIf;
+}
+
+/* End of File ocsd_gen_elem_list.h */
diff --git a/decoder/include/common/ocsd_gen_elem_stack.h b/decoder/include/common/ocsd_gen_elem_stack.h
new file mode 100644
index 0000000..64c525d
--- /dev/null
+++ b/decoder/include/common/ocsd_gen_elem_stack.h
@@ -0,0 +1,109 @@
+/*
+* \file ocsd_gen_elem_stack.h
+* \brief OpenCSD : Generic element output stack.
+*
+* \copyright Copyright (c) 2020, 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.
+*/
+
+#include "trc_gen_elem.h"
+#include "comp_attach_pt_t.h"
+#include "interfaces/trc_gen_elem_in_i.h"
+
+/* element stack to handle cases where a trace element can generate multiple output packets
+
+ maintains the "current" element, which might be sent independently of this stack, and also
+ ensures that persistent data in the output elements is maintained between elements.
+*/
+class OcsdGenElemStack
+{
+public:
+ OcsdGenElemStack();
+ ~OcsdGenElemStack();
+
+ void initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf);
+ void initCSID(const uint8_t CSID) { m_CSID = CSID; };
+
+ OcsdTraceElement &getCurrElem(); //!< get the current element.
+ ocsd_err_t resetElemStack(); //!< set pointers to base of stack
+ ocsd_err_t addElem(const ocsd_trc_index_t trc_pkt_idx); //!< add elem to stack and set current.
+ void setCurrElemIdx(const ocsd_trc_index_t trc_pkt_idx); //!< packet index for this element
+ ocsd_err_t addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type);
+
+ ocsd_datapath_resp_t sendElements(); //!< send elements on the stack
+ const int numElemToSend() const;
+
+private:
+ typedef struct _elemPtr {
+ OcsdTraceElement *pElem; //!< pointer to the listed trace element
+ ocsd_trc_index_t trc_pkt_idx; //!< packet index in the trace stream
+ } elemPtr_t;
+
+ const bool isInit(); //!< check correctly initialised.
+
+ ocsd_err_t growArray();
+ void copyPersistentData(int src, int dst); //!< copy across persistent state data between elements
+ void resetIndexes(); //!< clear down all indexes - reset or send complete.
+
+ elemPtr_t *m_pElemArray; //!< an array of pointers to elements.
+ int m_elemArraySize; //!< number of element pointers in the array
+
+ int m_elem_to_send; //!< number of live elements in the stack - init to 1.
+ int m_curr_elem_idx; //!< index into the element array.
+ int m_send_elem_idx; //!< next element to send.
+
+ //!< send packet info
+ uint8_t m_CSID;
+ componentAttachPt<ITrcGenElemIn> *m_sendIf; //!< element send interface.
+
+ bool m_is_init;
+};
+
+inline const int OcsdGenElemStack::numElemToSend() const
+{
+ return m_elem_to_send;
+}
+
+inline void OcsdGenElemStack::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf)
+{
+ m_sendIf = pGenElemIf;
+}
+
+inline void OcsdGenElemStack::setCurrElemIdx(const ocsd_trc_index_t trc_pkt_idx)
+{
+ m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx;
+}
+
+inline OcsdTraceElement &OcsdGenElemStack::getCurrElem()
+{
+ return *(m_pElemArray[m_curr_elem_idx].pElem);
+}
+
+
+/* End of File ocsd_gen_elem_stack.h */
diff --git a/decoder/include/common/ocsd_lib_dcd_register.h b/decoder/include/common/ocsd_lib_dcd_register.h
new file mode 100644
index 0000000..6ba4cf8
--- /dev/null
+++ b/decoder/include/common/ocsd_lib_dcd_register.h
@@ -0,0 +1,131 @@
+/*
+ * \file ocsd_lib_dcd_register.h
+ * \brief OpenCSD : Library decoder registration and management.
+ *
+ * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
+ */
+
+#ifndef ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
+#define ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
+
+
+/*
+ * 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.
+ */
+
+#include <map>
+
+#include "opencsd/ocsd_if_types.h"
+#include "common/ocsd_dcd_mngr_i.h"
+
+/*!
+ * @class OcsdLibDcdRegister : Registers decoders with the library
+ *
+ * library decoder register class allows decoders to be registered by name, and the register allows clients to access
+ * the list of names of registerd decoders.
+ *
+ * The decoders in the library are accessed through the decoder manager interface. This provides a set of functions to allow
+ * the creation, manipulation and destruction of registered decoders
+ *
+ */
+class OcsdLibDcdRegister
+{
+public:
+ static OcsdLibDcdRegister *getDecoderRegister();
+
+ static void deregisterAllDecoders(); //!< library cleanup - deregisters decoder managers and destroys the register object.
+ static const ocsd_trace_protocol_t getNextCustomProtocolID();
+ static void releaseLastCustomProtocolID();
+
+ const ocsd_err_t registerDecoderTypeByName(const std::string &name, IDecoderMngr *p_decoder_fact); //!< register a decoder manager interface
+ const ocsd_err_t getDecoderMngrByName(const std::string &name, IDecoderMngr **p_decoder_mngr);
+ const ocsd_err_t getDecoderMngrByType(const ocsd_trace_protocol_t decoderType, IDecoderMngr **p_decoder_mngr);
+
+ const bool isRegisteredDecoder(const std::string &name);
+ const bool getFirstNamedDecoder(std::string &name);
+ const bool getNextNamedDecoder(std::string &name);
+
+ const bool isRegisteredDecoderType(const ocsd_trace_protocol_t decoderType);
+
+private:
+ void registerBuiltInDecoders(); //!< register the list of build in decoder managers on first access of getDecoderMngrByName.
+ void deRegisterCustomDecoders(); //!< delete all custom decoders registered with the library.
+
+ std::map<const std::string, IDecoderMngr *> m_decoder_mngrs; //!< map linking names to decoder manager interfaces.
+ std::map<const std::string, IDecoderMngr *>::const_iterator m_iter; //!< iterator for name search.
+
+ 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 &) {};
+ OcsdLibDcdRegister& operator=(OcsdLibDcdRegister const &){ return *this; };
+ ~OcsdLibDcdRegister();
+
+ static OcsdLibDcdRegister *m_p_libMngr;
+ static bool m_b_registeredBuiltins;
+ static ocsd_trace_protocol_t m_nextCustomProtocolID;
+};
+
+/*!
+ * Typedef of function signature to create a decoder manager.
+ *
+ * @param *name : Registered name of the decoder.
+ */
+typedef IDecoderMngr *(*CreateMngr)(const std::string &name);
+
+/*!
+ * Template function to create a specific decoder manager class object.
+ *
+ * @param &name : Registered name of the decoder.
+ *
+ * @return IDecoderMngr * : pointer to the decoder manager base class interface.
+ */
+template <typename T> IDecoderMngr *createManagerInst(const std::string &name)
+{
+ return new (std::nothrow)T(name);
+}
+
+/*! Structure to contain the information needed to create and register a builtin decoder
+ * manager with the library
+ */
+typedef struct built_in_decoder_info {
+ IDecoderMngr *pMngr; //!< pointer to created decoder manager
+ CreateMngr PFn; //!< function to create the decoder manager.
+ const char *name; //!< registered name of the decoder.
+} built_in_decoder_info_t;
+
+//! Define to use to fill in an array of built_in_decoder_info_t structures.
+#define CREATE_BUILTIN_ENTRY(C,N) { 0, createManagerInst<C>, N }
+
+#endif // ARM_OCSD_LIB_DCD_REGISTER_H_INCLUDED
+
+/* End of File ocsd_lib_dcd_register.h */
diff --git a/decoder/include/common/ocsd_msg_logger.h b/decoder/include/common/ocsd_msg_logger.h
new file mode 100644
index 0000000..d83a022
--- /dev/null
+++ b/decoder/include/common/ocsd_msg_logger.h
@@ -0,0 +1,87 @@
+/*!
+ * \file ocsd_msg_logger.h
+ * \brief OpenCSD : Generic Message logger / printer
+ *
+ * \copyright Copyright (c) 2015, 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_MSG_LOGGER_H_INCLUDED
+#define ARM_OCSD_MSG_LOGGER_H_INCLUDED
+
+#include <string>
+#include <fstream>
+
+class ocsdMsgLogStrOutI
+{
+public:
+ ocsdMsgLogStrOutI() {};
+ virtual ~ocsdMsgLogStrOutI() {};
+
+ virtual void printOutStr(const std::string &outStr) = 0;
+};
+
+class ocsdMsgLogger
+{
+public:
+ ocsdMsgLogger();
+ ~ocsdMsgLogger();
+
+ /** Typedef enum providing flags to define the output methods for the message logger.
+ */
+ typedef enum {
+ OUT_NONE = 0, /*!< No output from logger*/
+ OUT_FILE = 1, /*!< Output to file */
+ OUT_STDERR = 2, /*!< Output to stderr */
+ OUT_STDOUT = 4, /*!< Output to stdout */
+ OUT_STR_CB = 8 /*!< output to external string callback interface */
+ } output_dest;
+
+ void setLogOpts(int logOpts); //!< set the output logging flags.
+ const int getLogOpts() const //! get the current output logging flags value.
+ { return m_outFlags; };
+
+ void setLogFileName(const char *fileName); //!< Set the output log filename, and enable logging to file.
+ void setStrOutFn(ocsdMsgLogStrOutI *p_IstrOut); //!< Set the output log string callback and enable logging to callback.
+
+ void LogMsg(const std::string &msg); //!< Log a message to the current set output channels.
+
+ const bool isLogging() const; //!< true if logging active
+
+private:
+ int m_outFlags;
+
+ std::string m_logFileName;
+ std::fstream m_out_file;
+ ocsdMsgLogStrOutI *m_pOutStrI;
+};
+
+#endif // ARM_OCSD_MSG_LOGGER_H_INCLUDED
+
+/* End of File ocsd_msg_logger.h */
diff --git a/decoder/include/common/ocsd_pe_context.h b/decoder/include/common/ocsd_pe_context.h
new file mode 100644
index 0000000..797881c
--- /dev/null
+++ b/decoder/include/common/ocsd_pe_context.h
@@ -0,0 +1,116 @@
+/*
+ * \file ocsd_pe_context.h
+ * \brief OpenCSD : Wrapper class for PE context
+ *
+ * \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_PE_CONTEXT_H_INCLUDED
+#define ARM_OCSD_PE_CONTEXT_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+
+/*! @class OcsdPeContext
+ * @brief Handler for the ocsd_pe_context structure.
+ *
+ * Reads and writes structure values, enforcing interaction rules between values
+ * and flags.
+ */
+class OcsdPeContext
+{
+public:
+ OcsdPeContext();
+ OcsdPeContext(const ocsd_pe_context *context);
+ ~OcsdPeContext() {};
+
+ OcsdPeContext &operator =(const OcsdPeContext &ctxt);
+ OcsdPeContext &operator =(const ocsd_pe_context *context);
+
+ void resetCtxt();
+
+ void setSecLevel(const ocsd_sec_level sl) { m_context.security_level = sl; };
+ void setEL(const ocsd_ex_level el) { m_context.exception_level = el; m_context.el_valid = el > ocsd_EL_unknown ? 1 : 0; };
+ void setCtxtID(const uint32_t id) { m_context.context_id = id; m_context.ctxt_id_valid = 1; };
+ void setVMID(const uint32_t id) { m_context.vmid = id; m_context.vmid_valid = 1; };
+ void set64bit(const bool is64bit) { m_context.bits64 = is64bit ? 1 : 0; };
+
+ const ocsd_sec_level getSecLevel() const { return m_context.security_level; };
+ const ocsd_ex_level getEL() const { return m_context.exception_level; };
+ const bool ELvalid() const { return (m_context.el_valid == 1); };
+ const uint32_t getCtxtID() const { return (m_context.ctxt_id_valid == 1) ? m_context.context_id : 0; };
+ const bool ctxtIDvalid() const { return (m_context.ctxt_id_valid == 1); };
+ const uint32_t getVMID() const { return (m_context.vmid_valid == 1) ? m_context.vmid : 0; };
+ const bool VMIDvalid() const { return (m_context.vmid_valid == 1); };
+
+ // only allow an immutable copy of the structure out to C-API land.
+ operator const ocsd_pe_context &() const { return m_context; };
+
+private:
+ ocsd_pe_context m_context;
+};
+
+inline OcsdPeContext::OcsdPeContext()
+{
+ resetCtxt();
+}
+
+inline OcsdPeContext::OcsdPeContext(const ocsd_pe_context *context)
+{
+ m_context = *context;
+}
+
+inline void OcsdPeContext::resetCtxt()
+{
+ // initialise the context
+ m_context.bits64 = 0;
+ m_context.context_id = 0;
+ m_context.ctxt_id_valid = 0;
+ m_context.el_valid = 0;
+ m_context.exception_level = ocsd_EL_unknown;
+ m_context.security_level = ocsd_sec_secure;
+ m_context.vmid = 0;
+ m_context.vmid_valid = 0;
+}
+
+inline OcsdPeContext & OcsdPeContext::operator =(const OcsdPeContext &ctxt)
+{
+ m_context = ctxt;
+ return *this;
+}
+
+inline OcsdPeContext & OcsdPeContext::operator =(const ocsd_pe_context *context)
+{
+ m_context = *context;
+ return *this;
+}
+
+
+#endif // ARM_OCSD_PE_CONTEXT_H_INCLUDED
+
+/* End of File ocsd_pe_context.h */
diff --git a/decoder/include/common/ocsd_version.h b/decoder/include/common/ocsd_version.h
new file mode 100644
index 0000000..b68c85f
--- /dev/null
+++ b/decoder/include/common/ocsd_version.h
@@ -0,0 +1,46 @@
+/*
+ * \file ocsd_version.h
+ * \brief OpenCSD :
+ *
+ * \copyright Copyright (c) 2015, 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_VERSION_H_INCLUDED
+#define ARM_OCSD_VERSION_H_INCLUDED
+
+class ocsdVersion
+{
+public:
+ static const uint32_t vers_num();
+ static const char *vers_str();
+};
+
+#endif // ARM_OCSD_VERSION_H_INCLUDED
+
+/* End of File ocsd_version.h */
diff --git a/decoder/include/common/trc_component.h b/decoder/include/common/trc_component.h
new file mode 100644
index 0000000..6096ac7
--- /dev/null
+++ b/decoder/include/common/trc_component.h
@@ -0,0 +1,149 @@
+/*!
+ * \file trc_component.h
+ * \brief OpenCSD : Base trace decode component.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_COMPONENT_H_INCLUDED
+#define ARM_TRC_COMPONENT_H_INCLUDED
+
+#include <string>
+#include "comp_attach_pt_t.h"
+#include "interfaces/trc_error_log_i.h"
+#include "ocsd_error.h"
+
+class errLogAttachMonitor;
+
+/** @addtogroup ocsd_infrastructure
+@{*/
+
+/*!
+ * @class TraceComponent
+ * @brief Base class for all decode components in the library.
+ *
+ * Provides error logging attachment point and component type and instance naming
+ * Interface for handling of component operational mode.
+ */
+class TraceComponent
+{
+public:
+ TraceComponent(const std::string &name);
+ TraceComponent(const std::string &name, int instIDNum);
+ virtual ~TraceComponent(); /**< Default Destructor */
+
+ const std::string &getComponentName() const { return m_name; };
+ void setComponentName(const std::string &name) { m_name = name; };
+
+ /** Error logger attachment point.*/
+ componentAttachPt<ITraceErrorLog> *getErrorLogAttachPt() { return &m_error_logger; };
+
+ /*!
+ * Set the operational mode for the component.
+ * This controls the way the component behaves under error conditions etc.
+ * These flags may also control output formats or data.
+ * Operation mode flags used are component specific and defined by derived classes.
+ *
+ * @param op_flags : Set of operation mode flags.
+ *
+ * @return ocsd_err_t : OCSD_OK if flags supported by this component, error if unsuppored
+ */
+ ocsd_err_t setComponentOpMode(uint32_t op_flags);
+
+ /*!
+ * Return the current operational mode flags values
+ *
+ * @return const uint32_t : Op Mode flags.
+ */
+ const uint32_t getComponentOpMode() const { return m_op_flags; };
+
+ /*!
+ * Get the supported operational mode flags for this component.
+ * Base class will return nothing supported.
+ * Derived class must set the value correctly for the component.
+ *
+ * @return const uint32_t : Supported flags values.
+ */
+ const uint32_t getSupportedOpModes() const { return m_supported_op_flags; };
+
+ /*!
+ * Set associated trace component - used by generic code to track
+ * packet processor / packet decoder pairs.
+ *
+ * @param *assocComp : pointer to the associated component
+ */
+ void setAssocComponent(TraceComponent *assocComp) { m_assocComp = assocComp; };
+
+
+ /*!
+ * get associated trace component pointer
+ *
+ * @return TraceComponent *: associated component.
+ */
+ TraceComponent *getAssocComponent() { return m_assocComp; };
+
+ /*!
+ * Log a message at the default severity on this component.
+ */
+ void LogDefMessage(const std::string &msg)
+ {
+ LogMessage(m_errVerbosity, msg);
+ }
+
+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();
+
+ void do_attach_notify(const int num_attached);
+ void Init(const std::string &name);
+
+ uint32_t m_op_flags; //!< current component operational mode flags.
+ uint32_t m_supported_op_flags; //!< supported component operational mode flags - derived class to intialise.
+
+private:
+ componentAttachPt<ITraceErrorLog> m_error_logger;
+ ocsd_hndl_err_log_t m_errLogHandle;
+ ocsd_err_severity_t m_errVerbosity;
+ errLogAttachMonitor *m_pErrAttachMon;
+
+ std::string m_name;
+
+ TraceComponent *m_assocComp; //!< associated component -> if this is a pkt decoder, associated pkt processor.
+};
+/** @}*/
+#endif // ARM_TRC_COMPONENT_H_INCLUDED
+
+/* End of File trc_component.h */
diff --git a/decoder/include/common/trc_core_arch_map.h b/decoder/include/common/trc_core_arch_map.h
new file mode 100644
index 0000000..aa976c3
--- /dev/null
+++ b/decoder/include/common/trc_core_arch_map.h
@@ -0,0 +1,77 @@
+/*!
+ * \file trc_core_arch_map.h
+ * \brief OpenCSD : Map core name strings to architecture profile constants.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_CORE_ARCH_MAP_H_INCLUDED
+#define ARM_TRC_CORE_ARCH_MAP_H_INCLUDED
+
+#include <map>
+#include <string>
+#include "opencsd/ocsd_if_types.h"
+
+/** @class CoreArchProfileMap
+ *
+ * @brief Map core / arch name to profile for decoder.
+ *
+ * Helper class for library clients to map core or architecture version names onto
+ * a profile / arch version pair suitable for use with the decode library.
+ *
+ * Valid core names are:-
+ * - Cortex-Axx : where xx = 5,7,12,15,17,32,35,53,55,57,65,72,73,75,76,77;
+ * - Cortex-Rxx : where xx = 5,7,8,52;
+ * - Cortex-Mxx : where xx = 0,0+,3,4,23,33;
+ *
+ * Valid architecture profile names are:-
+ * - ARMv7-A, ARMv7-R, ARMv7-M;
+ * - ARMv8-A, ARMv8.x-A, ARMv8-R, ARMv8-M;
+ * - ARM-AA64, ARM-aa64
+ *
+ */
+class CoreArchProfileMap
+{
+public:
+ CoreArchProfileMap();
+ ~CoreArchProfileMap() {};
+
+ ocsd_arch_profile_t getArchProfile(const std::string &coreName);
+
+private:
+ ocsd_arch_profile_t getPatternMatchCoreName(const std::string &coreName);
+
+ std::map<std::string, ocsd_arch_profile_t> core_profiles;
+ std::map<std::string, ocsd_arch_profile_t> arch_profiles;
+};
+
+#endif // ARM_TRC_CORE_ARCH_MAP_H_INCLUDED
+
+/* End of File trc_core_arch_map.h */
diff --git a/decoder/include/common/trc_cs_config.h b/decoder/include/common/trc_cs_config.h
new file mode 100644
index 0000000..9b2c130
--- /dev/null
+++ b/decoder/include/common/trc_cs_config.h
@@ -0,0 +1,62 @@
+/*
+ * \file trc_cs_config.h
+ * \brief OpenCSD : Trace component config base class.
+ *
+ * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
+ */
+#ifndef ARM_TRC_CS_CONFIG_H_INCLUDED
+#define ARM_TRC_CS_CONFIG_H_INCLUDED
+
+
+/*
+ * 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.
+ */
+
+/** @addtogroup ocsd_protocol_cfg
+@{*/
+
+/*!
+ * @class CSConfig
+ * @brief Base class for configuration data on CoreSight trace component.
+ *
+ * Defines common access functionality, common to all components.
+ * (e.g. trace ID).
+ *
+ */
+class CSConfig
+{
+public:
+ CSConfig() {};
+ virtual ~CSConfig() {};
+
+ virtual const uint8_t getTraceID() const = 0; //!< CoreSight Trace ID for this device.
+};
+
+/** @}*/
+
+#endif // ARM_TRC_CS_CONFIG_H_INCLUDED
+
+/* End of File trc_cs_config.h */ \ No newline at end of file
diff --git a/decoder/include/common/trc_frame_deformatter.h b/decoder/include/common/trc_frame_deformatter.h
new file mode 100644
index 0000000..cb2960f
--- /dev/null
+++ b/decoder/include/common/trc_frame_deformatter.h
@@ -0,0 +1,104 @@
+/*!
+ * \file trc_frame_deformatter.h
+ * \brief OpenCSD : De-format CoreSight formatted trace frame.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_FRAME_DEFORMATTER_H_INCLUDED
+#define ARM_TRC_FRAME_DEFORMATTER_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+
+#include "interfaces/trc_data_raw_in_i.h"
+#include "comp_attach_pt_t.h"
+
+class ITrcRawFrameIn;
+class ITrcDataMixIDIn;
+class ITrcSrcIndexCreator;
+class ITraceErrorLog;
+class TraceFmtDcdImpl;
+
+/** @defgroup ocsd_deformatter OpenCSD Library : Trace Frame Deformatter
+ @brief CoreSight Formatted Trace Frame - deformatting functionality.
+@{*/
+
+class TraceFormatterFrameDecoder : public ITrcDataIn
+{
+public:
+ TraceFormatterFrameDecoder();
+ TraceFormatterFrameDecoder(int instNum);
+ virtual ~TraceFormatterFrameDecoder();
+
+ /* the data input interface from the reader */
+ virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed);
+
+ /* attach a data processor to a stream ID output */
+ componentAttachPt<ITrcDataIn> *getIDStreamAttachPt(uint8_t ID);
+
+ /* attach a data processor to the raw frame output */
+ componentAttachPt<ITrcRawFrameIn> *getTrcRawFrameAttachPt();
+
+ componentAttachPt<ITrcSrcIndexCreator> *getTrcSrcIndexAttachPt();
+
+ componentAttachPt<ITraceErrorLog> *getErrLogAttachPt();
+
+ /* init decoder implementation object */
+ ocsd_err_t Init();
+
+ /* configuration - set operational mode for incoming stream (has FSYNCS etc) */
+ ocsd_err_t Configure(uint32_t cfg_flags);
+ const uint32_t getConfigFlags() const;
+
+ /* enable / disable ID streams - default as all enabled */
+ ocsd_err_t OutputFilterIDs(std::vector<uint8_t> &id_list, bool bEnable);
+ ocsd_err_t OutputFilterAllIDs(bool bEnable);
+
+ /* decode control */
+ ocsd_datapath_resp_t Reset(); /* reset the decode to the start state, drop partial data - propogate to attached components */
+ ocsd_datapath_resp_t Flush(); /* flush existing data if possible, retain state - propogate to attached components */
+
+ /* demux stats */
+ void SetDemuxStatsBlock(ocsd_demux_stats_t *pStatsBlock);
+
+private:
+ TraceFmtDcdImpl *m_pDecoder;
+ int m_instNum;
+
+};
+
+/** @}*/
+
+#endif // ARM_TRC_FRAME_DEFORMATTER_H_INCLUDED
+
+/* End of File trc_frame_deformatter.h */ \ No newline at end of file
diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h
new file mode 100644
index 0000000..25be807
--- /dev/null
+++ b/decoder/include/common/trc_gen_elem.h
@@ -0,0 +1,228 @@
+/*!
+ * \file trc_gen_elem.h
+ * \brief OpenCSD : Decoder Generic trace element output class.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_GEN_ELEM_H_INCLUDED
+#define ARM_TRC_GEN_ELEM_H_INCLUDED
+
+#include "opencsd/trc_gen_elem_types.h"
+#include "trc_printable_elem.h"
+#include "ocsd_pe_context.h"
+
+/** @addtogroup gen_trc_elem
+@{*/
+
+/*!
+ * @class OcsdTraceElement
+ * @brief Generic trace element class
+ *
+ */
+class OcsdTraceElement : public trcPrintableElem, public ocsd_generic_trace_elem
+{
+public:
+ OcsdTraceElement();
+ OcsdTraceElement(ocsd_gen_trc_elem_t type);
+ virtual ~OcsdTraceElement() {};
+
+ void init();
+
+// set elements API
+
+ void setType(const ocsd_gen_trc_elem_t type); //!< set type and init flags
+ void updateType(const ocsd_gen_trc_elem_t type); //!< change type only - no init
+
+ void setContext(const ocsd_pe_context &new_context) { context = new_context; };
+ void setISA(const ocsd_isa isa_update);
+
+ void setCycleCount(const uint32_t cycleCount);
+ void setEvent(const event_t ev_type, const uint16_t number);
+ void setTS(const uint64_t ts, const bool freqChange = false);
+
+ void setExcepMarker() { excep_data_marker = 1; };
+ void setExceptionNum(uint32_t excepNum) { exception_number = excepNum; };
+ void setTraceOnReason(const trace_on_reason_t reason);
+ void setUnSyncEOTReason(const unsync_info_t reason);
+ void setTransactionType(const trace_memtrans_t trans) { mem_trans = trans; };
+
+ void setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr, const int num_instr = 1);
+ void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size);
+ void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
+ void setLastInstrCond(const int is_cond) { this->last_instr_cond = is_cond; };
+
+ void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; };
+ void setExtendedDataPtr(const void *data_ptr);
+
+ void setSyncMarker(const trace_marker_payload_t &marker);
+
+// stringize the element
+
+ virtual void toString(std::string &str) const;
+
+// get elements API
+
+ OcsdTraceElement &operator =(const ocsd_generic_trace_elem* p_elem);
+
+ const ocsd_gen_trc_elem_t getType() const { return elem_type; };
+
+ // return current context
+ const ocsd_pe_context &getContext() const { return context; };
+
+ void copyPersistentData(const OcsdTraceElement &src);
+
+private:
+ void printSWInfoPkt(std::ostringstream &oss) const;
+ void clearPerPktData(); //!< clear flags that indicate validity / have values on a per packet basis
+
+};
+
+inline OcsdTraceElement::OcsdTraceElement(ocsd_gen_trc_elem_t type)
+{
+ elem_type = type;
+}
+
+inline OcsdTraceElement::OcsdTraceElement()
+{
+ elem_type = OCSD_GEN_TRC_ELEM_UNKNOWN;
+}
+
+inline void OcsdTraceElement::setCycleCount(const uint32_t cycleCount)
+{
+ cycle_count = cycleCount;
+ has_cc = 1;
+}
+
+inline void OcsdTraceElement::setEvent(const event_t ev_type, const uint16_t number)
+{
+ trace_event.ev_type = (uint16_t)ev_type;
+ trace_event.ev_number = ev_type == EVENT_NUMBERED ? number : 0;
+}
+
+inline void OcsdTraceElement::setAddrRange(const ocsd_vaddr_t st_addr, const ocsd_vaddr_t en_addr, const int num_instr /* = 1 */)
+{
+ this->st_addr = st_addr;
+ this->en_addr = en_addr;
+ this->num_instr_range = num_instr;
+}
+
+inline void OcsdTraceElement::setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size)
+{
+ last_instr_exec = exec ? 1 : 0;
+ last_instr_sz = size & 0x7;
+ this->last_i_type = last_i_type;
+ this->last_i_subtype = last_i_subtype;
+}
+
+inline void OcsdTraceElement::setType(const ocsd_gen_trc_elem_t type)
+{
+ // set the type and clear down the per element flags
+ elem_type = type;
+
+ clearPerPktData();
+}
+
+inline void OcsdTraceElement::updateType(const ocsd_gen_trc_elem_t type)
+{
+ elem_type = type;
+}
+
+inline void OcsdTraceElement::init()
+{
+ st_addr = en_addr = (ocsd_vaddr_t)-1;
+ isa = ocsd_isa_unknown;
+
+ cycle_count = 0;
+ timestamp = 0;
+
+ context.ctxt_id_valid = 0;
+ context.vmid_valid = 0;
+ context.el_valid = 0;
+
+ last_i_type = OCSD_INSTR_OTHER;
+ last_i_subtype = OCSD_S_INSTR_NONE;
+
+ clearPerPktData();
+}
+
+inline void OcsdTraceElement::clearPerPktData()
+{
+ flag_bits = 0; // bit-field with various flags.
+ exception_number = 0; // union with trace_on_reason / trace_event
+ ptr_extended_data = 0; // extended data pointer
+}
+
+inline void OcsdTraceElement::setTraceOnReason(const trace_on_reason_t reason)
+{
+ trace_on_reason = reason;
+}
+
+inline void OcsdTraceElement::setUnSyncEOTReason(const unsync_info_t reason)
+{
+ unsync_eot_info = reason;
+}
+
+inline void OcsdTraceElement::setISA(const ocsd_isa isa_update)
+{
+ isa = isa_update;
+ if(isa > ocsd_isa_unknown)
+ isa = ocsd_isa_unknown;
+}
+
+inline void OcsdTraceElement::setTS(const uint64_t ts, const bool freqChange /*= false*/)
+{
+ timestamp = ts;
+ cpu_freq_change = freqChange ? 1 : 0;
+ has_ts = 1;
+}
+
+inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr)
+{
+ extended_data = 1;
+ ptr_extended_data = data_ptr;
+}
+
+inline void OcsdTraceElement::setSyncMarker(const trace_marker_payload_t &marker)
+{
+ sync_marker = marker;
+}
+
+// set persistent data between output packets.
+inline void OcsdTraceElement::copyPersistentData(const OcsdTraceElement &src)
+{
+ isa = src.isa;
+ context = src.context;
+}
+
+/** @}*/
+
+#endif // ARM_TRC_GEN_ELEM_H_INCLUDED
+
+/* End of File trc_gen_elem.h */
diff --git a/decoder/include/common/trc_pkt_decode_base.h b/decoder/include/common/trc_pkt_decode_base.h
new file mode 100644
index 0000000..24ea2b0
--- /dev/null
+++ b/decoder/include/common/trc_pkt_decode_base.h
@@ -0,0 +1,317 @@
+/*!
+ * \file trc_pkt_decode_base.h
+ * \brief OpenCSD : Trace Packet decoder base class.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_PKT_DECODE_BASE_H_INCLUDED
+#define ARM_TRC_PKT_DECODE_BASE_H_INCLUDED
+
+#include "trc_component.h"
+#include "comp_attach_pt_t.h"
+
+#include "interfaces/trc_pkt_in_i.h"
+#include "interfaces/trc_gen_elem_in_i.h"
+#include "interfaces/trc_tgt_mem_access_i.h"
+#include "interfaces/trc_instr_decode_i.h"
+
+/** @defgroup ocsd_pkt_decode OpenCSD Library : Packet Decoders.
+
+ @brief Classes providing Protocol Packet Decoding capability.
+
+ Packet decoders convert incoming protocol packets from a packet processor,
+ into generic trace elements to be output to an analysis program.
+
+ Packet decoders can be:-
+ - PE decoders - converting ETM or PTM packets into instruction and data trace elements
+ - SW stimulus decoder - converting STM or ITM packets into software generated trace elements.
+ - Bus decoders - converting HTM packets into bus transaction elements.
+
+@{*/
+
+
+class TrcPktDecodeI : public TraceComponent
+{
+public:
+ TrcPktDecodeI(const char *component_name);
+ TrcPktDecodeI(const char *component_name, int instIDNum);
+ virtual ~TrcPktDecodeI() {};
+
+ componentAttachPt<ITrcGenElemIn> *getTraceElemOutAttachPt() { return &m_trace_elem_out; };
+ componentAttachPt<ITargetMemAccess> *getMemoryAccessAttachPt() { return &m_mem_access; };
+ componentAttachPt<IInstrDecode> *getInstrDecodeAttachPt() { return &m_instr_decode; };
+
+ void setUsesMemAccess(bool bUsesMemaccess) { m_uses_memaccess = bUsesMemaccess; };
+ const bool getUsesMemAccess() const { return m_uses_memaccess; };
+
+ void setUsesIDecode(bool bUsesIDecode) { m_uses_idecode = bUsesIDecode; };
+ const bool getUsesIDecode() const { return m_uses_idecode; };
+
+protected:
+
+ /* implementation packet decoding interface */
+ virtual ocsd_datapath_resp_t processPacket() = 0;
+ virtual ocsd_datapath_resp_t onEOT() = 0;
+ virtual ocsd_datapath_resp_t onReset() = 0;
+ virtual ocsd_datapath_resp_t onFlush() = 0;
+ virtual ocsd_err_t onProtocolConfig() = 0;
+ virtual const uint8_t getCoreSightTraceID() = 0;
+
+ /* init handling */
+ const bool checkInit();
+ /* Called on first init confirmation */
+ virtual void onFirstInitOK() {};
+
+ /* data output */
+ ocsd_datapath_resp_t outputTraceElement(const OcsdTraceElement &elem); // use current index
+ ocsd_datapath_resp_t outputTraceElementIdx(ocsd_trc_index_t idx, const OcsdTraceElement &elem); // use supplied index (where decoder caches elements)
+
+ /* target access */
+ ocsd_err_t accessMemory(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer);
+ ocsd_err_t invalidateMemAccCache();
+
+ /* instruction decode */
+ ocsd_err_t instrDecode(ocsd_instr_info *instr_info);
+
+ componentAttachPt<ITrcGenElemIn> m_trace_elem_out;
+ componentAttachPt<ITargetMemAccess> m_mem_access;
+ componentAttachPt<IInstrDecode> m_instr_decode;
+
+ ocsd_trc_index_t m_index_curr_pkt;
+
+ bool m_decode_init_ok; //!< set true if all attachments in place for decode. (remove checks in main throughput paths)
+ bool m_config_init_ok; //!< set true if config set.
+
+ std::string init_err_msg; //!< error message for init error
+
+ bool m_uses_memaccess;
+ bool m_uses_idecode;
+
+};
+
+inline TrcPktDecodeI::TrcPktDecodeI(const char *component_name) :
+ TraceComponent(component_name),
+ m_index_curr_pkt(0),
+ m_decode_init_ok(false),
+ m_config_init_ok(false),
+ m_uses_memaccess(true),
+ m_uses_idecode(true)
+{
+}
+
+inline TrcPktDecodeI::TrcPktDecodeI(const char *component_name, int instIDNum) :
+ TraceComponent(component_name, instIDNum),
+ m_index_curr_pkt(0),
+ m_decode_init_ok(false),
+ m_config_init_ok(false),
+ m_uses_memaccess(true),
+ m_uses_idecode(true)
+{
+}
+
+inline const bool TrcPktDecodeI::checkInit()
+{
+ if(!m_decode_init_ok)
+ {
+ if(!m_config_init_ok)
+ init_err_msg = "No decoder configuration information";
+ else if(!m_trace_elem_out.hasAttachedAndEnabled())
+ init_err_msg = "No element output interface attached and enabled";
+ else if(m_uses_memaccess && !m_mem_access.hasAttachedAndEnabled())
+ init_err_msg = "No memory access interface attached and enabled";
+ else if(m_uses_idecode && !m_instr_decode.hasAttachedAndEnabled())
+ init_err_msg = "No instruction decoder interface attached and enabled";
+ else
+ m_decode_init_ok = true;
+ if (m_decode_init_ok)
+ onFirstInitOK();
+ }
+ return m_decode_init_ok;
+}
+
+inline ocsd_datapath_resp_t TrcPktDecodeI::outputTraceElement(const OcsdTraceElement &elem)
+{
+ return m_trace_elem_out.first()->TraceElemIn(m_index_curr_pkt,getCoreSightTraceID(), elem);
+}
+
+inline ocsd_datapath_resp_t TrcPktDecodeI::outputTraceElementIdx(ocsd_trc_index_t idx, const OcsdTraceElement &elem)
+{
+ return m_trace_elem_out.first()->TraceElemIn(idx, getCoreSightTraceID(), elem);
+}
+
+inline ocsd_err_t TrcPktDecodeI::instrDecode(ocsd_instr_info *instr_info)
+{
+ if(m_uses_idecode)
+ return m_instr_decode.first()->DecodeInstruction(instr_info);
+ return OCSD_ERR_DCD_INTERFACE_UNUSED;
+}
+
+inline ocsd_err_t TrcPktDecodeI::accessMemory(const ocsd_vaddr_t address, const ocsd_mem_space_acc_t mem_space, uint32_t *num_bytes, uint8_t *p_buffer)
+{
+ if(m_uses_memaccess)
+ return m_mem_access.first()->ReadTargetMemory(address,getCoreSightTraceID(),mem_space, num_bytes,p_buffer);
+ return OCSD_ERR_DCD_INTERFACE_UNUSED;
+}
+
+inline ocsd_err_t TrcPktDecodeI::invalidateMemAccCache()
+{
+ if (!m_uses_memaccess)
+ return OCSD_ERR_DCD_INTERFACE_UNUSED;
+ m_mem_access.first()->InvalidateMemAccCache(getCoreSightTraceID());
+ return OCSD_OK;
+}
+
+/**********************************************************************/
+template <class P, class Pc>
+class TrcPktDecodeBase : public TrcPktDecodeI, public IPktDataIn<P>
+{
+public:
+ TrcPktDecodeBase(const char *component_name);
+ TrcPktDecodeBase(const char *component_name, int instIDNum);
+ virtual ~TrcPktDecodeBase();
+
+ virtual ocsd_datapath_resp_t PacketDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index_sop,
+ const P *p_packet_in);
+
+
+ /* protocol configuration */
+ ocsd_err_t setProtocolConfig(const Pc *config);
+ const Pc * getProtocolConfig() const { return m_config; };
+
+protected:
+ void ClearConfigObj();
+
+ /* the protocol configuration */
+ Pc * m_config;
+ /* the current input packet */
+ const P * m_curr_packet_in;
+
+};
+
+
+template <class P, class Pc> TrcPktDecodeBase<P, Pc>::TrcPktDecodeBase(const char *component_name) :
+ TrcPktDecodeI(component_name),
+ m_config(0)
+{
+}
+
+template <class P, class Pc> TrcPktDecodeBase<P, Pc>::TrcPktDecodeBase(const char *component_name, int instIDNum) :
+ TrcPktDecodeI(component_name,instIDNum),
+ m_config(0)
+{
+}
+
+template <class P, class Pc> TrcPktDecodeBase<P, Pc>::~TrcPktDecodeBase()
+{
+ ClearConfigObj();
+}
+
+template <class P, class Pc> ocsd_datapath_resp_t TrcPktDecodeBase<P, Pc>::PacketDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index_sop,
+ const P *p_packet_in)
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ if(!checkInit())
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_NOT_INIT,init_err_msg));
+ return OCSD_RESP_FATAL_NOT_INIT;
+ }
+
+ switch(op)
+ {
+ case OCSD_OP_DATA:
+ if(p_packet_in == 0)
+ {
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL));
+ resp = OCSD_RESP_FATAL_INVALID_PARAM;
+ }
+ else
+ {
+ m_curr_packet_in = p_packet_in;
+ m_index_curr_pkt = index_sop;
+ resp = processPacket();
+ }
+ break;
+
+ case OCSD_OP_EOT:
+ resp = onEOT();
+ break;
+
+ case OCSD_OP_FLUSH:
+ resp = onFlush();
+ break;
+
+ case OCSD_OP_RESET:
+ resp = onReset();
+ break;
+
+ default:
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL));
+ resp = OCSD_RESP_FATAL_INVALID_OP;
+ break;
+ }
+ return resp;
+}
+
+ /* protocol configuration */
+template <class P, class Pc> ocsd_err_t TrcPktDecodeBase<P, Pc>::setProtocolConfig(const Pc *config)
+{
+ ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
+ if(config != 0)
+ {
+ ClearConfigObj(); // remove any current config
+ m_config = new (std::nothrow) Pc(*config); // make a copy of the config - don't rely on the object passed in being valid outside the context of the call.
+ if(m_config != 0)
+ {
+ err = onProtocolConfig();
+ if(err == OCSD_OK)
+ m_config_init_ok = true;
+ }
+ else
+ err = OCSD_ERR_MEM;
+ }
+ return err;
+}
+
+template <class P, class Pc> void TrcPktDecodeBase<P, Pc>::ClearConfigObj()
+{
+ if(m_config)
+ {
+ delete m_config;
+ m_config = 0;
+ }
+}
+
+/** @}*/
+#endif // ARM_TRC_PKT_DECODE_BASE_H_INCLUDED
+
+/* End of File trc_pkt_decode_base.h */
diff --git a/decoder/include/common/trc_pkt_elem_base.h b/decoder/include/common/trc_pkt_elem_base.h
new file mode 100644
index 0000000..07604a6
--- /dev/null
+++ b/decoder/include/common/trc_pkt_elem_base.h
@@ -0,0 +1,49 @@
+/*
+ * \file trc_pkt_elem_base.h
+ * \brief Reference CoreSight Trace Decoder :
+ *
+ * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
+ */
+#ifndef ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
+#define ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
+
+/*
+ * 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.
+ */
+
+class TrcPacketBase
+{
+public:
+ TrcPacketBase() {};
+ virtual ~TrcPacketBase() {}
+
+ //! return the underlying C API packet structure
+ virtual const void *c_pkt() const = 0;
+};
+
+#endif // ARM_TRC_PKT_ELEM_BASE_H_INCLUDED
+
+/* End of File trc_pkt_elem_base.h */ \ No newline at end of file
diff --git a/decoder/include/common/trc_pkt_proc_base.h b/decoder/include/common/trc_pkt_proc_base.h
new file mode 100644
index 0000000..8ed7d83
--- /dev/null
+++ b/decoder/include/common/trc_pkt_proc_base.h
@@ -0,0 +1,456 @@
+/*!
+ * \file trc_pkt_proc_base.h
+ * \brief OpenCSD : Trace packet processor base class.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_PKT_PROC_BASE_H_INCLUDED
+#define ARM_TRC_PKT_PROC_BASE_H_INCLUDED
+
+#include "interfaces/trc_data_raw_in_i.h"
+#include "interfaces/trc_pkt_in_i.h"
+#include "interfaces/trc_pkt_raw_in_i.h"
+#include "interfaces/trc_indexer_pkt_i.h"
+
+#include "trc_component.h"
+#include "comp_attach_pt_t.h"
+#include "opencsd/ocsd_if_version.h"
+
+/** @defgroup ocsd_pkt_proc OpenCSD Library : Packet Processors.
+ @brief Classes providing Protocol Packet Processing capability.
+
+ Packet processors take an incoming byte stream and convert into discrete packets for the
+ required trace protocol.
+@{*/
+
+
+
+/*!
+ * @class TrcPktProcI
+ * @brief Base Packet processing interface
+ *
+ * Defines the packet processing methods that protocol specific processors must
+ * implement.
+ *
+ */
+class TrcPktProcI : public TraceComponent, public ITrcDataIn
+{
+public:
+ TrcPktProcI(const char *component_name);
+ TrcPktProcI(const char *component_name, int instIDNum);
+ virtual ~TrcPktProcI() {};
+
+ /** Trace byte data input interface - from ITrcDataIn.
+ */
+ virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed) = 0;
+
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats) = 0;
+ virtual void resetStats() = 0;
+protected:
+
+ /* implementation packet processing interface */
+
+ /*! @brief Implementation function for the OCSD_OP_DATA operation */
+ virtual ocsd_datapath_resp_t processData( const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed) = 0;
+
+ virtual ocsd_datapath_resp_t onEOT() = 0; //!< Implementation function for the OCSD_OP_EOT operation
+ virtual ocsd_datapath_resp_t onReset() = 0; //!< Implementation function for the OCSD_OP_RESET operation
+ virtual ocsd_datapath_resp_t onFlush() = 0; //!< Implementation function for the OCSD_OP_FLUSH operation
+ virtual ocsd_err_t onProtocolConfig() = 0; //!< Called when the configuration object is passed to the decoder.
+ virtual const bool isBadPacket() const = 0; //!< check if the current packet is an error / bad packet
+};
+
+inline TrcPktProcI::TrcPktProcI(const char *component_name) :
+ TraceComponent(component_name)
+{
+}
+
+inline TrcPktProcI::TrcPktProcI(const char *component_name, int instIDNum) :
+ TraceComponent(component_name,instIDNum)
+{
+}
+
+/*!
+ * @class TrcPktProcBase
+ * @brief Packet Processor base class. Provides common infrastructure and interconnections for packet processors.
+ *
+ * The class is a templated base class.
+ * - P - this is the packet object class.
+ * - Pt - this is the packet type class.
+ * - Pc - this is the packet configuration class.
+ *
+ * implementations will provide concrete classes for each of these to operate under the common infrastructures.
+ * The base provides the trace data in (ITrcDataIn) interface and operates on the incoming operation type.
+ *
+ * Implementions override the 'onFn()' and data process functions defined in TrcPktProcI,
+ * with the base class ensuring consistent ordering of operations.
+ *
+ */
+template <class P, class Pt, class Pc>
+class TrcPktProcBase : public TrcPktProcI
+{
+public:
+ TrcPktProcBase(const char *component_name);
+ TrcPktProcBase(const char *component_name, int instIDNum);
+ virtual ~TrcPktProcBase();
+
+ /** Byte trace data input interface defined in ITrcDataIn
+
+ The base class implementation processes the operation to call the
+ interface functions on TrcPktProcI.
+ */
+ virtual ocsd_datapath_resp_t TraceDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed);
+
+
+/* component attachment points */
+
+ //! Attachement point for the protocol packet output
+ componentAttachPt<IPktDataIn<P>> *getPacketOutAttachPt() { return &m_pkt_out_i; };
+ //! Attachment point for the protocol packet monitor
+ componentAttachPt<IPktRawDataMon<P>> *getRawPacketMonAttachPt() { return &m_pkt_raw_mon_i; };
+
+ //! Attachment point for a packet indexer
+ componentAttachPt<ITrcPktIndexer<Pt>> *getTraceIDIndexerAttachPt() { return &m_pkt_indexer_i; };
+
+/* protocol configuration */
+ //!< Set the protocol specific configuration for the decoder.
+ virtual ocsd_err_t setProtocolConfig(const Pc *config);
+ //!< Get the configuration for the decoder.
+ virtual const Pc *getProtocolConfig() const { return m_config; };
+
+/* stats block access - derived class must init stats for the block to be returned. */
+ virtual ocsd_err_t getStatsBlock(ocsd_decode_stats_t **pp_stats);
+ virtual void resetStats(); /* reset the counts - operates separately from decoder reset. */
+
+protected:
+
+ /* data output functions */
+ ocsd_datapath_resp_t outputDecodedPacket(const ocsd_trc_index_t index_sop, const P *pkt);
+
+ void outputRawPacketToMonitor( const ocsd_trc_index_t index_sop,
+ const P *pkt,
+ const uint32_t size,
+ const uint8_t *p_data);
+
+ void indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type);
+
+ ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata);
+
+ ocsd_datapath_resp_t outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen);
+
+ /*! Let the derived class figure out if it needs to collate and send raw data.
+ can improve wait for sync performance if we do not need to save and send unsynced data.
+ */
+ const bool hasRawMon() const;
+
+ /* the protocol configuration */
+ const Pc *m_config;
+
+ void ClearConfigObj(); // remove our copy of the config
+
+ const bool checkInit(); // return true if init (configured and at least one output sink attached), false otherwise.
+
+ /* stats block updates - called by derived protocol specific decoder */
+ void statsAddTotalCount(const uint64_t count) { m_stats.channel_total += count; };
+ void statsAddUnsyncCount(const uint64_t count) { m_stats.channel_unsynced += count; };
+ void statsAddBadSeqCount(const uint32_t count) { m_stats.bad_sequence_errs += count; };
+ void statsAddBadHdrCount(const uint32_t count) { m_stats.bad_header_errs += count; };
+ void statsInit() { m_stats_init = true; }; /* mark stats as in use */
+
+
+private:
+ /* decode control */
+ ocsd_datapath_resp_t Reset(const ocsd_trc_index_t index);
+ ocsd_datapath_resp_t Flush();
+ ocsd_datapath_resp_t EOT();
+
+ componentAttachPt<IPktDataIn<P>> m_pkt_out_i;
+ componentAttachPt<IPktRawDataMon<P>> m_pkt_raw_mon_i;
+
+ componentAttachPt<ITrcPktIndexer<Pt>> m_pkt_indexer_i;
+
+ bool m_b_is_init;
+
+ /* decode statistics block */
+ ocsd_decode_stats_t m_stats;
+ bool m_stats_init; /*< true if the specific decoder is using the stats */
+
+};
+
+template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name) :
+ TrcPktProcI(component_name),
+ m_config(0),
+ m_b_is_init(false),
+ m_stats_init(false)
+{
+ resetStats();
+}
+
+template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::TrcPktProcBase(const char *component_name, int instIDNum) :
+ TrcPktProcI(component_name, instIDNum),
+ m_config(0),
+ m_b_is_init(false),
+ m_stats_init(false)
+{
+ resetStats();
+}
+
+template<class P,class Pt, class Pc> TrcPktProcBase<P, Pt, Pc>::~TrcPktProcBase()
+{
+ ClearConfigObj();
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::TraceDataIn( const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index,
+ const uint32_t dataBlockSize,
+ const uint8_t *pDataBlock,
+ uint32_t *numBytesProcessed)
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+
+ switch(op)
+ {
+ case OCSD_OP_DATA:
+ if((dataBlockSize == 0) || (pDataBlock == 0) || (numBytesProcessed == 0))
+ {
+ if(numBytesProcessed)
+ *numBytesProcessed = 0; // ensure processed bytes value set to 0.
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor: Zero length data block or NULL pointer error\n"));
+ resp = OCSD_RESP_FATAL_INVALID_PARAM;
+ }
+ else
+ resp = processData(index,dataBlockSize,pDataBlock,numBytesProcessed);
+ break;
+
+ case OCSD_OP_EOT:
+ resp = EOT();
+ break;
+
+ case OCSD_OP_FLUSH:
+ resp = Flush();
+ break;
+
+ case OCSD_OP_RESET:
+ resp = Reset(index);
+ break;
+
+ default:
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_INVALID_PARAM_VAL,"Packet Processor : Unknown Datapath operation\n"));
+ resp = OCSD_RESP_FATAL_INVALID_OP;
+ break;
+ }
+ return resp;
+}
+
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Reset(const ocsd_trc_index_t index)
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+
+ // reset the trace decoder attachment on main data path.
+ if(m_pkt_out_i.hasAttachedAndEnabled())
+ resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_RESET,index,0);
+
+ // reset the packet processor implmentation
+ if(!OCSD_DATA_RESP_IS_FATAL(resp))
+ resp = onReset();
+
+ // packet monitor
+ if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
+ m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_RESET,index,0,0,0);
+
+ return resp;
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::Flush()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ ocsd_datapath_resp_t resplocal = OCSD_RESP_CONT;
+
+ // the trace decoder attachment on main data path.
+ if(m_pkt_out_i.hasAttachedAndEnabled())
+ resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_FLUSH,0,0); // flush up the data path first.
+
+ // if the connected components are flushed, not flush this one.
+ if(OCSD_DATA_RESP_IS_CONT(resp))
+ resplocal = onFlush(); // local flush
+
+ return (resplocal > resp) ? resplocal : resp;
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::EOT()
+{
+ ocsd_datapath_resp_t resp = onEOT(); // local EOT - mark any part packet as incomplete type and prepare to send
+
+ // the trace decoder attachment on main data path.
+ if(m_pkt_out_i.hasAttachedAndEnabled() && !OCSD_DATA_RESP_IS_FATAL(resp))
+ resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_EOT,0,0);
+
+ // packet monitor
+ if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
+ m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_EOT,0,0,0,0);
+
+ return resp;
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputDecodedPacket(const ocsd_trc_index_t index, const P *pkt)
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+
+ // bad packet filter.
+ if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOFWD_BAD_PKTS) && isBadPacket())
+ return resp;
+
+ // send a complete packet over the primary data path
+ if(m_pkt_out_i.hasAttachedAndEnabled())
+ resp = m_pkt_out_i.first()->PacketDataIn(OCSD_OP_DATA,index,pkt);
+ return resp;
+}
+
+template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::outputRawPacketToMonitor(
+ const ocsd_trc_index_t index_sop,
+ const P *pkt,
+ const uint32_t size,
+ const uint8_t *p_data)
+{
+ // never output 0 sized packets.
+ if(size == 0)
+ return;
+
+ // bad packet filter.
+ if((getComponentOpMode() & OCSD_OPFLG_PKTPROC_NOMON_BAD_PKTS) && isBadPacket())
+ return;
+
+ // packet monitor - this cannot return CONT / WAIT, but does get the raw packet data.
+ if(m_pkt_raw_mon_i.hasAttachedAndEnabled())
+ m_pkt_raw_mon_i.first()->RawPacketDataMon(OCSD_OP_DATA,index_sop,pkt,size,p_data);
+}
+
+template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::hasRawMon() const
+{
+ return m_pkt_raw_mon_i.hasAttachedAndEnabled();
+}
+
+template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::indexPacket(const ocsd_trc_index_t index_sop, const Pt *packet_type)
+{
+ // packet indexer - cannot return CONT / WAIT, just gets the current index and type.
+ if(m_pkt_indexer_i.hasAttachedAndEnabled())
+ m_pkt_indexer_i.first()->TracePktIndex(index_sop,packet_type);
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, std::vector<uint8_t> &pktdata)
+{
+ indexPacket(index_sop,pkt_type);
+ if(pktdata.size() > 0) // prevent out of range errors for 0 length vector.
+ outputRawPacketToMonitor(index_sop,pkt,(uint32_t)pktdata.size(),&pktdata[0]);
+ return outputDecodedPacket(index_sop,pkt);
+}
+
+template<class P,class Pt, class Pc> ocsd_datapath_resp_t TrcPktProcBase<P, Pt, Pc>::outputOnAllInterfaces(const ocsd_trc_index_t index_sop, const P *pkt, const Pt *pkt_type, const uint8_t *pktdata, uint32_t pktlen)
+{
+ indexPacket(index_sop,pkt_type);
+ outputRawPacketToMonitor(index_sop,pkt,pktlen,pktdata);
+ return outputDecodedPacket(index_sop,pkt);
+}
+
+template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::setProtocolConfig(const Pc *config)
+{
+ ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL;
+ if(config != 0)
+ {
+ ClearConfigObj();
+ m_config = new (std::nothrow) Pc(*config);
+ if(m_config != 0)
+ err = onProtocolConfig();
+ else
+ err = OCSD_ERR_MEM;
+ }
+ return err;
+}
+
+template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::ClearConfigObj()
+{
+ if(m_config)
+ {
+ delete m_config;
+ m_config = 0;
+ }
+}
+
+template<class P,class Pt, class Pc> const bool TrcPktProcBase<P, Pt, Pc>::checkInit()
+{
+ if(!m_b_is_init)
+ {
+ if( (m_config != 0) &&
+ (m_pkt_out_i.hasAttached() || m_pkt_raw_mon_i.hasAttached())
+ )
+ m_b_is_init = true;
+ }
+ return m_b_is_init;
+}
+
+template<class P,class Pt, class Pc> ocsd_err_t TrcPktProcBase<P, Pt, Pc>::getStatsBlock(ocsd_decode_stats_t **pp_stats)
+{
+
+ *pp_stats = &m_stats;
+ return m_stats_init ? OCSD_OK : OCSD_ERR_NOT_INIT;
+}
+
+template<class P,class Pt, class Pc> void TrcPktProcBase<P, Pt, Pc>::resetStats()
+{
+ m_stats.version = OCSD_VER_NUM;
+ m_stats.revision = OCSD_STATS_REVISION;
+ m_stats.channel_total = 0;
+ m_stats.channel_unsynced = 0;
+ m_stats.bad_header_errs = 0;
+ m_stats.bad_sequence_errs = 0;
+ m_stats.demux.frame_bytes = 0;
+ m_stats.demux.no_id_bytes = 0;
+ m_stats.demux.valid_id_bytes = 0;
+}
+
+/** @}*/
+
+#endif // ARM_TRC_PKT_PROC_BASE_H_INCLUDED
+
+/* End of File trc_pkt_proc_base.h */
diff --git a/decoder/include/common/trc_printable_elem.h b/decoder/include/common/trc_printable_elem.h
new file mode 100644
index 0000000..92a47e8
--- /dev/null
+++ b/decoder/include/common/trc_printable_elem.h
@@ -0,0 +1,91 @@
+/*!
+ * \file trc_printable_elem.h
+ * \brief OpenCSD : Standard printable element base class.
+ *
+ * \copyright Copyright (c) 2015, 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_TRC_PRINTABLE_ELEM_H_INCLUDED
+#define ARM_TRC_PRINTABLE_ELEM_H_INCLUDED
+
+#include <string>
+#include <cstdint>
+
+/** @addtogroup ocsd_infrastructure
+@{*/
+
+/*!
+ * @class trcPrintableElem
+ * @brief Class to provide trace element strings for printing
+ *
+ * Provide a standard interface to the trace packet classes to allow the packets
+ * to be printed in logging or tools.
+ *
+ * Provides some standard formatting functionality
+ *
+ */
+class trcPrintableElem
+{
+public:
+ trcPrintableElem() {};
+ virtual ~trcPrintableElem() {};
+ virtual void toString(std::string &str) const;
+ virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const;
+
+ // print formatting utilities
+ static void getValStr(std::string &valStr, const int valTotalBitSize, const int valValidBits, const uint64_t value, const bool asHex = true, const int updateBits = 0);
+
+};
+
+inline void trcPrintableElem::toString(std::string &str) const
+{
+ str = "Trace Element : print not implemented";
+}
+
+inline void trcPrintableElem::toStringFmt(const uint32_t /*fmtFlags*/, std::string &str) const
+{
+ toString(str);
+}
+
+/** static template string function - used in "C" API to provide generic printing */
+template<class Pc, class Pt>
+void trcPrintElemToString(const void *p_pkt, std::string &str)
+{
+ Pc pktClass;
+ pktClass = static_cast<const Pt *>(p_pkt);
+ pktClass.toString(str);
+}
+
+/** @}*/
+
+#endif // ARM_TRC_PRINTABLE_ELEM_H_INCLUDED
+
+/* End of File trc_printable_elem.h */
diff --git a/decoder/include/common/trc_raw_buffer.h b/decoder/include/common/trc_raw_buffer.h
new file mode 100644
index 0000000..67b8d24
--- /dev/null
+++ b/decoder/include/common/trc_raw_buffer.h
@@ -0,0 +1,96 @@
+/*
+* \file trc_raw_buffer.h
+* \brief OpenCSD : Trace raw data byte buffer
+*
+* \copyright Copyright (c) 2019, 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_TRC_RAW_BUFFER_H_INCLUDED
+#define ARM_TRC_RAW_BUFFER_H_INCLUDED
+
+#include <vector>
+
+class TraceRawBuffer
+{
+public:
+ TraceRawBuffer() :
+ m_bufSize(0),
+ m_bufProcessed(0),
+ m_pBuffer(0),
+ pkt(0)
+ {};
+ ~TraceRawBuffer() {};
+
+ // init the buffer
+ void init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet);
+ void copyByteToPkt(); // move a byte to the packet buffer
+ uint8_t peekNextByte(); // value of next byte in buffer.
+
+ bool empty() { return m_bufProcessed == m_bufSize; };
+ // bytes processed.
+ uint32_t processed() { return m_bufProcessed; };
+ // buffer size;
+ uint32_t size() { return m_bufSize; }
+
+private:
+ uint32_t m_bufSize;
+ uint32_t m_bufProcessed;
+ const uint8_t *m_pBuffer;
+ std::vector<uint8_t> *pkt;
+
+};
+
+// init the buffer
+inline void TraceRawBuffer::init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet)
+{
+ m_bufSize = size;
+ m_bufProcessed = 0;
+ m_pBuffer = rawtrace;
+ pkt = out_packet;
+}
+
+inline void TraceRawBuffer::copyByteToPkt()
+{
+ if (!empty()) {
+ pkt->push_back(m_pBuffer[m_bufProcessed]);
+ m_bufProcessed++;
+ }
+}
+
+inline uint8_t TraceRawBuffer::peekNextByte()
+{
+ uint8_t val = 0;
+ if (!empty())
+ val = m_pBuffer[m_bufProcessed];
+ return val;
+}
+
+#endif // ARM_TRC_RAW_BUFFER_H_INCLUDED
+
diff --git a/decoder/include/common/trc_ret_stack.h b/decoder/include/common/trc_ret_stack.h
new file mode 100644
index 0000000..a7f53d1
--- /dev/null
+++ b/decoder/include/common/trc_ret_stack.h
@@ -0,0 +1,114 @@
+/*
+* \file trc_ret_stack.h
+* \brief OpenCSD : trace decoder return stack feature.
+*
+* \copyright Copyright (c) 2017, 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_TRC_RET_STACK_H_INCLUDED
+#define ARM_TRC_RET_STACK_H_INCLUDED
+
+#include "opencsd/ocsd_if_types.h"
+
+// uncomment below for return stack logging
+// #define TRC_RET_STACK_DEBUG
+
+#ifdef TRC_RET_STACK_DEBUG
+class TraceComponent;
+#endif
+
+typedef struct _retStackElement
+{
+ ocsd_vaddr_t ret_addr;
+ ocsd_isa ret_isa;
+} retStackElement;
+
+class TrcAddrReturnStack
+{
+public:
+ TrcAddrReturnStack();
+ ~TrcAddrReturnStack() {};
+
+ void set_active(bool active)
+ {
+ m_active = active;
+ };
+
+ bool is_active() const
+ {
+ return m_active;
+ };
+
+ void push(const ocsd_vaddr_t addr, const ocsd_isa isa);
+ ocsd_vaddr_t pop(ocsd_isa &isa);
+ void flush();
+
+ bool overflow() const
+ {
+ return (bool)(num_entries < 0);
+ };
+
+ void set_pop_pending()
+ {
+ if (m_active)
+ m_pop_pending = true;
+ }
+
+ void clear_pop_pending()
+ {
+ m_pop_pending = false;
+ }
+
+ bool pop_pending() const
+ {
+ return m_pop_pending;
+ };
+
+private:
+ bool m_active;
+ bool m_pop_pending; // flag for decoder to indicate a pop might be needed depending on the next packet (ETMv4)
+
+ int head_idx;
+ int num_entries;
+ retStackElement m_stack[16];
+
+#ifdef TRC_RET_STACK_DEBUG
+public:
+ void set_dbg_logger(TraceComponent *pLogger) { m_p_debug_logger = pLogger; };
+private:
+ void LogOp(const char *pszOpString, ocsd_vaddr_t addr, int head_off, ocsd_isa isa);
+
+ TraceComponent *m_p_debug_logger;
+#endif // TRC_RET_STACK_DEBUG
+};
+
+#endif // ARM_TRC_RET_STACK_H_INCLUDED
+
+/* End of File trc_ret_stack.h */