xref: /freebsd-src/contrib/opencsd/decoder/source/stm/trc_pkt_decode_stm.cpp (revision b6aadd183a8fc19317f893a41f252b32a87759af)
1c120c564SAndrew Turner /*
2c120c564SAndrew Turner  * \file       trc_pkt_decode_stm.cpp
3c120c564SAndrew Turner  * \brief      OpenCSD : STM packet decoder - output generic SW trace packets.
4c120c564SAndrew Turner  *
5c120c564SAndrew Turner  * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
6c120c564SAndrew Turner  */
7c120c564SAndrew Turner 
8c120c564SAndrew Turner /*
9c120c564SAndrew Turner  * Redistribution and use in source and binary forms, with or without modification,
10c120c564SAndrew Turner  * are permitted provided that the following conditions are met:
11c120c564SAndrew Turner  *
12c120c564SAndrew Turner  * 1. Redistributions of source code must retain the above copyright notice,
13c120c564SAndrew Turner  * this list of conditions and the following disclaimer.
14c120c564SAndrew Turner  *
15c120c564SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright notice,
16c120c564SAndrew Turner  * this list of conditions and the following disclaimer in the documentation
17c120c564SAndrew Turner  * and/or other materials provided with the distribution.
18c120c564SAndrew Turner  *
19c120c564SAndrew Turner  * 3. Neither the name of the copyright holder nor the names of its contributors
20c120c564SAndrew Turner  * may be used to endorse or promote products derived from this software without
21c120c564SAndrew Turner  * specific prior written permission.
22c120c564SAndrew Turner  *
23c120c564SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24c120c564SAndrew Turner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25c120c564SAndrew Turner  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26c120c564SAndrew Turner  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27c120c564SAndrew Turner  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28c120c564SAndrew Turner  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29c120c564SAndrew Turner  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30c120c564SAndrew Turner  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31c120c564SAndrew Turner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32c120c564SAndrew Turner  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33c120c564SAndrew Turner  */
34c120c564SAndrew Turner 
35c120c564SAndrew Turner #include "opencsd/stm/trc_pkt_decode_stm.h"
36c120c564SAndrew Turner #define DCD_NAME "DCD_STM"
37c120c564SAndrew Turner 
TrcPktDecodeStm()38c120c564SAndrew Turner TrcPktDecodeStm::TrcPktDecodeStm()
39c120c564SAndrew Turner     : TrcPktDecodeBase(DCD_NAME)
40c120c564SAndrew Turner {
41c120c564SAndrew Turner     initDecoder();
42c120c564SAndrew Turner }
43c120c564SAndrew Turner 
TrcPktDecodeStm(int instIDNum)44c120c564SAndrew Turner TrcPktDecodeStm::TrcPktDecodeStm(int instIDNum)
45c120c564SAndrew Turner     : TrcPktDecodeBase(DCD_NAME, instIDNum)
46c120c564SAndrew Turner {
47c120c564SAndrew Turner     initDecoder();
48c120c564SAndrew Turner }
49c120c564SAndrew Turner 
~TrcPktDecodeStm()50c120c564SAndrew Turner TrcPktDecodeStm::~TrcPktDecodeStm()
51c120c564SAndrew Turner {
52c120c564SAndrew Turner     if(m_payload_buffer)
53c120c564SAndrew Turner         delete [] m_payload_buffer;
54c120c564SAndrew Turner     m_payload_buffer = 0;
55c120c564SAndrew Turner }
56c120c564SAndrew Turner 
57c120c564SAndrew Turner /* implementation packet decoding interface */
processPacket()58c120c564SAndrew Turner ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
59c120c564SAndrew Turner {
60c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
61c120c564SAndrew Turner     bool bPktDone = false;
62c120c564SAndrew Turner 
63c120c564SAndrew Turner     m_decode_pass1 = true;
64c120c564SAndrew Turner 
65c120c564SAndrew Turner     while(!bPktDone)
66c120c564SAndrew Turner     {
67c120c564SAndrew Turner         switch(m_curr_state)
68c120c564SAndrew Turner         {
69c120c564SAndrew Turner         case NO_SYNC:
70c120c564SAndrew Turner             m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
71*b6aadd18SAndrew Turner             m_output_elem.setUnSyncEOTReason(m_unsync_info);
72c120c564SAndrew Turner             resp = outputTraceElement(m_output_elem);
73c120c564SAndrew Turner             m_curr_state = WAIT_SYNC;
74c120c564SAndrew Turner             break;
75c120c564SAndrew Turner 
76c120c564SAndrew Turner         case WAIT_SYNC:
77c120c564SAndrew Turner             if(m_curr_packet_in->getPktType() == STM_PKT_ASYNC)
78c120c564SAndrew Turner                 m_curr_state = DECODE_PKTS;
79c120c564SAndrew Turner             bPktDone = true;
80c120c564SAndrew Turner             break;
81c120c564SAndrew Turner 
82c120c564SAndrew Turner         case DECODE_PKTS:
83c120c564SAndrew Turner             resp = decodePacket(bPktDone);
84c120c564SAndrew Turner             break;
85c120c564SAndrew Turner         }
86c120c564SAndrew Turner     }
87c120c564SAndrew Turner     return resp;
88c120c564SAndrew Turner }
89c120c564SAndrew Turner 
onEOT()90c120c564SAndrew Turner ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
91c120c564SAndrew Turner {
92c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
93c120c564SAndrew Turner     m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
94*b6aadd18SAndrew Turner     m_output_elem.setUnSyncEOTReason(UNSYNC_EOT);
95c120c564SAndrew Turner     resp = outputTraceElement(m_output_elem);
96c120c564SAndrew Turner     return resp;
97c120c564SAndrew Turner }
98c120c564SAndrew Turner 
onReset()99c120c564SAndrew Turner ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
100c120c564SAndrew Turner {
101c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
102*b6aadd18SAndrew Turner     m_unsync_info = UNSYNC_RESET_DECODER;
103c120c564SAndrew Turner     resetDecoder();
104c120c564SAndrew Turner     return resp;
105c120c564SAndrew Turner }
106c120c564SAndrew Turner 
onFlush()107c120c564SAndrew Turner ocsd_datapath_resp_t TrcPktDecodeStm::onFlush()
108c120c564SAndrew Turner {
109c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
110c120c564SAndrew Turner     // don't currently save unsent packets so nothing to flush
111c120c564SAndrew Turner     return resp;
112c120c564SAndrew Turner }
113c120c564SAndrew Turner 
onProtocolConfig()114c120c564SAndrew Turner ocsd_err_t TrcPktDecodeStm::onProtocolConfig()
115c120c564SAndrew Turner {
116c120c564SAndrew Turner     if(m_config == 0)
117c120c564SAndrew Turner         return OCSD_ERR_NOT_INIT;
118c120c564SAndrew Turner 
119c120c564SAndrew Turner     // static config - copy of CSID for easy reference
120c120c564SAndrew Turner     m_CSID = m_config->getTraceID();
121c120c564SAndrew Turner     return OCSD_OK;
122c120c564SAndrew Turner }
123c120c564SAndrew Turner 
initDecoder()124c120c564SAndrew Turner void TrcPktDecodeStm::initDecoder()
125c120c564SAndrew Turner {
126c120c564SAndrew Turner     m_payload_buffer = 0;
127c120c564SAndrew Turner     m_num_pkt_correlation = 1;  // fixed at single packet payload correlation - add feature later
128c120c564SAndrew Turner     m_CSID = 0;
129c120c564SAndrew Turner 
130c120c564SAndrew Turner     // base decoder state - STM requires no memory and instruction decode.
131c120c564SAndrew Turner     setUsesMemAccess(false);
132c120c564SAndrew Turner     setUsesIDecode(false);
133*b6aadd18SAndrew Turner     m_unsync_info = UNSYNC_INIT_DECODER;
134c120c564SAndrew Turner     resetDecoder();
135c120c564SAndrew Turner }
136c120c564SAndrew Turner 
resetDecoder()137c120c564SAndrew Turner void TrcPktDecodeStm::resetDecoder()
138c120c564SAndrew Turner {
139c120c564SAndrew Turner     m_curr_state = NO_SYNC;
140c120c564SAndrew Turner     m_payload_size = 0;
141c120c564SAndrew Turner     m_payload_used = 0;
142c120c564SAndrew Turner     m_payload_odd_nibble = false;
143c120c564SAndrew Turner     m_output_elem.init();
144c120c564SAndrew Turner     m_swt_packet_info.swt_flag_bits = 0;	// zero out everything
145c120c564SAndrew Turner     initPayloadBuffer();
146c120c564SAndrew Turner }
147c120c564SAndrew Turner 
initPayloadBuffer()148c120c564SAndrew Turner void TrcPktDecodeStm::initPayloadBuffer()
149c120c564SAndrew Turner {
150c120c564SAndrew Turner     // set up the payload buffer. If we are correlating indentical packets then
151c120c564SAndrew Turner     // need a buffer that is a multiple of 64bit packets.
152c120c564SAndrew Turner     // otherwise a single packet length will do.
153c120c564SAndrew Turner     if(m_payload_buffer)
154c120c564SAndrew Turner         delete [] m_payload_buffer;
155c120c564SAndrew Turner     m_payload_buffer = new (std::nothrow) uint8_t[m_num_pkt_correlation * sizeof(uint64_t)];
156c120c564SAndrew Turner }
157c120c564SAndrew Turner 
decodePacket(bool & bPktDone)158c120c564SAndrew Turner ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
159c120c564SAndrew Turner {
160c120c564SAndrew Turner     ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
161c120c564SAndrew Turner     bool bSendPacket = false;       // flag to indicate output required.
162c120c564SAndrew Turner 
163c120c564SAndrew Turner     bPktDone = true;    // assume complete unless 2nd pass required.
164c120c564SAndrew Turner     m_output_elem.setType(OCSD_GEN_TRC_ELEM_SWTRACE);
165c120c564SAndrew Turner     clearSWTPerPcktInfo();
166c120c564SAndrew Turner 
167c120c564SAndrew Turner     switch (m_curr_packet_in->getPktType())
168c120c564SAndrew Turner     {
169c120c564SAndrew Turner     case STM_PKT_BAD_SEQUENCE:   /**< Incorrect protocol sequence */
170c120c564SAndrew Turner     case STM_PKT_RESERVED:
171c120c564SAndrew Turner         resp = OCSD_RESP_FATAL_INVALID_DATA;
172*b6aadd18SAndrew Turner         m_unsync_info = UNSYNC_BAD_PACKET;
173c120c564SAndrew Turner     case STM_PKT_NOTSYNC:
174c120c564SAndrew Turner         resetDecoder();
175c120c564SAndrew Turner         break;
176c120c564SAndrew Turner 
177c120c564SAndrew Turner     case STM_PKT_VERSION:    /**< Version packet  - not relevant to generic (versionless) o/p */
178c120c564SAndrew Turner     case STM_PKT_ASYNC:      /**< Alignment synchronisation packet */
179c120c564SAndrew Turner     case STM_PKT_INCOMPLETE_EOT:     /**< Incomplete packet flushed at end of trace. */
180c120c564SAndrew Turner         // no action required.
181c120c564SAndrew Turner         break;
182c120c564SAndrew Turner 
183c120c564SAndrew Turner /* markers for valid packets*/
184c120c564SAndrew Turner     case STM_PKT_NULL:       /**< Null packet */
185c120c564SAndrew Turner         if(m_curr_packet_in->isTSPkt())
186c120c564SAndrew Turner             bSendPacket = true;     // forward NULL packet if associated timestamp.
187c120c564SAndrew Turner         break;
188c120c564SAndrew Turner 
189c120c564SAndrew Turner     case STM_PKT_FREQ:       /**< Frequency packet */
190c120c564SAndrew Turner         m_swt_packet_info.swt_frequency = 1;
191c120c564SAndrew Turner         updatePayload(bSendPacket);
192c120c564SAndrew Turner         break;
193c120c564SAndrew Turner 
194c120c564SAndrew Turner     case STM_PKT_TRIG:       /**< Trigger event packet. */
195c120c564SAndrew Turner         m_swt_packet_info.swt_trigger_event = 1;
196c120c564SAndrew Turner         updatePayload(bSendPacket);
197c120c564SAndrew Turner         break;
198c120c564SAndrew Turner 
199c120c564SAndrew Turner     case STM_PKT_GERR:       /**< Global error packet - protocol error but unknown which master had error */
200c120c564SAndrew Turner         m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
201c120c564SAndrew Turner         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
202c120c564SAndrew Turner         m_swt_packet_info.swt_global_err = 1;
203c120c564SAndrew Turner         m_swt_packet_info.swt_id_valid = 0;
204c120c564SAndrew Turner         updatePayload(bSendPacket);
205c120c564SAndrew Turner         break;
206c120c564SAndrew Turner 
207c120c564SAndrew Turner     case STM_PKT_MERR:       /**< Master error packet - current master detected an error (e.g. dropped trace) */
208c120c564SAndrew Turner         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
209c120c564SAndrew Turner         m_swt_packet_info.swt_master_err = 1;
210c120c564SAndrew Turner         updatePayload(bSendPacket);
211c120c564SAndrew Turner         break;
212c120c564SAndrew Turner 
213c120c564SAndrew Turner     case STM_PKT_M8:         /**< Set current master */
214c120c564SAndrew Turner         m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
215c120c564SAndrew Turner         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();  // forced to 0
216c120c564SAndrew Turner         m_swt_packet_info.swt_id_valid = 1;
217c120c564SAndrew Turner         break;
218c120c564SAndrew Turner 
219c120c564SAndrew Turner     case STM_PKT_C8:         /**< Set lower 8 bits of current channel - packet proc hadnles this */
220c120c564SAndrew Turner     case STM_PKT_C16:        /**< Set current channel */
221c120c564SAndrew Turner         m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
222c120c564SAndrew Turner         break;
223c120c564SAndrew Turner 
224c120c564SAndrew Turner     case STM_PKT_FLAG:       /**< Flag packet */
225c120c564SAndrew Turner         m_swt_packet_info.swt_marker_packet = 1;
226c120c564SAndrew Turner         bSendPacket = true;  // send 0 payload marker packet./
227c120c564SAndrew Turner         break;
228c120c564SAndrew Turner 
229c120c564SAndrew Turner 
230c120c564SAndrew Turner     case STM_PKT_D4:         /**< 4 bit data payload packet */
231c120c564SAndrew Turner     case STM_PKT_D8:         /**< 8 bit data payload packet */
232c120c564SAndrew Turner     case STM_PKT_D16:        /**< 16 bit data payload packet */
233c120c564SAndrew Turner     case STM_PKT_D32:        /**< 32 bit data payload packet */
234c120c564SAndrew Turner     case STM_PKT_D64:        /**< 64 bit data payload packet */
235c120c564SAndrew Turner         updatePayload(bSendPacket);
236c120c564SAndrew Turner         break;
237c120c564SAndrew Turner 
238c120c564SAndrew Turner     }
239c120c564SAndrew Turner 
240c120c564SAndrew Turner     if(bSendPacket)
241c120c564SAndrew Turner     {
242c120c564SAndrew Turner         if(m_curr_packet_in->isTSPkt())
243c120c564SAndrew Turner         {
244c120c564SAndrew Turner             m_output_elem.setTS(m_curr_packet_in->getTSVal());
245c120c564SAndrew Turner             m_swt_packet_info.swt_has_timestamp = 1;
246c120c564SAndrew Turner         }
247c120c564SAndrew Turner         m_output_elem.setSWTInfo(m_swt_packet_info);
248c120c564SAndrew Turner         resp = outputTraceElement(m_output_elem);
249c120c564SAndrew Turner     }
250c120c564SAndrew Turner 
251c120c564SAndrew Turner     return resp;
252c120c564SAndrew Turner }
253c120c564SAndrew Turner 
clearSWTPerPcktInfo()254c120c564SAndrew Turner void TrcPktDecodeStm::clearSWTPerPcktInfo()
255c120c564SAndrew Turner {
256c120c564SAndrew Turner     m_swt_packet_info.swt_flag_bits &= (uint32_t)(0x0 | SWT_ID_VALID_MASK);    // clear flags and current payload size (save id valid flag).
257c120c564SAndrew Turner }
258c120c564SAndrew Turner 
updatePayload(bool & bSendPacket)259c120c564SAndrew Turner void TrcPktDecodeStm::updatePayload(bool &bSendPacket)
260c120c564SAndrew Turner {
261c120c564SAndrew Turner     // without buffering similar packets - this function is quite simple
262c120c564SAndrew Turner     bSendPacket = true;
263c120c564SAndrew Turner     m_swt_packet_info.swt_payload_num_packets = 1;
264c120c564SAndrew Turner 
265c120c564SAndrew Turner     switch(m_curr_packet_in->getPktType())
266c120c564SAndrew Turner     {
267c120c564SAndrew Turner     case STM_PKT_D4:         /**< 4 bit data payload packet */
268c120c564SAndrew Turner         m_swt_packet_info.swt_payload_pkt_bitsize = 4;
269c120c564SAndrew Turner         *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD4Val();
270c120c564SAndrew Turner         break;
271c120c564SAndrew Turner 
272c120c564SAndrew Turner     case STM_PKT_D8:         /**< 8 bit data payload packet */
273c120c564SAndrew Turner     case STM_PKT_TRIG:       /**< Trigger event packet - 8 bits. */
274c120c564SAndrew Turner     case STM_PKT_GERR:       /**< error packet - 8 bits. */
275c120c564SAndrew Turner     case STM_PKT_MERR:       /**< error packet - 8 bits. */
276c120c564SAndrew Turner         m_swt_packet_info.swt_payload_pkt_bitsize = 8;
277c120c564SAndrew Turner         *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD8Val();
278c120c564SAndrew Turner         break;
279c120c564SAndrew Turner 
280c120c564SAndrew Turner     case STM_PKT_D16:        /**< 16 bit data payload packet */
281c120c564SAndrew Turner         m_swt_packet_info.swt_payload_pkt_bitsize = 16;
282c120c564SAndrew Turner         *(uint16_t *)m_payload_buffer = m_curr_packet_in->getD16Val();
283c120c564SAndrew Turner         break;
284c120c564SAndrew Turner 
285c120c564SAndrew Turner     case STM_PKT_D32:        /**< 32 bit data payload packet */
286c120c564SAndrew Turner     case STM_PKT_FREQ:       /**< Frequency packet */
287c120c564SAndrew Turner         m_swt_packet_info.swt_payload_pkt_bitsize = 32;
288c120c564SAndrew Turner         *(uint32_t *)m_payload_buffer = m_curr_packet_in->getD32Val();
289c120c564SAndrew Turner         break;
290c120c564SAndrew Turner 
291c120c564SAndrew Turner 
292c120c564SAndrew Turner     case STM_PKT_D64:        /**< 64 bit data payload packet */
293c120c564SAndrew Turner         m_swt_packet_info.swt_payload_pkt_bitsize = 64;
294c120c564SAndrew Turner         *(uint64_t *)m_payload_buffer = m_curr_packet_in->getD64Val();
295c120c564SAndrew Turner         break;
296c120c564SAndrew Turner     }
297c120c564SAndrew Turner     m_output_elem.setExtendedDataPtr(m_payload_buffer);
298c120c564SAndrew Turner     if (m_curr_packet_in->isMarkerPkt())
299c120c564SAndrew Turner         m_swt_packet_info.swt_marker_packet = 1;
300c120c564SAndrew Turner 
301c120c564SAndrew Turner }
302c120c564SAndrew Turner 
303c120c564SAndrew Turner /* End of File trc_pkt_decode_stm.cpp */
304