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