aboutsummaryrefslogtreecommitdiff
path: root/decoder/source/stm/trc_pkt_decode_stm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/source/stm/trc_pkt_decode_stm.cpp')
-rw-r--r--decoder/source/stm/trc_pkt_decode_stm.cpp299
1 files changed, 299 insertions, 0 deletions
diff --git a/decoder/source/stm/trc_pkt_decode_stm.cpp b/decoder/source/stm/trc_pkt_decode_stm.cpp
new file mode 100644
index 000000000000..a47e96312546
--- /dev/null
+++ b/decoder/source/stm/trc_pkt_decode_stm.cpp
@@ -0,0 +1,299 @@
+/*
+ * \file trc_pkt_decode_stm.cpp
+ * \brief OpenCSD : STM packet decoder - output generic SW trace packets.
+ *
+ * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opencsd/stm/trc_pkt_decode_stm.h"
+#define DCD_NAME "DCD_STM"
+
+TrcPktDecodeStm::TrcPktDecodeStm()
+ : TrcPktDecodeBase(DCD_NAME)
+{
+ initDecoder();
+}
+
+TrcPktDecodeStm::TrcPktDecodeStm(int instIDNum)
+ : TrcPktDecodeBase(DCD_NAME, instIDNum)
+{
+ initDecoder();
+}
+
+TrcPktDecodeStm::~TrcPktDecodeStm()
+{
+ if(m_payload_buffer)
+ delete [] m_payload_buffer;
+ m_payload_buffer = 0;
+}
+
+/* implementation packet decoding interface */
+ocsd_datapath_resp_t TrcPktDecodeStm::processPacket()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ bool bPktDone = false;
+
+ m_decode_pass1 = true;
+
+ while(!bPktDone)
+ {
+ switch(m_curr_state)
+ {
+ case NO_SYNC:
+ m_output_elem.setType(OCSD_GEN_TRC_ELEM_NO_SYNC);
+ resp = outputTraceElement(m_output_elem);
+ m_curr_state = WAIT_SYNC;
+ break;
+
+ case WAIT_SYNC:
+ if(m_curr_packet_in->getPktType() == STM_PKT_ASYNC)
+ m_curr_state = DECODE_PKTS;
+ bPktDone = true;
+ break;
+
+ case DECODE_PKTS:
+ resp = decodePacket(bPktDone);
+ break;
+ }
+ }
+ return resp;
+}
+
+ocsd_datapath_resp_t TrcPktDecodeStm::onEOT()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ m_output_elem.setType(OCSD_GEN_TRC_ELEM_EO_TRACE);
+ resp = outputTraceElement(m_output_elem);
+ return resp;
+}
+
+ocsd_datapath_resp_t TrcPktDecodeStm::onReset()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ resetDecoder();
+ return resp;
+}
+
+ocsd_datapath_resp_t TrcPktDecodeStm::onFlush()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ // don't currently save unsent packets so nothing to flush
+ return resp;
+}
+
+ocsd_err_t TrcPktDecodeStm::onProtocolConfig()
+{
+ if(m_config == 0)
+ return OCSD_ERR_NOT_INIT;
+
+ // static config - copy of CSID for easy reference
+ m_CSID = m_config->getTraceID();
+ return OCSD_OK;
+}
+
+void TrcPktDecodeStm::initDecoder()
+{
+ m_payload_buffer = 0;
+ m_num_pkt_correlation = 1; // fixed at single packet payload correlation - add feature later
+ m_CSID = 0;
+
+ // base decoder state - STM requires no memory and instruction decode.
+ setUsesMemAccess(false);
+ setUsesIDecode(false);
+
+ resetDecoder();
+}
+
+void TrcPktDecodeStm::resetDecoder()
+{
+ m_curr_state = NO_SYNC;
+ m_payload_size = 0;
+ m_payload_used = 0;
+ m_payload_odd_nibble = false;
+ m_output_elem.init();
+ m_swt_packet_info.swt_flag_bits = 0; // zero out everything
+ initPayloadBuffer();
+}
+
+void TrcPktDecodeStm::initPayloadBuffer()
+{
+ // set up the payload buffer. If we are correlating indentical packets then
+ // need a buffer that is a multiple of 64bit packets.
+ // otherwise a single packet length will do.
+ if(m_payload_buffer)
+ delete [] m_payload_buffer;
+ m_payload_buffer = new (std::nothrow) uint8_t[m_num_pkt_correlation * sizeof(uint64_t)];
+}
+
+ocsd_datapath_resp_t TrcPktDecodeStm::decodePacket(bool &bPktDone)
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ bool bSendPacket = false; // flag to indicate output required.
+
+ bPktDone = true; // assume complete unless 2nd pass required.
+ m_output_elem.setType(OCSD_GEN_TRC_ELEM_SWTRACE);
+ clearSWTPerPcktInfo();
+
+ switch (m_curr_packet_in->getPktType())
+ {
+ case STM_PKT_BAD_SEQUENCE: /**< Incorrect protocol sequence */
+ case STM_PKT_RESERVED:
+ resp = OCSD_RESP_FATAL_INVALID_DATA;
+ case STM_PKT_NOTSYNC:
+ resetDecoder();
+ break;
+
+ case STM_PKT_VERSION: /**< Version packet - not relevant to generic (versionless) o/p */
+ case STM_PKT_ASYNC: /**< Alignment synchronisation packet */
+ case STM_PKT_INCOMPLETE_EOT: /**< Incomplete packet flushed at end of trace. */
+ // no action required.
+ break;
+
+/* markers for valid packets*/
+ case STM_PKT_NULL: /**< Null packet */
+ if(m_curr_packet_in->isTSPkt())
+ bSendPacket = true; // forward NULL packet if associated timestamp.
+ break;
+
+ case STM_PKT_FREQ: /**< Frequency packet */
+ m_swt_packet_info.swt_frequency = 1;
+ updatePayload(bSendPacket);
+ break;
+
+ case STM_PKT_TRIG: /**< Trigger event packet. */
+ m_swt_packet_info.swt_trigger_event = 1;
+ updatePayload(bSendPacket);
+ break;
+
+ case STM_PKT_GERR: /**< Global error packet - protocol error but unknown which master had error */
+ m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
+ m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
+ m_swt_packet_info.swt_global_err = 1;
+ m_swt_packet_info.swt_id_valid = 0;
+ updatePayload(bSendPacket);
+ break;
+
+ case STM_PKT_MERR: /**< Master error packet - current master detected an error (e.g. dropped trace) */
+ m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
+ m_swt_packet_info.swt_master_err = 1;
+ updatePayload(bSendPacket);
+ break;
+
+ case STM_PKT_M8: /**< Set current master */
+ m_swt_packet_info.swt_master_id = m_curr_packet_in->getMaster();
+ m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel(); // forced to 0
+ m_swt_packet_info.swt_id_valid = 1;
+ break;
+
+ case STM_PKT_C8: /**< Set lower 8 bits of current channel - packet proc hadnles this */
+ case STM_PKT_C16: /**< Set current channel */
+ m_swt_packet_info.swt_channel_id = m_curr_packet_in->getChannel();
+ break;
+
+ case STM_PKT_FLAG: /**< Flag packet */
+ m_swt_packet_info.swt_marker_packet = 1;
+ bSendPacket = true; // send 0 payload marker packet./
+ break;
+
+
+ case STM_PKT_D4: /**< 4 bit data payload packet */
+ case STM_PKT_D8: /**< 8 bit data payload packet */
+ case STM_PKT_D16: /**< 16 bit data payload packet */
+ case STM_PKT_D32: /**< 32 bit data payload packet */
+ case STM_PKT_D64: /**< 64 bit data payload packet */
+ updatePayload(bSendPacket);
+ break;
+
+ }
+
+ if(bSendPacket)
+ {
+ if(m_curr_packet_in->isTSPkt())
+ {
+ m_output_elem.setTS(m_curr_packet_in->getTSVal());
+ m_swt_packet_info.swt_has_timestamp = 1;
+ }
+ m_output_elem.setSWTInfo(m_swt_packet_info);
+ resp = outputTraceElement(m_output_elem);
+ }
+
+ return resp;
+}
+
+void TrcPktDecodeStm::clearSWTPerPcktInfo()
+{
+ m_swt_packet_info.swt_flag_bits &= (uint32_t)(0x0 | SWT_ID_VALID_MASK); // clear flags and current payload size (save id valid flag).
+}
+
+void TrcPktDecodeStm::updatePayload(bool &bSendPacket)
+{
+ // without buffering similar packets - this function is quite simple
+ bSendPacket = true;
+ m_swt_packet_info.swt_payload_num_packets = 1;
+
+ switch(m_curr_packet_in->getPktType())
+ {
+ case STM_PKT_D4: /**< 4 bit data payload packet */
+ m_swt_packet_info.swt_payload_pkt_bitsize = 4;
+ *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD4Val();
+ break;
+
+ case STM_PKT_D8: /**< 8 bit data payload packet */
+ case STM_PKT_TRIG: /**< Trigger event packet - 8 bits. */
+ case STM_PKT_GERR: /**< error packet - 8 bits. */
+ case STM_PKT_MERR: /**< error packet - 8 bits. */
+ m_swt_packet_info.swt_payload_pkt_bitsize = 8;
+ *(uint8_t *)m_payload_buffer = m_curr_packet_in->getD8Val();
+ break;
+
+ case STM_PKT_D16: /**< 16 bit data payload packet */
+ m_swt_packet_info.swt_payload_pkt_bitsize = 16;
+ *(uint16_t *)m_payload_buffer = m_curr_packet_in->getD16Val();
+ break;
+
+ case STM_PKT_D32: /**< 32 bit data payload packet */
+ case STM_PKT_FREQ: /**< Frequency packet */
+ m_swt_packet_info.swt_payload_pkt_bitsize = 32;
+ *(uint32_t *)m_payload_buffer = m_curr_packet_in->getD32Val();
+ break;
+
+
+ case STM_PKT_D64: /**< 64 bit data payload packet */
+ m_swt_packet_info.swt_payload_pkt_bitsize = 64;
+ *(uint64_t *)m_payload_buffer = m_curr_packet_in->getD64Val();
+ break;
+ }
+ m_output_elem.setExtendedDataPtr(m_payload_buffer);
+ if (m_curr_packet_in->isMarkerPkt())
+ m_swt_packet_info.swt_marker_packet = 1;
+
+}
+
+/* End of File trc_pkt_decode_stm.cpp */