Upgrade OpenCSD to v1.4.0

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update OpenCSD
For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md

Bug: 263556196
Test: TreeHugger
Change-Id: I8683cfcc0d1283feab4e84c447f0887dc9797e0a
diff --git a/METADATA b/METADATA
index 936e234..dc28d14 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update OpenCSD
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "OpenCSD"
 description: "This library provides an API suitable for the decode of ARM(r) CoreSight(tm) trace streams."
 third_party {
@@ -9,11 +13,11 @@
     type: GIT
     value: "https://github.com/Linaro/OpenCSD.git"
   }
-  version: "v1.3.3"
+  version: "v1.4.0"
   license_type: RESTRICTED
   last_upgrade_date {
-    year: 2022
-    month: 11
-    day: 4
+    year: 2023
+    month: 1
+    day: 20
   }
 }
diff --git a/README.md b/README.md
index 85fa4d4..450c8e3 100644
--- a/README.md
+++ b/README.md
@@ -27,11 +27,11 @@
 CoreSight Trace Component Support.
 ----------------------------------
 
-_Current Version 1.3.3_
+_Current Version 1.4.0_
 
 ### Current support:
 
-- ETE   (v1.2) instruction trace - packet processing and packet decode.
+- ETE   (v1.3) instruction trace - packet processing and packet decode.
 - ETMv4 (v4.6 [A/R profile] v4.4 [M profile]) instruction trace - packet processing and packet decode.
 - PTM   (v1.1) instruction trace - packet processing and packet decode.
 - ETMv3 (v3.5) instruction trace - packet processing and packet decode.
@@ -286,6 +286,11 @@
                   and allowing fun with mis-aligned input data.
     - __Bugfix__: Fix silent failure if incorrect config flags set when setting up frame demux modes.
 
+- _Version 1.4.0_:
+    - __Update__: ETE: Add support for Arch v9.4 FEAT_ITE. ETE v1p3, sw trace instrumentation.
+                  Adds in new generic output packet type: OCSD_GEN_TRC_ELEM_INSTRUMENTATION.
+    - __Bugfix__: Fix memory leak in mispredict handling (github issue #52 from yabinc)
+
 
 Licence Information
 ===================
diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox
index d8e80cd..7590e47 100644
--- a/decoder/docs/doxygen_config.dox
+++ b/decoder/docs/doxygen_config.dox
@@ -38,7 +38,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.3.3
+PROJECT_NUMBER         = 1.4.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/decoder/docs/prog_guide/prog_guide_generic_pkts.md b/decoder/docs/prog_guide/prog_guide_generic_pkts.md
index 4a2f5b2..aad15b8 100644
--- a/decoder/docs/prog_guide/prog_guide_generic_pkts.md
+++ b/decoder/docs/prog_guide/prog_guide_generic_pkts.md
@@ -86,6 +86,8 @@
         unsync_info_t unsync_eot_info;      /* additional information for unsync / end-of-trace packets. */
 		trace_marker_payload_t sync_marker; /* marker element - sync later element to position in stream */
         trace_memtrans_t mem_trans;         /* memory transaction packet - transaction event */
+        trace_sw_ite_t sw_ite;              /* PE sw instrumentation using FEAT_ITE */
+
 	};
 
     const void *ptr_extended_data;        /* pointer to extended data buffer (data trace, sw trace payload) / custom structure */
@@ -327,6 +329,7 @@
 
 SW trace packets that include timestamp information will us the `has_ts` flag and fill in the timestamp value.
 
+These packets are generated by memory writes to STM / ITM trace hardware. 
 
 ### OCSD_GEN_TRC_ELEM_SYNC_MARKER ###
 __packet fields valid__: `sync_marker`
@@ -365,6 +368,19 @@
 } trace_memtrans_t;
 ~~~
 
