aboutsummaryrefslogtreecommitdiffstats
path: root/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.h
blob: 429f32711f3e652f86cc7a3a13ac324958ace1a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 * \file       trc_pkt_proc_etmv4i_impl.h
 * \brief      OpenCSD : Implementation of ETMv4 packet processing
 * 
 * \copyright  Copyright (c) 2015, 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_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED
#define ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED

#include "opencsd/etmv4/trc_pkt_proc_etmv4.h"
#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:
    EtmV4IPktProcImpl();
    ~EtmV4IPktProcImpl();

    void Initialise(TrcPktProcEtmV4I *p_interface);

    ocsd_err_t Configure(const EtmV4Config *p_config);


    ocsd_datapath_resp_t processData(  const ocsd_trc_index_t index,
                                        const uint32_t dataBlockSize,
                                        const uint8_t *pDataBlock,
                                        uint32_t *numBytesProcessed);
    ocsd_datapath_resp_t onEOT();
    ocsd_datapath_resp_t onReset();
    ocsd_datapath_resp_t onFlush();
    const bool isBadPacket() const;

protected:
    typedef enum _process_state {
        PROC_HDR,
        PROC_DATA,
        SEND_PKT,
        SEND_UNSYNCED,
        PROC_ERR,
    } process_state;
    
    process_state m_process_state;

    void InitPacketState();      // clear current packet state.
    void InitProcessorState();   // clear all previous process state

    /** packet processor configuration **/
    bool m_isInit;
    TrcPktProcEtmV4I *m_interface;       /**< The interface to the other decode components */

    // etmv4 hardware configuration
    EtmV4Config m_config;

    /** packet 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
    ocsd_trc_index_t m_blockIndex;     // index at the start of the current data block being processed

    // searching for sync
    bool m_is_sync;             //!< seen first sync packet
    bool m_first_trace_info;    //!< seen first trace info packet after sync
    bool m_sent_notsync_packet; //!< send one not sync packet if we see any unsynced data on the channel 
    unsigned m_dump_unsynced_bytes;  //!< number of unsynced bytes to send
    ocsd_trc_index_t m_update_on_unsync_packet_index;


private:
    // current processing state data - counts and flags to determine if a packet is complete.

    // TraceInfo Packet
    // flags to indicate processing progress for these sections is complete.
    struct _t_info_pkt_prog {
        uint8_t sectFlags;
        uint8_t ctrlBytes;                 
    }  m_tinfo_sections;

    #define TINFO_INFO_SECT 0x01
    #define TINFO_KEY_SECT  0x02 
    #define TINFO_SPEC_SECT 0x04
    #define TINFO_CYCT_SECT 0x08
    #define TINFO_CTRL      0x20
    #define TINFO_ALL_SECT  0x1F
    #define TINFO_ALL       0x3F


    // address and context packets 
    int m_addrBytes;
    uint8_t m_addrIS;
    bool m_bAddr64bit;
    int m_vmidBytes;    // bytes still to find
    int m_ctxtidBytes;  // bytes still to find
    bool m_bCtxtInfoDone;
    bool m_addr_done;

    // timestamp
    bool m_ccount_done; // done or not needed 
    bool m_ts_done;
    int m_ts_bytes;

    // exception
    int m_excep_size;

    // cycle count
    bool m_has_count;
    bool m_count_done;
    bool m_commit_done;

    // cond result
    bool m_F1P1_done;  // F1 payload 1 done
    bool m_F1P2_done;  // F1 payload 2 done
    bool m_F1has_P2;   // F1 has a payload 2

    // Q packets (use some from above too)
    bool m_has_addr;
    bool m_addr_short;
    bool m_addr_match;
    uint8_t m_Q_type;
    uint8_t m_QE;

    ocsd_datapath_resp_t outputPacket();
    ocsd_datapath_resp_t outputUnsyncedRawPacket(); 

    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);
    unsigned extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result);
    void extractAndSetContextInfo(const std::vector<uint8_t> &buffer, const int st_idx);
    int extract64BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint64_t &value);
    int extract32BitLongAddr(const std::vector<uint8_t> &buffer, const int st_idx, const uint8_t IS, uint32_t &value);
    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)(uint8_t);
    PPKTFN m_pIPktFn;

    struct _pkt_i_table_t {
        ocsd_etmv4_i_pkt_type pkt_type;
        PPKTFN pptkFn;
    } m_i_table[256];

    void BuildIPacketTable();

    void throwBadSequenceError(const char *pszExtMsg);
};


inline const bool EtmV4IPktProcImpl::isBadPacket() const
{
    return m_curr_packet.isBadPacket();
}

#endif // ARM_TRC_PKT_PROC_ETMV4I_IMPL_H_INCLUDED

/* End of File trc_pkt_proc_etmv4i_impl.h */