• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "opencsd/trc_gen_elem_types.h"
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 {
49     P0_UNKNOWN,
50     P0_ATOM,
51     P0_ADDR,
52     P0_CTXT,
53     P0_TRC_ON,
54     P0_EXCEP,
55     P0_EXCEP_RET,
56     P0_EVENT,
57     P0_TS,
58     P0_CC,
59     P0_TS_CC,
60     P0_MARKER,
61     P0_Q,
62     P0_OVERFLOW,
63     P0_FUNC_RET,
64     P0_SRC_ADDR,
65     P0_TRANS_TRACE_INIT,
66     P0_TRANS_START,
67     P0_TRANS_COMMIT,
68     P0_TRANS_FAIL
69 } p0_elem_t;
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);
~TrcStackElem()79      virtual ~TrcStackElem() {};
80 
getP0Type()81      const p0_elem_t getP0Type() const { return m_P0_type; };
getRootPkt()82      const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; };
getRootIndex()83      const ocsd_trc_index_t getRootIndex() const  { return m_root_idx; };
isP0()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 
TrcStackElem(p0_elem_t p0_type,const bool isP0,ocsd_etmv4_i_pkt_type root_pkt,ocsd_trc_index_t root_index)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 /************************************************************/
105 /** Address element */
106 
107 class TrcStackElemAddr : public TrcStackElem
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);
~TrcStackElemAddr()112     virtual ~TrcStackElemAddr() {};
113 
114     friend class EtmV4P0Stack;
115 
116 public:
setAddr(const etmv4_addr_val_t & addr_val)117     void setAddr(const etmv4_addr_val_t &addr_val) { m_addr_val = addr_val; };
getAddr()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 
TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)124 inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
125     TrcStackElem(P0_ADDR, false, root_pkt,root_index)
126 {
127     m_addr_val.val = 0;
128     m_addr_val.isa = 0;
129 }
130 
TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const bool src_addr)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 /************************************************************/
140 /** Q element */
141 class TrcStackQElem : public TrcStackElem
142 {
143 protected:
144     TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
~TrcStackQElem()145     virtual ~TrcStackQElem() {};
146 
147     friend class EtmV4P0Stack;
148 
149 public:
setInstrCount(const int instr_count)150     void setInstrCount(const int instr_count) { m_instr_count = instr_count; };
getInstrCount()151     const int getInstrCount() const { return m_instr_count;  }
152 
setAddr(const etmv4_addr_val_t & addr_val)153     void setAddr(const etmv4_addr_val_t &addr_val)
154     {
155         m_addr_val = addr_val;
156         m_has_addr = true;
157     };
getAddr()158     const etmv4_addr_val_t &getAddr() const { return m_addr_val; };
hasAddr()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 
TrcStackQElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)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 /************************************************************/
178 /** Context element */
179 
180 class TrcStackElemCtxt : public TrcStackElem
181 {
182 protected:
183     TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
~TrcStackElemCtxt()184     virtual ~TrcStackElemCtxt() {};
185 
186     friend class EtmV4P0Stack;
187 
188 public:
setContext(const etmv4_context_t & ctxt)189     void setContext(const  etmv4_context_t &ctxt) { m_context = ctxt; };
getContext()190     const  etmv4_context_t &getContext() const  { return m_context; };
setIS(const uint8_t IS)191     void setIS(const uint8_t IS) { m_IS = IS; };
getIS()192     const uint8_t getIS() const { return m_IS; };
193 
194 private:
195      etmv4_context_t m_context;
196      uint8_t m_IS;  //!< IS value at time of generation of packet.
197 };
198 
TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)199 inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
200     TrcStackElem(P0_CTXT, false, root_pkt,root_index)
201 {
202 }
203 
204 /************************************************************/
205 /** Exception element */
206 
207 class TrcStackElemExcept : public TrcStackElem
208 {
209 protected:
210     TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
~TrcStackElemExcept()211     virtual ~TrcStackElemExcept() {};
212 
213     friend class EtmV4P0Stack;
214 
215 public:
setPrevSame(bool bSame)216     void setPrevSame(bool bSame) { m_prev_addr_same = bSame; };
getPrevSame()217     const bool getPrevSame() const { return m_prev_addr_same; };
218 
setExcepNum(const uint16_t num)219     void setExcepNum(const uint16_t num) { m_excep_num = num; };
getExcepNum()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 
TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)227 inline TrcStackElemExcept::TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
228     TrcStackElem(P0_EXCEP, true, root_pkt,root_index),
229         m_prev_addr_same(false)
230 {
231 }
232 
233 /************************************************************/
234 /** Atom element */
235 
236 class TrcStackElemAtom : public TrcStackElem
237 {
238 protected:
239     TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
~TrcStackElemAtom()240     virtual ~TrcStackElemAtom() {};
241 
242     friend class EtmV4P0Stack;
243 
244 public:
setAtom(const ocsd_pkt_atom & atom)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();
isEmpty()250     const bool isEmpty() const { return (m_atom.num == 0); };
251 
252 private:
253     ocsd_pkt_atom m_atom;
254 };
255 
TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)256 inline TrcStackElemAtom::TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
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
commitOldest()263 inline const ocsd_atm_val TrcStackElemAtom::commitOldest()
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.
cancelNewest(const int nCancel)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
mispredictNewest()280 inline void TrcStackElemAtom::mispredictNewest()
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 /************************************************************/
290 /** Generic param element */
291 
292 class TrcStackElemParam : public TrcStackElem
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);
~TrcStackElemParam()296     virtual ~TrcStackElemParam() {};
297 
298     friend class EtmV4P0Stack;
299 
300 public:
setParam(const uint32_t param,const int nParamNum)301     void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; };
getParam(const int nParamNum)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 
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)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 /************************************************************/
314 /** Marker element */
315 
316 class TrcStackElemMarker : public TrcStackElem
317 {
318 protected:
319     TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
~TrcStackElemMarker()320     virtual ~TrcStackElemMarker() {};
321 
322     friend class EtmV4P0Stack;
323 
324 public:
setMarker(const trace_marker_payload_t & marker)325     void setMarker(const trace_marker_payload_t &marker) { m_marker = marker; };
getMarker()326     const trace_marker_payload_t &getMarker() const { return m_marker; };
327 
328 private:
329     trace_marker_payload_t m_marker;
330 };
331 
TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index)332 inline TrcStackElemMarker::TrcStackElemMarker(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
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 */
341 class EtmV4P0Stack
342 {
343 public:
EtmV4P0Stack()344     EtmV4P0Stack() {};
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
356     void from_front_init();
357     TrcStackElem *from_front_next();
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);
373     TrcStackElemMarker *createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker);
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;  //!< P0 decode element stack
378     std::vector<TrcStackElem *> m_popped_elem;  //!< save list of popped but not deleted elements.
379     std::deque<TrcStackElem *>::iterator m_iter;    //!< iterate across the list w/o removing stuff
380 };
381 
~EtmV4P0Stack()382 inline EtmV4P0Stack::~EtmV4P0Stack()
383 {
384     delete_all();
385     delete_popped();
386 }
387 
388 // put an element on the front of the stack
push_front(TrcStackElem * pElem)389 inline void EtmV4P0Stack::push_front(TrcStackElem *pElem)
390 {
391     m_P0_stack.push_front(pElem);
392 }
393 
394 // put an element on the back of the stack
push_back(TrcStackElem * pElem)395 inline void EtmV4P0Stack::push_back(TrcStackElem *pElem)
396 {
397     m_P0_stack.push_back(pElem);
398 }
399 
400 // pop last element pointer off the stack and stash it for later deletion
pop_back(bool pend_delete)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 
pop_front(bool pend_delete)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
delete_back()416 inline void EtmV4P0Stack::delete_back()
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
delete_front()427 inline void EtmV4P0Stack::delete_front()
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
back()440 inline TrcStackElem *EtmV4P0Stack::back()
441 {
442     return m_P0_stack.back();
443 }
444 
front()445 inline TrcStackElem *EtmV4P0Stack::front()
446 {
447     return m_P0_stack.front();
448 }
449 
450 // remove and delete all the elements left on the stack
delete_all()451 inline void EtmV4P0Stack::delete_all()
452 {
453     while (m_P0_stack.size() > 0)
454         delete_back();
455     m_P0_stack.clear();
456 }
457 
458 // delete list of popped elements.
delete_popped()459 inline void EtmV4P0Stack::delete_popped()
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
size()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 */
478