+### OCSD_GEN_TRC_ELEM_INSTRUMENTATION ###
+__packet fields valid__: `sw_ite`
+
+Software instrumentation packets generated by the PE `TRCIT` instruction (on cores with `FEAT_ITE`).
+
+The `sw_ite` structure has the fields defined below:-
+
+~~~{.c}
+typedef struct _sw_ite_t {
+    uint8_t el;             /* exception level for PE sw instrumentation instruction */
+    uint64_t value;         /* payload for PE sw instrumentation instruction */
+} trace_sw_ite_t;
+~~~
 
 ### OCSD_GEN_TRC_ELEM_CUSTOM ###
 __packet fields optional__: `extended_data -> ptr_extended_data`,_any others_
diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h
index 25be807..405abfe 100644
--- a/decoder/include/common/trc_gen_elem.h
+++ b/decoder/include/common/trc_gen_elem.h
@@ -75,12 +75,14 @@
 
     void setAddrRange(const ocsd_vaddr_t  st_addr, const ocsd_vaddr_t en_addr, const int num_instr = 1);
     void setLastInstrInfo(const bool exec, const ocsd_instr_type last_i_type, const ocsd_instr_subtype last_i_subtype, const uint8_t size);
-    void setAddrStart(const ocsd_vaddr_t  st_addr) { this->st_addr = st_addr; };
+    void setAddrStart(const ocsd_vaddr_t st_addr) { this->st_addr = st_addr; };
     void setLastInstrCond(const int is_cond) { this->last_instr_cond = is_cond; };
 
     void setSWTInfo(const ocsd_swt_info_t swt_info) { sw_trace_info = swt_info; };
     void setExtendedDataPtr(const void *data_ptr);
 
+    void setITEInfo(const trace_sw_ite_t sw_instrumentation) { sw_ite = sw_instrumentation; };
+
     void setSyncMarker(const trace_marker_payload_t &marker);
 
 // stringize the element
diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
index c5c609c..21bd7af 100644
--- a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
+++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
@@ -65,7 +65,8 @@
     P0_TRANS_TRACE_INIT,
     P0_TRANS_START,
     P0_TRANS_COMMIT,
-    P0_TRANS_FAIL
+    P0_TRANS_FAIL,
+    P0_ITE,
 } p0_elem_t;
 
 
@@ -334,6 +335,30 @@
 {
 }
 
+/************************************************************/
+/* Instrumentation element
+ */
+
+class TrcStackElemITE : public TrcStackElem
+{
+protected:
+    TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index);
+    virtual ~TrcStackElemITE() {};
+
+    friend class EtmV4P0Stack;
+
+public:
+    void setITE(const trace_sw_ite_t &ite) { m_ite = ite; };
+    const trace_sw_ite_t &getITE() { return m_ite; };
+
+private:
+    trace_sw_ite_t m_ite;
+};
+
+inline TrcStackElemITE::TrcStackElemITE(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
+    TrcStackElem(P0_ITE, false, root_pkt, root_index)
+{
+}
 
 /************************************************************/
 /* P0 element stack that allows push of elements, and deletion of elements when done.
@@ -372,6 +397,7 @@
     TrcStackQElem *createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count);
     TrcStackElemMarker *createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker);
     TrcStackElemAddr *createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val);
+    TrcStackElemITE *createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite);
 
 private:
     std::deque<TrcStackElem *> m_P0_stack;  //!< P0 decode element stack
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 65230ff..7838ece 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -100,6 +100,9 @@
     // process a transaction element
     ocsd_err_t processTransElem(TrcStackElem *pElem);
 
+    // process an Instrumentation element
+    ocsd_err_t processITEElem(TrcStackElem *pElem);
+
     // process a bad packet
     ocsd_err_t handleBadPacket(const char *reason, ocsd_trc_index_t index = OCSD_BAD_TRC_INDEX);
 
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
index 22f39d9..0240474 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h
@@ -160,6 +160,7 @@
     void setEvent(const uint8_t event_val);
 
     void setQType(const bool has_count, const uint32_t count, const bool has_addr, const bool addr_match, const uint8_t type);
+    void setITE(const uint8_t el, const uint64_t value);
 
     // packet status interface - get packet info.
     const ocsd_etmv4_i_pkt_type getType() const { return type; };
@@ -200,6 +201,10 @@
     const int getCommitElem() const { return commit_elements; };
     const int getCancelElem() const { return cancel_elements; };
 
+    // ITE
+    const uint8_t getITE_EL() const { return ite_pkt.el; };
+    const uint64_t getITE_value() const { return ite_pkt.value; };
+
     // packet type
     const bool isBadPacket() const;
 
@@ -539,6 +544,12 @@
     m_addr_stack.get_idx(idx, v_addr, v_addr_ISA);
 }
 
+inline void EtmV4ITrcPacket::setITE(const uint8_t el, const uint64_t value)
+{
+    ite_pkt.el = el;
+    ite_pkt.value = value;
+}
+
 /** @}*/
 
 #endif // ARM_TRC_PKT_ELEM_ETMV4I_H_INCLUDED
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
index 19388c3..58c0d78 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_proc_etmv4i.h
@@ -179,6 +179,7 @@
     void iPktQ(const uint8_t lastByte);
     void iAtom(const uint8_t lastByte);
     void iPktInvalidCfg(const uint8_t lastByte);  // packet invalid in current config.
+    void iPktITE(const uint8_t lastByte);
 
     unsigned extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit = 5);
     unsigned extractTSField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value);
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
index 38963d1..2a03b08 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h
@@ -2,7 +2,7 @@
  * \file       trc_pkt_types_etmv4.h
  * \brief      OpenCSD : ETMv4 / ETE packet info
  * 
