xref: /developtools/hiperf/include/spe_decoder.h (revision 48f512ce)
1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef SPE_DECODER_H
16#define SPE_DECODER_H
17
18#include <linux/const.h>
19#include <stddef.h>
20#include <stdint.h>
21
22#include "utilities.h"
23
24#define BIT_ULL(x)    (_BITULL(x))
25#define ULL(x)        (_ULL(x))
26#define UL(x)         (_UL(x))
27#define BIT(x)        (UL(1) << (x))
28#define BITS_PER_LONG __BITS_PER_LONG
29#define BITS_PER_LONG_LONG 64
30
31#define GENMASK_INPUT_CHECK(h, l) 0
32
33#define PR_GENMASK(h, l) \
34        (((~UL(0)) - (UL(1) << (l)) + 1) & \
35         (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
36#define GENMASK(h, l) \
37        (GENMASK_INPUT_CHECK(h, l) + PR_GENMASK(h, l))
38
39#define PR_GENMASK_ULL(h, l) \
40        (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
41         (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
42#define GENMASK_ULL(h, l) \
43        (GENMASK_INPUT_CHECK(h, l) + PR_GENMASK_ULL(h, l))
44
45#define PERF_SPE_PKT_DESC_MAX      256
46#define PERF_SPE_NEED_MORE_BYTES   (-1)
47#define PERF_SPE_BAD_PACKET        (-2)
48#define PERF_SPE_PKT_MAX_SZ        16
49
50namespace OHOS {
51namespace Developtools {
52namespace HiPerf {
53enum SpePktType {
54    PERF_SPE_BAD,
55    PERF_SPE_PAD,
56    PERF_SPE_END,
57    PERF_SPE_TIMESTAMP,
58    PERF_SPE_ADDRESS,
59    PERF_SPE_COUNTER,
60    PERF_SPE_CONTEXT,
61    PERF_SPE_OP_TYPE,
62    PERF_SPE_EVENTS,
63    PERF_SPE_DATA_SOURCE,
64};
65
66struct SpePkt {
67    SpePktType      type;
68    unsigned char   index;
69    uint64_t payload;
70};
71
72/* Short header (HEADER0) and extended header (HEADER1) */
73#define PERF_SPE_HEADER0_PAD                 0x0
74#define PERF_SPE_HEADER0_END                 0x1
75#define PERF_SPE_HEADER0_TIMESTAMP           0x71
76/* Mask for event & data source */
77#define PERF_SPE_HEADER0_MASK1               (GENMASK_ULL(7, 6) | GENMASK_ULL(3, 0))
78#define PERF_SPE_HEADER0_EVENTS              0x42
79#define PERF_SPE_HEADER0_SOURCE              0x43
80/* Mask for context & operation */
81#define PERF_SPE_HEADER0_MASK2               GENMASK_ULL(7, 2)
82#define PERF_SPE_HEADER0_CONTEXT             0x64
83#define PERF_SPE_HEADER0_OP_TYPE             0x48
84/* Mask for extended format */
85#define PERF_SPE_HEADER0_EXTENDED            0x20
86/* Mask for address & counter */
87#define PERF_SPE_HEADER0_MASK3               GENMASK_ULL(7, 3)
88#define PERF_SPE_HEADER0_ADDRESS             0xb0
89#define PERF_SPE_HEADER0_COUNTER             0x98
90#define PERF_SPE_HEADER1_ALIGNMENT           0x0
91
92#define PERF_SPE_HDR_SHORT_INDEX(h)         ((h) & GENMASK_ULL(2, 0))
93#define PERF_SPE_HDR_EXTENDED_INDEX(h0, h1)     (((h0) & GENMASK_ULL(1, 0)) << 3 | \
94                                                 PERF_SPE_HDR_SHORT_INDEX(h1))
95
96/* Address packet header */
97#define PERF_SPE_ADDR_PKT_HDR_INDEX_INS         0x0
98#define PERF_SPE_ADDR_PKT_HDR_INDEX_BRANCH      0x1
99#define PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT   0x2
100#define PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS   0x3
101#define PERF_SPE_ADDR_PKT_HDR_INDEX_PREV_BRANCH 0x4
102
103/* Address packet payload */
104#define PERF_SPE_ADDR_PKT_ADDR_BYTE7_SHIFT      56
105#define PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(v) ((v) & GENMASK_ULL(55, 0))
106#define PERF_SPE_ADDR_PKT_ADDR_GET_BYTE_6(v)        (((v) & GENMASK_ULL(55, 48)) >> 48)
107
108#define PERF_SPE_ADDR_PKT_GET_NS(v)         (((v) & BIT_ULL(63)) >> 63)
109#define PERF_SPE_ADDR_PKT_GET_EL(v)         (((v) & GENMASK_ULL(62, 61)) >> 61)
110#define PERF_SPE_ADDR_PKT_GET_CH(v)         (((v) & BIT_ULL(62)) >> 62)
111#define PERF_SPE_ADDR_PKT_GET_PAT(v)            (((v) & GENMASK_ULL(59, 56)) >> 56)
112
113#define PERF_SPE_ADDR_PKT_EL0                  0
114#define PERF_SPE_ADDR_PKT_EL1                  1
115#define PERF_SPE_ADDR_PKT_EL2                  2
116#define PERF_SPE_ADDR_PKT_EL3                  3
117
118/* Context packet header */
119#define PERF_SPE_CTX_PKT_HDR_INDEX(h)        ((h) & GENMASK_ULL(1, 0))
120
121/* Counter packet header */
122#define PERF_SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT     0x0
123#define PERF_SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT     0x1
124#define PERF_SPE_CNT_PKT_HDR_INDEX_TRANS_LAT     0x2
125
126/* Get bit 5th and 4th of the header */
127#define PERF_SPE_HDR_GET_BYTES_5_4(h)       (((h) & (GENMASK_ULL(5, 4))) >> 4)
128
129/* Event packet payload */
130enum SpeEvents {
131    EVENT_EXCEPTION_GEN        = 0,
132    EVENT_RETIRED              = 1,
133    EVENT_L1D_ACCESS           = 2,
134    EVENT_L1D_REFILL           = 3,
135    EVENT_TLB_ACCESS           = 4,
136    EVENT_TLB_WALK             = 5,
137    EVENT_NOT_TAKEN            = 6,
138    EVENT_MISPRED              = 7,
139    EVENT_LLC_ACCESS           = 8,
140    EVENT_LLC_MISS             = 9,
141    EVENT_REMOTE_ACCESS        = 10,
142    EVENT_ALIGNMENT            = 11,
143    EVENT_PARTIAL_PREDICATE    = 17,
144    EVENT_EMPTY_PREDICATE      = 18,
145};
146
147
148/* Operation packet header */
149#define PERF_SPE_OP_PKT_HDR_CLASS(h)             ((h) & GENMASK_ULL(1, 0))
150#define PERF_SPE_OP_PKT_HDR_CLASS_OTHER          0x0
151#define PERF_SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC   0x1
152#define PERF_SPE_OP_PKT_HDR_CLASS_BR_ERET        0x2
153
154#define PERF_SPE_OP_PKT_IS_OTHER_SVE_OP(v)       (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8)
155
156#define PERF_SPE_OP_PKT_COND                     BIT(0)
157
158#define PERF_SPE_OP_PKT_LDST_SUBCLASS_GET(v)     ((v) & GENMASK_ULL(7, 1))
159#define PERF_SPE_OP_PKT_LDST_SUBCLASS_GP_REG     0x0
160#define PERF_SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP    0x4
161#define PERF_SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10
162#define PERF_SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG  0x30
163#define PERF_SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG    0x14
164#define PERF_SPE_OP_PKT_LDST_SUBCLASS_MEMCPY     0x20
165#define PERF_SPE_OP_PKT_LDST_SUBCLASS_MEMSET     0x25
166
167#define PERF_SPE_OP_PKT_IS_LDST_ATOMIC(v)        (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2)
168
169#define PERF_SPE_OP_PKT_AR                       BIT(4)
170#define PERF_SPE_OP_PKT_EXCL                     BIT(3)
171#define PERF_SPE_OP_PKT_AT                       BIT(2)
172#define PERF_SPE_OP_PKT_ST                       BIT(0)
173
174#define PERF_SPE_OP_PKT_IS_LDST_SVE(v)           (((v) & (BIT(3) | BIT(1))) == 0x8)
175
176#define PERF_SPE_OP_PKT_SVE_SG                   BIT(7)
177/*
178 * SVE effective vector length (EVL) is stored in byte 0 bits [6:4];
179 * the length is rounded up to a power of two and use 32 as one step,
180 * so EVL calculation is:
181 *
182 *   32 * (2 ^ bits [6:4]) = 32 << (bits [6:4])
183 */
184#define PERF_SPE_OP_PKG_SVE_EVL(v)              (32 << (((v) & GENMASK_ULL(6, 4)) >> 4))
185#define PERF_SPE_OP_PKT_SVE_PRED                BIT(2)
186#define PERF_SPE_OP_PKT_SVE_FP                  BIT(1)
187
188#define PERF_SPE_OP_PKT_IS_INDIRECT_BRANCH(v)   (((v) & GENMASK_ULL(7, 1)) == 0x2)
189
190const int LEN_TYPE_BYTE    = 1;
191const int LEN_TYPE_HLFWRD  = 2;
192const int LEN_TYPE_WORD    = 4;
193const int LEN_TYPE_DBLEWRD = 8;
194/*16 bytes of width*/
195const int BYTE_WIDTH = 16;
196
197enum SpeSampleType {
198    PERF_SPE_L1D_ACCESS          = 1 << 0,
199    PERF_SPE_L1D_MISS            = 1 << 1,
200    PERF_SPE_LLC_ACCESS          = 1 << 2,
201    PERF_SPE_LLC_MISS            = 1 << 3,
202    PERF_SPE_TLB_ACCESS          = 1 << 4,
203    PERF_SPE_TLB_MISS            = 1 << 5,
204    PERF_SPE_BRANCH_MISS         = 1 << 6,
205    PERF_SPE_REMOTE_ACCESS       = 1 << 7,
206    PERF_SPE_SVE_PARTIAL_PRED    = 1 << 8,
207    PERF_SPE_SVE_EMPTY_PRED      = 1 << 9,
208};
209
210enum SpeOpType {
211    /* First level operation type */
212    PERF_SPE_OP_OTHER            = 1 << 0,
213    PERF_SPE_OP_LDST             = 1 << 1,
214    PERF_SPE_OP_BRANCH_ERET      = 1 << 2,
215
216    /* Second level operation type for OTHER */
217    PERF_SPE_OP_SVE_OTHER        = 1 << 16,
218    PERF_SPE_OP_SVE_FP           = 1 << 17,
219    PERF_SPE_OP_SVE_PRED_OTHER   = 1 << 18,
220
221    /* Second level operation type for LDST */
222    PERF_SPE_OP_LD               = 1 << 16,
223    PERF_SPE_OP_ST               = 1 << 17,
224    PERF_SPE_OP_ATOMIC           = 1 << 18,
225    PERF_SPE_OP_EXCL             = 1 << 19,
226    PERF_SPE_OP_AR               = 1 << 20,
227    PERF_SPE_OP_SIMD_FP          = 1 << 21,
228    PERF_SPE_OP_GP_REG           = 1 << 22,
229    PERF_SPE_OP_UNSPEC_REG       = 1 << 23,
230    PERF_SPE_OP_NV_SYSREG        = 1 << 24,
231    PERF_SPE_OP_SVE_LDST         = 1 << 25,
232    PERF_SPE_OP_SVE_PRED_LDST    = 1 << 26,
233    PERF_SPE_OP_SVE_SG           = 1 << 27,
234
235    /* Second level operation type for BRANCH_ERET */
236    PERF_SPE_OP_BR_COND          = 1 << 16,
237    PERF_SPE_OP_BR_INDIRECT      = 1 << 17,
238};
239
240enum SpeNeoverseDataSource {
241    PERF_SPE_NV_L1D           = 0x0,
242    PERF_SPE_NV_L2            = 0x8,
243    PERF_SPE_NV_PEER_CORE     = 0x9,
244    PERF_SPE_NV_LOCAL_CLUSTER = 0xa,
245    PERF_SPE_NV_SYS_CACHE     = 0xb,
246    PERF_SPE_NV_PEER_CLUSTER  = 0xc,
247    PERF_SPE_NV_REMOTE        = 0xd,
248    PERF_SPE_NV_DRAM          = 0xe,
249};
250
251struct SpeRecord {
252    u32 type;
253    int err;
254    u32 op;
255    u32 latency;
256    u64 from_ip;
257    u64 to_ip;
258    u64 timestamp;
259    u64 virt_addr;
260    u64 phys_addr;
261    u64 context_id;
262    u16 source;
263};
264
265struct SpeInsn;
266
267struct SpeBuffer {
268    const unsigned char *buf;
269    size_t len;
270    u64 offset;
271    u64 trace_nr;
272};
273
274struct SpeParams {
275    void *data;
276};
277
278struct SpeDecoder {
279    void *data;
280    struct SpeRecord record;
281    const unsigned char *buf;
282    size_t len;
283
284    struct SpePkt packet;
285};
286
287struct SpeDecoder *SpeDecoderNew(struct SpeParams *params);
288struct SpeDecoder *SpeDecoderDataNew(const unsigned char *speBuf, size_t speLen);
289void SpeDecoderFree(struct SpeDecoder *decoder);
290
291int SpeDecode(struct SpeDecoder *decoder);
292
293int SpePktDesc(const struct SpePkt *packet, char *buf, size_t len);
294bool SpeDumpRawData(unsigned char *buf, size_t len, int indent, FILE *outputDump);
295
296struct ReportItemAuxRawData {
297    u32 type;
298    float heating;
299    u64 count;
300    std::string comm;
301    u64 pc;
302    std::string SharedObject;
303    std::string Symbol;
304    u64 offset;
305};
306
307void AddReportItems(const std::vector<ReportItemAuxRawData>& auxRawData);
308void UpdateHeating();
309void DumpSpeReportData(int indent, FILE *outputDump);
310void DumpSpeReportHead(int indent, uint32_t type, uint64_t count);
311void GetSpeEventNameByType(uint32_t type, std::string& eventName);
312} // namespace HiPerf
313} // namespace Developtools
314} // namespace OHOS
315#endif // SPE_DECODER_H
316