| /* |
| * \file trc_pkt_elem_etmv4i.h |
| * \brief Reference CoreSight Trace Decoder : |
| * |
| * \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_ELEM_ETMV4I_H_INCLUDED |
| #define ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED |
| |
| #include "trc_pkt_types_etmv4.h" |
| #include "trc_printable_elem.h" |
| |
| /** @addtogroup trc_pkts |
| @{*/ |
| |
| /*! |
| * @class EtmV4ITrcPacket |
| * @brief ETMv4 Instuction Trace Protocol Packet. |
| * @ingroup trc_pkts |
| * |
| * This class represents a single ETMv4 data trace packet, along with intra packet state. |
| * |
| */ |
| class EtmV4ITrcPacket : public rctdl_etmv4_i_pkt, public trcPrintableElem |
| { |
| public: |
| EtmV4ITrcPacket(); |
| ~EtmV4ITrcPacket(); |
| |
| EtmV4ITrcPacket &operator =(const rctdl_etmv4_i_pkt* p_pkt); |
| |
| // update interface - set packet values |
| void initStartState(); //!< Set to initial state - no intra packet state valid. Use on start of trace / discontinuities. |
| void initNextPacket(); //!< clear any single packet only flags / state. |
| |
| void setType(const rctdl_etmv4_i_pkt_type pkt_type) { type = pkt_type; }; |
| void updateErrType(const rctdl_etmv4_i_pkt_type err_pkt_type); |
| |
| void clearTraceInfo(); //!< clear all the trace info data prior to setting for new trace info packet. |
| void setTraceInfo(const uint32_t infoVal); |
| void setTraceInfoKey(const uint32_t keyVal); |
| void setTraceInfoSpec(const uint32_t specVal); |
| void setTraceInfoCyct(const uint32_t cyctVal); |
| |
| void setTS(const uint64_t value, const uint8_t bits); |
| void setCycleCount(const uint32_t value); |
| void setCommitElements(const uint32_t commit_elem); |
| void setCancelElements(const uint32_t cancel_elem); |
| void setAtomPacket(const rctdl_pkt_atm_type type, const uint32_t En_bits, const uint8_t num); |
| |
| void setCondIF1(uint32_t const cond_key); |
| void setCondIF2(uint8_t const c_elem_idx); |
| void setCondIF3(uint8_t const num_c_elem, const bool finalElem); |
| |
| void setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2], const bool set2Keys); |
| void setCondRF2(const uint8_t key_incr, const uint8_t token); |
| void setCondRF3(const uint16_t tokens); |
| void setCondRF4(const uint8_t token); |
| |
| void setContextInfo(const bool update, const uint8_t EL = 0, const uint8_t NS = 0, const uint8_t SF = 0); |
| void setContextVMID(const uint32_t VMID); |
| void setContextCID(const uint32_t CID); |
| |
| void setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type); |
| |
| void set64BitAddress(const uint64_t addr, const uint8_t IS, const uint8_t update_bits); |
| void set32BitAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits); |
| void updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits); |
| void setAddressExactMatch(const uint8_t idx); |
| |
| void setDataSyncMarker(const uint8_t dsm_val); |
| void setEvent(const uint8_t event_val); |
| |
| void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type); |
| |
| // packet status interface - get packet info. |
| const rctdl_etmv4_i_pkt_type getType() const { return type; }; |
| const rctdl_etmv4_i_pkt_type getErrType() const { return err_type; }; |
| |
| const bool hasCommitElementsCount() const; //!< return true if this packet has set the commit packet count. |
| |
| // trace info |
| const etmv4_trace_info_t &getTraceInfo() const { return trace_info; }; |
| const uint32_t getCCThreshold() const; |
| const uint32_t getP0Key() const; |
| const uint32_t getCurrSpecDepth() const; |
| |
| // atom |
| const rctdl_pkt_atom &getAtom() const { return atom; }; |
| |
| // context |
| const etmv4_context_t &getContext() const { return context; }; |
| |
| // address |
| const uint8_t &getAddrMatch() const { return addr_exact_match_idx; }; |
| const rctdl_vaddr_t &getAddrVal() const { return v_addr.val; }; |
| const uint8_t &getAddrIS() const { return v_addr_ISA; }; |
| |
| // ts |
| const uint64_t getTS() const { return pkt_valid.bits.ts_valid ? ts.timestamp : 0; }; |
| |
| // cc |
| const uint32_t getCC() const { return pkt_valid.bits.cc_valid ? cycle_count : 0; }; |
| |
| // packet type |
| const bool isBadPacket() const; |
| |
| // printing |
| virtual void toString(std::string &str) const; |
| virtual void toStringFmt(const uint32_t fmtFlags, std::string &str) const; |
| |
| private: |
| const char *packetTypeName(const rctdl_etmv4_i_pkt_type type, const char **pDesc) const; |
| void contextStr(std::string &ctxtStr) const; |
| void atomSeq(std::string &valStr) const; |
| void addrMatchIdx(std::string &valStr) const; |
| void exceptionInfo(std::string &valStr) const; |
| }; |
| |
| inline void EtmV4ITrcPacket::updateErrType(const rctdl_etmv4_i_pkt_type err_pkt_type) |
| { |
| // set primary type to incoming error type, set packet err type to previous primary type. |
| err_type = type; |
| type = err_pkt_type; |
| } |
| |
| inline void EtmV4ITrcPacket::clearTraceInfo() |
| { |
| pkt_valid.bits.ts_valid = 0; |
| pkt_valid.bits.trace_info_valid = 0; |
| pkt_valid.bits.p0_key_valid = 0; |
| pkt_valid.bits.spec_depth_valid = 0; |
| pkt_valid.bits.cc_thresh_valid = 0; |
| |
| pkt_valid.bits.ts_valid = 0; // mark TS as invalid - must be re-updated after trace info. |
| } |
| |
| inline void EtmV4ITrcPacket::setTraceInfo(const uint32_t infoVal) |
| { |
| trace_info.val = infoVal; |
| pkt_valid.bits.trace_info_valid = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setTraceInfoKey(const uint32_t keyVal) |
| { |
| p0_key = keyVal; |
| pkt_valid.bits.p0_key_valid = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setTraceInfoSpec(const uint32_t specVal) |
| { |
| curr_spec_depth = specVal; |
| pkt_valid.bits.spec_depth_valid = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setTraceInfoCyct(const uint32_t cyctVal) |
| { |
| cc_threshold = cyctVal; |
| pkt_valid.bits.cc_thresh_valid = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setTS(const uint64_t value, const uint8_t bits) |
| { |
| uint64_t mask = (uint64_t)-1LL; |
| if(bits < 64) mask = (1ULL << bits) - 1; |
| ts.timestamp = (ts.timestamp & ~mask) | (value & mask); |
| ts.bits_changed = bits; |
| pkt_valid.bits.ts_valid = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setCycleCount(const uint32_t value) |
| { |
| pkt_valid.bits.cc_valid = 1; |
| cycle_count = value; |
| } |
| |
| inline void EtmV4ITrcPacket::setCommitElements(const uint32_t commit_elem) |
| { |
| pkt_valid.bits.commit_elem_valid = 1; |
| commit_elements = commit_elem; |
| } |
| |
| inline const uint32_t EtmV4ITrcPacket::getCCThreshold() const |
| { |
| if(pkt_valid.bits.cc_thresh_valid) |
| return cc_threshold; |
| return 0; |
| } |
| |
| inline const uint32_t EtmV4ITrcPacket::getP0Key() const |
| { |
| if(pkt_valid.bits.p0_key_valid) |
| return p0_key; |
| return 0; |
| } |
| |
| inline const uint32_t EtmV4ITrcPacket::getCurrSpecDepth() const |
| { |
| if(pkt_valid.bits.spec_depth_valid) |
| return curr_spec_depth; |
| return 0; |
| } |
| |
| inline void EtmV4ITrcPacket::setCancelElements(const uint32_t cancel_elem) |
| { |
| cancel_elements = cancel_elem; |
| } |
| |
| inline void EtmV4ITrcPacket::setAtomPacket(const rctdl_pkt_atm_type type, const uint32_t En_bits, const uint8_t num) |
| { |
| if(type == ATOM_REPEAT) |
| { |
| uint32_t bit_patt = En_bits & 0x1; |
| if(bit_patt) |
| { |
| // none zero - all 1s |
| bit_patt = (bit_patt << num) - 1; |
| } |
| atom.En_bits = bit_patt; |
| } |
| else |
| atom.En_bits = En_bits; |
| atom.num = num; |
| } |
| |
| inline void EtmV4ITrcPacket::setCondIF1(const uint32_t cond_key) |
| { |
| cond_instr.cond_key_set = 1; |
| cond_instr.f3_final_elem = 0; |
| cond_instr.f2_cond_incr = 0; |
| cond_instr.num_c_elem = 1; |
| cond_instr.cond_c_key = cond_key; |
| } |
| |
| inline void EtmV4ITrcPacket::setCondIF2(const uint8_t c_elem_idx) |
| { |
| cond_instr.cond_key_set = 0; |
| cond_instr.f3_final_elem = 0; |
| switch(c_elem_idx & 0x3) |
| { |
| case 0: |
| cond_instr.f2_cond_incr = 1; |
| cond_instr.num_c_elem = 1; |
| break; |
| |
| case 1: |
| cond_instr.f2_cond_incr = 0; |
| cond_instr.num_c_elem = 1; |
| break; |
| |
| case 2: |
| cond_instr.f2_cond_incr = 1; |
| cond_instr.num_c_elem = 2; |
| break; |
| } |
| } |
| |
| inline void EtmV4ITrcPacket::setCondIF3(const uint8_t num_c_elem, const bool finalElem) |
| { |
| cond_instr.cond_key_set = 0; |
| cond_instr.f3_final_elem = finalElem ? 1: 0; |
| cond_instr.f2_cond_incr = 0; |
| cond_instr.num_c_elem = num_c_elem; |
| } |
| |
| inline void EtmV4ITrcPacket::setCondRF1(const uint32_t key[2], const uint8_t res[2], const uint8_t CI[2],const bool set2Keys) |
| { |
| cond_result.key_res_0_set = 1; |
| cond_result.cond_r_key_0 = key[0]; |
| cond_result.res_0 = res[0]; |
| cond_result.ci_0 = CI[0]; |
| |
| if(set2Keys) |
| { |
| cond_result.key_res_1_set = 1; |
| cond_result.cond_r_key_1 = key[1]; |
| cond_result.res_1 = res[1]; |
| cond_result.ci_1 = CI[1]; |
| } |
| } |
| |
| |
| inline void EtmV4ITrcPacket::setCondRF2(const uint8_t key_incr, const uint8_t token) |
| { |
| cond_result.key_res_0_set = 0; |
| cond_result.key_res_1_set = 0; |
| cond_result.f2_key_incr = key_incr; |
| cond_result.f2f4_token = token; |
| } |
| |
| inline void EtmV4ITrcPacket::setCondRF3(const uint16_t tokens) |
| { |
| cond_result.key_res_0_set = 0; |
| cond_result.key_res_1_set = 0; |
| cond_result.f3_tokens = tokens; |
| } |
| |
| inline void EtmV4ITrcPacket::setCondRF4(const uint8_t token) |
| { |
| cond_result.key_res_0_set = 0; |
| cond_result.key_res_1_set = 0; |
| cond_result.f2f4_token = token; |
| } |
| |
| inline void EtmV4ITrcPacket::setContextInfo(const bool update, const uint8_t EL, const uint8_t NS, const uint8_t SF) |
| { |
| pkt_valid.bits.context_valid = 1; |
| if(update) |
| { |
| context.updated = 1; |
| context.EL = EL; |
| context.NS = NS; |
| context.SF = SF; |
| } |
| } |
| |
| inline void EtmV4ITrcPacket::setContextVMID(const uint32_t VMID) |
| { |
| pkt_valid.bits.context_valid = 1; |
| context.updated = 1; |
| context.VMID = VMID; |
| context.updated_v = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setContextCID(const uint32_t CID) |
| { |
| pkt_valid.bits.context_valid = 1; |
| context.updated = 1; |
| context.ctxtID = CID; |
| context.updated_c = 1; |
| } |
| |
| inline void EtmV4ITrcPacket::setExceptionInfo(const uint16_t excep_type, const uint8_t addr_interp, const uint8_t m_fault_pending, const uint8_t m_type) |
| { |
| exception_info.exceptionType = excep_type; |
| exception_info.addr_interp = addr_interp; |
| exception_info.m_fault_pending = m_fault_pending; |
| exception_info.m_type = m_type; |
| } |
| |
| inline void EtmV4ITrcPacket::set64BitAddress(const uint64_t addr, const uint8_t IS, const uint8_t update_bits) |
| { |
| uint64_t update_mask = (uint64_t)-1; |
| v_addr.pkt_bits = update_bits; |
| v_addr.size = VA_64BIT; |
| if(v_addr.valid_bits < update_bits) |
| v_addr.valid_bits = update_bits; |
| |
| if(update_bits < 64) |
| { |
| update_mask = ((uint64_t)1 << update_bits) - 1; |
| } |
| v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask); |
| v_addr_ISA = IS; |
| } |
| |
| inline void EtmV4ITrcPacket::set32BitAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits) |
| { |
| rctdl_vaddr_t update_mask = RCTDL_BIT_MASK(update_bits); |
| v_addr.pkt_bits = update_bits; |
| v_addr.size = VA_32BIT; |
| if((v_addr.valid_bits < update_bits) || (update_bits == 32) ) // account for dropping into AArch32 |
| v_addr.valid_bits = update_bits; |
| |
| v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask); |
| v_addr_ISA = IS; |
| } |
| |
| inline void EtmV4ITrcPacket::updateShortAddress(const uint32_t addr, const uint8_t IS, const uint8_t update_bits) |
| { |
| rctdl_vaddr_t update_mask = RCTDL_BIT_MASK(update_bits); |
| v_addr.pkt_bits = update_bits; |
| if(v_addr.valid_bits < update_bits) |
| v_addr.valid_bits = update_bits; |
| |
| v_addr.val = (v_addr.val & ~update_mask) | (addr & update_mask); |
| v_addr_ISA = IS; |
| } |
| |
| inline void EtmV4ITrcPacket::setAddressExactMatch(const uint8_t idx) |
| { |
| addr_exact_match_idx = idx; |
| } |
| |
| inline void EtmV4ITrcPacket::setDataSyncMarker(const uint8_t dsm_value) |
| { |
| dsm_val = dsm_value; |
| } |
| |
| inline void EtmV4ITrcPacket::setEvent(const uint8_t event_value) |
| { |
| event_val = event_value; |
| } |
| |
| inline void EtmV4ITrcPacket::setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type) |
| { |
| Q_pkt.q_count = count; |
| Q_pkt.q_type = type; |
| Q_pkt.count_present = has_count ? 1 : 0; |
| Q_pkt.addr_present = has_addr ? 1: 0; |
| Q_pkt.addr_match = addr_match ? 1 :0; |
| } |
| |
| inline const bool EtmV4ITrcPacket::isBadPacket() const |
| { |
| return (type >= ETM4_PKT_I_BAD_SEQUENCE); |
| } |
| |
| |
| /** @}*/ |
| |
| #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED |
| |
| /* End of File trc_pkt_elem_etmv4i.h */ |