- * \copyright  Copyright (c) 2015,2019 ARM Limited. All Rights Reserved.
+ * \copyright  Copyright (c) 2015,2019,2022 ARM Limited. All Rights Reserved.
  */
 
 
@@ -73,7 +73,7 @@
         ETM4_PKT_I_EXCEPT_RTN =         0x07,   /*!< b00000111 (ETE invalid) */
 
         /* unused encoding              0x08         b00001000 */
-        ETE_PKT_I_COMMIT_WIN_MV =       0x09,   /*!  b00001001 (ETE only - unused in current versions) */
+        ETE_PKT_I_ITE =                 0x09,   /*!  b00001001 (ETE only) */
         ETE_PKT_I_TRANS_ST =            0x0A,   /*!  b00001010 (ETE only) */
         ETE_PKT_I_TRANS_COMMIT =        0x0B,   /*!  b00001011 (ETE only) */
 
@@ -274,6 +274,11 @@
         };
     } Q_pkt;
 
+    struct {
+        uint8_t el;
+        uint64_t value;
+    } ite_pkt;
+
     //! valid bits for packet elements (addresses have their own valid bits).
     union {
         uint32_t val;
diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h
index 355204c..41033f0 100644
--- a/decoder/include/opencsd/ocsd_if_version.h
+++ b/decoder/include/opencsd/ocsd_if_version.h
@@ -43,8 +43,8 @@
 /** @name Library Versioning
 @{*/
 #define OCSD_VER_MAJOR 0x1 /**< Library Major Version */
-#define OCSD_VER_MINOR 0x3 /**< Library Minor Version */
-#define OCSD_VER_PATCH 0x3 /**< Library Patch Version */
+#define OCSD_VER_MINOR 0x4 /**< Library Minor Version */
+#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
 
 /** Library version number - MMMMnnpp format.
     MMMM = major version, 
@@ -53,7 +53,7 @@
 */
 #define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH) 
 
-#define OCSD_VER_STRING "1.3.3"    /**< Library Version string */
+#define OCSD_VER_STRING "1.4.0"    /**< Library Version string */
 #define OCSD_LIB_NAME "OpenCSD Library"  /**< Library name string */
 #define OCSD_LIB_SHORT_NAME "OCSD"    /**< Library Short name string */
 /** @}*/
diff --git a/decoder/include/opencsd/trc_gen_elem_types.h b/decoder/include/opencsd/trc_gen_elem_types.h
index 6c1fd09..99194d1 100644
--- a/decoder/include/opencsd/trc_gen_elem_types.h
+++ b/decoder/include/opencsd/trc_gen_elem_types.h
@@ -60,9 +60,10 @@
     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 - trigger or numbered event  */   
-    OCSD_GEN_TRC_ELEM_SWTRACE,         /*!< Software trace packet - may contain data payload. */
+    OCSD_GEN_TRC_ELEM_SWTRACE,         /*!< Software trace packet - may contain data payload. STM / ITM hardware trace with channel protocol */
     OCSD_GEN_TRC_ELEM_SYNC_MARKER,     /*!< Synchronisation marker - marks position in stream of an element that is output later. */
     OCSD_GEN_TRC_ELEM_MEMTRANS,        /*!< Trace indication of transactional memory operations. */
+    OCSD_GEN_TRC_ELEM_INSTRUMENTATION, /*!< PE instrumentation trace - PE generated SW trace, application dependent protocol. */
     OCSD_GEN_TRC_ELEM_CUSTOM,          /*!< Fully custom packet type - used by none-ARM architecture decoders */
 } ocsd_gen_trc_elem_t;
 
