This patchset adds more information about the final instuction in the Instruction Range generic packet.
i) A flag is set if the last instruction is conditional [last_instr_cond].
ii) for A32/T32 ISA, the instruction subtype will be set to 'Implied Return' [OCSD_S_INSTR_V7_IMPLIED_RET] if it is one of the instructions: mov pc,lr bx r14 pop {...,pc} ldr pc,[sp], #offset
These are used by the CPU return predictor and in general by compilers when a return is required.
The patchset also removes the uint32_t casts in the version #define OCSD_VER_NUM to enable correct use with pre-processor.
Mike Leach (3): opencsd: Generic output packet - add additional instruction info opencsd: docs: Update documents for new generic packet field opencsd: Update README etc for version 0.10.0
README.md | 6 +++-- decoder/docs/doxygen_config.dox | 2 +- decoder/docs/prog_guide/prog_guide_generic_pkts.md | 3 ++- decoder/include/common/trc_gen_elem.h | 1 + .../include/opencsd/etmv4/trc_pkt_decode_etmv4i.h | 2 ++ decoder/include/opencsd/ocsd_if_types.h | 1 + decoder/include/opencsd/ocsd_if_version.h | 8 +++--- decoder/include/opencsd/trc_gen_elem_types.h | 1 + decoder/source/etmv3/trc_pkt_decode_etmv3.cpp | 1 + decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 29 ++++++++++------------ decoder/source/i_dec/trc_i_decode.cpp | 1 + decoder/source/i_dec/trc_idec_arminst.cpp | 16 ++++++++++++ decoder/source/ocsd_dcd_tree.cpp | 1 - decoder/source/ptm/trc_pkt_decode_ptm.cpp | 2 ++ decoder/source/trc_gen_elem.cpp | 5 +++- 15 files changed, 53 insertions(+), 26 deletions(-)
Adds new instruction sub-type V7_IMPLIED_RET for the group of instructions in A32 and T32 that are considered returns.
Adds additional field to generic packet last_instr_cond to flag that the last instruction in the trace range was conditional.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/include/common/trc_gen_elem.h | 1 + .../include/opencsd/etmv4/trc_pkt_decode_etmv4i.h | 2 ++ decoder/include/opencsd/ocsd_if_types.h | 1 + decoder/include/opencsd/ocsd_if_version.h | 8 +++--- decoder/include/opencsd/trc_gen_elem_types.h | 1 + decoder/source/etmv3/trc_pkt_decode_etmv3.cpp | 1 + decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 29 ++++++++++------------ decoder/source/i_dec/trc_i_decode.cpp | 1 + decoder/source/i_dec/trc_idec_arminst.cpp | 16 ++++++++++++ decoder/source/ocsd_dcd_tree.cpp | 1 - decoder/source/ptm/trc_pkt_decode_ptm.cpp | 2 ++ decoder/source/trc_gen_elem.cpp | 5 +++- 12 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/decoder/include/common/trc_gen_elem.h b/decoder/include/common/trc_gen_elem.h index c345e26..1c4a47b 100644 --- a/decoder/include/common/trc_gen_elem.h +++ b/decoder/include/common/trc_gen_elem.h @@ -76,6 +76,7 @@ public: 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 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); diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h index b676dcd..e996878 100644 --- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h +++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h @@ -93,6 +93,8 @@ private:
ocsd_datapath_resp_t returnStackPop(); // pop return stack and update instruction address.
+ ocsd_datapath_resp_t outputTraceRange(const bool executed, ocsd_trc_index_t index); + //** intra packet state (see ETMv4 spec 6.2.1);
// timestamping diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h index def1657..b5a53f2 100644 --- a/decoder/include/opencsd/ocsd_if_types.h +++ b/decoder/include/opencsd/ocsd_if_types.h @@ -362,6 +362,7 @@ typedef enum _ocsd_instr_subtype { OCSD_S_INSTR_BR_LINK, /**< branch with link */ OCSD_S_INSTR_V8_RET, /**< v8 ret instruction - subtype of BR_INDIRECT */ OCSD_S_INSTR_V8_ERET, /**< v8 eret instruction - subtype of BR_INDIRECT */ + OCSD_S_INSTR_V7_IMPLIED_RET, /**< v7 instruction which could imply return e.g. MOV PC, LR; POP { ,pc} */ } ocsd_instr_subtype;
/** Instruction decode request structure. diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h index c056fd6..62a8c90 100644 --- a/decoder/include/opencsd/ocsd_if_version.h +++ b/decoder/include/opencsd/ocsd_if_version.h @@ -43,17 +43,17 @@ /** @name Library Versioning @{*/ #define OCSD_VER_MAJOR 0x0 /**< Library Major Version */ -#define OCSD_VER_MINOR 0x9 /**< Library Minor Version */ -#define OCSD_VER_PATCH 0x3 /**< Library Patch Version */ +#define OCSD_VER_MINOR 0xA /**< Library Minor Version */ +#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
/** Library version number - MMMMnnpp format. MMMM = major version, nn = minor version, pp = patch version */ -#define OCSD_VER_NUM (((uint32_t)OCSD_VER_MAJOR << 16) | ((uint32_t)OCSD_VER_MINOR << 8) | ((uint32_t)OCSD_VER_PATCH)) +#define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH)
-#define OCSD_VER_STRING "0.9.3" /**< Library Version string */ +#define OCSD_VER_STRING "0.10.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 80cc69a..0cf94cf 100644 --- a/decoder/include/opencsd/trc_gen_elem_types.h +++ b/decoder/include/opencsd/trc_gen_elem_types.h @@ -97,6 +97,7 @@ typedef struct _ocsd_generic_trace_elem { 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 last_instr_cond:1; /**< 1 if the last instruction was conditional */ }; uint32_t flag_bits; }; diff --git a/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp b/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp index 66ce697..0a15a33 100644 --- a/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp +++ b/decoder/source/etmv3/trc_pkt_decode_etmv3.cpp @@ -599,6 +599,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV3::processPHdr() pElem->setLastInstrInfo(atoms.getCurrAtomVal() == ATOM_E, m_code_follower.getInstrType(), m_code_follower.getInstrSubType(),m_code_follower.getInstrSize()); + pElem->setLastInstrCond(m_code_follower.isCondInstr()); pElem->setISA(isa); if(m_code_follower.hasNextAddr()) m_IAddr = m_code_follower.getNextAddr(); diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp index 036a1dc..7514825 100644 --- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp +++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp @@ -778,6 +778,15 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::outputEvent(TrcStackElemParam *pParamEl return outputTraceElementIdx(pParamElem->getRootIndex(),m_output_elem); }
+ocsd_datapath_resp_t TrcPktDecodeEtmV4I::outputTraceRange(const bool executed, ocsd_trc_index_t index) +{ + m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); + m_output_elem.setLastInstrInfo(executed, m_instr_info.type, m_instr_info.sub_type, m_instr_info.instr_size); + m_output_elem.setISA(m_instr_info.isa); + m_output_elem.setLastInstrCond(m_instr_info.is_conditional); + return outputTraceElementIdx(index, m_output_elem); +} + ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom, bool &bCont) { ocsd_datapath_resp_t resp = OCSD_RESP_CONT; @@ -834,10 +843,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom, bo } break; } - m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); - m_output_elem.setLastInstrInfo((atom == ATOM_E),m_instr_info.type, m_instr_info.sub_type, m_instr_info.instr_size); - m_output_elem.setISA(m_instr_info.isa); - resp = outputTraceElementIdx(pElem->getRootIndex(),m_output_elem); + resp = outputTraceRange((atom == ATOM_E), pElem->getRootIndex());
} else @@ -848,10 +854,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom, bo if(m_output_elem.st_addr != m_output_elem.en_addr) { // some trace before we were out of memory access range - m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); - m_output_elem.setLastInstrInfo(true,m_instr_info.type, m_instr_info.sub_type,m_instr_info.instr_size); - m_output_elem.setISA(m_instr_info.isa); - resp = outputTraceElementIdx(pElem->getRootIndex(),m_output_elem); + resp = outputTraceRange(true, pElem->getRootIndex()); }
if(m_mem_nacc_pending && OCSD_DATA_RESP_IS_CONT(resp)) @@ -970,10 +973,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processException() break; } } - m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); - m_output_elem.setLastInstrInfo(true,m_instr_info.type, m_instr_info.sub_type,m_instr_info.instr_size); - m_output_elem.setISA(m_instr_info.isa); - resp = outputTraceElementIdx(m_excep_index, m_output_elem); + resp = outputTraceRange(true, m_excep_index); m_excep_proc = EXCEP_EXCEP; } else @@ -984,10 +984,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processException() if(m_output_elem.st_addr != m_output_elem.en_addr) { // some trace before we were out of memory access range - m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); - m_output_elem.setLastInstrInfo(true,m_instr_info.type, m_instr_info.sub_type, m_instr_info.instr_size); - m_output_elem.setISA(m_instr_info.isa); - resp = outputTraceElementIdx(m_excep_index,m_output_elem); + resp = outputTraceRange(true, m_excep_index); }
m_excep_proc = m_mem_nacc_pending ? EXCEP_NACC : EXCEP_EXCEP; diff --git a/decoder/source/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp index 383303f..1fc2120 100644 --- a/decoder/source/i_dec/trc_i_decode.cpp +++ b/decoder/source/i_dec/trc_i_decode.cpp @@ -203,6 +203,7 @@ ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info) } }
+ instr_info->is_conditional = inst_Thumb_is_conditional(instr_info->opcode); instr_info->thumb_it_conditions = inst_Thumb_is_IT(instr_info->opcode);
return OCSD_OK; diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp index 252e33d..d4bf333 100644 --- a/decoder/source/i_dec/trc_idec_arminst.cpp +++ b/decoder/source/i_dec/trc_idec_arminst.cpp @@ -88,14 +88,21 @@ int inst_ARM_is_indirect_branch(uint32_t inst) } } else if ((inst & 0x0ff000d0) == 0x01200010) { /* BLX (register), BX */ + if ((inst & 0xF) == 0xE) + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX R14 */ } else if ((inst & 0x0e108000) == 0x08108000) { /* POP {...,pc} or LDMxx {...,pc} */ + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; } else if ((inst & 0x0e50f000) == 0x0410f000) { + if ( (inst & 0x000f0000) == 0x000D0000) + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm */ /* LDR PC,imm... inc. POP {PC} */ } else if ((inst & 0x0e50f010) == 0x0610f000) { /* LDR PC,reg */ } else if ((inst & 0x0fe0f000) == 0x01a0f000) { /* MOV PC,rx */ + if ((inst & 0xF) == 0xE) + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC, R14 */ } else if ((inst & 0x0f900080) == 0x01000000) { /* "Miscellaneous instructions" - in DP space */ is_indirect_branch = 0; @@ -174,10 +181,16 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link) *is_link = 1; instr_sub_type = OCSD_S_INSTR_BR_LINK; } + else if ((inst & 0x00780000) == 0x00700000) { + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */ + } } else if ((inst & 0xff000000) == 0xbd000000) { /* POP {pc} */ + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; } else if ((inst & 0xfd870000) == 0x44870000) { /* MOV PC,reg or ADD PC,reg */ + if ((inst & 0x00780000) == 0x00700000) + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */ } else if ((inst & 0xfff0ffe0) == 0xe8d0f000) { /* TBB/TBH */ } else if ((inst & 0xffd00000) == 0xe8100000) { @@ -192,10 +205,13 @@ int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link) /* LDR PC,literal (T2) */ } else if ((inst & 0xfff0f800) == 0xf850f800) { /* LDR PC,imm (T4) */ + if((inst & 0x000f0000) == 0x000E0000) + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm*/ } else if ((inst & 0xfff0ffc0) == 0xf850f000) { /* LDR PC,reg (T2) */ } else if ((inst & 0xfe508000) == 0xe8108000) { /* LDM PC */ + instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* POP {...,pc} */ } else { is_branch = 0; } diff --git a/decoder/source/ocsd_dcd_tree.cpp b/decoder/source/ocsd_dcd_tree.cpp index 815d327..283a8e5 100644 --- a/decoder/source/ocsd_dcd_tree.cpp +++ b/decoder/source/ocsd_dcd_tree.cpp @@ -323,7 +323,6 @@ ocsd_err_t DecodeTree::updateBinFileRegionMemAcc(const ocsd_file_mem_region_t *r if ((region_array == 0) || (num_regions == 0) || (filepath.length() == 0)) return OCSD_ERR_INVALID_PARAM_VAL;
- ocsd_err_t err = OCSD_ERR_INVALID_PARAM_VAL; TrcMemAccessorFile *pAcc = TrcMemAccessorFile::getExistingFileAccessor(filepath); if (!pAcc) return OCSD_ERR_INVALID_PARAM_VAL; diff --git a/decoder/source/ptm/trc_pkt_decode_ptm.cpp b/decoder/source/ptm/trc_pkt_decode_ptm.cpp index 938711e..6673f78 100644 --- a/decoder/source/ptm/trc_pkt_decode_ptm.cpp +++ b/decoder/source/ptm/trc_pkt_decode_ptm.cpp @@ -580,6 +580,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con m_output_elem.setISA(m_curr_pe_state.isa); if(m_curr_packet_in->hasCC()) m_output_elem.setCycleCount(m_curr_packet_in->getCCVal()); + m_output_elem.setLastInstrCond(m_instr_info.is_conditional); resp = outputTraceElementIdx(m_index_curr_pkt,m_output_elem);
m_curr_pe_state.instr_addr = m_instr_info.instr_addr; @@ -596,6 +597,7 @@ ocsd_datapath_resp_t TrcPktDecodePtm::processAtomRange(const ocsd_atm_val A, con m_output_elem.setType(OCSD_GEN_TRC_ELEM_INSTR_RANGE); m_output_elem.setLastInstrInfo(true,m_instr_info.type, m_instr_info.sub_type,m_instr_info.instr_size); m_output_elem.setISA(m_curr_pe_state.isa); + m_output_elem.setLastInstrCond(m_instr_info.is_conditional); resp = outputTraceElementIdx(m_index_curr_pkt,m_output_elem); } } diff --git a/decoder/source/trc_gen_elem.cpp b/decoder/source/trc_gen_elem.cpp index 5b0bbc7..545a48f 100644 --- a/decoder/source/trc_gen_elem.cpp +++ b/decoder/source/trc_gen_elem.cpp @@ -71,7 +71,8 @@ static const char *instr_sub_type[] = { "--- ", "b+link ", "A64:ret ", - "A64:eret " + "A64:eret ", + "V7:impl ret", };
#define ST_SIZE (sizeof(instr_sub_type) / sizeof(const char *)) @@ -113,6 +114,8 @@ void OcsdTraceElement::toString(std::string &str) const oss << instr_type[last_i_type]; if((last_i_subtype != OCSD_S_INSTR_NONE) && ((int)last_i_subtype < ST_SIZE)) oss << instr_sub_type[last_i_subtype]; + if (last_instr_cond) + oss << " <cond>"; break;
case OCSD_GEN_TRC_ELEM_ADDR_NACC:
Additional field added to the generic output packets. Documentation updated to reflect the use of this field.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/docs/prog_guide/prog_guide_generic_pkts.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/decoder/docs/prog_guide/prog_guide_generic_pkts.md b/decoder/docs/prog_guide/prog_guide_generic_pkts.md index fbf7bb4..d6c57f8 100644 --- a/decoder/docs/prog_guide/prog_guide_generic_pkts.md +++ b/decoder/docs/prog_guide/prog_guide_generic_pkts.md @@ -70,6 +70,7 @@ typedef struct _ocsd_generic_trace_elem { 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 last_instr_cond:1; /* 1 if the last instruction was conditional */ }; uint32_t flag_bits; }; @@ -121,7 +122,7 @@ __packet fields valid__: None Element output before the decoder has synchronised with the input stream, or synchronisation is lost.
### OCSD_GEN_TRC_ELEM_INSTR_RANGE ### -__packet fields valid__: `isa, st_addr, en_addr, last_i_type, last_i_subtype, last_instr_exec, last_instr_sz, num_instr_range` +__packet fields valid__: `isa, st_addr, en_addr, last_i_type, last_i_subtype, last_instr_exec, last_instr_sz, num_instr_range, last_instr_cond`
__packet fields optional__: `has_cc -> cycle_count,`
Signed-off-by: Mike Leach mike.leach@linaro.org --- README.md | 6 ++++-- decoder/docs/doxygen_config.dox | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md index 548fbbe..a0e37e1 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Releases will appear on the master branch in the git repository with an appropri CoreSight Trace Component Support. ----------------------------------
-_Current Version 0.9.3_ +_Current Version 0.10.0_
### Current support:
@@ -142,7 +142,9 @@ Version and Modification Information AutoFDO: update documentation for AutoFDO usage and add in "record.sh" script - _Version 0.9.3_: Bugfix: Test snapshot library not handling 'offset' parameters in dump file sections. Install: ocsd_if_version.h moved to opencsd/include to allow installation on OS & use in compiling client apps. - +- _Version 0.10.0_: __Updates__: Add additional information about the last instruction to the generice output packet. + __Docs__: update docs for updated output packet. + __Bugfix__: typecast removed from OCSD_VER_NUM in ocsd_if_version.h to allow use in C pre-processor.
Licence Information diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox index 94596c8..0ca0cf7 100644 --- a/decoder/docs/doxygen_config.dox +++ b/decoder/docs/doxygen_config.dox @@ -38,7 +38,7 @@ PROJECT_NAME = "OpenCSD - CoreSight Trace Decode Library" # could be handy for archiving the generated documentation or if some version # control system is used.
-PROJECT_NUMBER = 0.9.2 +PROJECT_NUMBER = 0.10.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