1 /*
2  * \file       trc_pkt_decode_ptm.h
3  * \brief      OpenCSD : PTM packet decoder.
4  *
5  * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
6  */
7 
8 /*
9  * Redistribution and use in source and binary forms, with or without modification,
10  * are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 #ifndef ARM_TRC_PKT_DECODE_PTM_H_INCLUDED
35 #define ARM_TRC_PKT_DECODE_PTM_H_INCLUDED
36 
37 #include "common/trc_pkt_decode_base.h"
38 #include "opencsd/ptm/trc_pkt_elem_ptm.h"
39 #include "opencsd/ptm/trc_cmp_cfg_ptm.h"
40 #include "common/trc_gen_elem.h"
41 #include "common/trc_ret_stack.h"
42 
43 /**************** Atom handling class **************************************/
44 class PtmAtoms
45 {
46 public:
47     PtmAtoms() {};
48     ~PtmAtoms() {};
49 
50     //! initialise the atom and index values
51     void initAtomPkt(const ocsd_pkt_atom &atom, const ocsd_trc_index_t &root_index);
52 
53     const ocsd_atm_val getCurrAtomVal() const;
54     const int numAtoms() const; //!< number of atoms
55     const ocsd_trc_index_t pktIndex() const; //!< originating packet index
56 
57     void clearAtom();   //!<  clear the current atom, set the next.
58     void clearAll(); //!< clear all
59 
60 private:
61     ocsd_pkt_atom m_atom;
62     ocsd_trc_index_t m_root_index; //!< root index for the atom packet
63 };
64 
65 inline void PtmAtoms::initAtomPkt(const ocsd_pkt_atom &atom, const ocsd_trc_index_t &root_index)
66 {
67     m_atom = atom;
68     m_root_index = root_index;
69 }
70 
71 inline const ocsd_atm_val PtmAtoms::getCurrAtomVal() const
72 {
73     return (m_atom.En_bits & 0x1) ?  ATOM_E : ATOM_N;
74 }
75 
76 inline const int PtmAtoms::numAtoms() const
77 {
78     return m_atom.num;
79 }
80 
81 inline const ocsd_trc_index_t PtmAtoms::pktIndex() const
82 {
83     return m_root_index;
84 }
85 
86 inline void PtmAtoms::clearAtom()
87 {
88     if(m_atom.num)
89     {
90         m_atom.num--;
91         m_atom.En_bits >>=1;
92     }
93 }
94 
95 inline void PtmAtoms::clearAll()
96 {
97     m_atom.num = 0;
98 }
99 
100 /********** Main decode class ****************************************************/
101 class TrcPktDecodePtm : public TrcPktDecodeBase<PtmTrcPacket, PtmConfig>
102 {
103 public:
104     TrcPktDecodePtm();
105     TrcPktDecodePtm(int instIDNum);
106     virtual ~TrcPktDecodePtm();
107 
108 protected:
109     /* implementation packet decoding interface */
110     virtual ocsd_datapath_resp_t processPacket();
111     virtual ocsd_datapath_resp_t onEOT();
112     virtual ocsd_datapath_resp_t onReset();
113     virtual ocsd_datapath_resp_t onFlush();
114     virtual ocsd_err_t onProtocolConfig();
115     virtual const uint8_t getCoreSightTraceID() { return m_CSID; };
116 
117     /* local decode methods */
118 
119 private:
120     /** operation for the trace instruction follower */
121     typedef enum {
122         TRACE_WAYPOINT,     //!< standard operation - trace to waypoint - default op
123         TRACE_TO_ADDR_EXCL, //!< trace to supplied address - address is 1st instuction not executed.
124         TRACE_TO_ADDR_INCL  //!< trace to supplied address - address is last instruction executed.
125     } waypoint_trace_t;
126 
127     void initDecoder();
128     void resetDecoder();
129 
130     ocsd_datapath_resp_t decodePacket();
131     ocsd_datapath_resp_t contProcess();
132     ocsd_datapath_resp_t processIsync();
133     ocsd_datapath_resp_t processBranch();
134     ocsd_datapath_resp_t processWPUpdate();
135     ocsd_datapath_resp_t processAtom();
136     ocsd_err_t traceInstrToWP(bool &bWPFound, const waypoint_trace_t traceWPOp = TRACE_WAYPOINT, const ocsd_vaddr_t nextAddrMatch = 0);      //!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed.
137     ocsd_datapath_resp_t processAtomRange(const ocsd_atm_val A, const char *pkt_msg, const waypoint_trace_t traceWPOp = TRACE_WAYPOINT, const ocsd_vaddr_t nextAddrMatch = 0);
138     void checkPendingNacc(ocsd_datapath_resp_t &resp);
139 
140     uint8_t m_CSID; //!< Coresight trace ID for this decoder.
141 
142 //** Other processor state;
143 
144     // trace decode FSM
145     typedef enum {
146         NO_SYNC,        //!< pre start trace - init state or after reset or overflow, loss of sync.
147         WAIT_SYNC,      //!< waiting for sync packet.
148         WAIT_ISYNC,     //!< waiting for isync packet after 1st ASYNC.
149         DECODE_PKTS,    //!< processing input packet
150         CONT_ISYNC,     //!< continue processing isync packet after WAIT.
151         CONT_ATOM,      //!< continue processing atom packet after WAIT.
152         CONT_WPUP,      //!< continue processing WP update packet after WAIT.
153         CONT_BRANCH,    //!< continue processing Branch packet after WAIT.
154     } processor_state_t;
155 
156     processor_state_t m_curr_state;
157     unsync_info_t m_unsync_info;
158 
159     const bool processStateIsCont() const;
160 
161     // PE decode state - address and isa
162 
163     //! Structure to contain the PE addr and ISA state.
164     typedef struct _ptm_pe_addr_state {
165             ocsd_isa isa;              //!< current isa.
166             ocsd_vaddr_t instr_addr;   //!< current address.
167             bool valid;     //!< address valid - false if we need an address to continue decode.
168     } ptm_pe_addr_state;
169 
170     ptm_pe_addr_state m_curr_pe_state;  //!< current instruction state for PTM decode.
171     ocsd_pe_context m_pe_context;      //!< current context information
172 
173     // packet decode state
174     bool m_need_isync;   //!< need context to continue
175 
176     ocsd_instr_info m_instr_info;  //!< instruction info for code follower - in address is the next to be decoded.
177 
178     bool m_mem_nacc_pending;    //!< need to output a memory access failure packet
179     ocsd_vaddr_t m_nacc_addr;  //!< address of memory access failure
180 
181     bool m_i_sync_pe_ctxt;  //!< isync has pe context.
182 
183     PtmAtoms m_atoms;           //!< atoms to process in an atom packet
184 
185     TrcAddrReturnStack m_return_stack;  //!< trace return stack.
186 
187 //** output element
188     OcsdTraceElement m_output_elem;
189 };
190 
191 inline const bool TrcPktDecodePtm::processStateIsCont() const
192 {
193     return (bool)(m_curr_state >= CONT_ISYNC);
194 }
195 
196 #endif // ARM_TRC_PKT_DECODE_PTM_H_INCLUDED
197 
198 /* End of File trc_pkt_decode_ptm.h */
199