1/* 2 * \file ocsd_code_follower.h 3 * \brief OpenCSD : Code follower for instruction trace decode 4 * 5 * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved. 6 */ 7 8/* 9 * Redistribution and use in source and binary forms, with or without modification, 10 * are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the copyright holder nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#ifndef ARM_OCSD_CODE_FOLLOWER_H_INCLUDED 36#define ARM_OCSD_CODE_FOLLOWER_H_INCLUDED 37 38#include "opencsd/ocsd_if_types.h" 39#include "opencsd/trc_pkt_types.h" 40#include "comp_attach_pt_t.h" 41#include "interfaces/trc_tgt_mem_access_i.h" 42#include "interfaces/trc_instr_decode_i.h" 43 44/*! 45 * @class OcsdCodeFollower 46 * @brief The code follower looks for waypoints or addresses. 47 * 48 * Code follower used to determine the trace ranges for Atom or other waypoint 49 * elements. Uses memory accessor and I decoder to follow the code path. 50 * 51 */ 52class OcsdCodeFollower 53{ 54public: 55 OcsdCodeFollower(); 56 ~OcsdCodeFollower(); 57 58//*********** setup API 59 void initInterfaces(componentAttachPt<ITargetMemAccess> *pMemAccess, componentAttachPt<IInstrDecode> *pIDecode); 60 61// set information for decode operation - static or occasionally changing settings 62// per decode values are passed as parameters into the decode API calls. 63 void setArchProfile(const ocsd_arch_profile_t profile); //!< core profile 64 void setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule); //!< memory space to use for access (filtered by S/NS, EL etc). 65 void setMemSpaceCSID(const uint8_t csid); //!< memory spaces might be partitioned by CSID 66 void setISA(const ocsd_isa isa); //!< set the ISA for the decode. 67 void setDSBDMBasWP(); //!< DSB and DMB can be treated as WP in some archs. 68 69//********** code following API 70 71 // standard WP search - for program flow trace 72 //ocsd_err_t followToAtomWP(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A); 73 74 // PTM exception code may require follow to an address 75 //ocsd_err_t followToAddress(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A, const ocsd_vaddr_t addrMatch); 76 77 // single instruction atom format such as ETMv3 78 ocsd_err_t followSingleAtom(const ocsd_vaddr_t addrStart, const ocsd_atm_val A); 79 80 // follow N instructions 81 // ocsd_err_t followNInstructions(idec_res_t &op_result) // ETMv4 Q elements 82 83//*********************** results API 84 const ocsd_vaddr_t getRangeSt() const; //!< inclusive start address of decoded range (value passed in) 85 const ocsd_vaddr_t getRangeEn() const; //!< exclusive end address of decoded range (first instruction _not_ executed / potential next instruction). 86 const bool hasRange() const; //!< we have a valid range executed (may be false if nacc). 87 88 const bool hasNextAddr() const; //!< we have calulated the next address - otherwise this is needed from trace packets. 89 const ocsd_vaddr_t getNextAddr() const; //!< next address - valid if hasNextAddr() true. 90 91 // information on last instruction executed in range. 92 const ocsd_instr_type getInstrType() const; //!< last instruction type 93 const ocsd_instr_subtype getInstrSubType() const; //!< last instruction sub-type 94 const bool isCondInstr() const; //!< is a conditional instruction 95 const bool isLink() const; //!< is a link (branch with link etc) 96 const bool ISAChanged() const; //!< next ISA different from input ISA. 97 const ocsd_isa nextISA() const; //!< ISA for next instruction 98 const uint8_t getInstrSize() const; //!< Get the last instruction size. 99 100 // information on error conditions 101 const bool isNacc() const; //!< true if Memory Not Accessible (nacc) error occurred 102 void clearNacc(); //!< clear the nacc error flag 103 const ocsd_vaddr_t getNaccAddr() const; //!< get the nacc error address. 104 105private: 106 bool initFollowerState(); //!< clear all the o/p data and flags, check init valid. 107 108 ocsd_err_t decodeSingleOpCode(); //!< decode single opcode address from current m_inst_info packet 109 110 ocsd_instr_info m_instr_info; 111 112 ocsd_vaddr_t m_st_range_addr; //!< start of excuted range - inclusive address. 113 ocsd_vaddr_t m_en_range_addr; //!< end of executed range - exclusive address. 114 ocsd_vaddr_t m_next_addr; //!< calcuated next address (could be eo range of branch address, not set for indirect branches) 115 bool m_b_next_valid; //!< true if next address valid, false if need address from trace packets. 116 117 //! memory space rule to use when accessing memory. 118 ocsd_mem_space_acc_t m_mem_acc_rule; 119 //! memory space csid to use when accessing memory. 120 uint8_t m_mem_space_csid; 121 122 ocsd_vaddr_t m_nacc_address; //!< memory address that was inaccessible - failed read @ start, or during follow operation 123 bool m_b_nacc_err; //!< memory NACC error - required address was unavailable. 124 125 //! pointers to the memory access and i decode interfaces. 126 componentAttachPt<ITargetMemAccess> *m_pMemAccess; 127 componentAttachPt<IInstrDecode> *m_pIDecode; 128 129}; 130 131#endif // ARM_OCSD_CODE_FOLLOWER_H_INCLUDED 132 133//*********** setup API 134inline void OcsdCodeFollower::setArchProfile(const ocsd_arch_profile_t profile) 135{ 136 m_instr_info.pe_type = profile; 137} 138 139inline void OcsdCodeFollower::setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule) 140{ 141 m_mem_acc_rule = mem_acc_rule; 142} 143 144inline void OcsdCodeFollower::setMemSpaceCSID(const uint8_t csid) 145{ 146 m_mem_space_csid = csid; 147} 148 149inline void OcsdCodeFollower::setISA(const ocsd_isa isa) 150{ 151 m_instr_info.isa = isa; 152} 153 154inline void OcsdCodeFollower::setDSBDMBasWP() 155{ 156 m_instr_info.dsb_dmb_waypoints = 1; 157} 158 159//**************************************** results API 160inline const ocsd_vaddr_t OcsdCodeFollower::getRangeSt() const 161{ 162 return m_st_range_addr; 163} 164 165inline const ocsd_vaddr_t OcsdCodeFollower::getRangeEn() const 166{ 167 return m_en_range_addr; 168} 169 170inline const bool OcsdCodeFollower::hasRange() const 171{ 172 return m_st_range_addr < m_en_range_addr; 173} 174 175inline const bool OcsdCodeFollower::hasNextAddr() const 176{ 177 return m_b_next_valid; 178} 179 180inline const ocsd_vaddr_t OcsdCodeFollower::getNextAddr() const 181{ 182 return m_next_addr; 183} 184 185// information on last instruction executed in range. 186inline const ocsd_instr_type OcsdCodeFollower::getInstrType() const 187{ 188 return m_instr_info.type; 189} 190 191inline const ocsd_instr_subtype OcsdCodeFollower::getInstrSubType() const 192{ 193 return m_instr_info.sub_type; 194} 195 196inline const uint8_t OcsdCodeFollower::getInstrSize() const 197{ 198 return m_instr_info.instr_size; 199} 200 201inline const bool OcsdCodeFollower::isCondInstr() const 202{ 203 return (bool)(m_instr_info.is_conditional == 1); 204} 205 206inline const bool OcsdCodeFollower::isLink() const 207{ 208 return (bool)(m_instr_info.is_link == 1); 209} 210 211inline const bool OcsdCodeFollower::ISAChanged() const 212{ 213 return (bool)(m_instr_info.isa != m_instr_info.next_isa); 214} 215 216inline const ocsd_isa OcsdCodeFollower::nextISA() const 217{ 218 return m_instr_info.next_isa; 219} 220 221// information on error conditions 222inline const bool OcsdCodeFollower::isNacc() const 223{ 224 return m_b_nacc_err; 225} 226 227inline void OcsdCodeFollower::clearNacc() 228{ 229 m_b_nacc_err = false; 230} 231 232inline const ocsd_vaddr_t OcsdCodeFollower::getNaccAddr() const 233{ 234 return m_nacc_address; 235} 236 237/* End of File ocsd_code_follower.h */ 238