1 /* 2 * \file trc_etmv4_stack_elem.h 3 * \brief OpenCSD : 4 * 5 * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. 6 */ 7 /* 8 * Redistribution and use in source and binary forms, with or without modification, 9 * are permitted provided that the following conditions are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of the copyright holder nor the names of its contributors 19 * may be used to endorse or promote products derived from this software without 20 * specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 #ifndef ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED 34 #define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED 35 36 #include "opencsd/etmv4/trc_pkt_types_etmv4.h" 37 38 #include <deque> 39 #include <vector> 40 41 /* ETMv4 I trace stack elements 42 Speculation requires that we stack certain elements till they are committed or 43 cancelled. (P0 elements + other associated parts.) 44 */ 45 46 typedef enum _p0_elem_t 47 { 48 P0_UNKNOWN, 49 P0_ATOM, 50 P0_ADDR, 51 P0_CTXT, 52 P0_TRC_ON, 53 P0_EXCEP, 54 P0_EXCEP_RET, 55 P0_EVENT, 56 P0_TS, 57 P0_CC, 58 P0_TS_CC, 59 P0_OVERFLOW 60 } p0_elem_t; 61 62 63 /************************************************************/ 64 /***Trace stack element base class - 65 record originating packet type and index in buffer*/ 66 67 class TrcStackElem { 68 public: 69 TrcStackElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 70 virtual ~TrcStackElem() {}; 71 72 const p0_elem_t getP0Type() const { return m_P0_type; }; 73 const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; }; 74 const ocsd_trc_index_t getRootIndex() const { return m_root_idx; }; 75 const bool isP0() const { return m_is_P0; }; 76 77 private: 78 ocsd_etmv4_i_pkt_type m_root_pkt; 79 ocsd_trc_index_t m_root_idx; 80 p0_elem_t m_P0_type; 81 82 protected: 83 bool m_is_P0; // true if genuine P0 - commit / cancellable, false otherwise 84 85 }; 86 87 inline TrcStackElem::TrcStackElem(p0_elem_t p0_type, const bool isP0, ocsd_etmv4_i_pkt_type root_pkt, ocsd_trc_index_t root_index) : 88 m_root_pkt(root_pkt), 89 m_root_idx(root_index), 90 m_P0_type(p0_type), 91 m_is_P0(isP0) 92 { 93 } 94 95 /************************************************************/ 96 /** Address element */ 97 98 class TrcStackElemAddr : public TrcStackElem 99 { 100 protected: 101 TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 102 virtual ~TrcStackElemAddr() {}; 103 104 friend class EtmV4P0Stack; 105 106 public: 107 void setAddr(const etmv4_addr_val_t &addr_val) { m_addr_val = addr_val; }; 108 const etmv4_addr_val_t &getAddr() const { return m_addr_val; }; 109 110 private: 111 etmv4_addr_val_t m_addr_val; 112 }; 113 114 inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : 115 TrcStackElem(P0_ADDR, false, root_pkt,root_index) 116 { 117 m_addr_val.val = 0; 118 m_addr_val.isa = 0; 119 } 120 121 /************************************************************/ 122 /** Context element */ 123 124 class TrcStackElemCtxt : public TrcStackElem 125 { 126 protected: 127 TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 128 virtual ~TrcStackElemCtxt() {}; 129 130 friend class EtmV4P0Stack; 131 132 public: 133 void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; }; 134 const etmv4_context_t &getContext() const { return m_context; }; 135 136 private: 137 etmv4_context_t m_context; 138 }; 139 140 inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : 141 TrcStackElem(P0_CTXT, false, root_pkt,root_index) 142 { 143 } 144 145 /************************************************************/ 146 /** Exception element */ 147 148 class TrcStackElemExcept : public TrcStackElem 149 { 150 protected: 151 TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 152 virtual ~TrcStackElemExcept() {}; 153 154 friend class EtmV4P0Stack; 155 156 public: 157 void setPrevSame(bool bSame) { m_prev_addr_same = bSame; }; 158 const bool getPrevSame() const { return m_prev_addr_same; }; 159 160 void setExcepNum(const uint16_t num) { m_excep_num = num; }; 161 const uint16_t getExcepNum() const { return m_excep_num; }; 162 163 private: 164 bool m_prev_addr_same; 165 uint16_t m_excep_num; 166 }; 167 168 inline TrcStackElemExcept::TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : 169 TrcStackElem(P0_EXCEP, true, root_pkt,root_index), 170 m_prev_addr_same(false) 171 { 172 } 173 174 /************************************************************/ 175 /** Atom element */ 176 177 class TrcStackElemAtom : public TrcStackElem 178 { 179 protected: 180 TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 181 virtual ~TrcStackElemAtom() {}; 182 183 friend class EtmV4P0Stack; 184 185 public: 186 void setAtom(const ocsd_pkt_atom &atom) { m_atom = atom; }; 187 188 const ocsd_atm_val commitOldest(); 189 int cancelNewest(const int nCancel); 190 const bool isEmpty() const { return (m_atom.num == 0); }; 191 192 private: 193 ocsd_pkt_atom m_atom; 194 }; 195 196 inline TrcStackElemAtom::TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : 197 TrcStackElem(P0_ATOM, true, root_pkt,root_index) 198 { 199 m_atom.num = 0; 200 } 201 202 // commit oldest - get value and remove it from pattern 203 inline const ocsd_atm_val TrcStackElemAtom::commitOldest() 204 { 205 ocsd_atm_val val = (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N; 206 m_atom.num--; 207 m_atom.En_bits >>= 1; 208 return val; 209 } 210 211 // cancel newest - just reduce the atom count. 212 inline int TrcStackElemAtom::cancelNewest(const int nCancel) 213 { 214 int nRemove = (nCancel <= m_atom.num) ? nCancel : m_atom.num; 215 m_atom.num -= nRemove; 216 return nRemove; 217 } 218 219 /************************************************************/ 220 /** Generic param element */ 221 222 class TrcStackElemParam : public TrcStackElem 223 { 224 protected: 225 TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 226 virtual ~TrcStackElemParam() {}; 227 228 friend class EtmV4P0Stack; 229 230 public: 231 void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; }; 232 const uint32_t &getParam(const int nParamNum) const { return m_param[(nParamNum & 0x3)]; }; 233 234 private: 235 uint32_t m_param[4]; 236 }; 237 238 inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : 239 TrcStackElem(p0_type, isP0, root_pkt,root_index) 240 { 241 } 242 243 /************************************************************/ 244 /* P0 element stack that allows push of elements, and deletion of elements when done. 245 */ 246 class EtmV4P0Stack 247 { 248 public: 249 EtmV4P0Stack() {}; 250 ~EtmV4P0Stack(); 251 252 void push_front(TrcStackElem *pElem); 253 void pop_back(); 254 TrcStackElem *back(); 255 size_t size(); 256 257 void delete_all(); 258 void delete_back(); 259 void delete_popped(); 260 261 // creation functions - create and push if successful. 262 TrcStackElemParam *createParamElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const std::vector<uint32_t> ¶ms); 263 TrcStackElemParam *createParamElemNoParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); 264 TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom); 265 TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum); 266 TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context); 267 TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val); 268 269 private: 270 std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack 271 std::vector<TrcStackElem *> m_popped_elem; //!< save list of popped but not deleted elements. 272 273 }; 274 275 inline EtmV4P0Stack::~EtmV4P0Stack() 276 { 277 delete_all(); 278 delete_popped(); 279 } 280 281 // put an element on the front of the stack 282 inline void EtmV4P0Stack::push_front(TrcStackElem *pElem) 283 { 284 m_P0_stack.push_front(pElem); 285 } 286 287 // pop last element pointer off the stack and stash it for later deletion 288 inline void EtmV4P0Stack::pop_back() 289 { 290 m_popped_elem.push_back(m_P0_stack.back()); 291 m_P0_stack.pop_back(); 292 } 293 294 // pop last element pointer off the stack and delete immediately 295 inline void EtmV4P0Stack::delete_back() 296 { 297 if (m_P0_stack.size() > 0) 298 { 299 TrcStackElem* pElem = m_P0_stack.back(); 300 delete pElem; 301 m_P0_stack.pop_back(); 302 } 303 } 304 305 // get a pointer to the last element on the stack 306 inline TrcStackElem *EtmV4P0Stack::back() 307 { 308 return m_P0_stack.back(); 309 } 310 311 // remove and delete all the elements left on the stack 312 inline void EtmV4P0Stack::delete_all() 313 { 314 while (m_P0_stack.size() > 0) 315 delete_back(); 316 m_P0_stack.clear(); 317 } 318 319 // delete list of popped elements. 320 inline void EtmV4P0Stack::delete_popped() 321 { 322 while (m_popped_elem.size() > 0) 323 { 324 delete m_popped_elem.back(); 325 m_popped_elem.pop_back(); 326 } 327 m_popped_elem.clear(); 328 } 329 330 // get current number of elements on the stack 331 inline size_t EtmV4P0Stack::size() 332 { 333 return m_P0_stack.size(); 334 } 335 336 #endif // ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED 337 338 /* End of File trc_etmv4_stack_elem.h */ 339