]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/opencsd/decoder/source/stm/trc_pkt_decode_stm.cpp
Re-add opencsd as a vendor import from the dist directory
[FreeBSD/FreeBSD.git] / contrib / opencsd / decoder / source / stm / trc_pkt_decode_stm.cpp
1 /*
2  * \file       trc_pkt_decode_stm.cpp
3  * \brief      OpenCSD : STM packet decoder - output generic SW trace packets.
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 "opencsd/stm/trc_pkt_decode_stm.h"
36 #define DCD_NAME "DCD_STM"
37
38 TrcPktDecodeStm::TrcPktDecodeStm()
39     : TrcPktDecodeBase(DCD_NAME)
40 {
41     initDecoder();
42 }
43
44 TrcPktDecodeStm::TrcPktDecodeStm(int instIDNum)
45     : TrcPktDecodeBase(DCD_NAME, instIDNum)
46 {
47     initDecoder();
48 }
49
50 TrcPktDecodeStm::~TrcPktDecodeStm()
51 {
52     if(m_payload_buffer)
53         delete [] m_payload_buffer;
54     m_payload_buffer = 0;
55 }
56
57 /* implementation packet decoding interface */
58 ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
59 {
60     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
61     bool bPktDone = false;
62
63     m_decode_pass1 = true;
64
65     while(!bPktDone)
66     {
67         switch(m_curr_state)
68         {
69         case NO_SYNC:
70             m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
71             resp = outputTraceElement(m_output_elem);
72             m_curr_state = WAIT_SYNC;
73             break;
74
75         case WAIT_SYNC:
76             if(m_curr_packet_in->getPktType() == STM_PKT_ASYNC)
77                 m_curr_state = DECODE_PKTS;
78             bPktDone = true;
79             break;
80
81         case DECODE_PKTS:
82             resp = decodePacket(bPktDone);
83             break;
84         }
85     }
86     return resp;
87 }
88
89 ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
90 {
91     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
92     m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
93     resp = outputTraceElement(m_output_elem);
94     return resp;
95 }
96
97 ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
98 {
99     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
100     resetDecoder();
101     return resp;
102 }
103
104 ocsd_datapath_resp_t TrcPktDecodeStm::onFlush()
105 {
106     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
107     // don't currently save unsent packets so nothing to flush
108     return resp;
109 }
110
111 ocsd_err_t TrcPktDecodeStm::onProtocolConfig()
112 {
113     if(m_config == 0)
114         return OCSD_ERR_NOT_INIT;
115
116     // static config - copy of CSID for easy reference
117     m_CSID = m_config->getTraceID();
118     return OCSD_OK;
119 }
120
121 void TrcPktDecodeStm::initDecoder()
122 {
123     m_payload_buffer = 0;
124     m_num_pkt_correlation = 1;  // fixed at single packet payload correlation - add feature later
125     m_CSID = 0;
126
127     // base decoder state - STM requires no memory and instruction decode.
128     setUsesMemAccess(false);
129     setUsesIDecode(false);
130
131     resetDecoder();
132 }
133
134 void TrcPktDecodeStm::resetDecoder()
135 {
136     m_curr_state = NO_SYNC;
137     m_payload_size = 0;     
138     m_payload_used = 0; 
139     m_payload_odd_nibble = false;
140     m_output_elem.init();
141     m_swt_packet_info.swt_flag_bits = 0;        // zero out everything
142     initPayloadBuffer();
143 }
144
145 void TrcPktDecodeStm::initPayloadBuffer()
146 {
147     // set up the payload buffer. If we are correlating indentical packets then 
148     // need a buffer that is a multiple of 64bit packets.
149     // otherwise a single packet length will do.
150     if(m_payload_buffer)
151         delete [] m_payload_buffer;
152     m_payload_buffer = new (std::nothrow) uint8_t[m_num_pkt_correlation * sizeof(uint64_t)];
153 }
154
155 ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
156 {
157     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
158     bool bSendPacket = false;       // flag to indicate output required.
159
160     bPktDone = true;    // assume complete unless 2nd pass required.
161     m_output_elem.setType(OCSD_GEN_TRC_ELEM_SWTRACE);
162     clearSWTPerPcktInfo();
163     
164     switch (m_curr_packet_in->getPktType())
165     {
166     case STM_PKT_BAD_SEQUENCE:   /**< Incorrect protocol sequence */
167     case STM_PKT_RESERVED:
168         resp = OCSD_RESP_FATAL_INVALID_DATA;
169     case STM_PKT_NOTSYNC:
170         resetDecoder();
171         break;
172
173     case STM_PKT_VERSION:    /**< Version packet  - not relevant to generic (versionless) o/p */
174     case STM_PKT_ASYNC:      /**< Alignment synchronisation packet */
175     case STM_PKT_INCOMPLETE_EOT:     /**< Incomplete packet flushed at end of trace. */
176         // no action required.
177         break;
178
179 /* markers for valid packets*/
180     case STM_PKT_NULL:       /**< Null packet */
181         if(m_curr_packet_in->isTSPkt())
182             bSendPacket = true;     // forward NULL packet if associated timestamp.
183         break;
184         
185     case STM_PKT_FREQ:       /**< Frequency packet */
186         m_swt_packet_info.swt_frequency = 1;
187         updatePayload(bSendPacket);
188         break;
189
190     case STM_PKT_TRIG:       /**< Trigger event packet. */
191         m_swt_packet_info.swt_trigger_event = 1;
192         updatePayload(bSendPacket);
193         break;
194
195     case STM_PKT_GERR:       /**< Global error packet - protocol error but unknown which master had error */
196         m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
197         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel(); 
198         m_swt_packet_info.swt_global_err = 1;
199         m_swt_packet_info.swt_id_valid = 0;
200         updatePayload(bSendPacket);
201         break;
202
203     case STM_PKT_MERR:       /**< Master error packet - current master detected an error (e.g. dropped trace) */
204         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel(); 
205         m_swt_packet_info.swt_master_err = 1;
206         updatePayload(bSendPacket);
207         break;
208
209     case STM_PKT_M8:         /**< Set current master */
210         m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
211         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();  // forced to 0
212         m_swt_packet_info.swt_id_valid = 1;
213         break;
214
215     case STM_PKT_C8:         /**< Set lower 8 bits of current channel - packet proc hadnles this */
216     case STM_PKT_C16:        /**< Set current channel */
217         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel(); 
218         break;
219
220     case STM_PKT_FLAG:       /**< Flag packet */
221         m_swt_packet_info.swt_marker_packet = 1;
222         bSendPacket = true;  // send 0 payload marker packet./
223         break;
224         
225
226     case STM_PKT_D4:         /**< 4 bit data payload packet */
227     case STM_PKT_D8:         /**< 8 bit data payload packet */
228     case STM_PKT_D16:        /**< 16 bit data payload packet */
229     case STM_PKT_D32:        /**< 32 bit data payload packet */
230     case STM_PKT_D64:        /**< 64 bit data payload packet */
231         updatePayload(bSendPacket);
232         break;
233
234     }
235
236     if(bSendPacket)
237     {
238         if(m_curr_packet_in->isTSPkt())
239         {
240             m_output_elem.setTS(m_curr_packet_in->getTSVal());
241             m_swt_packet_info.swt_has_timestamp = 1;
242         }
243         m_output_elem.setSWTInfo(m_swt_packet_info);
244         resp = outputTraceElement(m_output_elem);
245     }
246     
247     return resp;
248 }
249
250 void TrcPktDecodeStm::clearSWTPerPcktInfo()
251 {
252     m_swt_packet_info.swt_flag_bits &= (uint32_t)(0x0 | SWT_ID_VALID_MASK);    // clear flags and current payload size (save id valid flag).
253 }
254
255 void TrcPktDecodeStm::updatePayload(bool &bSendPacket)
256 {
257     // without buffering similar packets - this function is quite simple
258     bSendPacket = true;
259     m_swt_packet_info.swt_payload_num_packets = 1;
260
261     switch(m_curr_packet_in->getPktType())
262     {
263     case STM_PKT_D4:         /**< 4 bit data payload packet */
264         m_swt_packet_info.swt_payload_pkt_bitsize = 4;
265         *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD4Val();
266         break;
267
268     case STM_PKT_D8:         /**< 8 bit data payload packet */
269     case STM_PKT_TRIG:       /**< Trigger event packet - 8 bits. */
270     case STM_PKT_GERR:       /**< error packet - 8 bits. */
271     case STM_PKT_MERR:       /**< error packet - 8 bits. */
272         m_swt_packet_info.swt_payload_pkt_bitsize = 8;
273         *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD8Val();
274         break;
275
276     case STM_PKT_D16:        /**< 16 bit data payload packet */
277         m_swt_packet_info.swt_payload_pkt_bitsize = 16;
278         *(uint16_t *)m_payload_buffer = m_curr_packet_in->getD16Val();
279         break;
280
281     case STM_PKT_D32:        /**< 32 bit data payload packet */
282     case STM_PKT_FREQ:       /**< Frequency packet */
283         m_swt_packet_info.swt_payload_pkt_bitsize = 32;
284         *(uint32_t *)m_payload_buffer = m_curr_packet_in->getD32Val();
285         break;
286
287
288     case STM_PKT_D64:        /**< 64 bit data payload packet */
289         m_swt_packet_info.swt_payload_pkt_bitsize = 64;
290         *(uint64_t *)m_payload_buffer = m_curr_packet_in->getD64Val();
291         break;
292     }
293     m_output_elem.setExtendedDataPtr(m_payload_buffer);
294     if (m_curr_packet_in->isMarkerPkt())
295         m_swt_packet_info.swt_marker_packet = 1;
296
297 }
298
299 /* End of File trc_pkt_decode_stm.cpp */