2 * \file trc_pkt_decode_stm.cpp
3 * \brief OpenCSD : STM packet decoder - output generic SW trace packets.
5 * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
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.
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.
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.
35 #include "opencsd/stm/trc_pkt_decode_stm.h"
36 #define DCD_NAME "DCD_STM"
38 TrcPktDecodeStm::TrcPktDecodeStm()
39 : TrcPktDecodeBase(DCD_NAME)
44 TrcPktDecodeStm::TrcPktDecodeStm(int instIDNum)
45 : TrcPktDecodeBase(DCD_NAME, instIDNum)
50 TrcPktDecodeStm::~TrcPktDecodeStm()
53 delete [] m_payload_buffer;
57 /* implementation packet decoding interface */
58 ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
60 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
61 bool bPktDone = false;
63 m_decode_pass1 = true;
70 m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
71 resp = outputTraceElement(m_output_elem);
72 m_curr_state = WAIT_SYNC;
76 if(m_curr_packet_in->getPktType() == STM_PKT_ASYNC)
77 m_curr_state = DECODE_PKTS;
82 resp = decodePacket(bPktDone);
89 ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
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);
97 ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
99 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
104 ocsd_datapath_resp_t TrcPktDecodeStm::onFlush()
106 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
107 // don't currently save unsent packets so nothing to flush
111 ocsd_err_t TrcPktDecodeStm::onProtocolConfig()
114 return OCSD_ERR_NOT_INIT;
116 // static config - copy of CSID for easy reference
117 m_CSID = m_config->getTraceID();
121 void TrcPktDecodeStm::initDecoder()
123 m_payload_buffer = 0;
124 m_num_pkt_correlation = 1; // fixed at single packet payload correlation - add feature later
127 // base decoder state - STM requires no memory and instruction decode.
128 setUsesMemAccess(false);
129 setUsesIDecode(false);
134 void TrcPktDecodeStm::resetDecoder()
136 m_curr_state = NO_SYNC;
139 m_payload_odd_nibble = false;
140 m_output_elem.init();
141 m_swt_packet_info.swt_flag_bits = 0; // zero out everything
145 void TrcPktDecodeStm::initPayloadBuffer()
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.
151 delete [] m_payload_buffer;
152 m_payload_buffer = new (std::nothrow) uint8_t[m_num_pkt_correlation * sizeof(uint64_t)];
155 ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
157 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
158 bool bSendPacket = false; // flag to indicate output required.
160 bPktDone = true; // assume complete unless 2nd pass required.
161 m_output_elem.setType(OCSD_GEN_TRC_ELEM_SWTRACE);
162 clearSWTPerPcktInfo();
164 switch (m_curr_packet_in->getPktType())
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:
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.
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.
185 case STM_PKT_FREQ: /**< Frequency packet */
186 m_swt_packet_info.swt_frequency = 1;
187 updatePayload(bSendPacket);
190 case STM_PKT_TRIG: /**< Trigger event packet. */
191 m_swt_packet_info.swt_trigger_event = 1;
192 updatePayload(bSendPacket);
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);
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);
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;
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();
220 case STM_PKT_FLAG: /**< Flag packet */
221 m_swt_packet_info.swt_marker_packet = 1;
222 bSendPacket = true; // send 0 payload marker packet./
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);
238 if(m_curr_packet_in->isTSPkt())
240 m_output_elem.setTS(m_curr_packet_in->getTSVal());
241 m_swt_packet_info.swt_has_timestamp = 1;
243 m_output_elem.setSWTInfo(m_swt_packet_info);
244 resp = outputTraceElement(m_output_elem);
250 void TrcPktDecodeStm::clearSWTPerPcktInfo()
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).
255 void TrcPktDecodeStm::updatePayload(bool &bSendPacket)
257 // without buffering similar packets - this function is quite simple
259 m_swt_packet_info.swt_payload_num_packets = 1;
261 switch(m_curr_packet_in->getPktType())
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();
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();
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();
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();
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();
293 m_output_elem.setExtendedDataPtr(m_payload_buffer);
294 if (m_curr_packet_in->isMarkerPkt())
295 m_swt_packet_info.swt_marker_packet = 1;
299 /* End of File trc_pkt_decode_stm.cpp */