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