Hi Mathieu,

Thanks for looking at this, a few comments inline....

Mike

On 12 June 2016 at 18:49, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
On 3 June 2016 at 02:26, Mike Leach <mike.leach@linaro.org> wrote:

Please provide a description of the changes presented this patch.


> Signed-off-by: Mike Leach <mike.leach@linaro.org>
> ---
>  .../ref_trace_decode_lib.vcxproj                   |   2 +
>  .../ref_trace_decode_lib.vcxproj.filters           |   6 +
>  decoder/include/common/ocsd_code_follower.h        | 225 +++++++++++++++++++++
>  decoder/include/common/ocsd_pe_context.h           |   4 +-
>  decoder/include/ocsd_if_types.h                    |   2 +
>  decoder/source/ocsd_code_follower.cpp              | 155 ++++++++++++++
>  6 files changed, 392 insertions(+), 2 deletions(-)
>  create mode 100644 decoder/include/common/ocsd_code_follower.h
>  create mode 100644 decoder/source/ocsd_code_follower.cpp
>
> diff --git a/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj b/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj
> index 07aad23..2dc5f0c 100644
> --- a/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj
> +++ b/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj
> @@ -304,6 +304,7 @@
>    <ItemGroup>
>      <ClInclude Include="..\..\..\include\common\comp_attach_notifier_i.h" />
>      <ClInclude Include="..\..\..\include\common\comp_attach_pt_t.h" />
> +    <ClInclude Include="..\..\..\include\common\ocsd_code_follower.h" />
>      <ClInclude Include="..\..\..\include\common\ocsd_dcd_tree.h" />
>      <ClInclude Include="..\..\..\include\common\ocsd_dcd_tree_elem.h" />
>      <ClInclude Include="..\..\..\include\common\ocsd_error.h" />
> @@ -390,6 +391,7 @@
>      <ClCompile Include="..\..\..\source\mem_acc\trc_mem_acc_cb.cpp" />
>      <ClCompile Include="..\..\..\source\mem_acc\trc_mem_acc_file.cpp" />
>      <ClCompile Include="..\..\..\source\mem_acc\trc_mem_acc_mapper.cpp" />
> +    <ClCompile Include="..\..\..\source\ocsd_code_follower.cpp" />
>      <ClCompile Include="..\..\..\source\ocsd_dcd_tree.cpp" />
>      <ClCompile Include="..\..\..\source\ocsd_error.cpp" />
>      <ClCompile Include="..\..\..\source\ocsd_error_logger.cpp" />
> diff --git a/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters b/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters
> index 34a7737..c221d2f 100644
> --- a/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters
> +++ b/decoder/build/win/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters
> @@ -284,6 +284,9 @@
>      <ClInclude Include="..\..\..\include\common\ocsd_pe_context.h">
>        <Filter>Header Files\common</Filter>
>      </ClInclude>
> +    <ClInclude Include="..\..\..\include\common\ocsd_code_follower.h">
> +      <Filter>Header Files\common</Filter>
> +    </ClInclude>
>    </ItemGroup>
>    <ItemGroup>
>      <ClCompile Include="..\..\..\source\trc_component.cpp">
> @@ -388,5 +391,8 @@
>      <ClCompile Include="..\..\..\source\ocsd_version.cpp">
>        <Filter>Source Files</Filter>
>      </ClCompile>
> +    <ClCompile Include="..\..\..\source\ocsd_code_follower.cpp">
> +      <Filter>Source Files</Filter>
> +    </ClCompile>
>    </ItemGroup>
>  </Project>
> \ No newline at end of file
> diff --git a/decoder/include/common/ocsd_code_follower.h b/decoder/include/common/ocsd_code_follower.h
> new file mode 100644
> index 0000000..f05ad5b
> --- /dev/null
> +++ b/decoder/include/common/ocsd_code_follower.h
> @@ -0,0 +1,225 @@
> +/*
> + * \file       ocsd_code_follower.h
> + * \brief      OpenCSD : Code follower for instruction trace decode
> + *
> + * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
> + */
> +
> +/*
> + * Redistribution and use in source and binary forms, with or without modification,
> + * are permitted provided that the following conditions are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright notice,
> + * this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright notice,
> + * this list of conditions and the following disclaimer in the documentation
> + * and/or other materials provided with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its contributors
> + * may be used to endorse or promote products derived from this software without
> + * specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
> +#define ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
> +
> +#include "ocsd_if_types.h"
> +#include "trc_pkt_types.h"
> +#include "comp_attach_pt_t.h"
> +#include "interfaces/trc_tgt_mem_access_i.h"
> +#include "interfaces/trc_instr_decode_i.h"
> +
> +/*!
> + * @class OcsdCodeFollower
> + * @brief The code follower looks for waypoints or addresses.
> + *
> + *  Code follower used to determine the trace ranges for Atom or other waypoint
> + *  elements. Uses memory accessor and I decoder to follow the code path.
> + *
> + */
> +class OcsdCodeFollower
> +{
> +public:
> +    OcsdCodeFollower();
> +    ~OcsdCodeFollower();
> +
> +//*********** setup API
> +    void initInterfaces(componentAttachPt<ITargetMemAccess> *pMemAccess, componentAttachPt<IInstrDecode> *pIDecode);
> +
> +// set information for decode operation - static or occasionally changing settings
> +// per decode values are passed as parameters into the decode API calls.
> +    void setCoreProfile(const ocsd_arch_profile_t profile);             //!< core profile
> +    void setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule);    //!< memory space to use for access (filtered by S/NS, EL etc).
> +    void setMemSpaceCSID(const uint8_t csid);                           //!< memory spaces might be partitioned by CSID
> +    void setISA(const ocsd_isa isa);    //!< set the ISA for the decode.
> +    void setDSBDMBasWP();   //!< DSB and DMB can be treated as WP in some archs.
> +
> +//********** code following API
> +
> +    // standard WP search - for program flow trace
> +    //ocsd_err_t followToAtomWP(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
> +
> +    // PTM exception code may require follow to an address
> +    //ocsd_err_t followToAddress(idec_res_t &op_result, const ocsd_vaddr_t addrStart, const ocsd_atm_val A, const ocsd_vaddr_t addrMatch);
> +
> +    // single instruction atom format such as ETMv3
> +    ocsd_err_t followSingleAtom(const ocsd_vaddr_t addrStart, const ocsd_atm_val A);
> +
> +    // follow N instructions
> +    // ocsd_err_t followNInstructions(idec_res_t &op_result) // ETMv4 Q elements
> +
> +//*********************** results API
> +    const ocsd_vaddr_t getRangeSt() const;  //!< inclusive start address of decoded range (value passed in)
> +    const ocsd_vaddr_t getRangeEn() const;  //!< exclusive end address of decoded range (first instruction _not_ executed / potential next instruction).
> +
> +    const bool hasNextAddr() const;         //!< we have calulated the next address - otherwise this is needed from trace packets.
> +    const ocsd_vaddr_t getNextAddr() const; //!< next address - valid if hasNextAddr() true.
> +
> +    // information on last instruction executed in range.
> +    const ocsd_instr_type getInstrType() const;         //!< last instruction type
> +    const ocsd_instr_subtype getInstrSubType() const;   //!< last instruction sub-type
> +    const bool isCondInstr() const;                     //!< is a conditional instruction
> +    const bool isLink() const;                          //!< is a link (branch with link etc)
> +    const bool ISAChanged() const;                      //!< next ISA different from input ISA.
> +    const ocsd_isa nextISA() const;                     //!< ISA for next instruction
> +
> +    // information on error conditions
> +    const bool isNacc() const;                  //!< true if Memory Not Accessible (nacc) error occurred
> +    void clearNacc();                           //!< clear the nacc error flag
> +    const ocsd_vaddr_t getNaccAddr() const;     //!< get the nacc error address.
> +
> +private:
> +    bool initFollowerState();       //!< clear all the o/p data and flags, check init valid.
> +
> +    ocsd_err_t decodeSingleOpCode();      //!< decode single opcode address from current m_inst_info packet
> +
> +    ocsd_instr_info m_instr_info;
> +
> +    ocsd_vaddr_t m_st_range_addr;   //!< start of excuted range - inclusive address.
> +    ocsd_vaddr_t m_en_range_addr;   //!< end of executed range - exclusive address.
> +    ocsd_vaddr_t m_next_addr;       //!< calcuated next address (could be eo range of branch address, not set for indirect branches)
> +    bool m_b_next_valid;            //!< true if next address valid, false if need address from trace packets.
> +
> +    //! memory space rule to use when accessing memory.
> +    ocsd_mem_space_acc_t m_mem_acc_rule;
> +    //! memory space csid to use when accessing memory.
> +    uint8_t              m_mem_space_csid;
> +
> +    ocsd_vaddr_t m_nacc_address;    //!< memory address that was inaccessible - failed read @ start, or during follow operation
> +    bool m_b_nacc_err;              //!< memory NACC error - required address was unavailable.
> +
> +    //! pointers to the memory access and i decode interfaces.
> +    componentAttachPt<ITargetMemAccess> *m_pMemAccess;
> +    componentAttachPt<IInstrDecode> *m_pIDecode;
> +
> +};
> +
> +#endif // ARM_OCSD_CODE_FOLLOWER_H_INCLUDED
> +
> +//*********** setup API
> +inline void OcsdCodeFollower::setCoreProfile(const ocsd_arch_profile_t profile)
> +{
> +    m_instr_info.pe_type = profile;
> +}
> +
> +inline void OcsdCodeFollower::setMemSpaceAccess(const ocsd_mem_space_acc_t mem_acc_rule)
> +{
> +    m_mem_acc_rule = mem_acc_rule;
> +}
> +
> +inline void  OcsdCodeFollower::setMemSpaceCSID(const uint8_t csid)
> +{
> +    m_mem_space_csid = csid;
> +}
> +
> +inline void OcsdCodeFollower::setISA(const ocsd_isa isa)
> +{
> +    m_instr_info.isa = isa;
> +}
> +
> +inline void OcsdCodeFollower::setDSBDMBasWP()
> +{
> +    m_instr_info.dsb_dmb_waypoints = 1;
> +}
> +
> +//**************************************** results API
> +inline const ocsd_vaddr_t OcsdCodeFollower::getRangeSt() const
> +{
> +    return m_st_range_addr;
> +}
> +
> +inline const ocsd_vaddr_t OcsdCodeFollower::getRangeEn() const
> +{
> +    return m_en_range_addr;
> +}
> +
> +inline const bool OcsdCodeFollower::hasNextAddr() const
> +{
> +    return m_b_next_valid;
> +}
> +
> +inline const ocsd_vaddr_t OcsdCodeFollower::getNextAddr() const
> +{
> +    return m_next_addr;
> +}
> +
> +// information on last instruction executed in range.
> +inline const ocsd_instr_type OcsdCodeFollower::getInstrType() const
> +{
> +    return m_instr_info.type;
> +}
> +
> +inline const ocsd_instr_subtype OcsdCodeFollower::getInstrSubType() const
> +{
> +    return m_instr_info.sub_type;
> +}
> +
> +inline const bool OcsdCodeFollower::isCondInstr() const
> +{
> +    return (bool)(m_instr_info.is_conditional == 1);
> +}
> +
> +inline const bool OcsdCodeFollower::isLink() const
> +{
> +    return (bool)(m_instr_info.is_link == 1);
> +}
> +
> +inline const bool OcsdCodeFollower::ISAChanged() const
> +{
> +    return (bool)(m_instr_info.isa != m_instr_info.next_isa);
> +}
> +
> +inline const ocsd_isa OcsdCodeFollower::nextISA() const
> +{
> +    return m_instr_info.next_isa;
> +}
> +
> +// information on error conditions
> +inline const bool OcsdCodeFollower::isNacc() const
> +{
> +    return m_b_nacc_err;
> +}
> +
> +inline void OcsdCodeFollower::clearNacc()
> +{
> +    m_b_nacc_err = false;
> +}
> +
> +inline const ocsd_vaddr_t OcsdCodeFollower::getNaccAddr() const
> +{
> +    return m_nacc_address;
> +}
> +
> +/* End of File ocsd_code_follower.h */
> diff --git a/decoder/include/common/ocsd_pe_context.h b/decoder/include/common/ocsd_pe_context.h
> index 37764d9..fe06e90 100644
> --- a/decoder/include/common/ocsd_pe_context.h
> +++ b/decoder/include/common/ocsd_pe_context.h
> @@ -51,7 +51,7 @@ public:
>      void resetCtxt();
>
>      void setSecLevel(const ocsd_sec_level sl) { m_context.security_level = sl; };
> -    void setEL(const ocsd_ex_level el) { m_context.exception_level = el; m_context.el_valid = 1; };
> +    void setEL(const ocsd_ex_level el) { m_context.exception_level = el; m_context.el_valid = el > ocsd_EL_unknown ? 1 : 0; };
>      void setCtxtID(const uint32_t id) { m_context.context_id = id; m_context.ctxt_id_valid = 1; };
>      void setVMID(const uint32_t id) { m_context.vmid = id; m_context.vmid_valid = 1; };
>      void set64bit(const bool is64bit) { m_context.bits64 = is64bit ? 1 : 0; };
> @@ -83,7 +83,7 @@ inline void OcsdPeContext::resetCtxt()
>      m_context.context_id = 0;
>      m_context.ctxt_id_valid = 0;
>      m_context.el_valid = 0;
> -    m_context.exception_level = ocsd_EL0;
> +    m_context.exception_level = ocsd_EL_unknown;
>      m_context.security_level = ocsd_sec_secure;
>      m_context.vmid = 0;
>      m_context.vmid_valid = 0;
> diff --git a/decoder/include/ocsd_if_types.h b/decoder/include/ocsd_if_types.h
> index 3fa3032..9e4b051 100644
> --- a/decoder/include/ocsd_if_types.h
> +++ b/decoder/include/ocsd_if_types.h
> @@ -110,6 +110,7 @@ typedef enum _ocsd_err_t {
>      OCSD_ERR_UNSUPP_DECODE_PKT,        /**< Packet not supported in decoder */
>      OCSD_ERR_BAD_DECODE_PKT,           /**< reserved or unknown packet in decoder. */
>      OCSD_ERR_COMMIT_PKT_OVERRUN,       /**< overrun in commit packet stack - tried to commit more than available */
> +    OCSD_ERR_MEM_NACC,                 /**< unable to access required memory address */
>      /* decode tree errors */
>      OCSD_ERR_DCDT_NO_FORMATTER,         /**< No formatter in use - operation not valid. */
>      /* target memory access errors */
> @@ -330,6 +331,7 @@ typedef enum _ocsd_sec_level
>  */
>  typedef enum _ocsd_ex_level
>  {
> +    ocsd_EL_unknown = -1, /**< EL unknown / unsupported in trace */

Can I suggest ocsd_ELERR ?
EL unknown is most appropriate here - this is a genuine unknown, not an error situation.

ETMv4 traces ELs explicitly - EL will be unknown until we see the first context packet.
ETMv3.5 traces hyp bit - EL will be EL2 if hyp bit active, unknown otherwise.
ETMv3.4 and below, PTM - no explicit EL tracing - EL unknown all the time.

 

>      ocsd_EL0 = 0,  /**< EL0 */
>      ocsd_EL1,      /**< EL1 */
>      ocsd_EL2,      /**< EL2 */
> diff --git a/decoder/source/ocsd_code_follower.cpp b/decoder/source/ocsd_code_follower.cpp
> new file mode 100644
> index 0000000..b52704e
> --- /dev/null
> +++ b/decoder/source/ocsd_code_follower.cpp
> @@ -0,0 +1,155 @@
> +/*
> + * \file       ocsd_code_follower.cpp
> + * \brief      OpenCSD : Instruction Code path follower.
> + *
> + * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
> + */
> +
> +
> +/*
> + * Redistribution and use in source and binary forms, with or without modification,
> + * are permitted provided that the following conditions are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright notice,
> + * this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright notice,
> + * this list of conditions and the following disclaimer in the documentation
> + * and/or other materials provided with the distribution.
> + *
> + * 3. Neither the name of the copyright holder nor the names of its contributors
> + * may be used to endorse or promote products derived from this software without
> + * specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "common/ocsd_code_follower.h"
> +
> +OcsdCodeFollower::OcsdCodeFollower()
> +{
> +    m_instr_info.pe_type.arch = ARCH_UNKNOWN;
> +    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.instr_addr = 0;
> +    m_instr_info.opcode = 0;
> +    m_pMemAccess = 0;
> +    m_pIDecode = 0;
> +    m_mem_space_csid = 0;
> +    m_st_range_addr =  m_en_range_addr = m_next_addr = 0;
> +    m_b_next_valid = false;
> +    m_b_nacc_err = false;
> +}
> +
> +OcsdCodeFollower::~OcsdCodeFollower()
> +{
> +}
> +
> +void OcsdCodeFollower::initInterfaces(componentAttachPt<ITargetMemAccess> *pMemAccess, componentAttachPt<IInstrDecode> *pIDecode)
> +{
> +    m_pMemAccess = pMemAccess;
> +    m_pIDecode = pIDecode;
> +}
> +
> +bool OcsdCodeFollower::initFollowerState()
> +{
> +    bool initDone = false;
> +
> +    // reset per follow flags
> +    m_b_next_valid = false;
> +    m_b_nacc_err = false;
> +
> +    // set range addresses
> +    m_en_range_addr = m_next_addr = m_st_range_addr;
> +
> +// check initialisation is valid.
> +
> +    // must have attached memory access and i-decode objects
> +    if(m_pMemAccess && m_pIDecode)
> +    {
> +        initDone = (m_pMemAccess->hasAttachedAndEnabled() && m_pIDecode->hasAttachedAndEnabled());
> +    }
> +    return initDone;
> +}
> +
> +/*!
> + * Decodes an instruction at a single location, calculates the next address
> + * if possible according to the instruction type and atom.
> + *
> + * @param addrStart : Address of the instruction
> + * @param A :  Atom value - E or N
> + *
> + * @return ocsd_err_t : OCSD_OK - decode correct, check flags for next address
> + *                    : OCSD_ERR_MEM_NACC - unable to access memory area @ address - need new address in trace packet stream.
> + *                    : OCSD_ERR_NOT_INIT - not initialised - fatal.
> + *                    : OCSD_<other>  - other error occured - fatal.
> + */
> +ocsd_err_t OcsdCodeFollower::followSingleAtom(const ocsd_vaddr_t addrStart, const ocsd_atm_val A)
> +{
> +    ocsd_err_t err = OCSD_ERR_NOT_INIT;
> +    if(initFollowerState())

if (!initFollowerState)
        return err;

> +    {
> +        m_st_range_addr = m_instr_info.instr_addr = addrStart;
> +        err = decodeSingleOpCode();
> +        if(err == OCSD_OK)

 if (err != OCSD_OK)
        return err;

That way you avoid the imbrication.

> +        {
> +            // set end range - always after the instruction executed.
> +            m_en_range_addr = m_instr_info.instr_addr + m_instr_info.instr_size;
> +
> +            // assume next addr is the instruction after
> +            m_next_addr = m_en_range_addr;
> +            m_b_next_valid = true;
> +
> +            // case when next address is different
> +            switch(m_instr_info.type)
> +            {
> +            case OCSD_INSTR_BR:
> +                if(A == ATOM_E) // executed the direct branch
> +                    m_next_addr = m_instr_info.branch_addr;
> +                break;
> +
> +            case OCSD_INSTR_BR_INDIRECT:
> +                if(A == ATOM_E) // executed indirect branch
> +                    m_b_next_valid = false;
> +                break;
> +            }
> +        }
> +    }
> +    return err;
> +}
> +
> +
> +ocsd_err_t OcsdCodeFollower::decodeSingleOpCode()
> +{
> +    ocsd_err_t err = OCSD_OK;
> +    uint32_t bytesReq = 4;

This initialisation isn't necessary.
 
It really rather is - it is the buffer size passed into ReadTargetMemory(). A comment will be added though
 

> +    uint32_t opcode;
> +    err = m_pMemAccess->first()->ReadTargetMemory(m_instr_info.instr_addr,m_mem_space_csid,m_mem_acc_rule,&bytesReq,(uint8_t *)&opcode);
> +    if(err == OCSD_OK)
> +    {
> +        if(bytesReq == 4)       // got memory.

Please explain the hard coded value.
Check on number of bytes returned by memory access - will add comment
 

> +        {
> +            m_instr_info.opcode = opcode;
> +            err = m_pIDecode->first()->DecodeInstruction(&m_instr_info);
> +        }
> +        else       // memory unavailable.
> +        {
> +            m_b_nacc_err = true;
> +            m_nacc_address = m_instr_info.instr_addr;
> +            err = OCSD_ERR_MEM_NACC;
> +        }
> +    }
> +    return err;
> +}
> +
> +/* End of File ocsd_code_follower.cpp */
> --
> 1.9.1
>
> _______________________________________________
> CoreSight mailing list
> CoreSight@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/coresight



--
Mike Leach
Principal Engineer, ARM Ltd.
Blackburn Design Centre. UK