STM full decoder outputs generic trace elements of the SWT type. These consist of the current master + channel, along with payload and optional markers and timestamps if present.
Generic trace output type added to cover software trace along with packet printer.
Adds decoder into the linux makefiles.
Signed-off-by: Mike Leach mike.leach@linaro.org --- .gitignore | 2 + decoder/build/linux/ref_trace_decode_lib/makefile | 3 +- decoder/include/common/trc_gen_elem.h | 31 ++-- decoder/include/ocsd_if_types.h | 29 ++-- decoder/include/stm/trc_dcd_mngr_stm.h | 8 +- decoder/include/stm/trc_pkt_decode_stm.h | 24 ++- decoder/include/stm/trc_pkt_elem_stm.h | 4 +- decoder/include/stm/trc_pkt_types_stm.h | 2 +- decoder/include/trc_gen_elem_types.h | 21 ++- decoder/source/stm/trc_pkt_decode_stm.cpp | 198 +++++++++++++++++++++- decoder/source/stm/trc_pkt_proc_stm.cpp | 5 +- decoder/source/trc_gen_elem.cpp | 70 +++++++- decoder/source/trc_printable_elem.cpp | 4 +- 13 files changed, 348 insertions(+), 53 deletions(-)
diff --git a/.gitignore b/.gitignore index c98b5a6..ebaf552 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ ref_trace_decoder/tests/build/win/trc_pkt_lister/x64/Release-dll/* *.orig decoder/docs/html/* *.orig +*.VC.db +*.VC.VC.opendb diff --git a/decoder/build/linux/ref_trace_decode_lib/makefile b/decoder/build/linux/ref_trace_decode_lib/makefile index b650331..5d89999 100644 --- a/decoder/build/linux/ref_trace_decode_lib/makefile +++ b/decoder/build/linux/ref_trace_decode_lib/makefile @@ -83,7 +83,8 @@ MEMACCOBJ= $(BUILD_DIR)/trc_mem_acc_mapper.o \ $(BUILD_DIR)/trc_mem_acc_cb.o
STMOBJ= $(BUILD_DIR)/trc_pkt_elem_stm.o \ - $(BUILD_DIR)/trc_pkt_proc_stm.o + $(BUILD_DIR)/trc_pkt_proc_stm.o \ + $(BUILD_DIR)/trc_pkt_decode_stm.o
OBJECTS=$(BUILD_DIR)/ocsd_code_follower.o \ $(BUILD_DIR)/ocsd_dcd_tree.o \ diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h index 97c3a45..2f4182b 100644 --- a/decoder/include/common/trc_gen_elem.h +++ b/decoder/include/common/trc_gen_elem.h @@ -65,7 +65,7 @@ public:
void setCycleCount(const uint32_t cycleCount); void setEvent(const event_t ev_type, const uint16_t number); - void setTS(const uint64_t ts, const bool freqChange = false) { timestamp = ts; cpu_freq_change = freqChange ? 1 : 0; }; + void setTS(const uint64_t ts, const bool freqChange = false);
void setExcepMarker() { excep_data_marker = 1; }; void setExceptionNum(uint32_t excepNum) { exception_number = excepNum; }; @@ -77,9 +77,8 @@ public: void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype); void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
- void setSWTMaster(const uint16_t master_id) { sw_trace_info.swt_master_id = master_id; }; - void setSWTChannel(const uint16_t chan_id) { sw_trace_info.swt_channel_id = chan_id; }; - void setSWTErrPkt(const bool m_err = false); + void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; }; + void setExtendedDataPtr(const void *data_ptr);
// stringize the element
@@ -96,6 +95,7 @@ public:
private: + void printSWInfoPkt(std::ostringstream &oss) const; void clearPerPktData(); //!< clear flags that indicate validity / have values on a per packet basis
}; @@ -168,12 +168,9 @@ inline void OcsdTraceElement::init()
inline void OcsdTraceElement::clearPerPktData() { - cpu_freq_change = 0; - has_cc = 0; - last_instr_exec = 0; - excep_ret_addr = 0; - exception_number = 0; // union with trace_on_reason / trace_event - excep_data_marker = 0; + flag_bits = 0; // union with trace_on_reason / trace_event + + ptr_extended_data = 0; // extended data pointer }
inline void OcsdTraceElement::setTraceOnReason(const trace_on_reason_t reason) @@ -188,6 +185,20 @@ inline void OcsdTraceElement::setISA(const ocsd_isa isa_update) isa = ocsd_isa_unknown; }
+inline void OcsdTraceElement::setTS(const uint64_t ts, const bool freqChange /*= false*/) +{ + timestamp = ts; + cpu_freq_change = freqChange ? 1 : 0; + has_ts = 1; +} + +inline void OcsdTraceElement::setExtendedDataPtr(const void *data_ptr) +{ + extended_data = 1; + ptr_extended_data = data_ptr; +} + + /** @}*/
#endif // ARM_TRC_GEN_ELEM_H_INCLUDED diff --git a/decoder/include/ocsd_if_types.h b/decoder/include/ocsd_if_types.h index 0477903..776487a 100644 --- a/decoder/include/ocsd_if_types.h +++ b/decoder/include/ocsd_if_types.h @@ -37,8 +37,8 @@
#include <stdint.h> #include <stddef.h> -#ifdef _MSC_VER -/** VS2010 does not support inttypes - temp fix till we update the compiler support */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +/** VS2010 does not support inttypes - remove when VS2010 support is dropped */ #define __PRI64_PREFIX "ll" #define PRIX64 __PRI64_PREFIX "X" #define PRIu64 __PRI64_PREFIX "u" @@ -561,17 +561,26 @@ typedef enum _ocsd_trace_protocol_t { typedef struct _ocsd_swt_info { uint16_t swt_master_id; uint16_t swt_channel_id; - struct { - uint32_t swt_payload_pkt_bitsize:8; /**< Packet size in bits of the payload packets */ - uint32_t swt_payload_num_packets:8; /**< number of consecutive packets of this type in the payload data */ - uint32_t swt_marker_packet:1; /**< packet is marker / flag packet */ - uint32_t swt_has_timestamp:1; /**< packet has timestamp. */ - uint32_t swt_marker_first:1; /**< for multiple packet payloads, this indicates if any marker is on first or last packet */ - uint32_t swt_master_err:1; /**< current master has error */ - uint32_t swt_global_err:1; /**< global error */ + union { + struct { + uint32_t swt_payload_pkt_bitsize:8; /**< [bits 0:7 ] Packet size in bits of the payload packets */ + uint32_t swt_payload_num_packets:8; /**< [bits 8:15 ] number of consecutive packets of this type in the payload data */ + uint32_t swt_marker_packet:1; /**< [bit 16 ] packet is marker / flag packet */ + uint32_t swt_has_timestamp:1; /**< [bit 17 ] packet has timestamp. */ + uint32_t swt_marker_first:1; /**< [bit 18 ] for multiple packet payloads, this indicates if any marker is on first or last packet */ + uint32_t swt_master_err:1; /**< [bit 19 ] current master has error - payload is error code */ + uint32_t swt_global_err:1; /**< [bit 20 ] global error - payload is error code - master and channel ID not valid */ + uint32_t swt_trigger_event:1; /**< [bit 21 ] trigger event packet - payload is event number */ + uint32_t swt_frequency:1; /**< [bit 22 ] frequency packet - payload is frequency */ + uint32_t swt_id_valid:1; /**< [bit 23 ] master & channel ID has been set by input stream */ + }; + uint32_t swt_flag_bits; }; } ocsd_swt_info_t;
+/** mask for the swt_id_valid flag - need to retain between packets */ +#define SWT_ID_VALID_MASK (0x1 << 23) + /** @}*/
/** @}*/ diff --git a/decoder/include/stm/trc_dcd_mngr_stm.h b/decoder/include/stm/trc_dcd_mngr_stm.h index 740925d..33632c6 100644 --- a/decoder/include/stm/trc_dcd_mngr_stm.h +++ b/decoder/include/stm/trc_dcd_mngr_stm.h @@ -35,18 +35,20 @@ #define ARM_TRC_DCD_MNGR_STM_H_INCLUDED
#include "common/ocsd_dcd_mngr.h" +#include "trc_pkt_decode_stm.h" #include "trc_pkt_proc_stm.h" #include "trc_cmp_cfg_stm.h" #include "trc_pkt_types_stm.h"
-class DecoderMngrStm : public DecodeMngrPktProc< StmTrcPacket, +class DecoderMngrStm : public DecodeMngrFullDcd< StmTrcPacket, ocsd_stm_pkt_type, STMConfig, ocsd_stm_cfg, - TrcPktProcStm> + TrcPktProcStm, + TrcPktDecodeStm> { public: - DecoderMngrStm(const std::string &name) : DecodeMngrPktProc(name,OCSD_PROTOCOL_STM) {}; + DecoderMngrStm(const std::string &name) : DecodeMngrFullDcd(name,OCSD_PROTOCOL_STM) {}; virtual ~DecoderMngrStm() {}; };
diff --git a/decoder/include/stm/trc_pkt_decode_stm.h b/decoder/include/stm/trc_pkt_decode_stm.h index eb113ce..dc295f4 100644 --- a/decoder/include/stm/trc_pkt_decode_stm.h +++ b/decoder/include/stm/trc_pkt_decode_stm.h @@ -51,7 +51,7 @@ public: TrcPktDecodeStm(); TrcPktDecodeStm(int instIDNum); virtual ~TrcPktDecodeStm(); - + protected: /* implementation packet decoding interface */ virtual ocsd_datapath_resp_t processPacket(); @@ -67,25 +67,33 @@ private: void initDecoder(); void resetDecoder(); void initPayloadBuffer(); + bool isInit() { return (bool)((m_config != 0) && (m_payload_buffer != 0)); }; + ocsd_datapath_resp_t decodePacket(bool &bPktDone); //!< decode the current incoming packet + void clearSWTPerPcktInfo(); + void updatePayload(bool &bSendPacket);
typedef enum { NO_SYNC, //!< pre start trace - init state or after reset or overflow, loss of sync. WAIT_SYNC, //!< waiting for sync packet. - DECODE_PKTS, //!< processing input packet + DECODE_PKTS //!< processing input packet. } processor_state_t;
processor_state_t m_curr_state; - - uint8_t m_curr_master; //!< current active master ID - uint16_t m_curr_channel; //!< current active channel ID
- uint8_t *m_payload_buffer; //!< payload buffer - allocated for one of multiple packets according to config - int m_payload_used; //!< payload used in bytes - int m_payload_size; //!< payload size in bytes + ocsd_swt_info_t m_swt_packet_info; + + uint8_t *m_payload_buffer; //!< payload buffer - allocated for one or multiple packets according to config + int m_payload_size; //!< payload buffer total size in bytes. + int m_payload_used; //!< payload buffer used in bytes - current payload size. bool m_payload_odd_nibble; //!< last used byte in payload contains a single 4 bit packet. + int m_num_pkt_correlation; //!< number of identical payload packets to buffer up before output. - fixed at 1 till later update
uint8_t m_CSID; //!< Coresight trace ID for this decoder.
+ bool m_decode_pass1; //!< flag to indicate 1st pass of packet decode. + + + //** output element OcsdTraceElement m_output_elem; //!< output packet }; diff --git a/decoder/include/stm/trc_pkt_elem_stm.h b/decoder/include/stm/trc_pkt_elem_stm.h index 79c9595..738e452 100644 --- a/decoder/include/stm/trc_pkt_elem_stm.h +++ b/decoder/include/stm/trc_pkt_elem_stm.h @@ -84,7 +84,7 @@ public: const uint8_t getMaster() const; const uint16_t getChannel() const; const ocsd_stm_ts_type getTSType() const; - const uint64_t getCurrentTSVal() const; + const uint64_t getTSVal() const;
const uint8_t getD4Val() const; const uint8_t getD8Val() const; @@ -197,7 +197,7 @@ inline const ocsd_stm_ts_type StmTrcPacket::getTSType() const return ts_type; }
-inline const uint64_t StmTrcPacket::getCurrentTSVal() const +inline const uint64_t StmTrcPacket::getTSVal() const { return timestamp; } diff --git a/decoder/include/stm/trc_pkt_types_stm.h b/decoder/include/stm/trc_pkt_types_stm.h index bc2035f..0192b5c 100644 --- a/decoder/include/stm/trc_pkt_types_stm.h +++ b/decoder/include/stm/trc_pkt_types_stm.h @@ -104,7 +104,7 @@ typedef struct _ocsd_stm_pkt uint8_t master; /**< current master */ uint16_t channel; /**< current channel */
- uint64_t timestamp; /**< latest timestamp value */ + uint64_t timestamp; /**< latest timestamp value -> as binary - packet processor does grey decoding */ uint8_t pkt_ts_bits; /**< timestamp bits updated this packet */ uint8_t pkt_has_ts; /**< current packet has associated timestamp (ts bits can be 0 if same value as last time) */
diff --git a/decoder/include/trc_gen_elem_types.h b/decoder/include/trc_gen_elem_types.h index 22ed7dc..440bc19 100644 --- a/decoder/include/trc_gen_elem_types.h +++ b/decoder/include/trc_gen_elem_types.h @@ -87,14 +87,17 @@ typedef struct _ocsd_generic_trace_elem { ocsd_instr_subtype last_i_subtype; /**< sub type for last instruction in range */
//! per element flags - struct { - uint32_t last_instr_exec:1; /**< 1 if last instruction in range was executed; */ - uint32_t has_cc:1; /**< 1 if this packet has a valid cycle count included (e.g. cycle count included as part of instruction range packet, always 1 for pure cycle count packet.*/ - uint32_t cpu_freq_change:1; /**< 1 if this packet indicates a change in CPU frequency */ - uint32_t excep_ret_addr:1; /**< 1 if en_addr is the preferred exception return address on exception packet type */ - uint32_t excep_data_marker:1; /**< 1 if the exception entry packet is a data push marker only, with no address information (used typically in v7M trace for marking data pushed onto stack) */ - uint32_t extended_data:1; /**< 1 if the packet extended data pointer is valid. Allows packet extensions for custom decoders, or additional data payloads for data trace. */ - uint32_t has_ts:1; /**< 1 if the packet has an associated timestamp - e.g. SW/STM trace TS+Payload as a single packet */ + union { + struct { + uint32_t last_instr_exec:1; /**< 1 if last instruction in range was executed; */ + uint32_t has_cc:1; /**< 1 if this packet has a valid cycle count included (e.g. cycle count included as part of instruction range packet, always 1 for pure cycle count packet.*/ + uint32_t cpu_freq_change:1; /**< 1 if this packet indicates a change in CPU frequency */ + uint32_t excep_ret_addr:1; /**< 1 if en_addr is the preferred exception return address on exception packet type */ + uint32_t excep_data_marker:1; /**< 1 if the exception entry packet is a data push marker only, with no address information (used typically in v7M trace for marking data pushed onto stack) */ + uint32_t extended_data:1; /**< 1 if the packet extended data pointer is valid. Allows packet extensions for custom decoders, or additional data payloads for data trace. */ + uint32_t has_ts:1; /**< 1 if the packet has an associated timestamp - e.g. SW/STM trace TS+Payload as a single packet */ + }; + uint32_t flag_bits; };
//! packet specific payloads @@ -105,7 +108,7 @@ typedef struct _ocsd_generic_trace_elem { ocsd_swt_info_t sw_trace_info; /**< software trace packet info */ };
- void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */ + const void *ptr_extended_data; /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */
} ocsd_generic_trace_elem;
diff --git a/decoder/source/stm/trc_pkt_decode_stm.cpp b/decoder/source/stm/trc_pkt_decode_stm.cpp index 9185b6c..e0ddc3e 100644 --- a/decoder/source/stm/trc_pkt_decode_stm.cpp +++ b/decoder/source/stm/trc_pkt_decode_stm.cpp @@ -1,6 +1,6 @@ /* * \file trc_pkt_decode_stm.cpp - * \brief OpenCSD : + * \brief OpenCSD : STM packet decoder - output generic SW trace packets. * * \copyright Copyright (c) 2016, ARM Limited. All Rights Reserved. */ @@ -57,18 +57,55 @@ TrcPktDecodeStm::~TrcPktDecodeStm() /* 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() @@ -84,19 +121,25 @@ ocsd_err_t TrcPktDecodeStm::onProtocolConfig() void TrcPktDecodeStm::initDecoder() { m_payload_buffer = 0; - m_payload_used = 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_curr_master = 0; - m_curr_channel = 0; m_payload_size = 0; + m_payload_used = 0; m_payload_odd_nibble = false; - m_CSID = 0; m_output_elem.init(); + m_swt_packet_info.swt_flag_bits = 0; // zero out everything + initPayloadBuffer(); }
void TrcPktDecodeStm::initPayloadBuffer() @@ -104,7 +147,152 @@ 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;
}
diff --git a/decoder/source/stm/trc_pkt_proc_stm.cpp b/decoder/source/stm/trc_pkt_proc_stm.cpp index f16acb8..242ee1c 100644 --- a/decoder/source/stm/trc_pkt_proc_stm.cpp +++ b/decoder/source/stm/trc_pkt_proc_stm.cpp @@ -752,7 +752,10 @@ void TrcPktProcStm::stmPktTriggerTS() void TrcPktProcStm::stmPktFreq() { if(m_num_nibbles == 3) + { m_curr_packet.setPacketType(STM_PKT_FREQ,false); + m_val32 = 0; + } stmExtractVal32(11); if(m_num_nibbles == 11) { @@ -868,7 +871,7 @@ void TrcPktProcStm::stmExtractTS() uint8_t new_bits = m_req_ts_nibbles * 4; if(m_curr_packet.getTSType() == STM_TS_GREY) { - uint64_t gray_val = bin_to_gray(m_curr_packet.getCurrentTSVal()); + uint64_t gray_val = bin_to_gray(m_curr_packet.getTSVal()); if(new_bits == 64) { gray_val = m_ts_update_value; diff --git a/decoder/source/trc_gen_elem.cpp b/decoder/source/trc_gen_elem.cpp index 92cc721..33f8dcb 100644 --- a/decoder/source/trc_gen_elem.cpp +++ b/decoder/source/trc_gen_elem.cpp @@ -52,7 +52,9 @@ static const char *s_elem_descs[][2] = {"OCSD_GEN_TRC_ELEM_EXCEPTION_RET","Expection return"}, {"OCSD_GEN_TRC_ELEM_TIMESTAMP","Timestamp - preceding elements happeded before this time."}, {"OCSD_GEN_TRC_ELEM_CYCLE_COUNT","Cycle count - cycles since last cycle count value - associated with a preceding instruction range."}, - {"OCSD_GEN_TRC_ELEM_EVENT","Event - numbered event or trigger"} + {"OCSD_GEN_TRC_ELEM_EVENT","Event - numbered event or trigger"}, + {"OCSD_GEN_TRC_ELEM_SWTRACE","Software trace packet - may contain data payload."}, + {"OCSD_GEN_TRC_ELEM_CUSTOM","Fully custom packet type."} };
static const char *instr_type[] = { @@ -143,6 +145,10 @@ void OcsdTraceElement::toString(std::string &str) const oss << " [ TS=0x" << std::setfill('0') << std::setw(12) << std::hex << timestamp << "]; "; break;
+ case OCSD_GEN_TRC_ELEM_SWTRACE: + printSWInfoPkt(oss); + break; + default: break; } if(has_cc) @@ -162,6 +168,68 @@ OcsdTraceElement &OcsdTraceElement::operator =(const ocsd_generic_trace_elem* p_ return *this; }
+ +void OcsdTraceElement::printSWInfoPkt(std::ostringstream & oss) const +{ + if (!sw_trace_info.swt_global_err) + { + if (sw_trace_info.swt_id_valid) + { + oss << " (Ma:0x" << std::setfill('0') << std::setw(2) << std::hex << sw_trace_info.swt_master_id << "; "; + oss << "Ch:0x" << std::setfill('0') << std::setw(2) << std::hex << sw_trace_info.swt_channel_id << ") "; + } + else + oss << "(Ma:0x??; Ch:0x??" << ") "; + + if (sw_trace_info.swt_payload_pkt_bitsize > 0) + { + oss << "0x" << std::setfill('0') << std::hex; + if (sw_trace_info.swt_payload_pkt_bitsize == 4) + { + oss << std::setw(1); + oss << (uint16_t)(((uint8_t *)ptr_extended_data)[0] & 0xF); + } + else + { + switch (sw_trace_info.swt_payload_pkt_bitsize) + { + case 8: + // force uint8 to uint16 so oss 'sees' them as something to be stringised, rather than absolute char values + oss << std::setw(2) << (uint16_t)((uint8_t *)ptr_extended_data)[0]; + break; + case 16: + oss << std::setw(4) << ((uint16_t *)ptr_extended_data)[0]; + break; + case 32: + oss << std::setw(8) << ((uint32_t *)ptr_extended_data)[0]; + break; + case 64: + oss << std::setw(16) << ((uint64_t *)ptr_extended_data)[0]; + break; + default: + oss << "{Data Error : unsupported bit width.}"; + break; + } + } + oss << "; "; + } + if (sw_trace_info.swt_marker_packet) + oss << "+Mrk "; + if (sw_trace_info.swt_trigger_event) + oss << "Trig "; + if (sw_trace_info.swt_has_timestamp) + oss << " [ TS=0x" << std::setfill('0') << std::setw(12) << std::hex << timestamp << "]; "; + if (sw_trace_info.swt_frequency) + oss << "Freq"; + if (sw_trace_info.swt_master_err) + oss << "{Master Error.}"; + } + else + { + oss << "{Global Error.}"; + } +} + /* void OcsdTraceElement::toString(const ocsd_generic_trace_elem *p_elem, std::string &str) { diff --git a/decoder/source/trc_printable_elem.cpp b/decoder/source/trc_printable_elem.cpp index 8d270e1..2fd49d9 100644 --- a/decoder/source/trc_printable_elem.cpp +++ b/decoder/source/trc_printable_elem.cpp @@ -35,8 +35,8 @@ #include "common/trc_printable_elem.h" #include <cassert> #include <cstring> -#ifdef _MSC_VER -/** VS2010 does not support inttypes - temp fix till we update the compiler support */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) + /** VS2010 does not support inttypes - remove when VS2010 support is dropped */ #define __PRI64_PREFIX "ll" #define PRIX64 __PRI64_PREFIX "X" #define PRIu64 __PRI64_PREFIX "u"