@@ -104,6 +105,11 @@
     OCSD_MEM_TRANS_FAIL,      /**< Transactional memory sequence failed - operations since start of transaction have been unwound. */  
 } trace_memtrans_t;
 
+typedef struct _sw_ite_t {
+    uint8_t el;             /**< exception level for PE sw instrumentation instruction */
+    uint64_t value;         /**< payload for PE sw instrumentation instruction */
+} trace_sw_ite_t;
+
 typedef struct _ocsd_generic_trace_elem {
     ocsd_gen_trc_elem_t elem_type;   /**< Element type - remaining data interpreted according to this value */
     ocsd_isa           isa;          /**< instruction set for executed instructions */
@@ -142,6 +148,7 @@
         unsync_info_t unsync_eot_info;      /**< additional information for unsync / end-of-trace packets. */
         trace_marker_payload_t sync_marker; /**< marker element - sync later element to position in stream */
         trace_memtrans_t mem_trans;         /**< memory transaction packet - transaction event */
+        trace_sw_ite_t sw_ite;              /**< PE sw instrumentation using FEAT_ITE */
     };
 
     const void *ptr_extended_data;        /**< pointer to extended data buffer (data trace, sw trace payload) / custom structure */
diff --git a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
index 1207444..a5d8894 100644
--- a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
+++ b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
@@ -150,6 +150,18 @@
     return pElem;
 }
 
+TrcStackElemITE *EtmV4P0Stack::createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite)
+{
+    TrcStackElemITE *pElem = new (std::nothrow) TrcStackElemITE(root_pkt, root_index);
+    if (pElem)
+    {
+        pElem->setITE(ite);
+        push_front(pElem);
+    }
+    return pElem;
+}
+
+
 // iteration functions
 void EtmV4P0Stack::from_front_init()
 {
@@ -172,6 +184,10 @@
     erase_iter = m_iter;
     erase_iter--;
     m_P0_stack.erase(erase_iter);
+
+    // explicitly delete the item here as the caller can no longer reference it.
+    // fixes memory leak from github issue #52
+    delete *erase_iter;
 }
 
 
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index a9b059a..89c4505 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -564,12 +564,19 @@
         }
         break;
 
-    /*** presently unsupported packets ***/
-    /* ETE commit window - not supported in current ETE versions - blocked by packet processor */
-    case ETE_PKT_I_COMMIT_WIN_MV:
-        err = OCSD_ERR_UNSUPP_DECODE_PKT;
-        err = handlePacketSeqErr(err, m_index_curr_pkt, "ETE Commit Window Move, unsupported packet type.");
+        /* PE Instrumentation packet */
+    case ETE_PKT_I_ITE:
+        {
+            trace_sw_ite_t ite_pkt;
+
+            ite_pkt.el = m_curr_packet_in->getITE_EL();
+            ite_pkt.value = m_curr_packet_in->getITE_value();
+            if (m_P0_stack.createITEElem(m_curr_packet_in->getType(), m_index_curr_pkt, ite_pkt) == 0)
+                bAllocErr = true;
+        }
         break;
+
+    /*** presently unsupported packets ***/
         /* conditional instruction tracing */
     case ETM4_PKT_I_COND_FLUSH:
     case ETM4_PKT_I_COND_I_F1:
