1 /*
2  * \file       ocsd_gen_elem_list.h
3  * \brief      OpenCSD : Generic element output list.
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 #include <list>
36 #include "trc_gen_elem.h"
37 #include "comp_attach_pt_t.h"
38 #include "interfaces/trc_gen_elem_in_i.h"
39 
40 /*!
41  * @class OcsdGenElemList
42  * @brief Maintain a list of elements to be output
43  *
44  * Each incoming packet can result in multiple output elements.
45  * These are stacked in this class prior to entering the output phase of processing.
46  *
47  * This should remove some of the requirement on the packet processing to be re-enterant,
48  * simplifying this code.
49  *
50  * Last element(s) on this list can be marked pending to allow for later cancellation.
51  * (This required for cancel element in ETMv3 exeception branch).
52  *
53  * The "list" is actually a ring buffer - maintaining pointers to indicate current valid elements.
54  * This buffer can increase on demand, but will only be released at the end of a decode session.
55  */
56 class OcsdGenElemList
57 {
58 public:
59     OcsdGenElemList();
60     ~OcsdGenElemList();
61 
62     void initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf);
63     void initCSID(const uint8_t CSID) { m_CSID = CSID; };
64 
65     void reset();   //!< reset the element list.
66 
67     OcsdTraceElement *getNextElem(const ocsd_trc_index_t trc_pkt_idx); //!< get next free element on the stack (add one to the output)
68     const int getNumElem() const;                                      //!< return the total number of elements on the stack (inlcuding any pended ones).
69 
70     const ocsd_gen_trc_elem_t getElemType(const int entryN) const;    //!< get the type for the nth element in the stack (0 indexed)
71 
72     void pendLastNElem(int numPend);    //!< Last element to be pended prior to cancel/commit decision.
73     void commitAllPendElem();           //!< commit all pended elements.
74     void cancelPendElem();              //!< cancel the last pended element on the stack.
75     const int numPendElem() const;      //!< return the number of pended elements.
76 
77     /*! Send all of the none pended elements
78         Stop sending when all sent or _CONT response.
79      */
80     ocsd_datapath_resp_t sendElements();
81     const bool elemToSend() const;  //!< true if any none-pending elements left to send.
82 
83 private:
84 
85     void growArray();
86     const int getAdjustedIdx(int idxIn) const;  //!< get adjusted index into circular buffer.
87 
88 
89     // list element contains pointer and byte index in trace stream
90     typedef struct _elemPtr {
91         OcsdTraceElement *pElem;        //!< pointer to the listed trace element
92         ocsd_trc_index_t trc_pkt_idx;   //!< packet index in the trace stream
93     } elemPtr_t;
94 
95     elemPtr_t *m_pElemArray;    //!< an array of pointers to elements.
96     int m_elemArraySize;        //!< number of element pointers in the array
97 
98     int m_firstElemIdx;        //!< internal index in array of first element in use.
99     int m_numUsed;             //!< number of elements in use
100     int m_numPend;             //!< internal count of pended elements.
101 
102     uint8_t m_CSID;
103 
104     componentAttachPt<ITrcGenElemIn> *m_sendIf; //!< element send interface.
105 };
106 
107 inline const int OcsdGenElemList::getAdjustedIdx(int idxIn) const
108 {
109     if(idxIn >= m_elemArraySize)
110         idxIn -= m_elemArraySize;
111     return idxIn;
112 }
113 
114 inline const int OcsdGenElemList::getNumElem() const
115 {
116     return m_numUsed;
117 }
118 
119 inline const int OcsdGenElemList::numPendElem() const
120 {
121     return m_numPend;
122 }
123 
124 inline void OcsdGenElemList::pendLastNElem(int numPend)
125 {
126     if(numPend >= getNumElem())
127         m_numPend = numPend;
128 }
129 
130 inline void OcsdGenElemList::commitAllPendElem()
131 {
132      m_numPend = 0;
133 }
134 
135 inline void OcsdGenElemList::cancelPendElem()
136 {
137     if(m_numPend > 0)
138     {
139         m_numUsed -= m_numPend;
140     }
141 }
142 
143 inline const bool OcsdGenElemList::elemToSend() const
144 {
145     return ((getNumElem() - m_numPend) > 0);
146 }
147 
148 inline void OcsdGenElemList::initSendIf(componentAttachPt<ITrcGenElemIn> *pGenElemIf)
149 {
150     m_sendIf = pGenElemIf;
151 }
152 
153 /* End of File ocsd_gen_elem_list.h */
154