diff options
Diffstat (limited to 'decoder/include/common/ocsd_dcd_tree.h')
-rw-r--r-- | decoder/include/common/ocsd_dcd_tree.h | 453 |
1 files changed, 453 insertions, 0 deletions
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 */ |