@@ -854,6 +861,10 @@
             case P0_TRANS_TRACE_INIT:
                 err = processTransElem(pElem);
                 break;
+
+            case P0_ITE:
+                err = processITEElem(pElem);
+                break;
             }
 
             if(bPopElem)
@@ -957,6 +968,10 @@
         case P0_MARKER:
             err = processMarkerElem(pElem);
             break;
+
+        case P0_ITE:
+            err = processITEElem(pElem);
+            break;
         }
         m_P0_stack.delete_back();
     }
@@ -1013,6 +1028,7 @@
                     case P0_CC:
                     case P0_TS_CC:
                     case P0_MARKER:
+                    case P0_ITE:
                         m_P0_stack.pop_front(false);
                         temp.push_back(pElem);
                         break;
@@ -1114,6 +1130,8 @@
         pElem = m_P0_stack.back();
         if (pElem->getP0Type() == P0_MARKER)
             err = processMarkerElem(pElem);
+        else if (pElem->getP0Type() == P0_MARKER)
+            err = processITEElem(pElem);
         else
             err = processTS_CC_EventElem(pElem);
         m_P0_stack.delete_back();
@@ -1206,6 +1224,18 @@
     return err;
 }
 
+ocsd_err_t TrcPktDecodeEtmV4I::processITEElem(TrcStackElem *pElem)
+{
+    ocsd_err_t err = OCSD_OK;
+    TrcStackElemITE *pITEElem = dynamic_cast<TrcStackElemITE *>(pElem);
+
+    err = m_out_elem.addElemType(pElem->getRootIndex(), OCSD_GEN_TRC_ELEM_INSTRUMENTATION);
+    if (!err) {
+        outElem().setITEInfo(pITEElem->getITE());
+    }
+    return err;
+}
+
 ocsd_err_t TrcPktDecodeEtmV4I::addElemCC(TrcStackElemParam *pParamElem)
 {
     ocsd_err_t err = OCSD_OK;
diff --git a/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
index b417540..825b5f7 100644
--- a/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp
@@ -275,6 +275,14 @@
             }
         }
         break;
+
+    case ETE_PKT_I_ITE:
+        {
+            std::ostringstream oss;
+            oss << "; EL" << std::dec << (int)ite_pkt.el << "; Payload=0x" << std::hex << ite_pkt.value;
+            str += oss.str();
+        }
+        break;
     }
 
 }   
@@ -360,12 +368,7 @@
         pName = "I_EXCEPT_RTN";
         pDesc = "Exception Return.";
         break;
-
-    case ETE_PKT_I_COMMIT_WIN_MV:
-        pName = "I_COMMIT_WIN_MV";
-        pDesc = "Commit window move.";
-        break;
-
+    
     case ETE_PKT_I_TRANS_ST:
         pName = "I_TRANS_ST";
         pDesc = "Transaction Start.";
@@ -642,6 +645,11 @@
         pDesc = "Transaction Fail.";
         break;
 
+    case ETE_PKT_I_ITE:
+        pName = "I_ITE";
+        pDesc = "Instrumentation";
+        break;
+
     default:
         break;
     }
diff --git a/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
index d0573d6..d767bdc 100644
--- a/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp
@@ -1250,6 +1250,23 @@
     m_process_state = SEND_PKT;
 }
 
