Patchset updates ETMv4 trace decoder to support protocols up to ETMv4.4 Update of instruction decode library made to cover new instructions - primarily authenticated pointer calls and returns.
Set will form part of next OpenCSD library release at 0.11.0
Mike
Mike Leach (5): opencsd: ETMv4.4: update common types and etm 4 config opencsd: ETMv4.4: Update all decoders to init new parameters opencsd: ETMv4.4: Update instruction decoder. opencsd: ETMv4.4: protocol decoder modifications. opencsd: Update lib version
decoder/include/i_dec/trc_i_decode.h | 1 + decoder/include/i_dec/trc_idec_arminst.h | 9 + .../include/opencsd/etmv4/trc_cmp_cfg_etmv4.h | 20 +- .../opencsd/etmv4/trc_etmv4_stack_elem.h | 3 +- .../opencsd/etmv4/trc_pkt_elem_etmv4i.h | 5 +- .../opencsd/etmv4/trc_pkt_types_etmv4.h | 137 ++++--- decoder/include/opencsd/ocsd_if_types.h | 11 +- decoder/include/opencsd/ocsd_if_version.h | 6 +- decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp | 2 + .../source/etmv4/trc_pkt_decode_etmv4i.cpp | 24 ++ .../source/etmv4/trc_pkt_proc_etmv4i_impl.cpp | 374 ++++++++++++------ .../source/etmv4/trc_pkt_proc_etmv4i_impl.h | 75 ++-- decoder/source/i_dec/trc_i_decode.cpp | 50 ++- decoder/source/i_dec/trc_idec_arminst.cpp | 99 ++++- decoder/source/ocsd_code_follower.cpp | 1 + decoder/source/ptm/trc_pkt_decode_ptm.cpp | 1 + 16 files changed, 586 insertions(+), 232 deletions(-)
Updating decoder to ETMv4.4 specification. Add common type updates for additional features Update ETMv4 config for new parameters
Signed-off-by: Mike Leach mike.leach@linaro.org --- .../include/opencsd/etmv4/trc_cmp_cfg_etmv4.h | 20 +++++++++++++++++-- decoder/include/opencsd/ocsd_if_types.h | 11 ++++++++-- decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp | 2 ++ 3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h index a3f8835..1d72d97 100644 --- a/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h +++ b/decoder/include/opencsd/etmv4/trc_cmp_cfg_etmv4.h @@ -108,6 +108,7 @@ public: /* idr 1 */ const uint8_t MajVersion() const; const uint8_t MinVersion() const; + const uint8_t FullVersion() const;
/* idr 2 */ const uint32_t iaSizeMax() const; @@ -117,6 +118,7 @@ public: const uint32_t dvSize() const; const uint32_t ccSize() const; const bool vmidOpt() const; + const bool wfiwfeBranch() const;
/* id regs 8-13*/ const uint32_t MaxSpecDepth() const; @@ -180,7 +182,11 @@ private: bool m_condTraceCalc; CondITrace_t m_CondTrace;
+protected: ocsd_etmv4_cfg m_cfg; + uint8_t m_MajVer; + uint8_t m_MinVer; + };
/* idr 0 */ @@ -265,14 +271,18 @@ inline const bool EtmV4Config::commitOpt1() const /* idr 1 */ inline const uint8_t EtmV4Config::MajVersion() const { - return (uint8_t)((m_cfg.reg_idr1 >> 8) & 0xF); + return m_MajVer; }
inline const uint8_t EtmV4Config::MinVersion() const { - return (uint8_t)((m_cfg.reg_idr1 >> 4) & 0xF); + return m_MinVer; }
+inline const uint8_t EtmV4Config::FullVersion() const +{ + return (m_MajVer << 4) | m_MinVer; +}
/* idr 2 */ inline const uint32_t EtmV4Config::iaSizeMax() const @@ -320,6 +330,12 @@ inline const bool EtmV4Config::vmidOpt() const return (bool)((m_cfg.reg_idr2 & 0x20000000) == 0x20000000) && (MinVersion() > 0); }
+inline const bool EtmV4Config::wfiwfeBranch() const +{ + return (bool)((m_cfg.reg_idr2 & 0x80000000) && (FullVersion() >= 0x43)); +} + + /* id regs 8-13*/
inline const uint32_t EtmV4Config::MaxSpecDepth() const diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h index b5a53f2..2fc0fda 100644 --- a/decoder/include/opencsd/ocsd_if_types.h +++ b/decoder/include/opencsd/ocsd_if_types.h @@ -272,11 +272,16 @@ typedef enum _ocsd_dcd_tree_src_t { /** Core Architecture Version */ typedef enum _ocsd_arch_version { ARCH_UNKNOWN, /**< unknown architecture */ + ARCH_CUSTOM, /**< None ARM, custom architecture */ ARCH_V7, /**< V7 architecture */ ARCH_V8, /**< V8 architecture */ - ARCH_CUSTOM, /**< None ARM, custom architecture */ + ARCH_V8r3, /**< V8.3 architecture */ } ocsd_arch_version_t;
+// macros for arch version comparisons. +#define OCSD_IS_V8_ARCH(arch) ((arch >= ARCH_V8) && (arch <= ARCH_V8r3)) +#define OCSD_MIN_V8_ARCH(arch) (arch >= ARCH_V8) + /** Core Profile */ typedef enum _ocsd_core_profile { profile_Unknown, /**< Unknown profile */ @@ -351,7 +356,8 @@ typedef enum _ocsd_instr_type { OCSD_INSTR_BR, /**< Immediate Branch instruction */ OCSD_INSTR_BR_INDIRECT, /**< Indirect Branch instruction */ OCSD_INSTR_ISB, /**< Barrier : ISB instruction */ - OCSD_INSTR_DSB_DMB /**< Barrier : DSB or DMB instruction */ + OCSD_INSTR_DSB_DMB, /**< Barrier : DSB or DMB instruction */ + OCSD_INSTR_WFI_WFE, /**< WFI or WFE traced as direct branch */ } ocsd_instr_type;
/** instruction sub types - addiitonal information passed to the output packets @@ -378,6 +384,7 @@ typedef struct _ocsd_instr_info { ocsd_vaddr_t instr_addr; /**< Input: Instruction address. */ uint32_t opcode; /**< Input: Opcode at address. 16 bit opcodes will use MS 16bits of parameter. */ uint8_t dsb_dmb_waypoints; /**< Input: DMB and DSB are waypoints */ + uint8_t wfi_wfe_branch; /**< Input: WFI, WFE classed as direct branches */
/* instruction decode info */ ocsd_instr_type type; /**< Decoder: Current instruction type. */ diff --git a/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp b/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp index 7db0fa6..9f5b373 100644 --- a/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp +++ b/decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp @@ -75,6 +75,8 @@ void EtmV4Config::PrivateInit() m_VMIDSize = 0; m_condTraceCalc = false; m_CondTrace = COND_TR_DIS; + m_MajVer = (uint8_t)((m_cfg.reg_idr1 >> 8) & 0xF); + m_MinVer = (uint8_t)((m_cfg.reg_idr1 >> 4) & 0xF); }
void EtmV4Config::CalcQSupp()
All protocol decoders to use or init to 0 the new parameters in common type structures.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 1 + decoder/source/ocsd_code_follower.cpp | 1 + decoder/source/ptm/trc_pkt_decode_ptm.cpp | 1 + 3 files changed, 3 insertions(+)
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp index 0d1acb3..42f2699 100644 --- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp +++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp @@ -151,6 +151,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::onProtocolConfig()
// set up static trace instruction decode elements m_instr_info.dsb_dmb_waypoints = 0; + m_instr_info.wfi_wfe_branch = m_config->wfiwfeBranch() ? 1 : 0; m_instr_info.pe_type.arch = m_config->archVersion(); m_instr_info.pe_type.profile = m_config->coreProfile();
diff --git a/decoder/source/ocsd_code_follower.cpp b/decoder/source/ocsd_code_follower.cpp index 229859e..4386eb4 100644 --- a/decoder/source/ocsd_code_follower.cpp +++ b/decoder/source/ocsd_code_follower.cpp @@ -41,6 +41,7 @@ OcsdCodeFollower::OcsdCodeFollower() m_instr_info.pe_type.profile = profile_Unknown; m_instr_info.isa = ocsd_isa_unknown; m_instr_info.dsb_dmb_waypoints = 0; + m_instr_info.wfi_wfe_branch = 0; m_instr_info.instr_addr = 0; m_instr_info.opcode = 0; m_pMemAccess = 0; diff --git a/decoder/source/ptm/trc_pkt_decode_ptm.cpp b/decoder/source/ptm/trc_pkt_decode_ptm.cpp index 6673f78..94ed5ac 100644 --- a/decoder/source/ptm/trc_pkt_decode_ptm.cpp +++ b/decoder/source/ptm/trc_pkt_decode_ptm.cpp @@ -179,6 +179,7 @@ ocsd_err_t TrcPktDecodePtm::onProtocolConfig() m_instr_info.pe_type.profile = m_config->coreProfile(); m_instr_info.pe_type.arch = m_config->archVersion(); m_instr_info.dsb_dmb_waypoints = m_config->dmsbWayPt() ? 1 : 0; + m_instr_info.wfi_wfe_branch = 0; return err; }
Instruction decode updated to recognise new instructions in v8.x architecture that are used as P0 elements in ETMv4.x trace.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/i_dec/trc_i_decode.h | 1 + decoder/include/i_dec/trc_idec_arminst.h | 9 +++ decoder/source/i_dec/trc_i_decode.cpp | 50 ++++++++++-- decoder/source/i_dec/trc_idec_arminst.cpp | 99 ++++++++++++++++++++++- 4 files changed, 152 insertions(+), 7 deletions(-)
diff --git a/decoder/include/i_dec/trc_i_decode.h b/decoder/include/i_dec/trc_i_decode.h index ac31a79..0285f41 100644 --- a/decoder/include/i_dec/trc_i_decode.h +++ b/decoder/include/i_dec/trc_i_decode.h @@ -49,6 +49,7 @@ private: ocsd_err_t DecodeA32(ocsd_instr_info *instr_info); ocsd_err_t DecodeA64(ocsd_instr_info *instr_info); ocsd_err_t DecodeT32(ocsd_instr_info *instr_info); + void SetArchVersion(ocsd_instr_info *instr_info); };
#endif // ARM_TRC_I_DECODE_H_INCLUDED diff --git a/decoder/include/i_dec/trc_idec_arminst.h b/decoder/include/i_dec/trc_idec_arminst.h index 6654375..8697f68 100644 --- a/decoder/include/i_dec/trc_idec_arminst.h +++ b/decoder/include/i_dec/trc_idec_arminst.h @@ -75,6 +75,7 @@ int inst_ARM_is_direct_branch(uint32_t inst); int inst_Thumb_is_direct_branch(uint32_t inst); int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond); int inst_A64_is_direct_branch(uint32_t inst); +int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link);
/* Get branch destination for a direct branch. @@ -86,6 +87,7 @@ int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc); int inst_ARM_is_indirect_branch(uint32_t inst); int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link); int inst_Thumb_is_indirect_branch(uint32_t inst); +int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link); int inst_A64_is_indirect_branch(uint32_t inst);
int inst_ARM_is_branch_and_link(uint32_t inst); @@ -111,6 +113,10 @@ arm_barrier_t inst_ARM_barrier(uint32_t inst); arm_barrier_t inst_Thumb_barrier(uint32_t inst); arm_barrier_t inst_A64_barrier(uint32_t inst);
+int inst_ARM_wfiwfe(uint32_t inst); +int inst_Thumb_wfiwfe(uint32_t inst); +int inst_A64_wfiwfe(uint32_t inst); + /* Test whether an instruction is definitely undefined, e.g. because allocated to a "permanently UNDEFINED" space (UDF mnemonic). @@ -127,6 +133,9 @@ int inst_A64_is_UDF(uint32_t inst); ocsd_instr_subtype get_instr_subtype(); void clear_instr_subtype();
+/* set arch version info. */ +void set_arch_version(uint16_t version); + #endif // ARM_TRC_IDEC_ARMINST_H_INCLUDED
/* End of File trc_idec_arminst.h */ diff --git a/decoder/source/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp index 1fc2120..5ffc926 100644 --- a/decoder/source/i_dec/trc_i_decode.cpp +++ b/decoder/source/i_dec/trc_i_decode.cpp @@ -40,6 +40,8 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info) { ocsd_err_t err = OCSD_OK; clear_instr_subtype(); + SetArchVersion(instr_info); + switch(instr_info->isa) { case ocsd_isa_arm: @@ -65,6 +67,23 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info) return err; }
+void TrcIDecode::SetArchVersion(ocsd_instr_info *instr_info) +{ + uint16_t arch = 0x0700; + bool m_profile = (instr_info->pe_type.profile == profile_CortexM); + + switch (instr_info->pe_type.arch) + { + case ARCH_V8: arch = 0x0800; break; + case ARCH_V8r3: arch = 0x0803; break; + case ARCH_V7: + default: + break; + } + set_arch_version(arch); +} + + ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info) { uint32_t branchAddr = 0; @@ -107,7 +126,13 @@ ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info) break; } } - + else if (instr_info->wfi_wfe_branch) + { + if (inst_ARM_wfiwfe(instr_info->opcode)) + { + instr_info->type = OCSD_INSTR_WFI_WFE; + } + } instr_info->is_conditional = inst_ARM_is_conditional(instr_info->opcode);
return OCSD_OK; @@ -123,17 +148,17 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info) instr_info->next_isa = instr_info->isa; // assume same ISA instr_info->is_link = 0;
- if(inst_A64_is_indirect_branch(instr_info->opcode)) + if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link)) { instr_info->type = OCSD_INSTR_BR_INDIRECT; - instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode); +// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode); } - else if(inst_A64_is_direct_branch(instr_info->opcode)) + else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link)) { inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr); instr_info->type = OCSD_INSTR_BR; instr_info->branch_addr = (ocsd_vaddr_t)branchAddr; - instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode); +// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode); } else if((barrier = inst_A64_barrier(instr_info->opcode)) != ARM_BARRIER_NONE) { @@ -150,6 +175,13 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info) break; } } + else if (instr_info->wfi_wfe_branch) + { + if (inst_A64_wfiwfe(instr_info->opcode)) + { + instr_info->type = OCSD_INSTR_WFI_WFE; + } + }
instr_info->is_conditional = inst_A64_is_conditional(instr_info->opcode);
@@ -202,7 +234,13 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info) break; } } - + else if (instr_info->wfi_wfe_branch) + { + if (inst_Thumb_wfiwfe(instr_info->opcode)) + { + instr_info->type = OCSD_INSTR_WFI_WFE; + } + } instr_info->is_conditional = inst_Thumb_is_conditional(instr_info->opcode); instr_info->thumb_it_conditions = inst_Thumb_is_IT(instr_info->opcode);
diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp index f3f2732..09964a1 100644 --- a/decoder/source/i_dec/trc_idec_arminst.cpp +++ b/decoder/source/i_dec/trc_idec_arminst.cpp @@ -45,6 +45,9 @@ block identification and trace decode.
static ocsd_instr_subtype instr_sub_type = OCSD_S_INSTR_NONE;
+/* need to spot the architecture version for certain instructions */ +static uint16_t arch_version = 0x70; + ocsd_instr_subtype get_instr_subtype() { return instr_sub_type; @@ -55,6 +58,11 @@ void clear_instr_subtype() instr_sub_type = OCSD_S_INSTR_NONE; }
+void set_arch_version(uint16_t version) +{ + arch_version = version; +} + int inst_ARM_is_direct_branch(uint32_t inst) { int is_direct_branch = 1; @@ -73,6 +81,16 @@ int inst_ARM_is_direct_branch(uint32_t inst) return is_direct_branch; }
+int inst_ARM_wfiwfe(uint32_t inst) +{ + if ( ((inst & 0xf0000000) != 0xf0000000) && + ((inst & 0x0ffffffe) == 0x0320f002) + ) + /* WFI & WFE may be traced as branches in etm4.3 ++ */ + return 1; + return 0; +} + int inst_ARM_is_indirect_branch(uint32_t inst) { int is_indirect_branch = 1; @@ -163,6 +181,22 @@ int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *i return is_direct_branch; }
+int inst_Thumb_wfiwfe(uint32_t inst) +{ + int is_wfiwfe = 1; + /* WFI, WFE may be branches in etm4.3++ */ + if ((inst & 0xfffffffe) == 0xf3af8002) { + /* WFI & WFE (encoding T2) */ + } + else if ((inst & 0xffef0000) == 0xbf200000) { + /* WFI & WFE (encoding T1) */ + } + else { + is_wfiwfe = 0; + } + return is_wfiwfe; +} + int inst_Thumb_is_indirect_branch(uint32_t inst) { uint8_t link; @@ -175,7 +209,7 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link) int is_branch = 1;
if ((inst & 0xff000000) == 0x47000000) { - /* BX, BLX (reg) */ + /* BX, BLX (reg) [v8M includes BXNS, BLXNS] */ if (inst & 0x00800000) { *is_link = 1; instr_sub_type = OCSD_S_INSTR_BR_LINK; @@ -221,6 +255,12 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link) }
int inst_A64_is_direct_branch(uint32_t inst) +{ + uint8_t link = 0; + return inst_A64_is_direct_branch_link(inst, &link); +} + +int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link) { int is_direct_branch = 1; if ((inst & 0x7c000000) == 0x34000000) { @@ -229,23 +269,69 @@ int inst_A64_is_direct_branch(uint32_t inst) /* B<cond> */ } else if ((inst & 0x7c000000) == 0x14000000) { /* B, BL imm */ + if (inst & 0x80000000) { + *is_link = 1; + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } } else { is_direct_branch = 0; } return is_direct_branch; }
+int inst_A64_wfiwfe(uint32_t inst) +{ + /* WFI, WFE may be traced as branches in etm 4.3++ */ + if ((inst & 0xffffffdf) == 0xd503205f) + return 1; + return 0; +} + int inst_A64_is_indirect_branch(uint32_t inst) +{ + uint8_t link = 0; + return inst_A64_is_indirect_branch_link(inst, &link); +} + +int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link) { int is_indirect_branch = 1; + if ((inst & 0xffdffc1f) == 0xd61f0000) { /* BR, BLR */ + if (inst & 0x00200000) { + *is_link = 1; + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } } else if ((inst & 0xfffffc1f) == 0xd65f0000) { instr_sub_type = OCSD_S_INSTR_V8_RET; /* RET */ } else if ((inst & 0xffffffff) == 0xd69f03e0) { /* ERET */ instr_sub_type = OCSD_S_INSTR_V8_ERET; + } else if (arch_version >= 0x0803) { + /* new pointer auth instr for v8.3 arch */ + if ((inst & 0xffdff800) == 0xd61f0800) { + /* BRAA, BRAB, BLRAA, BLRBB */ + if (inst & 0x00200000) { + *is_link = 1; + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } + } else if ((inst & 0xffdff81F) == 0xd71f081F) { + /* BRAAZ, BRABZ, BLRAAZ, BLRBBZ */ + if (inst & 0x00200000) { + *is_link = 1; + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } + } else if ((inst & 0xfffffbff) == 0xd69f0bff) { + /* ERETAA, ERETAB */ + instr_sub_type = OCSD_S_INSTR_V8_ERET; + } else if ((inst & 0xfffffbff) == 0xd65f0bff) { + /* RETAA, RETAB */ + instr_sub_type = OCSD_S_INSTR_V8_RET; + } else { + is_indirect_branch = 0; + } } else { is_indirect_branch = 0; } @@ -419,6 +505,17 @@ int inst_A64_is_branch_and_link(uint32_t inst) } else if ((inst & 0xfc000000) == 0x94000000) { /* BL */ instr_sub_type = OCSD_S_INSTR_BR_LINK; + } else if (arch_version >= 0x0803) { + /* new pointer auth instr for v8.3 arch */ + if ((inst & 0xfffff800) == 0xd73f0800) { + /* BLRAA, BLRBB */ + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } else if ((inst & 0xfffff81F) == 0xd63f081F) { + /* BLRAAZ, BLRBBZ */ + instr_sub_type = OCSD_S_INSTR_BR_LINK; + } else { + is_branch = 0; + } } else { is_branch = 0; }
Re-jig packet types enum to list in numeric order.
Make some packet types ETM version dependent - fail if not applicable to current version or configuration.
Update processing loop to run all data inside try catch block.
Add handling for additional packet types introduced in protocols up to ETMv4.4.
Signed-off-by: Mike Leach mike.leach@linaro.org --- .../opencsd/etmv4/trc_etmv4_stack_elem.h | 3 +- .../opencsd/etmv4/trc_pkt_elem_etmv4i.h | 5 +- .../opencsd/etmv4/trc_pkt_types_etmv4.h | 137 ++++--- .../source/etmv4/trc_pkt_decode_etmv4i.cpp | 23 ++ .../source/etmv4/trc_pkt_proc_etmv4i_impl.cpp | 374 ++++++++++++------ .../source/etmv4/trc_pkt_proc_etmv4i_impl.h | 75 ++-- 6 files changed, 399 insertions(+), 218 deletions(-)
diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h index 8bf0fb0..d5d88cb 100644 --- a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h +++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h @@ -56,7 +56,8 @@ typedef enum _p0_elem_t P0_TS, P0_CC, P0_TS_CC, - P0_OVERFLOW + P0_OVERFLOW, + P0_FUNC_RET, } p0_elem_t;
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h index a5fbed9..d823ad3 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_elem_etmv4i.h @@ -115,7 +115,7 @@ public: void initNextPacket(); //!< clear any single packet only flags / state.
void setType(const ocsd_etmv4_i_pkt_type pkt_type) { type = pkt_type; }; - void updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type); + void updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t val = 0);
void clearTraceInfo(); //!< clear all the trace info data prior to setting for new trace info packet. void setTraceInfo(const uint32_t infoVal); @@ -208,11 +208,12 @@ private: Etmv4PktAddrStack m_addr_stack; };
-inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type) +inline void EtmV4ITrcPacket::updateErrType(const ocsd_etmv4_i_pkt_type err_pkt_type, const uint8_t err_val /* = 0 */) { // set primary type to incoming error type, set packet err type to previous primary type. err_type = type; type = err_pkt_type; + err_hdr_val = err_val; }
inline void EtmV4ITrcPacket::clearTraceInfo() diff --git a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h index b22a2b9..dd69a4b 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h @@ -1,8 +1,8 @@ /* * \file trc_pkt_types_etmv4.h - * \brief OpenCSD : + * \brief OpenCSD : ETMv4 packet info * - * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. + * \copyright Copyright (c) 2015,2019 ARM Limited. All Rights Reserved. */
@@ -56,80 +56,95 @@ typedef enum _ocsd_etmv4_i_pkt_type ETM4_PKT_I_BAD_SEQUENCE = 0x300, /*!< invalid sequence for packet type. */ ETM4_PKT_I_BAD_TRACEMODE, /*!< invalid packet type for this trace mode. */ ETM4_PKT_I_RESERVED, /*!< packet type reserved. */ + ETM4_PKT_I_RESERVED_CFG, /*!< packet type reserved for current configuration */
/* I stream packet types. */ /* extension header. */ - ETM4_PKT_I_EXTENSION = 0x00, /*!< b00000000 */ + ETM4_PKT_I_EXTENSION = 0x00, /*!< b00000000 */ + + /* sync */ + ETM4_PKT_I_TRACE_INFO = 0x01, /*!< b00000001 */ + // timestamp + ETM4_PKT_I_TIMESTAMP = 0x02, /*!< b0000001x */ + ETM4_PKT_I_TRACE_ON = 0x04, /*!< b00000100 */ + ETM4_PKT_I_FUNC_RET = 0x05, /*!< b00000101 (V8M only) */ + // Exceptions + ETM4_PKT_I_EXCEPT = 0x06, /*!< b00000110 */ + ETM4_PKT_I_EXCEPT_RTN = 0x07, /*!< b00000111 */ + + /* unused encodings 0x08-0xB b00001000 to b00001011 */ + + /* cycle count packets */ + ETM4_PKT_I_CCNT_F2 = 0x0C, /*!< b0000110x */ + ETM4_PKT_I_CCNT_F1 = 0x0E, /*!< b0000111x */ + ETM4_PKT_I_CCNT_F3 = 0x10, /*!< b0001xxxx */ + + // data synchronisation markers + ETM4_PKT_I_NUM_DS_MKR = 0x20, /*!< b00100xxx */ + ETM4_PKT_I_UNNUM_DS_MKR = 0x28, /*!< b00101000 to b00101100 0x2C */ + + // speculation + ETM4_PKT_I_COMMIT = 0x2D, /*!< b00101101 */ + ETM4_PKT_I_CANCEL_F1 = 0x2E, /*!< b0010111x */ + ETM4_PKT_I_MISPREDICT = 0x30, /*!< b001100xx */ + ETM4_PKT_I_CANCEL_F2 = 0x34, /*!< b001101xx */ + ETM4_PKT_I_CANCEL_F3 = 0x38, /*!< b00111xxx */
- /* address amd context */ - ETM4_PKT_I_ADDR_CTXT_L_32IS0 = 0x82, /*!< b10000010 */ + /* conditional instruction tracing */ + ETM4_PKT_I_COND_I_F2 = 0x40, /*!< b01000000 - b01000010 */ + ETM4_PKT_I_COND_FLUSH = 0x43, /*!< b01000011 */ + ETM4_PKT_I_COND_RES_F4 = 0x44, /*!< b0100010x, b01000110 */ + /* unused encoding 0x47 b01000111 */ + ETM4_PKT_I_COND_RES_F2 = 0x48, /*!< b0100100x, b01001010, b0100110x, b01001110 */ + /* unused encodings 0x4B,0x4F b01001011, b01001111 */ + ETM4_PKT_I_COND_RES_F3 = 0x50, /*!< b0101xxxx */ + /* unused encodings 0x60-0x67 b01100xxx */ + ETM4_PKT_I_COND_RES_F1 = 0x68, /*!< b011010xx, b0110111x 0x68-0x6B, 0x6e-0x6F */ + ETM4_PKT_I_COND_I_F1 = 0x6C, /*!< b01101100 */ + ETM4_PKT_I_COND_I_F3 = 0x6D, /*!< b01101101 */ + + // event trace + ETM4_PKT_I_IGNORE = 0x70, /*!< b01110000 */ + ETM4_PKT_I_EVENT = 0x71, /*!< b01110001 to 0x01111111 0x7F */ + + /* address and context */ + ETM4_PKT_I_CTXT = 0x80, /*!< b1000000x */ + ETM4_PKT_I_ADDR_CTXT_L_32IS0 = 0x82, /*!< b10000010 */ ETM4_PKT_I_ADDR_CTXT_L_32IS1, /*!< b10000011 */ - /* unused encoding b10000100 */ - ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */ + /* unused encoding 0x84 b10000100 */ + ETM4_PKT_I_ADDR_CTXT_L_64IS0 = 0x85, /*!< b10000101 */ ETM4_PKT_I_ADDR_CTXT_L_64IS1, /*!< b10000110 */ - /* unused encoding b10000111 */ - ETM4_PKT_I_CTXT = 0x80, /*!< b1000000x */ - ETM4_PKT_I_ADDR_MATCH = 0x90, /*!< b10010000 to b10010010 */ - ETM4_PKT_I_ADDR_L_32IS0 = 0x9A, /*!< b10011010 */ + /* unused encoding 0x87 b10000111 */ + /* unused encodings 0x88-0x8F b10001xxx */ + ETM4_PKT_I_ADDR_MATCH = 0x90, /*!< b10010000 to b10010010 0x92 */ + /* unused encodings 0x93-0x94 b10010011 to b10010010 */ + ETM4_PKT_I_ADDR_S_IS0 = 0x95, /*!< b10010101 */ + ETM4_PKT_I_ADDR_S_IS1, /*!< b10010110 */ + /* unused encodings 0x97 b10010111 to b10011001 0x99 */ + ETM4_PKT_I_ADDR_L_32IS0 = 0x9A, /*!< b10011010 */ ETM4_PKT_I_ADDR_L_32IS1, /*!< b10011011 */ - /* unused encoding b10011100 */ - ETM4_PKT_I_ADDR_L_64IS0 = 0x9D, /*!< b10011101 */ + /* unused encoding 0x9C b10011100 */ + ETM4_PKT_I_ADDR_L_64IS0 = 0x9D, /*!< b10011101 */ ETM4_PKT_I_ADDR_L_64IS1, /*!< b10011110 */ - /* unused encoding b10011111 */ - ETM4_PKT_I_ADDR_S_IS0 = 0x95, /*!< b10010101 */ - ETM4_PKT_I_ADDR_S_IS1, /*!< b10010110 */ - /* unused encoding b10010111 - unused encoding b10011000 - unused encoding b10011001 */ + /* unused encoding 0x9F b10011111 */
/* Q packets */ ETM4_PKT_I_Q = 0xA0, /*!< b1010xxxx */
- /* Atom packets */ - ETM4_PKT_I_ATOM_F1 = 0xF6, /*!< b1111011x */ - ETM4_PKT_I_ATOM_F2 = 0xD8, /*!< b110110xx */ - ETM4_PKT_I_ATOM_F3 = 0xF8, //!< b11111xxx - ETM4_PKT_I_ATOM_F4 = 0xDC, //!< b110111xx - ETM4_PKT_I_ATOM_F5 = 0xD5, //!< b11010101 - b11010111, b11110101 - ETM4_PKT_I_ATOM_F6 = 0xC0, //!< b11000000 - b11010100, b11100000 - b11110100 + /* unused encodings 0xB0-0xBF b1011xxxx */
- /* conditional instruction tracing */ - ETM4_PKT_I_COND_FLUSH = 0x43, //!< b01000011 - ETM4_PKT_I_COND_I_F1 = 0x6C, //!< b01101100 - ETM4_PKT_I_COND_I_F2 = 0x40, //!< b01000000 - b01000010 - ETM4_PKT_I_COND_I_F3 = 0x6D, //!< b01101101 - ETM4_PKT_I_COND_RES_F1 = 0x68, //!< b0110111x, b011010xx - ETM4_PKT_I_COND_RES_F2 = 0x48, //!< b0100100x, b01001010, b0100110x, b01001110 - ETM4_PKT_I_COND_RES_F3 = 0x50, //!< b0101xxxx - ETM4_PKT_I_COND_RES_F4 = 0x44, //!< b0100010x, b01000110 + /* Atom packets */ + ETM4_PKT_I_ATOM_F6 = 0xC0, /*!< b11000000 - b11010100 0xC0 - 0xD4, b11100000 - b11110100 0xE0 - 0xF4 */ + ETM4_PKT_I_ATOM_F5 = 0xD5, /*!< b11010101 - b11010111 0xD5 - 0xD7, b11110101 0xF5 */ + ETM4_PKT_I_ATOM_F2 = 0xD8, /*!< b110110xx to 0xDB */ + ETM4_PKT_I_ATOM_F4 = 0xDC, /*!< b110111xx to 0xDF */ + ETM4_PKT_I_ATOM_F1 = 0xF6, /*!< b1111011x to 0xF7 */ + ETM4_PKT_I_ATOM_F3 = 0xF8, /*!< b11111xxx to 0xFF */
- /* cycle count packets */ - ETM4_PKT_I_CCNT_F1 = 0x0E, //!< b0000111x - ETM4_PKT_I_CCNT_F2 = 0x0C, //!< b0000110x - ETM4_PKT_I_CCNT_F3 = 0x10, //!< b0001xxxx - // data synchronisation markers - ETM4_PKT_I_NUM_DS_MKR = 0x20, //!< b00100xxx - ETM4_PKT_I_UNNUM_DS_MKR = 0x28, //!< b00101000 - b00101100 - // event trace - ETM4_PKT_I_EVENT = 0x70, //!< b0111xxxx - // Exceptions - ETM4_PKT_I_EXCEPT = 0x06, //!< b00000110 - ETM4_PKT_I_EXCEPT_RTN = 0x07, //!< b00000111 - // timestamp - ETM4_PKT_I_TIMESTAMP = 0x02, //!< b0000001x - // speculation - ETM4_PKT_I_CANCEL_F1 = 0x2E, //!< b0010111x - ETM4_PKT_I_CANCEL_F2 = 0x34, //!< b001101xx - ETM4_PKT_I_CANCEL_F3 = 0x38, //!< b00111xxx - ETM4_PKT_I_COMMIT = 0x2D, //!< b00101101 - ETM4_PKT_I_MISPREDICT = 0x30, //!< b001100xx - // Sync - ETM4_PKT_I_TRACE_INFO = 0x01, //!< b00000001 - ETM4_PKT_I_TRACE_ON = 0x04, //!< b00000100 // extension packets - follow 0x00 header ETM4_PKT_I_ASYNC = 0x100, //!< b00000000 ETM4_PKT_I_DISCARD = 0x103, //!< b00000011 - ETM4_PKT_I_OVERFLOW = 0x105 //!< b00000101 + ETM4_PKT_I_OVERFLOW = 0x105, //!< b00000101
} ocsd_etmv4_i_pkt_type;
@@ -139,7 +154,7 @@ typedef union _etmv4_trace_info_t { uint32_t cc_enabled:1; //!< 1 if cycle count enabled uint32_t cond_enabled:3; //!< conditional trace enabeld type uint32_t p0_load:1; //!< 1 if tracing with P0 load elements (for data trace) - uint32_t p0_store:1; //1< 1 if tracing with P0 store elements (for data trace) + uint32_t p0_store:1; //!< 1 if tracing with P0 store elements (for data trace) } bits; //!< bitfields for trace info value. } etmv4_trace_info_t;
@@ -259,6 +274,7 @@ typedef struct _ocsd_etmv4_i_pkt
// original header type when packet type changed to error on decode error. ocsd_etmv4_i_pkt_type err_type; + uint8_t err_hdr_val;
} ocsd_etmv4_i_pkt;
@@ -342,6 +358,7 @@ typedef struct _ocsd_etmv4_cfg ocsd_core_profile_t core_prof; /**< Core Profile */ } ocsd_etmv4_cfg;
+ /** @}*/ /** @}*/ #endif // ARM_TRC_PKT_TYPES_ETMV4_H_INCLUDED diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp index 42f2699..e4c0db4 100644 --- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp +++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp @@ -251,6 +251,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) switch(m_curr_packet_in->getType()) { case ETM4_PKT_I_ASYNC: // nothing to do with this packet. + case ETM4_PKT_I_IGNORE: // or this one. break;
case ETM4_PKT_I_TRACE_INFO: @@ -351,6 +352,21 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) bool bV7MProfile = (m_config->archVersion() == ARCH_V7) && (m_config->coreProfile() == profile_CortexM); if (m_P0_stack.createParamElemNoParam(P0_EXCEP_RET, bV7MProfile, m_curr_packet_in->getType(), m_index_curr_pkt) == 0) bAllocErr = true; + else if (bV7MProfile) + m_curr_spec_depth++; + } + break; + + case ETM4_PKT_I_FUNC_RET: + { + // P0 element iff V8M profile, otherwise ignore + if (OCSD_IS_V8_ARCH(m_config->archVersion()) && (m_config->coreProfile() == profile_CortexM)) + { + if (m_P0_stack.createParamElemNoParam(P0_FUNC_RET, true, m_curr_packet_in->getType(), m_index_curr_pkt) == 0) + bAllocErr = true; + else + m_curr_spec_depth++; + } } break;
@@ -624,6 +640,13 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::commitElements(bool &Complete) if(pElem->isP0()) // are we on a core that counts ERET as P0? m_P0_commit--; break; + + case P0_FUNC_RET: + // func ret is V8M - data trace only - hint that data has been popped off the stack. + // at this point nothing to do till the decoder starts handling data trace. + if (pElem->isP0()) + m_P0_commit--; + break; }
if(bPopElem) diff --git a/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp b/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp index 8d17d83..0607c19 100644 --- a/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp +++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp @@ -34,12 +34,46 @@
#include "trc_pkt_proc_etmv4i_impl.h"
+/* Trace raw input buffer class */ +TraceRawBuffer::TraceRawBuffer() +{ + m_bufSize = 0; + m_bufProcessed = 0; + m_pBuffer = 0; + pkt = 0; +} + +// init the buffer +void TraceRawBuffer::init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet) +{ + m_bufSize = size; + m_bufProcessed = 0; + m_pBuffer = rawtrace; + pkt = out_packet; +} + +void TraceRawBuffer::copyByteToPkt() +{ + if (!empty()) { + pkt->push_back(m_pBuffer[m_bufProcessed]); + m_bufProcessed++; + } +} +uint8_t TraceRawBuffer::peekNextByte() +{ + uint8_t val = 0; + if (!empty()) + val = m_pBuffer[m_bufProcessed]; + return val; +} + +/* trace etmv4 packet processing class */ EtmV4IPktProcImpl::EtmV4IPktProcImpl() : m_isInit(false), m_interface(0), m_first_trace_info(false) { - BuildIPacketTable(); + }
EtmV4IPktProcImpl::~EtmV4IPktProcImpl() @@ -62,6 +96,7 @@ ocsd_err_t EtmV4IPktProcImpl::Configure(const EtmV4Config *p_config) if(p_config != 0) { m_config = *p_config; + BuildIPacketTable(); // packet table based on config } else { @@ -78,64 +113,81 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind uint32_t *numBytesProcessed) { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; - m_blockBytesProcessed = 0; + m_trcIn.init(dataBlockSize, pDataBlock, &m_currPacketData); m_blockIndex = index; - uint8_t currByte; - while( ( (m_blockBytesProcessed < dataBlockSize) || - ((m_blockBytesProcessed == dataBlockSize) && (m_process_state == SEND_PKT)) ) && - OCSD_DATA_RESP_IS_CONT(resp)) + bool done = false; + uint8_t nextByte; + + do { - currByte = pDataBlock[m_blockBytesProcessed]; try { - switch(m_process_state) + /* while (((m_blockBytesProcessed < dataBlockSize) || + ((m_blockBytesProcessed == dataBlockSize) && (m_process_state == SEND_PKT))) && + OCSD_DATA_RESP_IS_CONT(resp))*/ + while ( (!m_trcIn.empty() || (m_process_state == SEND_PKT)) && + OCSD_DATA_RESP_IS_CONT(resp) + ) { - case PROC_HDR: - m_packet_index = m_blockIndex + m_blockBytesProcessed; - if(m_is_sync) - { - m_pIPktFn = m_i_table[currByte].pptkFn; - m_curr_packet.type = m_i_table[currByte].pkt_type; - } - else + switch (m_process_state) { - // unsynced - process data until we see a sync point - m_pIPktFn = &EtmV4IPktProcImpl::iNotSync; - m_curr_packet.type = ETM4_PKT_I_NOTSYNC; + case PROC_HDR: + m_packet_index = m_blockIndex + m_trcIn.processed(); + if (m_is_sync) + { + nextByte = m_trcIn.peekNextByte(); + m_pIPktFn = m_i_table[nextByte].pptkFn; + m_curr_packet.type = m_i_table[nextByte].pkt_type; + } + else + { + // unsynced - process data until we see a sync point + m_pIPktFn = &EtmV4IPktProcImpl::iNotSync; + m_curr_packet.type = ETM4_PKT_I_NOTSYNC; + } + m_process_state = PROC_DATA; + + case PROC_DATA: + // loop till full packet or no more data... + while (!m_trcIn.empty() && (m_process_state == PROC_DATA)) + { + nextByte = m_trcIn.peekNextByte(); + m_trcIn.copyByteToPkt(); // move next byte into the packet + // m_currPacketData.push_back(pDataBlock[m_blockBytesProcessed]); + // m_blockBytesProcessed++; + (this->*m_pIPktFn)(nextByte); + } + break; + + case SEND_PKT: + resp = outputPacket(); + InitPacketState(); + m_process_state = PROC_HDR; + break; + + case SEND_UNSYNCED: + resp = outputUnsyncedRawPacket(); + if (m_update_on_unsync_packet_index != 0) + { + m_packet_index = m_update_on_unsync_packet_index; + m_update_on_unsync_packet_index = 0; + } + m_process_state = PROC_DATA; // after dumping unsynced data, still in data mode. + break; } - m_process_state = PROC_DATA; - - case PROC_DATA: - m_currPacketData.push_back(pDataBlock[m_blockBytesProcessed]); - m_blockBytesProcessed++; - (this->*m_pIPktFn)(); - break; - - case SEND_PKT: - resp = outputPacket(); - InitPacketState(); - m_process_state = PROC_HDR; - break; - - case SEND_UNSYNCED: - resp = outputUnsyncedRawPacket(); - if(m_update_on_unsync_packet_index != 0) - { - m_packet_index = m_update_on_unsync_packet_index; - m_update_on_unsync_packet_index = 0; - } - m_process_state = PROC_DATA; // after dumping unsynced data, still in data mode. - break; } + done = true; } catch(ocsdError &err) { + done = true; m_interface->LogError(err); if( (err.getErrorCode() == OCSD_ERR_BAD_PACKET_SEQ) || (err.getErrorCode() == OCSD_ERR_INVALID_PCKT_HDR)) { // send invalid packets up the pipe to let the next stage decide what to do. m_process_state = SEND_PKT; + done = false; } else { @@ -145,14 +197,15 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::processData( const ocsd_trc_index_t ind } catch(...) { + done = true; /// vv bad at this point. resp = OCSD_RESP_FATAL_SYS_ERR; const ocsdError &fatal = ocsdError(OCSD_ERR_SEV_ERROR,OCSD_ERR_FAIL,m_packet_index,m_config.getTraceID(),"Unknown System Error decoding trace."); m_interface->LogError(fatal); } - } + } while (!done);
- *numBytesProcessed = m_blockBytesProcessed; + *numBytesProcessed = m_trcIn.processed(); return resp; }
@@ -230,38 +283,35 @@ ocsd_datapath_resp_t EtmV4IPktProcImpl::outputUnsyncedRawPacket() return resp; }
-void EtmV4IPktProcImpl::iNotSync() +void EtmV4IPktProcImpl::iNotSync(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); // peek at the byte being processed... - // is it an extension byte? - if(lastByte == 0x00) // TBD : add check for forced sync in here? + if (lastByte == 0x00) // TBD : add check for forced sync in here? { - if(m_currPacketData.size() > 1) + if (m_currPacketData.size() > 1) { m_dump_unsynced_bytes = m_currPacketData.size() - 1; m_process_state = SEND_UNSYNCED; // outputting some data then update packet index after so output indexes accurate - m_update_on_unsync_packet_index = m_blockIndex + m_blockBytesProcessed - 1; + m_update_on_unsync_packet_index = m_blockIndex + m_trcIn.processed() - 1; } else - m_packet_index = m_blockIndex + m_blockBytesProcessed - 1; // set it up now otherwise. + m_packet_index = m_blockIndex + m_trcIn.processed() - 1; // set it up now otherwise.
- m_pIPktFn = m_i_table[lastByte].pptkFn; + m_pIPktFn = m_i_table[lastByte].pptkFn; } - else if(m_currPacketData.size() >= 8) + else if (m_currPacketData.size() >= 8) { m_dump_unsynced_bytes = m_currPacketData.size(); m_process_state = SEND_UNSYNCED; // outputting some data then update packet index after so output indexes accurate - m_update_on_unsync_packet_index = m_blockIndex + m_blockBytesProcessed; + m_update_on_unsync_packet_index = m_blockIndex + m_trcIn.processed(); } }
-void EtmV4IPktProcImpl::iPktNoPayload() +void EtmV4IPktProcImpl::iPktNoPayload(const uint8_t lastByte) { // some expansion may be required... - uint8_t lastByte = m_currPacketData.back(); switch(m_curr_packet.type) { case ETM4_PKT_I_ADDR_MATCH: @@ -281,20 +331,27 @@ void EtmV4IPktProcImpl::iPktNoPayload() case ETM4_PKT_I_COND_FLUSH: case ETM4_PKT_I_EXCEPT_RTN: case ETM4_PKT_I_TRACE_ON: + case ETM4_PKT_I_FUNC_RET: + case ETM4_PKT_I_IGNORE: default: break; } m_process_state = SEND_PKT; // now just send it.... }
-void EtmV4IPktProcImpl::iPktReserved() +void EtmV4IPktProcImpl::iPktReserved(const uint8_t lastByte) { - m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED); // swap type for err type + m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED, lastByte); // swap type for err type throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR,m_packet_index,m_config.getTraceID()); }
-void EtmV4IPktProcImpl::iPktExtension() +void EtmV4IPktProcImpl::iPktInvalidCfg(const uint8_t lastByte) +{ + m_curr_packet.updateErrType(ETM4_PKT_I_RESERVED_CFG, lastByte); // swap type for err type + throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_INVALID_PCKT_HDR, m_packet_index, m_config.getTraceID()); +} + +void EtmV4IPktProcImpl::iPktExtension(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); if(m_currPacketData.size() == 2) { // not sync and not next by 0x00 - not sync sequence @@ -331,9 +388,8 @@ void EtmV4IPktProcImpl::iPktExtension() } }
-void EtmV4IPktProcImpl::iPktASync() +void EtmV4IPktProcImpl::iPktASync(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); if(lastByte != 0x00) { // not sync and not next by 0x00 - not sync sequence if < 12 @@ -372,9 +428,8 @@ void EtmV4IPktProcImpl::iPktASync() } }
-void EtmV4IPktProcImpl::iPktTraceInfo() +void EtmV4IPktProcImpl::iPktTraceInfo(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); if(m_currPacketData.size() == 1) // header { //clear flags @@ -445,11 +500,8 @@ void EtmV4IPktProcImpl::iPktTraceInfo()
}
-void EtmV4IPktProcImpl::iPktTimestamp() +void EtmV4IPktProcImpl::iPktTimestamp(const uint8_t lastByte) { - // save the latest byte - uint8_t lastByte = m_currPacketData.back(); - // process the header byte if(m_currPacketData.size() == 1) { @@ -498,9 +550,9 @@ void EtmV4IPktProcImpl::iPktTimestamp() } }
-void EtmV4IPktProcImpl::iPktException() +void EtmV4IPktProcImpl::iPktException(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); + uint16_t excep_type = 0;
switch(m_currPacketData.size()) { @@ -512,7 +564,7 @@ void EtmV4IPktProcImpl::iPktException()
if(m_currPacketData.size() == (unsigned)m_excep_size) { - uint16_t excep_type = (m_currPacketData[1] >> 1) & 0x1F; + excep_type = (m_currPacketData[1] >> 1) & 0x1F; uint8_t addr_interp = (m_currPacketData[1] & 0x40) >> 5 | (m_currPacketData[1] & 0x1); uint8_t m_fault_pending = 0; uint8_t m_type = (m_config.coreProfile() == profile_CortexM) ? 1 : 0; @@ -530,11 +582,10 @@ void EtmV4IPktProcImpl::iPktException() } }
-void EtmV4IPktProcImpl::iPktCycleCntF123() +void EtmV4IPktProcImpl::iPktCycleCntF123(const uint8_t lastByte) { ocsd_etmv4_i_pkt_type format = m_curr_packet.type;
- uint8_t lastByte = m_currPacketData.back(); if( m_currPacketData.size() == 1) { m_count_done = m_commit_done = false; @@ -606,9 +657,8 @@ void EtmV4IPktProcImpl::iPktCycleCntF123() } }
-void EtmV4IPktProcImpl::iPktSpeclRes() -{ - uint8_t lastByte = m_currPacketData.back(); +void EtmV4IPktProcImpl::iPktSpeclRes(const uint8_t lastByte) +{ if(m_currPacketData.size() == 1) { switch(m_curr_packet.getType()) @@ -650,9 +700,8 @@ void EtmV4IPktProcImpl::iPktSpeclRes() } }
-void EtmV4IPktProcImpl::iPktCondInstr() +void EtmV4IPktProcImpl::iPktCondInstr(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); bool bF1Done = false;
if(m_currPacketData.size() == 1) @@ -691,10 +740,8 @@ void EtmV4IPktProcImpl::iPktCondInstr() } }
-void EtmV4IPktProcImpl::iPktCondResult() +void EtmV4IPktProcImpl::iPktCondResult(const uint8_t lastByte) { - //static ocsd_etmv4_i_pkt_type format = ETM4_PKT_I_COND_RES_F1; // conditional result formats F1-F4 - uint8_t lastByte = m_currPacketData.back(); if(m_currPacketData.size() == 1) { m_F1P1_done = false; // F1 payload 1 done @@ -763,10 +810,10 @@ void EtmV4IPktProcImpl::iPktCondResult() } }
-void EtmV4IPktProcImpl::iPktContext() +void EtmV4IPktProcImpl::iPktContext(const uint8_t lastByte) { bool bSendPacket = false; - uint8_t lastByte = m_currPacketData.back(); + if(m_currPacketData.size() == 1) { if((lastByte & 0x1) == 0) @@ -840,10 +887,8 @@ void EtmV4IPktProcImpl::extractAndSetContextInfo(const std::vector<uint8_t> &buf } }
-void EtmV4IPktProcImpl::iPktAddrCtxt() +void EtmV4IPktProcImpl::iPktAddrCtxt(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); - if( m_currPacketData.size() == 1) { m_addrIS = 0; @@ -910,13 +955,14 @@ void EtmV4IPktProcImpl::iPktAddrCtxt() } }
-void EtmV4IPktProcImpl::iPktShortAddr() +void EtmV4IPktProcImpl::iPktShortAddr(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); - if(m_currPacketData.size() == 1) + if (m_currPacketData.size() == 1) { m_addr_done = false; - m_addrIS = (lastByte == ETM4_PKT_I_ADDR_S_IS0) ? 0 : 1; + m_addrIS = 0; + if (lastByte == ETM4_PKT_I_ADDR_S_IS1) + m_addrIS = 1; } else if(!m_addr_done) { @@ -954,7 +1000,7 @@ int EtmV4IPktProcImpl::extractShortAddr(const std::vector<uint8_t> &buffer, cons return idx; }
-void EtmV4IPktProcImpl::iPktLongAddr() +void EtmV4IPktProcImpl::iPktLongAddr(const uint8_t lastByte) { if(m_currPacketData.size() == 1) { @@ -998,10 +1044,8 @@ void EtmV4IPktProcImpl::iPktLongAddr() } }
-void EtmV4IPktProcImpl::iPktQ() +void EtmV4IPktProcImpl::iPktQ(const uint8_t lastByte) { - uint8_t lastByte = m_currPacketData.back(); - if(m_currPacketData.size() == 1) { m_Q_type = lastByte & 0xF; @@ -1112,7 +1156,7 @@ void EtmV4IPktProcImpl::iPktQ()
}
-void EtmV4IPktProcImpl::iAtom() +void EtmV4IPktProcImpl::iAtom(const uint8_t lastByte) { // patterns lsbit = oldest atom, ms bit = newest. static const uint32_t f4_patterns[] = { @@ -1122,7 +1166,6 @@ void EtmV4IPktProcImpl::iAtom() 0x5 // NENE };
- uint8_t lastByte = m_currPacketData.back(); uint8_t pattIdx = 0, pattCount = 0; uint32_t pattern;
@@ -1212,13 +1255,23 @@ void EtmV4IPktProcImpl::BuildIPacketTable() m_i_table[0x04].pkt_type = ETM4_PKT_I_TRACE_ON; m_i_table[0x04].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
+ + // b0000 0101 - Funct ret V8M + m_i_table[0x05].pkt_type = ETM4_PKT_I_FUNC_RET; + if ((m_config.coreProfile() == profile_CortexM) && + (OCSD_IS_V8_ARCH(m_config.archVersion())) && + (m_config.FullVersion() >= 0x42)) + { + m_i_table[0x05].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + } + // b0000 0110 - exception m_i_table[0x06].pkt_type = ETM4_PKT_I_EXCEPT; m_i_table[0x06].pptkFn = &EtmV4IPktProcImpl::iPktException;
// b0000 0111 - exception return m_i_table[0x07].pkt_type = ETM4_PKT_I_EXCEPT_RTN; - m_i_table[0x07].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + m_i_table[0x07].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload;
// b0000 110x - cycle count f2 // b0000 111x - cycle count f1 @@ -1238,22 +1291,27 @@ void EtmV4IPktProcImpl::BuildIPacketTable() // b0010 0xxx - NDSM for(int i = 0; i < 8; i++) { - m_i_table[0x20+i].pkt_type = ETM4_PKT_I_NUM_DS_MKR; - m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + m_i_table[0x20 + i].pkt_type = ETM4_PKT_I_NUM_DS_MKR; + if (m_config.enabledDataTrace()) + m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + else + m_i_table[0x20+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0010 10xx, b0010 1100 - UDSM for(int i = 0; i < 5; i++) { m_i_table[0x28+i].pkt_type = ETM4_PKT_I_UNNUM_DS_MKR; - m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + if (m_config.enabledDataTrace()) + m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + else + m_i_table[0x28+i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0010 1101 - commit m_i_table[0x2D].pkt_type = ETM4_PKT_I_COMMIT; m_i_table[0x2D].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes;
- // b0010 111x - cancel f1 for(int i = 0; i < 2; i++) { @@ -1284,68 +1342,107 @@ void EtmV4IPktProcImpl::BuildIPacketTable() m_i_table[0x38+i].pptkFn = &EtmV4IPktProcImpl::iPktSpeclRes; }
+ bool bCondValid = m_config.hasCondTrace() && m_config.enabledCondITrace(); + // b0100 000x, b0100 0010 - cond I f2 - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_i_table[0x40+i].pkt_type = ETM4_PKT_I_COND_I_F2; - m_i_table[0x40+i].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + m_i_table[0x40 + i].pkt_type = ETM4_PKT_I_COND_I_F2; + if (bCondValid) + m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + else + m_i_table[0x40 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0100 0011 - cond flush m_i_table[0x43].pkt_type = ETM4_PKT_I_COND_FLUSH; - m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + if (bCondValid) + m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; + else + m_i_table[0x43].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
// b0100 010x, b0100 0110 - cond res f4 - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_i_table[0x44+i].pkt_type = ETM4_PKT_I_COND_RES_F4; - m_i_table[0x44+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[0x44 + i].pkt_type = ETM4_PKT_I_COND_RES_F4; + if (bCondValid) + m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[0x44 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0100 100x, b0100 0110 - cond res f2 // b0100 110x, b0100 1110 - cond res f2 - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_i_table[0x48+i].pkt_type = ETM4_PKT_I_COND_RES_F2; - m_i_table[0x48+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[0x48 + i].pkt_type = ETM4_PKT_I_COND_RES_F2; + if (bCondValid) + m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[0x48 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; } - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_i_table[0x4C+i].pkt_type = ETM4_PKT_I_COND_RES_F2; - m_i_table[0x4C+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[0x4C + i].pkt_type = ETM4_PKT_I_COND_RES_F2; + if (bCondValid) + m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[0x4C + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0101xxxx - cond res f3 - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { - m_i_table[0x50+i].pkt_type = ETM4_PKT_I_COND_RES_F3; - m_i_table[0x50+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[0x50 + i].pkt_type = ETM4_PKT_I_COND_RES_F3; + if (bCondValid) + m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[0x50 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b011010xx - cond res f1 - for(int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { - m_i_table[0x68+i].pkt_type = ETM4_PKT_I_COND_RES_F1; - m_i_table[0x68+i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[0x68 + i].pkt_type = ETM4_PKT_I_COND_RES_F1; + if (bCondValid) + m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[0x68 + i].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; }
// b0110 1100 - cond instr f1 m_i_table[0x6C].pkt_type = ETM4_PKT_I_COND_I_F1; - m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + if (bCondValid) + m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + else + m_i_table[0x6C].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
// b0110 1101 - cond instr f3 m_i_table[0x6D].pkt_type = ETM4_PKT_I_COND_I_F3; - m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + if (bCondValid) + m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktCondInstr; + else + m_i_table[0x6D].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg;
// b0110111x - cond res f1 - for(int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { // G++ cannot understand [0x6E+i] so change these round - m_i_table[i+0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1; - m_i_table[i+0x6E].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + m_i_table[i + 0x6E].pkt_type = ETM4_PKT_I_COND_RES_F1; + if (bCondValid) + m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktCondResult; + else + m_i_table[i + 0x6E].pptkFn = &EtmV4IPktProcImpl::iPktInvalidCfg; + } + + // ETM 4.3 introduces ignore packets + if (m_config.FullVersion() >= 0x43) + { + m_i_table[0x70].pkt_type = ETM4_PKT_I_IGNORE; + m_i_table[0x70].pptkFn = &EtmV4IPktProcImpl::iPktNoPayload; }
- // b01110001 - b01111111 - cond res f1 + // b01110001 - b01111111 - event trace for(int i = 0; i < 15; i++) { m_i_table[0x71+i].pkt_type = ETM4_PKT_I_EVENT; @@ -1399,12 +1496,27 @@ void EtmV4IPktProcImpl::BuildIPacketTable() m_i_table[0x9D+i].pkt_type = (i == 0) ? ETM4_PKT_I_ADDR_L_64IS0 : ETM4_PKT_I_ADDR_L_64IS1; m_i_table[0x9D+i].pptkFn = &EtmV4IPktProcImpl::iPktLongAddr; } - + // b1010xxxx - Q packet - for(int i = 0; i < 16; i++) - { - m_i_table[0xA0+i].pkt_type = ETM4_PKT_I_Q; - m_i_table[0xA0+i].pptkFn = &EtmV4IPktProcImpl::iPktQ; + for (int i = 0; i < 16; i++) + { + m_i_table[0xA0 + i].pkt_type = ETM4_PKT_I_Q; + // certain Q type codes are reserved. + switch (i) { + case 0x3: + case 0x4: + case 0x7: + case 0x8: + case 0x9: + case 0xD: + case 0xE: + // don't update pkt fn - leave at default reserved. + break; + default: + // if this config supports Q elem - otherwise reserved again. + if (m_config.hasQElem()) + m_i_table[0xA0 + i].pptkFn = &EtmV4IPktProcImpl::iPktQ; + } }
// Atom Packets - all no payload but have specific pattern generation fn diff --git a/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.h b/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.h index 5c79c25..429f327 100644 --- a/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.h +++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.h @@ -39,6 +39,31 @@ #include "opencsd/etmv4/trc_cmp_cfg_etmv4.h" #include "opencsd/etmv4/trc_pkt_elem_etmv4i.h"
+class TraceRawBuffer +{ +public: + TraceRawBuffer(); + ~TraceRawBuffer() {}; + + // init the buffer + void init(const uint32_t size, const uint8_t *rawtrace, std::vector<uint8_t> *out_packet); + void copyByteToPkt(); // move a byte to the packet buffer + uint8_t peekNextByte(); // value of next byte in buffer. + + bool empty() { return m_bufProcessed == m_bufSize; }; + // bytes processed. + uint32_t processed() { return m_bufProcessed; }; + // buffer size; + uint32_t size() { return m_bufSize; } + +private: + uint32_t m_bufSize; + uint32_t m_bufProcessed; + const uint8_t *m_pBuffer; + std::vector<uint8_t> *pkt; + +}; + class EtmV4IPktProcImpl { public: @@ -81,11 +106,12 @@ protected: EtmV4Config m_config;
/** packet data **/ - std::vector<uint8_t> m_currPacketData; // raw data + TraceRawBuffer m_trcIn; // trace data in buffer + std::vector<uint8_t> m_currPacketData; // raw data packet int m_currPktIdx; // index into raw packet when expanding EtmV4ITrcPacket m_curr_packet; // expanded packet ocsd_trc_index_t m_packet_index; // index of the start of the current packet - uint32_t m_blockBytesProcessed; // number of bytes processed in the current data block +// uint32_t m_blockBytesProcessed; // number of bytes processed in the current data block ocsd_trc_index_t m_blockIndex; // index at the start of the current data block being processed
// searching for sync @@ -110,9 +136,9 @@ private: #define TINFO_KEY_SECT 0x02 #define TINFO_SPEC_SECT 0x04 #define TINFO_CYCT_SECT 0x08 - #define TINFO_CTRL 0x10 - #define TINFO_ALL_SECT 0x0F - #define TINFO_ALL 0x1F + #define TINFO_CTRL 0x20 + #define TINFO_ALL_SECT 0x1F + #define TINFO_ALL 0x3F
// address and context packets @@ -152,24 +178,25 @@ private: ocsd_datapath_resp_t outputPacket(); ocsd_datapath_resp_t outputUnsyncedRawPacket();
- void iNotSync(); // not synced yet - void iPktNoPayload(); // process a single byte packet - void iPktReserved(); // deal with reserved header value - void iPktExtension(); - void iPktASync(); - void iPktTraceInfo(); - void iPktTimestamp(); - void iPktException(); - void iPktCycleCntF123(); - void iPktSpeclRes(); - void iPktCondInstr(); - void iPktCondResult(); - void iPktContext(); - void iPktAddrCtxt(); - void iPktShortAddr(); - void iPktLongAddr(); - void iPktQ(); - void iAtom(); + void iNotSync(const uint8_t lastByte); // not synced yet + void iPktNoPayload(const uint8_t lastByte); // process a single byte packet + void iPktReserved(const uint8_t lastByte); // deal with reserved header value + void iPktExtension(const uint8_t lastByte); + void iPktASync(const uint8_t lastByte); + void iPktTraceInfo(const uint8_t lastByte); + void iPktTimestamp(const uint8_t lastByte); + void iPktException(const uint8_t lastByte); + void iPktCycleCntF123(const uint8_t lastByte); + void iPktSpeclRes(const uint8_t lastByte); + void iPktCondInstr(const uint8_t lastByte); + void iPktCondResult(const uint8_t lastByte); + void iPktContext(const uint8_t lastByte); + void iPktAddrCtxt(const uint8_t lastByte); + void iPktShortAddr(const uint8_t lastByte); + void iPktLongAddr(const uint8_t lastByte); + void iPktQ(const uint8_t lastByte); + void iAtom(const uint8_t lastByte); + void iPktInvalidCfg(const uint8_t lastByte); // packet invalid in current config.
unsigned extractContField(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t &value, const unsigned byte_limit = 5); unsigned extractContField64(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint64_t &value, const unsigned byte_limit = 9); @@ -180,7 +207,7 @@ private: int extractShortAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value, int &bits);
// packet processing is table driven. - typedef void (EtmV4IPktProcImpl::*PPKTFN)(void); + typedef void (EtmV4IPktProcImpl::*PPKTFN)(uint8_t); PPKTFN m_pIPktFn;
struct _pkt_i_table_t {
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/opencsd/ocsd_if_version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h index 91ad4d7..e211181 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 0x0 /**< Library Major Version */ -#define OCSD_VER_MINOR 0xA /**< Library Minor Version */ -#define OCSD_VER_PATCH 0x1 /**< Library Patch Version */ +#define OCSD_VER_MINOR 0xB /**< 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 "0.10.1" /**< Library Version string */ +#define OCSD_VER_STRING "0.11.0-dev" /**< Library Version string */ #define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */ #define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */ /** @}*/