OpenCSD - CoreSight Trace Decode Library  1.3.3
trc_etmv4_stack_elem.h
Go to the documentation of this file.
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 
38 
39 #include <deque>
40 #include <vector>
41 
42 /* ETMv4 I trace stack elements
43  Speculation requires that we stack certain elements till they are committed or
44  cancelled. (P0 elements + other associated parts.)
45 */
46 
47 typedef enum _p0_elem_t
48 {
70 
71 
72 /************************************************************/
73 /***Trace stack element base class -
74  record originating packet type and index in buffer*/
75 
76 class TrcStackElem {
77 public:
78  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);
79  virtual ~TrcStackElem() {};
80 
81  const p0_elem_t getP0Type() const { return m_P0_type; };
82  const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; };
83  const ocsd_trc_index_t getRootIndex() const { return m_root_idx; };
84  const bool isP0() const { return m_is_P0; };
85 
86 private:
87  ocsd_etmv4_i_pkt_type m_root_pkt;
88  ocsd_trc_index_t m_root_idx;
89  p0_elem_t m_P0_type;
90 
91 protected:
92  bool m_is_P0; // true if genuine P0 - commit / cancellable, false otherwise
93 
94 };
95 
96 inline TrcStackElem::TrcStackElem(p0_elem_t p0_type, const bool isP0, ocsd_etmv4_i_pkt_type root_pkt, ocsd_trc_index_t root_index) :
97  m_root_pkt(root_pkt),
98  m_root_idx(root_index),
99  m_P0_type(p0_type),
100  m_is_P0(isP0)
101 {
102 }
103 
104 /************************************************************/
108 {
109 protected:
110  TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
111  TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr);
112  virtual ~TrcStackElemAddr() {};
113 
114  friend class EtmV4P0Stack;
115 
116 public:
117  void setAddr(const etmv4_addr_val_t &addr_val) { m_addr_val = addr_val; };
118  const etmv4_addr_val_t &getAddr() const { return m_addr_val; };
119 
120 private:
121  etmv4_addr_val_t m_addr_val;
122 };
123 
125  TrcStackElem(P0_ADDR, false, root_pkt,root_index)
126 {
127  m_addr_val.val = 0;
128  m_addr_val.isa = 0;
129 }
130 
131 inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool src_addr) :
132  TrcStackElem(src_addr ? P0_SRC_ADDR : P0_ADDR, false, root_pkt, root_index)
133 {
134  m_addr_val.val = 0;
135  m_addr_val.isa = 0;
136 }
137 
138 
139 /************************************************************/
142 {
143 protected:
144  TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
145  virtual ~TrcStackQElem() {};
146 
147  friend class EtmV4P0Stack;
148 
149 public:
150  void setInstrCount(const int instr_count) { m_instr_count = instr_count; };
151  const int getInstrCount() const { return m_instr_count; }
152 
153  void setAddr(const etmv4_addr_val_t &addr_val)
154  {
155  m_addr_val = addr_val;
156  m_has_addr = true;
157  };
158  const etmv4_addr_val_t &getAddr() const { return m_addr_val; };
159  const bool hasAddr() const { return m_has_addr; };
160 
161 private:
162  bool m_has_addr;
163  etmv4_addr_val_t m_addr_val;
164  int m_instr_count;
165 
166 };
167 
168 inline TrcStackQElem::TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
169  TrcStackElem(P0_Q , true, root_pkt, root_index)
170 {
171  m_addr_val.val = 0;
172  m_addr_val.isa = 0;
173  m_has_addr = false;
174  m_instr_count = 0;
175 }
176 
177 /************************************************************/
181 {
182 protected:
183  TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
184  virtual ~TrcStackElemCtxt() {};
185 
186  friend class EtmV4P0Stack;
187 
188 public:
189  void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; };
190  const etmv4_context_t &getContext() const { return m_context; };
191  void setIS(const uint8_t IS) { m_IS = IS; };
192  const uint8_t getIS() const { return m_IS; };
193 
194 private:
195  etmv4_context_t m_context;
196  uint8_t m_IS;
197 };
198 
200  TrcStackElem(P0_CTXT, false, root_pkt,root_index)
201 {
202 }
203 
204 /************************************************************/
208 {
209 protected:
210  TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
211  virtual ~TrcStackElemExcept() {};
212 
213  friend class EtmV4P0Stack;
214 
215 public:
216  void setPrevSame(bool bSame) { m_prev_addr_same = bSame; };
217  const bool getPrevSame() const { return m_prev_addr_same; };
218 
219  void setExcepNum(const uint16_t num) { m_excep_num = num; };
220  const uint16_t getExcepNum() const { return m_excep_num; };
221 
222 private:
223  bool m_prev_addr_same;
224  uint16_t m_excep_num;
225 };
226 
228  TrcStackElem(P0_EXCEP, true, root_pkt,root_index),
229  m_prev_addr_same(false)
230 {
231 }
232 
233 /************************************************************/
237 {
238 protected:
239  TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
240  virtual ~TrcStackElemAtom() {};
241 
242  friend class EtmV4P0Stack;
243 
244 public:
245  void setAtom(const ocsd_pkt_atom &atom) { m_atom = atom; };
246 
247  const ocsd_atm_val commitOldest();
248  int cancelNewest(const int nCancel);
249  void mispredictNewest();
250  const bool isEmpty() const { return (m_atom.num == 0); };
251 
252 private:
253  ocsd_pkt_atom m_atom;
254 };
255 
257  TrcStackElem(P0_ATOM, true, root_pkt,root_index)
258 {
259  m_atom.num = 0;
260 }
261 
262 // commit oldest - get value and remove it from pattern
264 {
265  ocsd_atm_val val = (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N;
266  m_atom.num--;
267  m_atom.En_bits >>= 1;
268  return val;
269 }
270 
271 // cancel newest - just reduce the atom count.
272 inline int TrcStackElemAtom::cancelNewest(const int nCancel)
273 {
274  int nRemove = (nCancel <= m_atom.num) ? nCancel : m_atom.num;
275  m_atom.num -= nRemove;
276  return nRemove;
277 }
278 
279 // mispredict newest - flip the bit of the newest atom
281 {
282  uint32_t mask = 0x1 << (m_atom.num - 1);
283  if (m_atom.En_bits & mask)
284  m_atom.En_bits &= ~mask;
285  else
286  m_atom.En_bits |= mask;
287 }
288 
289 /************************************************************/
293 {
294 protected:
295  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);
296  virtual ~TrcStackElemParam() {};
297 
298  friend class EtmV4P0Stack;
299 
300 public:
301  void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; };
302  const uint32_t &getParam(const int nParamNum) const { return m_param[(nParamNum & 0x3)]; };
303 
304 private:
305  uint32_t m_param[4];
306 };
307 
308 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) :
309  TrcStackElem(p0_type, isP0, root_pkt,root_index)
310 {
311 }
312 
313 /************************************************************/
317 {
318 protected:
319  TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
320  virtual ~TrcStackElemMarker() {};
321 
322  friend class EtmV4P0Stack;
323 
324 public:
325  void setMarker(const trace_marker_payload_t &marker) { m_marker = marker; };
326  const trace_marker_payload_t &getMarker() const { return m_marker; };
327 
328 private:
329  trace_marker_payload_t m_marker;
330 };
331 
333  TrcStackElem(P0_MARKER, false, root_pkt, root_index)
334 {
335 }
336 
337 
338 /************************************************************/
339 /* P0 element stack that allows push of elements, and deletion of elements when done.
340 */
342 {
343 public:
345  ~EtmV4P0Stack();
346 
347  void push_front(TrcStackElem *pElem);
348  void push_back(TrcStackElem *pElem); // insert element when processing
349  void pop_back(bool pend_delete = true);
350  void pop_front(bool pend_delete = true);
351  TrcStackElem *back();
352  TrcStackElem *front();
353  size_t size();
354 
355  // iterate through stack from front
358  void erase_curr_from_front(); // erase the element last returned
359 
360  void delete_all();
361  void delete_back();
362  void delete_front();
363  void delete_popped();
364 
365  // creation functions - create and push if successful.
366  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> &params);
367  TrcStackElem *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, bool back = false);
368  TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom);
369  TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum);
370  TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back = false);
371  TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
372  TrcStackQElem *createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count);
374  TrcStackElemAddr *createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
375 
376 private:
377  std::deque<TrcStackElem *> m_P0_stack;
378  std::vector<TrcStackElem *> m_popped_elem;
379  std::deque<TrcStackElem *>::iterator m_iter;
380 };
381 
383 {
384  delete_all();
385  delete_popped();
386 }
387 
388 // put an element on the front of the stack
390 {
391  m_P0_stack.push_front(pElem);
392 }
393 
394 // put an element on the back of the stack
396 {
397  m_P0_stack.push_back(pElem);
398 }
399 
400 // pop last element pointer off the stack and stash it for later deletion
401 inline void EtmV4P0Stack::pop_back(bool pend_delete /* = true */)
402 {
403  if (pend_delete)
404  m_popped_elem.push_back(m_P0_stack.back());
405  m_P0_stack.pop_back();
406 }
407 
408 inline void EtmV4P0Stack::pop_front(bool pend_delete /* = true */)
409 {
410  if (pend_delete)
411  m_popped_elem.push_back(m_P0_stack.front());
412  m_P0_stack.pop_front();
413 }
414 
415 // pop last element pointer off the stack and delete immediately
417 {
418  if (m_P0_stack.size() > 0)
419  {
420  TrcStackElem* pElem = m_P0_stack.back();
421  delete pElem;
422  m_P0_stack.pop_back();
423  }
424 }
425 
426 // pop first element pointer off the stack and delete immediately
428 {
429  if (m_P0_stack.size() > 0)
430  {
431  TrcStackElem* pElem = m_P0_stack.front();
432  delete pElem;
433  m_P0_stack.pop_front();
434  }
435 }
436 
437 
438 
439 // get a pointer to the last element on the stack
441 {
442  return m_P0_stack.back();
443 }
444 
446 {
447  return m_P0_stack.front();
448 }
449 
450 // remove and delete all the elements left on the stack
452 {
453  while (m_P0_stack.size() > 0)
454  delete_back();
455  m_P0_stack.clear();
456 }
457 
458 // delete list of popped elements.
460 {
461  while (m_popped_elem.size() > 0)
462  {
463  delete m_popped_elem.back();
464  m_popped_elem.pop_back();
465  }
466  m_popped_elem.clear();
467 }
468 
469 // get current number of elements on the stack
470 inline size_t EtmV4P0Stack::size()
471 {
472  return m_P0_stack.size();
473 }
474 
475 #endif // ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED
476 
477 /* End of File trc_etmv4_stack_elem.h */
void from_front_init()
TrcStackElemMarker * createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker)
void erase_curr_from_front()
TrcStackElemExcept * createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum)
TrcStackElem * from_front_next()
void pop_front(bool pend_delete=true)
TrcStackElem * front()
TrcStackQElem * createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count)
TrcStackElemCtxt * createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back=false)
TrcStackElem * 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, bool back=false)
TrcStackElemAtom * createAtomElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom)
void push_front(TrcStackElem *pElem)
TrcStackElem * back()
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 > &params)
TrcStackElemAddr * createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val)
void push_back(TrcStackElem *pElem)
void pop_back(bool pend_delete=true)
TrcStackElemAddr * createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val)
TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
const etmv4_addr_val_t & getAddr() const
void setAddr(const etmv4_addr_val_t &addr_val)
int cancelNewest(const int nCancel)
const bool isEmpty() const
void setAtom(const ocsd_pkt_atom &atom)
TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
const ocsd_atm_val commitOldest()
void setIS(const uint8_t IS)
TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
void setContext(const etmv4_context_t &ctxt)
const etmv4_context_t & getContext() const
const uint8_t getIS() const
void setPrevSame(bool bSame)
const bool getPrevSame() const
TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
void setExcepNum(const uint16_t num)
const uint16_t getExcepNum() const
const ocsd_trc_index_t getRootIndex() const
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)
virtual ~TrcStackElem()
const bool isP0() const
const ocsd_etmv4_i_pkt_type getRootPkt() const
const p0_elem_t getP0Type() const
const trace_marker_payload_t & getMarker() const
TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
void setMarker(const trace_marker_payload_t &marker)
void setParam(const uint32_t param, const int nParamNum)
const uint32_t & getParam(const int nParamNum) const
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)
TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index)
void setInstrCount(const int instr_count)
const int getInstrCount() const
const bool hasAddr() const
const etmv4_addr_val_t & getAddr() const
void setAddr(const etmv4_addr_val_t &addr_val)
uint32_t ocsd_trc_index_t
Definition: ocsd_if_types.h:67
enum _ocsd_atm_val ocsd_atm_val
enum _ocsd_etmv4_i_pkt_type ocsd_etmv4_i_pkt_type
@ ATOM_N
Definition: trc_pkt_types.h:80
@ ATOM_E
Definition: trc_pkt_types.h:81
ocsd_vaddr_t val
Address value.
uint8_t isa
instruction set.
uint32_t En_bits
Definition: trc_pkt_types.h:90
@ P0_TRANS_START
@ P0_TRANS_TRACE_INIT
@ P0_FUNC_RET
@ P0_TRANS_FAIL
@ P0_EXCEP_RET
@ P0_EVENT
@ P0_MARKER
@ P0_TRC_ON
@ P0_TRANS_COMMIT
@ P0_OVERFLOW
@ P0_TS_CC
@ P0_SRC_ADDR
@ P0_EXCEP
@ P0_UNKNOWN
enum _p0_elem_t p0_elem_t
OpenCSD : Decoder Output Generic Element types.