+void TrcPktProcEtmV4I::iPktITE(const uint8_t /* lastByte */)
+{
+    uint64_t value;
+    int shift = 0;
+
+    /* packet is always 10 bytes, Header, EL info byte, 8 bytes payload */
+    if (m_currPacketData.size() == 10) {
+        value = 0;
+        for (int i = 2; i < 10; i++) {
+            value |= ((uint64_t)m_currPacketData[i]) << shift;
+            shift += 8;
+        }
+        m_curr_packet.setITE(m_currPacketData[1], value);
+        m_process_state = SEND_PKT;
+    }
+}
+
 // header byte processing is table driven.
 void TrcPktProcEtmV4I::BuildIPacketTable()   
 {
@@ -1306,7 +1323,8 @@
     else
         m_i_table[0x07].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
 
-    // b00001010, b00001011 ETE TRANS packets 
+    // b00001010, b00001011 ETE TRANS packets
+    // b00001001 - ETE sw instrumentation packet
     if (m_config.MajVersion() >= 0x5)
     {
         m_i_table[0x0A].pkt_type = ETE_PKT_I_TRANS_ST;
@@ -1314,6 +1332,13 @@
 
         m_i_table[0x0B].pkt_type = ETE_PKT_I_TRANS_COMMIT;
         m_i_table[0x0B].pptkFn = &TrcPktProcEtmV4I::iPktNoPayload;
+
+        // FEAT_ITE - sw instrumentation packet
+        if (m_config.MinVersion() >= 0x3)
+        {
+            m_i_table[0x09].pkt_type = ETE_PKT_I_ITE;
+            m_i_table[0x09].pptkFn = &TrcPktProcEtmV4I::iPktITE;
+        }
     }
 
     // b0000 110x - cycle count f2
diff --git a/decoder/source/trc_gen_elem.cpp b/decoder/source/trc_gen_elem.cpp
index b2e6772..c94c5a7 100644
--- a/decoder/source/trc_gen_elem.cpp
+++ b/decoder/source/trc_gen_elem.cpp
@@ -54,9 +54,10 @@
     {"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_SWTRACE","Software trace packet - may contain data payload."},
+    {"OCSD_GEN_TRC_ELEM_SWTRACE","Software trace packet - may contain data payload. STM / ITM hardware trace with channel protocol."},
     {"OCSD_GEN_TRC_ELEM_SYNC_MARKER","Synchronisation marker - marks position in stream of an element that is output later."},
     {"OCSD_GEN_TRC_ELEM_MEMTRANS","Trace indication of transactional memory operations."},
+    {"OCSD_GEN_TRC_ELEM_INSTRUMENTATION", "PE instrumentation trace - PE generated SW trace, application dependent protocol."},
     {"OCSD_GEN_TRC_ELEM_CUSTOM","Fully custom packet type."}
 };
 
@@ -219,6 +220,10 @@
                 oss << s_transaction_type[mem_trans];
             break;
 
+        case OCSD_GEN_TRC_ELEM_INSTRUMENTATION:
+            oss << "EL" << std::dec << (int)sw_ite.el << "; 0x" << std::setfill('0') << std::setw(16) << std::hex << sw_ite.value;
+            break;
+
         default: break;
         }
         if(has_cc)
diff --git a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj
index 05ff8b6..985a84e 100644
--- a/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj
+++ b/decoder/tests/build/win-vs2022/c_api_pkt_print_test/c_api_pkt_print_test.vcxproj
@@ -55,6 +55,7 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>MultiByte</CharacterSet>
     <PlatformToolset>v143</PlatformToolset>
+    <EnableASAN>true</EnableASAN>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
diff --git a/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj
index a6f43d2..e1daff7 100644
--- a/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj
+++ b/decoder/tests/build/win-vs2022/trc_pkt_lister/trc_pkt_lister.vcxproj
@@ -46,6 +46,7 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>MultiByte</CharacterSet>
     <PlatformToolset>v143</PlatformToolset>
+    <EnableASAN>false</EnableASAN>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-dll|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
diff --git a/decoder/tests/run_pkt_decode_tests-ete.bash b/decoder/tests/run_pkt_decode_tests-ete.bash
index 1bf60a5..a9fe0cc 100755
--- a/decoder/tests/run_pkt_decode_tests-ete.bash
+++ b/decoder/tests/run_pkt_decode_tests-ete.bash
@@ -55,6 +55,7 @@
                               "002-ack_test_scr"
                               "ete-bc-instr"
                               "ete_ip"
