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 50 namespace OHOS { 51 namespace Developtools { 52 namespace HiPerf { 53 enum 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 66 struct 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 */ 130 enum 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 190 const int LEN_TYPE_BYTE = 1; 191 const int LEN_TYPE_HLFWRD = 2; 192 const int LEN_TYPE_WORD = 4; 193 const int LEN_TYPE_DBLEWRD = 8; 194 /*16 bytes of width*/ 195 const int BYTE_WIDTH = 16; 196 197 enum 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 210 enum 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 240 enum 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 251 struct 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 265 struct SpeInsn; 266 267 struct SpeBuffer { 268 const unsigned char *buf; 269 size_t len; 270 u64 offset; 271 u64 trace_nr; 272 }; 273 274 struct SpeParams { 275 void *data; 276 }; 277 278 struct SpeDecoder { 279 void *data; 280 struct SpeRecord record; 281 const unsigned char *buf; 282 size_t len; 283 284 struct SpePkt packet; 285 }; 286 287 struct SpeDecoder *SpeDecoderNew(struct SpeParams *params); 288 struct SpeDecoder *SpeDecoderDataNew(const unsigned char *speBuf, size_t speLen); 289 void SpeDecoderFree(struct SpeDecoder *decoder); 290 291 int SpeDecode(struct SpeDecoder *decoder); 292 293 int SpePktDesc(const struct SpePkt *packet, char *buf, size_t len); 294 bool SpeDumpRawData(unsigned char *buf, size_t len, int indent, FILE *outputDump); 295 296 struct 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 307 void AddReportItems(const std::vector<ReportItemAuxRawData>& auxRawData); 308 void UpdateHeating(); 309 void DumpSpeReportData(int indent, FILE *outputDump); 310 void DumpSpeReportHead(int indent, uint32_t type, uint64_t count); 311 void GetSpeEventNameByType(uint32_t type, std::string& eventName); 312 } // namespace HiPerf 313 } // namespace Developtools 314 } // namespace OHOS 315 #endif // SPE_DECODER_H 316