+                              "ete-ite-instr"
                               "ete_mem"
                               "ete_spec_1"
                               "ete_spec_2"
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s1.ini b/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s1.ini
new file mode 100644
index 0000000..23947f3
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s1.ini
@@ -0,0 +1,15 @@
+[device]
+name=ETE_0_s1
+class=trace_source
+type=ETE
+
+
+[regs]
+TRCCONFIGR=0x8001
+TRCTRACEIDR=0x1
+TRCDEVARCH=0x47735a13
+TRCIDR0=0x28c1cea1
+TRCIDR1=0x4100fff0
+TRCIDR2=0xd0001088
+TRCIDR8=0x0
+
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s2.ini b/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s2.ini
new file mode 100644
index 0000000..063b076
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/ETE_0_s2.ini
@@ -0,0 +1,15 @@
+[device]
+name=ETE_0_s2
+class=trace_source
+type=ETE
+
+
+[regs]
+TRCCONFIGR=0x8001
+TRCTRACEIDR=0x1
+TRCDEVARCH=0x47735a13
+TRCIDR0=0x28c1cea1
+TRCIDR1=0x4100fff0
+TRCIDR2=0xd0001088
+TRCIDR8=0x0
+
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/OTHERS_exec b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/OTHERS_exec
new file mode 100644
index 0000000..502b47e
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/OTHERS_exec
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/TEST_NON_DET_CODE_exec b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/TEST_NON_DET_CODE_exec
new file mode 100644
index 0000000..047e0a9
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/TEST_NON_DET_CODE_exec
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_NON_DET_CODE_exec b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_NON_DET_CODE_exec
new file mode 100644
index 0000000..c31090b
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_NON_DET_CODE_exec
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_TEST_CODE_exec b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_TEST_CODE_exec
new file mode 100644
index 0000000..d5741ab
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/bindir_64/VAL_TEST_CODE_exec
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/cpu_0.ini b/decoder/tests/snapshots-ete/ete-ite-instr/cpu_0.ini
new file mode 100644
index 0000000..8283585
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/cpu_0.ini
@@ -0,0 +1,32 @@
+[device]
+name=cpu_0
+class=core
+type=ARM-AA64
+
+[regs]
+PC(size:64)=0x0
+SP(size:64)=0
+SCTLR_EL1=0x0
+CPSR=0x0
+
+
+[dump1]
+file=bindir_64/OTHERS_exec
+address=0x00060000
+length=0x1bf68
+
+[dump2]
+file=bindir_64/VAL_TEST_CODE_exec
+address=0x01000000
+length=0x2cb60
+
+[dump3]
+file=bindir_64/VAL_NON_DET_CODE_exec
+address=0x00010000
+length=0x20814
+
+[dump4]
+file=bindir_64/TEST_NON_DET_CODE_exec
+address=0x00050000
+length=0x14c
+
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/session1.bin b/decoder/tests/snapshots-ete/ete-ite-instr/session1.bin
new file mode 100644
index 0000000..489ae58
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/session1.bin
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/session2.bin b/decoder/tests/snapshots-ete/ete-ite-instr/session2.bin
new file mode 100644
index 0000000..e5c164e
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/session2.bin
Binary files differ
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/snapshot.ini b/decoder/tests/snapshots-ete/ete-ite-instr/snapshot.ini
new file mode 100644
index 0000000..299b376
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/snapshot.ini
@@ -0,0 +1,12 @@
+[snapshot]
+version=1.0
+description=checker_metadata.ini
+
+[device_list]
+device0=cpu_0.ini
+device1=ETE_0_s1.ini
+device2=ETE_0_s2.ini
+
+[trace]
+metadata=trace.ini
+
diff --git a/decoder/tests/snapshots-ete/ete-ite-instr/trace.ini b/decoder/tests/snapshots-ete/ete-ite-instr/trace.ini
new file mode 100644
index 0000000..1880b66
--- /dev/null
+++ b/decoder/tests/snapshots-ete/ete-ite-instr/trace.ini
@@ -0,0 +1,22 @@
+[trace_buffers]
+buffers=buffer2
+
+[buffer1]
+name=ETB_1
+file=session1.bin
+format=source_data
+
+[buffer2]
+name=ETB_2
+file=session2.bin
+format=source_data
+
+
+[source_buffers]
+ETE_0_s1=ETB_1
+ETE_0_s2=ETB_2
+
+[core_trace_sources]
+cpu_0=ETE_0_s1
+cpu_0=ETE_0_s2
+