148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci 1648f512ceSopenharmony_ci#include "spe_decoder.h" 1748f512ceSopenharmony_ci#include "hiperf_hilog.h" 1848f512ceSopenharmony_ci 1948f512ceSopenharmony_ci#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 2048f512ceSopenharmony_ci#define LE16_TO_CPU bswap_16 2148f512ceSopenharmony_ci#define LE32_TO_CPU bswap_32 2248f512ceSopenharmony_ci#define LE64_TO_CPU bswap_64 2348f512ceSopenharmony_ci#else 2448f512ceSopenharmony_ci#define LE16_TO_CPU 2548f512ceSopenharmony_ci#define LE32_TO_CPU 2648f512ceSopenharmony_ci#define LE64_TO_CPU 2748f512ceSopenharmony_ci#endif 2848f512ceSopenharmony_ci 2948f512ceSopenharmony_cinamespace OHOS { 3048f512ceSopenharmony_cinamespace Developtools { 3148f512ceSopenharmony_cinamespace HiPerf { 3248f512ceSopenharmony_ciconstexpr const int UN_PRMT = -1; 3348f512ceSopenharmony_ci 3448f512ceSopenharmony_ciconst char *SpePktName(enum SpePktType type) 3548f512ceSopenharmony_ci{ 3648f512ceSopenharmony_ci const char* spePacketName; 3748f512ceSopenharmony_ci switch (type) { 3848f512ceSopenharmony_ci case PERF_SPE_PAD: spePacketName = "PAD"; break; 3948f512ceSopenharmony_ci case PERF_SPE_END: spePacketName = "END"; break; 4048f512ceSopenharmony_ci case PERF_SPE_TIMESTAMP: spePacketName = "TS"; break; 4148f512ceSopenharmony_ci case PERF_SPE_ADDRESS: spePacketName = "ADDR"; break; 4248f512ceSopenharmony_ci case PERF_SPE_COUNTER: spePacketName = "LAT"; break; 4348f512ceSopenharmony_ci case PERF_SPE_CONTEXT: spePacketName = "CONTEXT"; break; 4448f512ceSopenharmony_ci case PERF_SPE_OP_TYPE: spePacketName = "OP-TYPE"; break; 4548f512ceSopenharmony_ci case PERF_SPE_EVENTS: spePacketName = "EVENTS"; break; 4648f512ceSopenharmony_ci case PERF_SPE_DATA_SOURCE: spePacketName = "DATA-SOURCE"; break; 4748f512ceSopenharmony_ci default: spePacketName = "INVALID"; break; 4848f512ceSopenharmony_ci } 4948f512ceSopenharmony_ci return spePacketName; 5048f512ceSopenharmony_ci} 5148f512ceSopenharmony_ci 5248f512ceSopenharmony_cistatic unsigned int SpePayloadLen(unsigned char hdr) 5348f512ceSopenharmony_ci{ 5448f512ceSopenharmony_ci return 1U << PERF_SPE_HDR_GET_BYTES_5_4(hdr); 5548f512ceSopenharmony_ci} 5648f512ceSopenharmony_ci 5748f512ceSopenharmony_cistatic int SpeGetPayload(const unsigned char *buf, size_t len, 5848f512ceSopenharmony_ci unsigned char extHdr, struct SpePkt *packet) 5948f512ceSopenharmony_ci{ 6048f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 6148f512ceSopenharmony_ci size_t payloadLen = SpePayloadLen(buf[extHdr]); 6248f512ceSopenharmony_ci if (len < 1 + extHdr + payloadLen) { 6348f512ceSopenharmony_ci return PERF_SPE_NEED_MORE_BYTES; 6448f512ceSopenharmony_ci } 6548f512ceSopenharmony_ci buf += 1 + extHdr; 6648f512ceSopenharmony_ci 6748f512ceSopenharmony_ci switch (payloadLen) { 6848f512ceSopenharmony_ci case LEN_TYPE_BYTE: packet->payload = *(reinterpret_cast<const uint8_t *>(buf)); break; 6948f512ceSopenharmony_ci case LEN_TYPE_HLFWRD: packet->payload = LE16_TO_CPU(*reinterpret_cast<const uint16_t *>(buf)); break; 7048f512ceSopenharmony_ci case LEN_TYPE_WORD: packet->payload = LE32_TO_CPU(*reinterpret_cast<const uint32_t *>(buf)); break; 7148f512ceSopenharmony_ci case LEN_TYPE_DBLEWRD: packet->payload = LE64_TO_CPU(*reinterpret_cast<const uint64_t *>(buf)); break; 7248f512ceSopenharmony_ci default: return PERF_SPE_BAD_PACKET; 7348f512ceSopenharmony_ci } 7448f512ceSopenharmony_ci 7548f512ceSopenharmony_ci return 1 + extHdr + payloadLen; 7648f512ceSopenharmony_ci} 7748f512ceSopenharmony_ci 7848f512ceSopenharmony_cistatic int SpeGetPad(struct SpePkt *packet) 7948f512ceSopenharmony_ci{ 8048f512ceSopenharmony_ci CHECK_TRUE(packet == nullptr, -1, 1, "Invalid pointer!"); 8148f512ceSopenharmony_ci packet->type = PERF_SPE_PAD; 8248f512ceSopenharmony_ci return 1; 8348f512ceSopenharmony_ci} 8448f512ceSopenharmony_ci 8548f512ceSopenharmony_cistatic int SpeGetAlignment(const unsigned char *buf, size_t len, 8648f512ceSopenharmony_ci struct SpePkt *packet) 8748f512ceSopenharmony_ci{ 8848f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 8948f512ceSopenharmony_ci unsigned int alignment = 1 << ((buf[0] & 0xf) + 1); 9048f512ceSopenharmony_ci 9148f512ceSopenharmony_ci if (len < alignment) 9248f512ceSopenharmony_ci return PERF_SPE_NEED_MORE_BYTES; 9348f512ceSopenharmony_ci 9448f512ceSopenharmony_ci packet->type = PERF_SPE_PAD; 9548f512ceSopenharmony_ci return alignment - (((uintptr_t)buf) & (alignment - 1)); 9648f512ceSopenharmony_ci} 9748f512ceSopenharmony_ci 9848f512ceSopenharmony_cistatic int SpeGetEnd(struct SpePkt *packet) 9948f512ceSopenharmony_ci{ 10048f512ceSopenharmony_ci CHECK_TRUE(packet == nullptr, -1, 1, "Invalid pointer!"); 10148f512ceSopenharmony_ci packet->type = PERF_SPE_END; 10248f512ceSopenharmony_ci return 1; 10348f512ceSopenharmony_ci} 10448f512ceSopenharmony_ci 10548f512ceSopenharmony_cistatic int SpeGetTimestamp(const unsigned char *buf, size_t len, 10648f512ceSopenharmony_ci struct SpePkt *packet) 10748f512ceSopenharmony_ci{ 10848f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 10948f512ceSopenharmony_ci packet->type = PERF_SPE_TIMESTAMP; 11048f512ceSopenharmony_ci return SpeGetPayload(buf, len, 0, packet); 11148f512ceSopenharmony_ci} 11248f512ceSopenharmony_ci 11348f512ceSopenharmony_cistatic int SpeGetEvents(const unsigned char *buf, size_t len, 11448f512ceSopenharmony_ci struct SpePkt *packet) 11548f512ceSopenharmony_ci{ 11648f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 11748f512ceSopenharmony_ci packet->type = PERF_SPE_EVENTS; 11848f512ceSopenharmony_ci packet->index = SpePayloadLen(buf[0]); 11948f512ceSopenharmony_ci return SpeGetPayload(buf, len, 0, packet); 12048f512ceSopenharmony_ci} 12148f512ceSopenharmony_ci 12248f512ceSopenharmony_cistatic int SpeGetDataSource(const unsigned char *buf, size_t len, 12348f512ceSopenharmony_ci struct SpePkt *packet) 12448f512ceSopenharmony_ci{ 12548f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 12648f512ceSopenharmony_ci packet->type = PERF_SPE_DATA_SOURCE; 12748f512ceSopenharmony_ci return SpeGetPayload(buf, len, 0, packet); 12848f512ceSopenharmony_ci} 12948f512ceSopenharmony_ci 13048f512ceSopenharmony_cistatic int SpeGetContext(const unsigned char *buf, size_t len, 13148f512ceSopenharmony_ci struct SpePkt *packet) 13248f512ceSopenharmony_ci{ 13348f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 13448f512ceSopenharmony_ci packet->type = PERF_SPE_CONTEXT; 13548f512ceSopenharmony_ci packet->index = PERF_SPE_CTX_PKT_HDR_INDEX(buf[0]); 13648f512ceSopenharmony_ci return SpeGetPayload(buf, len, 0, packet); 13748f512ceSopenharmony_ci} 13848f512ceSopenharmony_ci 13948f512ceSopenharmony_cistatic int SpeGetOpType(const unsigned char *buf, size_t len, 14048f512ceSopenharmony_ci struct SpePkt *packet) 14148f512ceSopenharmony_ci{ 14248f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 14348f512ceSopenharmony_ci packet->type = PERF_SPE_OP_TYPE; 14448f512ceSopenharmony_ci packet->index = PERF_SPE_OP_PKT_HDR_CLASS(buf[0]); 14548f512ceSopenharmony_ci return SpeGetPayload(buf, len, 0, packet); 14648f512ceSopenharmony_ci} 14748f512ceSopenharmony_ci 14848f512ceSopenharmony_cistatic int SpeGetCounter(const unsigned char *buf, size_t len, 14948f512ceSopenharmony_ci const unsigned char extHdr, struct SpePkt *packet) 15048f512ceSopenharmony_ci{ 15148f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 15248f512ceSopenharmony_ci packet->type = PERF_SPE_COUNTER; 15348f512ceSopenharmony_ci if (extHdr) { 15448f512ceSopenharmony_ci packet->index = PERF_SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]); 15548f512ceSopenharmony_ci } else { 15648f512ceSopenharmony_ci packet->index = PERF_SPE_HDR_SHORT_INDEX(buf[0]); 15748f512ceSopenharmony_ci } 15848f512ceSopenharmony_ci 15948f512ceSopenharmony_ci return SpeGetPayload(buf, len, extHdr, packet); 16048f512ceSopenharmony_ci} 16148f512ceSopenharmony_ci 16248f512ceSopenharmony_cistatic int SpeGetAddr(const unsigned char *buf, size_t len, 16348f512ceSopenharmony_ci const unsigned char extHdr, struct SpePkt *packet) 16448f512ceSopenharmony_ci{ 16548f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 16648f512ceSopenharmony_ci packet->type = PERF_SPE_ADDRESS; 16748f512ceSopenharmony_ci if (extHdr) { 16848f512ceSopenharmony_ci packet->index = PERF_SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]); 16948f512ceSopenharmony_ci } else { 17048f512ceSopenharmony_ci packet->index = PERF_SPE_HDR_SHORT_INDEX(buf[0]); 17148f512ceSopenharmony_ci } 17248f512ceSopenharmony_ci 17348f512ceSopenharmony_ci return SpeGetPayload(buf, len, extHdr, packet); 17448f512ceSopenharmony_ci} 17548f512ceSopenharmony_ci 17648f512ceSopenharmony_cistatic int SpeDoGetPacket(const unsigned char *buf, size_t len, 17748f512ceSopenharmony_ci struct SpePkt *packet) 17848f512ceSopenharmony_ci{ 17948f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 18048f512ceSopenharmony_ci unsigned int hdr; 18148f512ceSopenharmony_ci unsigned char extHdr = 0; 18248f512ceSopenharmony_ci 18348f512ceSopenharmony_ci memset_s(packet, sizeof(struct SpePkt), 0, sizeof(struct SpePkt)); 18448f512ceSopenharmony_ci 18548f512ceSopenharmony_ci if (!len) { 18648f512ceSopenharmony_ci return PERF_SPE_NEED_MORE_BYTES; 18748f512ceSopenharmony_ci } 18848f512ceSopenharmony_ci 18948f512ceSopenharmony_ci hdr = buf[0]; 19048f512ceSopenharmony_ci if (hdr == PERF_SPE_HEADER0_PAD) { 19148f512ceSopenharmony_ci return SpeGetPad(packet); 19248f512ceSopenharmony_ci } else if (hdr == PERF_SPE_HEADER0_END) { /* no timestamp at end of record */ 19348f512ceSopenharmony_ci return SpeGetEnd(packet); 19448f512ceSopenharmony_ci } 19548f512ceSopenharmony_ci if (hdr == PERF_SPE_HEADER0_TIMESTAMP) { 19648f512ceSopenharmony_ci return SpeGetTimestamp(buf, len, packet); 19748f512ceSopenharmony_ci } else if ((hdr & PERF_SPE_HEADER0_MASK1) == PERF_SPE_HEADER0_EVENTS) { 19848f512ceSopenharmony_ci return SpeGetEvents(buf, len, packet); 19948f512ceSopenharmony_ci } else if ((hdr & PERF_SPE_HEADER0_MASK1) == PERF_SPE_HEADER0_SOURCE) { 20048f512ceSopenharmony_ci return SpeGetDataSource(buf, len, packet); 20148f512ceSopenharmony_ci } else if ((hdr & PERF_SPE_HEADER0_MASK2) == PERF_SPE_HEADER0_CONTEXT) { 20248f512ceSopenharmony_ci return SpeGetContext(buf, len, packet); 20348f512ceSopenharmony_ci } else if ((hdr & PERF_SPE_HEADER0_MASK2) == PERF_SPE_HEADER0_OP_TYPE) { 20448f512ceSopenharmony_ci return SpeGetOpType(buf, len, packet); 20548f512ceSopenharmony_ci } 20648f512ceSopenharmony_ci if ((hdr & PERF_SPE_HEADER0_MASK2) == PERF_SPE_HEADER0_EXTENDED) { 20748f512ceSopenharmony_ci /* 16-bit extended format header */ 20848f512ceSopenharmony_ci if (len == 1) { 20948f512ceSopenharmony_ci return PERF_SPE_BAD_PACKET; 21048f512ceSopenharmony_ci } 21148f512ceSopenharmony_ci 21248f512ceSopenharmony_ci extHdr = 1; 21348f512ceSopenharmony_ci hdr = buf[1]; 21448f512ceSopenharmony_ci if (hdr == PERF_SPE_HEADER1_ALIGNMENT) { 21548f512ceSopenharmony_ci return SpeGetAlignment(buf, len, packet); 21648f512ceSopenharmony_ci } 21748f512ceSopenharmony_ci } 21848f512ceSopenharmony_ci 21948f512ceSopenharmony_ci /* 22048f512ceSopenharmony_ci * The short format header's byte 0 or the extended format header's 22148f512ceSopenharmony_ci * byte 1 has been assigned to 'hdr', which uses the same encoding for 22248f512ceSopenharmony_ci * address packet and counter packet, so don't need to distinguish if 22348f512ceSopenharmony_ci * it's short format or extended format and handle in once. 22448f512ceSopenharmony_ci */ 22548f512ceSopenharmony_ci if ((hdr & PERF_SPE_HEADER0_MASK3) == PERF_SPE_HEADER0_ADDRESS) { 22648f512ceSopenharmony_ci return SpeGetAddr(buf, len, extHdr, packet); 22748f512ceSopenharmony_ci } 22848f512ceSopenharmony_ci 22948f512ceSopenharmony_ci if ((hdr & PERF_SPE_HEADER0_MASK3) == PERF_SPE_HEADER0_COUNTER) { 23048f512ceSopenharmony_ci return SpeGetCounter(buf, len, extHdr, packet); 23148f512ceSopenharmony_ci } 23248f512ceSopenharmony_ci return PERF_SPE_BAD_PACKET; 23348f512ceSopenharmony_ci} 23448f512ceSopenharmony_ci 23548f512ceSopenharmony_ciint SpeGetPacket(const unsigned char *buf, size_t len, 23648f512ceSopenharmony_ci struct SpePkt *packet) 23748f512ceSopenharmony_ci{ 23848f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 23948f512ceSopenharmony_ci int ret = SpeDoGetPacket(buf, len, packet); 24048f512ceSopenharmony_ci /* put multiple consecutive PADs on the same line, up to 24148f512ceSopenharmony_ci * the fixed-width output format of 16 bytes per line. 24248f512ceSopenharmony_ci */ 24348f512ceSopenharmony_ci if (ret > 0 && packet->type == PERF_SPE_PAD) { 24448f512ceSopenharmony_ci while (ret < BYTE_WIDTH && len > (size_t)ret && !buf[ret]) { 24548f512ceSopenharmony_ci ret += 1; 24648f512ceSopenharmony_ci } 24748f512ceSopenharmony_ci } 24848f512ceSopenharmony_ci return ret; 24948f512ceSopenharmony_ci} 25048f512ceSopenharmony_ci 25148f512ceSopenharmony_cistatic int SpePktOutString(int *err, char **bufPtr, size_t *bufLen, 25248f512ceSopenharmony_ci const char *fmt, ...) 25348f512ceSopenharmony_ci{ 25448f512ceSopenharmony_ci CHECK_TRUE(*bufPtr == nullptr || bufLen == nullptr || fmt == nullptr, -1, 1, "Invalid pointer!"); 25548f512ceSopenharmony_ci va_list args; 25648f512ceSopenharmony_ci int ret = 0; 25748f512ceSopenharmony_ci 25848f512ceSopenharmony_ci /* If any errors occur, exit */ 25948f512ceSopenharmony_ci if (err && *err) { 26048f512ceSopenharmony_ci return *err; 26148f512ceSopenharmony_ci } 26248f512ceSopenharmony_ci 26348f512ceSopenharmony_ci va_start(args, fmt); 26448f512ceSopenharmony_ci ret = vsnprintf_s(*bufPtr, *bufLen, *bufLen - 1, fmt, args); 26548f512ceSopenharmony_ci va_end(args); 26648f512ceSopenharmony_ci 26748f512ceSopenharmony_ci if (ret < 0) { 26848f512ceSopenharmony_ci if (err && !*err) { 26948f512ceSopenharmony_ci *err = ret; 27048f512ceSopenharmony_ci } 27148f512ceSopenharmony_ci 27248f512ceSopenharmony_ci /* 27348f512ceSopenharmony_ci * If the return value is *bufLen or greater, the output was 27448f512ceSopenharmony_ci * truncated and the buffer overflowed. 27548f512ceSopenharmony_ci */ 27648f512ceSopenharmony_ci } else if ((size_t)ret >= *bufLen) { 27748f512ceSopenharmony_ci (*bufPtr)[*bufLen - 1] = '\0'; 27848f512ceSopenharmony_ci 27948f512ceSopenharmony_ci /* 28048f512ceSopenharmony_ci * Set *err to 'ret' to avoid overflow if tries to 28148f512ceSopenharmony_ci * fill this buffer sequentially. 28248f512ceSopenharmony_ci */ 28348f512ceSopenharmony_ci if (err && !*err) { 28448f512ceSopenharmony_ci *err = ret; 28548f512ceSopenharmony_ci } 28648f512ceSopenharmony_ci } else { 28748f512ceSopenharmony_ci *bufPtr += ret; 28848f512ceSopenharmony_ci *bufLen -= ret; 28948f512ceSopenharmony_ci } 29048f512ceSopenharmony_ci 29148f512ceSopenharmony_ci return ret; 29248f512ceSopenharmony_ci} 29348f512ceSopenharmony_ci 29448f512ceSopenharmony_cistatic int SpePktDescEvent(const struct SpePkt *packet, 29548f512ceSopenharmony_ci char *buf, size_t bufLen) 29648f512ceSopenharmony_ci{ 29748f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 29848f512ceSopenharmony_ci u64 payload = packet->payload; 29948f512ceSopenharmony_ci int err = 0; 30048f512ceSopenharmony_ci 30148f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "EV"); 30248f512ceSopenharmony_ci if (payload & BIT(EVENT_EXCEPTION_GEN)) { 30348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " EXCEPTION-GEN"); 30448f512ceSopenharmony_ci } 30548f512ceSopenharmony_ci if (payload & BIT(EVENT_RETIRED)) { 30648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " RETIRED"); 30748f512ceSopenharmony_ci } 30848f512ceSopenharmony_ci if (payload & BIT(EVENT_L1D_ACCESS)) { 30948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " L1D-ACCESS"); 31048f512ceSopenharmony_ci } 31148f512ceSopenharmony_ci if (payload & BIT(EVENT_L1D_REFILL)) { 31248f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " L1D-REFILL"); 31348f512ceSopenharmony_ci } 31448f512ceSopenharmony_ci if (payload & BIT(EVENT_TLB_ACCESS)) { 31548f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " TLB-ACCESS"); 31648f512ceSopenharmony_ci } 31748f512ceSopenharmony_ci if (payload & BIT(EVENT_TLB_WALK)) { 31848f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " TLB-REFILL"); 31948f512ceSopenharmony_ci } 32048f512ceSopenharmony_ci if (payload & BIT(EVENT_NOT_TAKEN)) { 32148f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " NOT-TAKEN"); 32248f512ceSopenharmony_ci } 32348f512ceSopenharmony_ci if (payload & BIT(EVENT_MISPRED)) { 32448f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " MISPRED"); 32548f512ceSopenharmony_ci } 32648f512ceSopenharmony_ci if (payload & BIT(EVENT_LLC_ACCESS)) { 32748f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " LLC-ACCESS"); 32848f512ceSopenharmony_ci } 32948f512ceSopenharmony_ci if (payload & BIT(EVENT_LLC_MISS)) { 33048f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " LLC-REFILL"); 33148f512ceSopenharmony_ci } 33248f512ceSopenharmony_ci if (payload & BIT(EVENT_REMOTE_ACCESS)) { 33348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " REMOTE-ACCESS"); 33448f512ceSopenharmony_ci } 33548f512ceSopenharmony_ci if (payload & BIT(EVENT_ALIGNMENT)) { 33648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " ALIGNMENT"); 33748f512ceSopenharmony_ci } 33848f512ceSopenharmony_ci if (payload & BIT(EVENT_PARTIAL_PREDICATE)) { 33948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " SVE-PARTIAL-PRED"); 34048f512ceSopenharmony_ci } 34148f512ceSopenharmony_ci if (payload & BIT(EVENT_EMPTY_PREDICATE)) { 34248f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " SVE-EMPTY-PRED"); 34348f512ceSopenharmony_ci } 34448f512ceSopenharmony_ci 34548f512ceSopenharmony_ci return err; 34648f512ceSopenharmony_ci} 34748f512ceSopenharmony_ci 34848f512ceSopenharmony_cistatic int SpePktDescOpType(const struct SpePkt *packet, 34948f512ceSopenharmony_ci char *buf, size_t bufLen) 35048f512ceSopenharmony_ci{ 35148f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 35248f512ceSopenharmony_ci u64 payload = packet->payload; 35348f512ceSopenharmony_ci int err = 0; 35448f512ceSopenharmony_ci 35548f512ceSopenharmony_ci switch (packet->index) { 35648f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_OTHER: 35748f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_OTHER_SVE_OP(payload)) { 35848f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "SVE-OTHER"); 35948f512ceSopenharmony_ci 36048f512ceSopenharmony_ci /* SVE effective vector length */ 36148f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " EVLEN %d", 36248f512ceSopenharmony_ci PERF_SPE_OP_PKG_SVE_EVL(payload)); 36348f512ceSopenharmony_ci 36448f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_SVE_FP) 36548f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " FP"); 36648f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_SVE_PRED) 36748f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " PRED"); 36848f512ceSopenharmony_ci } else { 36948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "OTHER"); 37048f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " %s", 37148f512ceSopenharmony_ci payload & PERF_SPE_OP_PKT_COND ? 37248f512ceSopenharmony_ci "COND-SELECT" : "INSN-OTHER"); 37348f512ceSopenharmony_ci } 37448f512ceSopenharmony_ci break; 37548f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC: 37648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, 37748f512ceSopenharmony_ci payload & 0x1 ? "ST" : "LD"); 37848f512ceSopenharmony_ci 37948f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_LDST_ATOMIC(payload)) { 38048f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_AT) 38148f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " AT"); 38248f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_EXCL) 38348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " EXCL"); 38448f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_AR) 38548f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " AR"); 38648f512ceSopenharmony_ci } 38748f512ceSopenharmony_ci 38848f512ceSopenharmony_ci switch (PERF_SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) { 38948f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP: 39048f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " SIMD-FP"); 39148f512ceSopenharmony_ci break; 39248f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_GP_REG: 39348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " GP-REG"); 39448f512ceSopenharmony_ci break; 39548f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG: 39648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " UNSPEC-REG"); 39748f512ceSopenharmony_ci break; 39848f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG: 39948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " NV-SYSREG"); 40048f512ceSopenharmony_ci break; 40148f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG: 40248f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " MTE-TAG"); 40348f512ceSopenharmony_ci break; 40448f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_MEMCPY: 40548f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " MEMCPY"); 40648f512ceSopenharmony_ci break; 40748f512ceSopenharmony_ci case PERF_SPE_OP_PKT_LDST_SUBCLASS_MEMSET: 40848f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " MEMSET"); 40948f512ceSopenharmony_ci break; 41048f512ceSopenharmony_ci default: 41148f512ceSopenharmony_ci break; 41248f512ceSopenharmony_ci } 41348f512ceSopenharmony_ci 41448f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_LDST_SVE(payload)) { 41548f512ceSopenharmony_ci /* SVE effective vector length */ 41648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " EVLEN %d", 41748f512ceSopenharmony_ci PERF_SPE_OP_PKG_SVE_EVL(payload)); 41848f512ceSopenharmony_ci 41948f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_SVE_PRED) 42048f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " PRED"); 42148f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_SVE_SG) 42248f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " SG"); 42348f512ceSopenharmony_ci } 42448f512ceSopenharmony_ci break; 42548f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_BR_ERET: 42648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "B"); 42748f512ceSopenharmony_ci 42848f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_COND) 42948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " COND"); 43048f512ceSopenharmony_ci 43148f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_INDIRECT_BRANCH(payload)) 43248f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, " IND"); 43348f512ceSopenharmony_ci 43448f512ceSopenharmony_ci break; 43548f512ceSopenharmony_ci default: 43648f512ceSopenharmony_ci /* Unknown packet index */ 43748f512ceSopenharmony_ci err = UN_PRMT; 43848f512ceSopenharmony_ci break; 43948f512ceSopenharmony_ci } 44048f512ceSopenharmony_ci 44148f512ceSopenharmony_ci return err; 44248f512ceSopenharmony_ci} 44348f512ceSopenharmony_ci 44448f512ceSopenharmony_cistatic int SpePktDescAddr(const struct SpePkt *packet, 44548f512ceSopenharmony_ci char *buf, size_t bufLen) 44648f512ceSopenharmony_ci{ 44748f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 44848f512ceSopenharmony_ci int ns; 44948f512ceSopenharmony_ci int el; 45048f512ceSopenharmony_ci int idx = packet->index; 45148f512ceSopenharmony_ci int ch; 45248f512ceSopenharmony_ci int pat; 45348f512ceSopenharmony_ci u64 payload = packet->payload; 45448f512ceSopenharmony_ci int err = 0; 45548f512ceSopenharmony_ci static const char *idxName[] = {"PC", "TGT", "VA", "PA", "PBT"}; 45648f512ceSopenharmony_ci 45748f512ceSopenharmony_ci switch (idx) { 45848f512ceSopenharmony_ci case PERF_SPE_ADDR_PKT_HDR_INDEX_INS: 45948f512ceSopenharmony_ci case PERF_SPE_ADDR_PKT_HDR_INDEX_BRANCH: 46048f512ceSopenharmony_ci case PERF_SPE_ADDR_PKT_HDR_INDEX_PREV_BRANCH: 46148f512ceSopenharmony_ci ns = !!PERF_SPE_ADDR_PKT_GET_NS(payload); 46248f512ceSopenharmony_ci el = PERF_SPE_ADDR_PKT_GET_EL(payload); 46348f512ceSopenharmony_ci payload = PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload); 46448f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, 46548f512ceSopenharmony_ci "%s 0x%llx el%d ns=%d", 46648f512ceSopenharmony_ci idxName[idx], payload, el, ns); 46748f512ceSopenharmony_ci break; 46848f512ceSopenharmony_ci case PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT: 46948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, 47048f512ceSopenharmony_ci "VA 0x%llx", payload); 47148f512ceSopenharmony_ci break; 47248f512ceSopenharmony_ci case PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS: 47348f512ceSopenharmony_ci ns = !!PERF_SPE_ADDR_PKT_GET_NS(payload); 47448f512ceSopenharmony_ci ch = !!PERF_SPE_ADDR_PKT_GET_CH(payload); 47548f512ceSopenharmony_ci pat = PERF_SPE_ADDR_PKT_GET_PAT(payload); 47648f512ceSopenharmony_ci payload = PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload); 47748f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, 47848f512ceSopenharmony_ci "PA 0x%llx ns=%d ch=%d pat=%x", 47948f512ceSopenharmony_ci payload, ns, ch, pat); 48048f512ceSopenharmony_ci break; 48148f512ceSopenharmony_ci default: 48248f512ceSopenharmony_ci /* Unknown packet index */ 48348f512ceSopenharmony_ci err = UN_PRMT; 48448f512ceSopenharmony_ci break; 48548f512ceSopenharmony_ci } 48648f512ceSopenharmony_ci 48748f512ceSopenharmony_ci return err; 48848f512ceSopenharmony_ci} 48948f512ceSopenharmony_ci 49048f512ceSopenharmony_cistatic int SpePktDesCont(const struct SpePkt *packet, 49148f512ceSopenharmony_ci char *buf, size_t bufLen) 49248f512ceSopenharmony_ci{ 49348f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 49448f512ceSopenharmony_ci u64 payload = packet->payload; 49548f512ceSopenharmony_ci const char *name = SpePktName(packet->type); 49648f512ceSopenharmony_ci int err = 0; 49748f512ceSopenharmony_ci 49848f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "%s %d ", name, 49948f512ceSopenharmony_ci (unsigned short)payload); 50048f512ceSopenharmony_ci 50148f512ceSopenharmony_ci switch (packet->index) { 50248f512ceSopenharmony_ci case PERF_SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT: 50348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "TOT"); 50448f512ceSopenharmony_ci break; 50548f512ceSopenharmony_ci case PERF_SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT: 50648f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "ISSUE"); 50748f512ceSopenharmony_ci break; 50848f512ceSopenharmony_ci case PERF_SPE_CNT_PKT_HDR_INDEX_TRANS_LAT: 50948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &bufLen, "XLAT"); 51048f512ceSopenharmony_ci break; 51148f512ceSopenharmony_ci default: 51248f512ceSopenharmony_ci break; 51348f512ceSopenharmony_ci } 51448f512ceSopenharmony_ci 51548f512ceSopenharmony_ci return err; 51648f512ceSopenharmony_ci} 51748f512ceSopenharmony_ci 51848f512ceSopenharmony_ciint SpePktDesc(const struct SpePkt *packet, char *buf, 51948f512ceSopenharmony_ci size_t bufLen) 52048f512ceSopenharmony_ci{ 52148f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr || packet == nullptr, -1, 1, "Invalid pointer!"); 52248f512ceSopenharmony_ci int idx = packet->index; 52348f512ceSopenharmony_ci unsigned long long payload = packet->payload; 52448f512ceSopenharmony_ci const char *name = SpePktName(packet->type); 52548f512ceSopenharmony_ci char *bufOrig = buf; 52648f512ceSopenharmony_ci size_t blen = bufLen; 52748f512ceSopenharmony_ci int err = 0; 52848f512ceSopenharmony_ci 52948f512ceSopenharmony_ci switch (packet->type) { 53048f512ceSopenharmony_ci case PERF_SPE_BAD: 53148f512ceSopenharmony_ci case PERF_SPE_PAD: 53248f512ceSopenharmony_ci case PERF_SPE_END: 53348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &blen, "%s", name); 53448f512ceSopenharmony_ci break; 53548f512ceSopenharmony_ci case PERF_SPE_EVENTS: 53648f512ceSopenharmony_ci err = SpePktDescEvent(packet, buf, bufLen); 53748f512ceSopenharmony_ci break; 53848f512ceSopenharmony_ci case PERF_SPE_OP_TYPE: 53948f512ceSopenharmony_ci err = SpePktDescOpType(packet, buf, bufLen); 54048f512ceSopenharmony_ci break; 54148f512ceSopenharmony_ci case PERF_SPE_DATA_SOURCE: 54248f512ceSopenharmony_ci case PERF_SPE_TIMESTAMP: 54348f512ceSopenharmony_ci SpePktOutString(&err, &buf, &blen, "%s %lld", name, payload); 54448f512ceSopenharmony_ci break; 54548f512ceSopenharmony_ci case PERF_SPE_ADDRESS: 54648f512ceSopenharmony_ci err = SpePktDescAddr(packet, buf, bufLen); 54748f512ceSopenharmony_ci break; 54848f512ceSopenharmony_ci case PERF_SPE_CONTEXT: 54948f512ceSopenharmony_ci SpePktOutString(&err, &buf, &blen, "%s 0x%lx el%d", 55048f512ceSopenharmony_ci name, (unsigned long)payload, idx + 1); 55148f512ceSopenharmony_ci break; 55248f512ceSopenharmony_ci case PERF_SPE_COUNTER: 55348f512ceSopenharmony_ci err = SpePktDesCont(packet, buf, bufLen); 55448f512ceSopenharmony_ci break; 55548f512ceSopenharmony_ci default: 55648f512ceSopenharmony_ci /* Unknown packet type */ 55748f512ceSopenharmony_ci err = UN_PRMT; 55848f512ceSopenharmony_ci break; 55948f512ceSopenharmony_ci } 56048f512ceSopenharmony_ci 56148f512ceSopenharmony_ci /* If any errors are detected, the raw data is output*/ 56248f512ceSopenharmony_ci if (err) { 56348f512ceSopenharmony_ci err = 0; 56448f512ceSopenharmony_ci SpePktOutString(&err, &bufOrig, &bufLen, "%s 0x%llx (%d)", 56548f512ceSopenharmony_ci name, payload, packet->index); 56648f512ceSopenharmony_ci } 56748f512ceSopenharmony_ci 56848f512ceSopenharmony_ci return err; 56948f512ceSopenharmony_ci} 57048f512ceSopenharmony_ci 57148f512ceSopenharmony_cistatic u64 SpeCalcIp(int index, u64 payload) 57248f512ceSopenharmony_ci{ 57348f512ceSopenharmony_ci u64 ns; 57448f512ceSopenharmony_ci u64 el; 57548f512ceSopenharmony_ci u64 val; 57648f512ceSopenharmony_ci 57748f512ceSopenharmony_ci /* Instruction virtual address or Branch target address */ 57848f512ceSopenharmony_ci if (index == PERF_SPE_ADDR_PKT_HDR_INDEX_INS || 57948f512ceSopenharmony_ci index == PERF_SPE_ADDR_PKT_HDR_INDEX_BRANCH) { 58048f512ceSopenharmony_ci ns = PERF_SPE_ADDR_PKT_GET_NS(payload); 58148f512ceSopenharmony_ci el = PERF_SPE_ADDR_PKT_GET_EL(payload); 58248f512ceSopenharmony_ci 58348f512ceSopenharmony_ci /* Clean highest byte */ 58448f512ceSopenharmony_ci payload = PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload); 58548f512ceSopenharmony_ci 58648f512ceSopenharmony_ci /* Fill highest byte for EL1 or EL2 (VHE) mode */ 58748f512ceSopenharmony_ci if (ns && (el == PERF_SPE_ADDR_PKT_EL1 || el == PERF_SPE_ADDR_PKT_EL2)) { 58848f512ceSopenharmony_ci payload |= 0xffULL << PERF_SPE_ADDR_PKT_ADDR_BYTE7_SHIFT; 58948f512ceSopenharmony_ci } 59048f512ceSopenharmony_ci 59148f512ceSopenharmony_ci /* Data access virtual address */ 59248f512ceSopenharmony_ci } else if (index == PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) { 59348f512ceSopenharmony_ci /* Clean tags */ 59448f512ceSopenharmony_ci payload = PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload); 59548f512ceSopenharmony_ci 59648f512ceSopenharmony_ci /* 59748f512ceSopenharmony_ci * Armv8 ARM (ARM DDI 0487F.c), chapter "D10.2.1 Address packet" 59848f512ceSopenharmony_ci * defines the data virtual address payload format, the top byte 59948f512ceSopenharmony_ci * (bits [63:56]) is assigned as top-byte tag; so we only can 60048f512ceSopenharmony_ci * retrieve address value from bits [55:0]. 60148f512ceSopenharmony_ci * 60248f512ceSopenharmony_ci * According to Documentation/arch/arm64/memory.rst, if detects the 60348f512ceSopenharmony_ci * specific pattern in bits [55:52] of payload which falls in 60448f512ceSopenharmony_ci * the kernel space, should fixup the top byte and this allows 60548f512ceSopenharmony_ci * perf tool to parse DSO symbol for data address correctly. 60648f512ceSopenharmony_ci * 60748f512ceSopenharmony_ci * For this reason, if detects the bits [55:52] is 0xf, will 60848f512ceSopenharmony_ci * fill 0xff into the top byte. 60948f512ceSopenharmony_ci */ 61048f512ceSopenharmony_ci val = PERF_SPE_ADDR_PKT_ADDR_GET_BYTE_6(payload); 61148f512ceSopenharmony_ci if ((val & 0xf0ULL) == 0xf0ULL) { 61248f512ceSopenharmony_ci payload |= 0xffULL << PERF_SPE_ADDR_PKT_ADDR_BYTE7_SHIFT; 61348f512ceSopenharmony_ci } 61448f512ceSopenharmony_ci 61548f512ceSopenharmony_ci /* Data access physical address */ 61648f512ceSopenharmony_ci } else if (index == PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) { 61748f512ceSopenharmony_ci /* Clean highest byte */ 61848f512ceSopenharmony_ci payload = PERF_SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload); 61948f512ceSopenharmony_ci } else { 62048f512ceSopenharmony_ci static u32 seen_idx = 0; 62148f512ceSopenharmony_ci if (!(seen_idx & BIT(index))) { 62248f512ceSopenharmony_ci seen_idx |= BIT(index); 62348f512ceSopenharmony_ci HLOGV("ignoring address packet index: 0x%x\n", index); 62448f512ceSopenharmony_ci } 62548f512ceSopenharmony_ci } 62648f512ceSopenharmony_ci 62748f512ceSopenharmony_ci return payload; 62848f512ceSopenharmony_ci} 62948f512ceSopenharmony_ci 63048f512ceSopenharmony_cistruct SpeDecoder *SpeDecoderNew(struct SpeParams *params) 63148f512ceSopenharmony_ci{ 63248f512ceSopenharmony_ci CHECK_TRUE(params == nullptr, nullptr, 1, "Invalid pointer!"); 63348f512ceSopenharmony_ci struct SpeDecoder *decoder; 63448f512ceSopenharmony_ci 63548f512ceSopenharmony_ci decoder = static_cast<struct SpeDecoder*>(malloc(sizeof(struct SpeDecoder))); 63648f512ceSopenharmony_ci if (!decoder) { 63748f512ceSopenharmony_ci return NULL; 63848f512ceSopenharmony_ci } 63948f512ceSopenharmony_ci 64048f512ceSopenharmony_ci decoder->data = params->data; 64148f512ceSopenharmony_ci 64248f512ceSopenharmony_ci return decoder; 64348f512ceSopenharmony_ci} 64448f512ceSopenharmony_ci 64548f512ceSopenharmony_civoid SpeDecoderFree(struct SpeDecoder *decoder) 64648f512ceSopenharmony_ci{ 64748f512ceSopenharmony_ci CHECK_TRUE(decoder == nullptr, NO_RETVAL, 1, "Invalid pointer!"); 64848f512ceSopenharmony_ci free(decoder); 64948f512ceSopenharmony_ci} 65048f512ceSopenharmony_ci 65148f512ceSopenharmony_cistatic int SpeGetNextPacket(struct SpeDecoder *decoder) 65248f512ceSopenharmony_ci{ 65348f512ceSopenharmony_ci CHECK_TRUE(decoder == nullptr, -1, 1, "Invalid pointer!"); 65448f512ceSopenharmony_ci int ret = 1; 65548f512ceSopenharmony_ci 65648f512ceSopenharmony_ci do { 65748f512ceSopenharmony_ci if (!decoder->len) { 65848f512ceSopenharmony_ci /* Failed to read out trace data */ 65948f512ceSopenharmony_ci if (ret <= 0) { 66048f512ceSopenharmony_ci return ret; 66148f512ceSopenharmony_ci } 66248f512ceSopenharmony_ci } 66348f512ceSopenharmony_ci 66448f512ceSopenharmony_ci ret = SpeGetPacket(decoder->buf, decoder->len, 66548f512ceSopenharmony_ci &decoder->packet); 66648f512ceSopenharmony_ci if (ret <= 0) { 66748f512ceSopenharmony_ci /* Move forward for 1 byte */ 66848f512ceSopenharmony_ci decoder->buf += 1; 66948f512ceSopenharmony_ci decoder->len -= 1; 67048f512ceSopenharmony_ci return -EBADMSG; 67148f512ceSopenharmony_ci } 67248f512ceSopenharmony_ci 67348f512ceSopenharmony_ci decoder->buf += ret; 67448f512ceSopenharmony_ci decoder->len -= static_cast<size_t>(ret); 67548f512ceSopenharmony_ci } while (decoder->packet.type == PERF_SPE_PAD); 67648f512ceSopenharmony_ci return 1; 67748f512ceSopenharmony_ci} 67848f512ceSopenharmony_ci 67948f512ceSopenharmony_cistatic int SpeReadRecord(struct SpeDecoder *decoder) 68048f512ceSopenharmony_ci{ 68148f512ceSopenharmony_ci u64 payload; 68248f512ceSopenharmony_ci u64 ip; 68348f512ceSopenharmony_ci CHECK_TRUE(decoder == nullptr, -1, 1, "Invalid pointer!"); 68448f512ceSopenharmony_ci memset_s(&decoder->record, sizeof(decoder->record), 0, sizeof(decoder->record)); 68548f512ceSopenharmony_ci decoder->record.context_id = (u64)-1; 68648f512ceSopenharmony_ci 68748f512ceSopenharmony_ci while (true) { 68848f512ceSopenharmony_ci int err = SpeGetNextPacket(decoder); 68948f512ceSopenharmony_ci if (err <= 0) { 69048f512ceSopenharmony_ci return err; 69148f512ceSopenharmony_ci } 69248f512ceSopenharmony_ci 69348f512ceSopenharmony_ci int idx = decoder->packet.index; 69448f512ceSopenharmony_ci payload = decoder->packet.payload; 69548f512ceSopenharmony_ci 69648f512ceSopenharmony_ci switch (decoder->packet.type) { 69748f512ceSopenharmony_ci case PERF_SPE_TIMESTAMP: 69848f512ceSopenharmony_ci decoder->record.timestamp = payload; 69948f512ceSopenharmony_ci return 1; 70048f512ceSopenharmony_ci case PERF_SPE_END: 70148f512ceSopenharmony_ci return 1; 70248f512ceSopenharmony_ci case PERF_SPE_ADDRESS: 70348f512ceSopenharmony_ci ip = SpeCalcIp(idx, payload); 70448f512ceSopenharmony_ci if (idx == PERF_SPE_ADDR_PKT_HDR_INDEX_INS) { 70548f512ceSopenharmony_ci decoder->record.from_ip = ip; 70648f512ceSopenharmony_ci } else if (idx == PERF_SPE_ADDR_PKT_HDR_INDEX_BRANCH) { 70748f512ceSopenharmony_ci decoder->record.to_ip = ip; 70848f512ceSopenharmony_ci } else if (idx == PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) { 70948f512ceSopenharmony_ci decoder->record.virt_addr = ip; 71048f512ceSopenharmony_ci } else if (idx == PERF_SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) { 71148f512ceSopenharmony_ci decoder->record.phys_addr = ip; 71248f512ceSopenharmony_ci } 71348f512ceSopenharmony_ci break; 71448f512ceSopenharmony_ci case PERF_SPE_COUNTER: 71548f512ceSopenharmony_ci if (idx == PERF_SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT) { 71648f512ceSopenharmony_ci decoder->record.latency = payload; 71748f512ceSopenharmony_ci } 71848f512ceSopenharmony_ci break; 71948f512ceSopenharmony_ci case PERF_SPE_CONTEXT: 72048f512ceSopenharmony_ci decoder->record.context_id = payload; 72148f512ceSopenharmony_ci break; 72248f512ceSopenharmony_ci case PERF_SPE_OP_TYPE: 72348f512ceSopenharmony_ci switch (idx) { 72448f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC: 72548f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_LDST; 72648f512ceSopenharmony_ci if (payload & PERF_SPE_OP_PKT_ST) { 72748f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_ST; 72848f512ceSopenharmony_ci } else { 72948f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_LD; 73048f512ceSopenharmony_ci } 73148f512ceSopenharmony_ci 73248f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_LDST_SVE(payload)) { 73348f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_SVE_LDST; 73448f512ceSopenharmony_ci } 73548f512ceSopenharmony_ci break; 73648f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_OTHER: 73748f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_OTHER; 73848f512ceSopenharmony_ci if (PERF_SPE_OP_PKT_IS_OTHER_SVE_OP(payload)) { 73948f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_SVE_OTHER; 74048f512ceSopenharmony_ci } 74148f512ceSopenharmony_ci break; 74248f512ceSopenharmony_ci case PERF_SPE_OP_PKT_HDR_CLASS_BR_ERET: 74348f512ceSopenharmony_ci decoder->record.op |= PERF_SPE_OP_BRANCH_ERET; 74448f512ceSopenharmony_ci break; 74548f512ceSopenharmony_ci default: 74648f512ceSopenharmony_ci HLOGV("Get packet error!"); 74748f512ceSopenharmony_ci } 74848f512ceSopenharmony_ci break; 74948f512ceSopenharmony_ci case PERF_SPE_EVENTS: 75048f512ceSopenharmony_ci if (payload & BIT(EVENT_L1D_REFILL)) { 75148f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_L1D_MISS; 75248f512ceSopenharmony_ci } 75348f512ceSopenharmony_ci 75448f512ceSopenharmony_ci if (payload & BIT(EVENT_L1D_ACCESS)) { 75548f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_L1D_ACCESS; 75648f512ceSopenharmony_ci } 75748f512ceSopenharmony_ci 75848f512ceSopenharmony_ci if (payload & BIT(EVENT_TLB_WALK)) { 75948f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_TLB_MISS; 76048f512ceSopenharmony_ci } 76148f512ceSopenharmony_ci 76248f512ceSopenharmony_ci if (payload & BIT(EVENT_TLB_ACCESS)) { 76348f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_TLB_ACCESS; 76448f512ceSopenharmony_ci } 76548f512ceSopenharmony_ci 76648f512ceSopenharmony_ci if (payload & BIT(EVENT_LLC_MISS)) { 76748f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_LLC_MISS; 76848f512ceSopenharmony_ci } 76948f512ceSopenharmony_ci 77048f512ceSopenharmony_ci if (payload & BIT(EVENT_LLC_ACCESS)) { 77148f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_LLC_ACCESS; 77248f512ceSopenharmony_ci } 77348f512ceSopenharmony_ci 77448f512ceSopenharmony_ci if (payload & BIT(EVENT_REMOTE_ACCESS)) { 77548f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_REMOTE_ACCESS; 77648f512ceSopenharmony_ci } 77748f512ceSopenharmony_ci 77848f512ceSopenharmony_ci if (payload & BIT(EVENT_MISPRED)) { 77948f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_BRANCH_MISS; 78048f512ceSopenharmony_ci } 78148f512ceSopenharmony_ci 78248f512ceSopenharmony_ci if (payload & BIT(EVENT_PARTIAL_PREDICATE)) { 78348f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_SVE_PARTIAL_PRED; 78448f512ceSopenharmony_ci } 78548f512ceSopenharmony_ci 78648f512ceSopenharmony_ci if (payload & BIT(EVENT_EMPTY_PREDICATE)) { 78748f512ceSopenharmony_ci decoder->record.type |= PERF_SPE_SVE_EMPTY_PRED; 78848f512ceSopenharmony_ci } 78948f512ceSopenharmony_ci break; 79048f512ceSopenharmony_ci case PERF_SPE_DATA_SOURCE: 79148f512ceSopenharmony_ci decoder->record.source = payload; 79248f512ceSopenharmony_ci break; 79348f512ceSopenharmony_ci case PERF_SPE_BAD: 79448f512ceSopenharmony_ci break; 79548f512ceSopenharmony_ci case PERF_SPE_PAD: 79648f512ceSopenharmony_ci break; 79748f512ceSopenharmony_ci default: 79848f512ceSopenharmony_ci printf("Get packet error!\n"); 79948f512ceSopenharmony_ci return -1; 80048f512ceSopenharmony_ci } 80148f512ceSopenharmony_ci } 80248f512ceSopenharmony_ci return 0; 80348f512ceSopenharmony_ci} 80448f512ceSopenharmony_ci 80548f512ceSopenharmony_ciint SpeDecode(struct SpeDecoder *decoder) 80648f512ceSopenharmony_ci{ 80748f512ceSopenharmony_ci CHECK_TRUE(decoder == nullptr, -1, 1, "Invalid pointer!"); 80848f512ceSopenharmony_ci return SpeReadRecord(decoder); 80948f512ceSopenharmony_ci} 81048f512ceSopenharmony_ci 81148f512ceSopenharmony_cistruct SpeDecoder *SpeDecoderDataNew(const unsigned char *speBuf, size_t speLen) 81248f512ceSopenharmony_ci{ 81348f512ceSopenharmony_ci CHECK_TRUE(speBuf == nullptr, nullptr, 1, "Invalid pointer!"); 81448f512ceSopenharmony_ci struct SpeDecoder *decoder; 81548f512ceSopenharmony_ci 81648f512ceSopenharmony_ci decoder = reinterpret_cast<SpeDecoder *>(malloc(sizeof(struct SpeDecoder))); 81748f512ceSopenharmony_ci if (!decoder) { 81848f512ceSopenharmony_ci return NULL; 81948f512ceSopenharmony_ci } 82048f512ceSopenharmony_ci memset_s(decoder, sizeof(struct SpeDecoder), 0, sizeof(struct SpeDecoder)); 82148f512ceSopenharmony_ci 82248f512ceSopenharmony_ci decoder->buf = speBuf; 82348f512ceSopenharmony_ci decoder->len = speLen; 82448f512ceSopenharmony_ci 82548f512ceSopenharmony_ci return decoder; 82648f512ceSopenharmony_ci} 82748f512ceSopenharmony_ci 82848f512ceSopenharmony_cibool SpeDumpRawData(unsigned char *buf, size_t len, int indent, FILE *outputDump) 82948f512ceSopenharmony_ci{ 83048f512ceSopenharmony_ci CHECK_TRUE(buf == nullptr, false, 1, "Invalid pointer!"); 83148f512ceSopenharmony_ci if (outputDump != nullptr) { 83248f512ceSopenharmony_ci g_outputDump = outputDump; 83348f512ceSopenharmony_ci } 83448f512ceSopenharmony_ci struct SpePkt packet; 83548f512ceSopenharmony_ci size_t pos = 0; 83648f512ceSopenharmony_ci int pktLen; 83748f512ceSopenharmony_ci int i; 83848f512ceSopenharmony_ci char desc[PERF_SPE_PKT_DESC_MAX]; 83948f512ceSopenharmony_ci 84048f512ceSopenharmony_ci PRINT_INDENT(indent, ". ... ARM SPE data: size %#zx bytes\n", len); 84148f512ceSopenharmony_ci while (len) { 84248f512ceSopenharmony_ci int ret = SpeGetPacket(buf, len, &packet); 84348f512ceSopenharmony_ci if (ret > 0) { 84448f512ceSopenharmony_ci pktLen = ret; 84548f512ceSopenharmony_ci } else { 84648f512ceSopenharmony_ci pktLen = 1; 84748f512ceSopenharmony_ci } 84848f512ceSopenharmony_ci PRINT_INDENT(indent, "."); 84948f512ceSopenharmony_ci PRINT_INDENT(indent, " %08zx: ", pos); 85048f512ceSopenharmony_ci for (i = 0; i < pktLen; i++) { 85148f512ceSopenharmony_ci PRINT_INDENT(indent, " %02x", buf[i]); 85248f512ceSopenharmony_ci } 85348f512ceSopenharmony_ci for (; i < 16; i++) { // 16 : space 85448f512ceSopenharmony_ci PRINT_INDENT(indent, " "); 85548f512ceSopenharmony_ci } 85648f512ceSopenharmony_ci if (ret > 0) { 85748f512ceSopenharmony_ci ret = SpePktDesc(&packet, desc, 85848f512ceSopenharmony_ci PERF_SPE_PKT_DESC_MAX); 85948f512ceSopenharmony_ci if (!ret) { 86048f512ceSopenharmony_ci PRINT_INDENT(indent, " %s\n", desc); 86148f512ceSopenharmony_ci } 86248f512ceSopenharmony_ci } else { 86348f512ceSopenharmony_ci PRINT_INDENT(indent, " Bad packet!\n"); 86448f512ceSopenharmony_ci } 86548f512ceSopenharmony_ci pos += static_cast<size_t>(pktLen); 86648f512ceSopenharmony_ci buf += pktLen; 86748f512ceSopenharmony_ci if (len >= static_cast<size_t>(pktLen)) { 86848f512ceSopenharmony_ci len -= static_cast<size_t>(pktLen); 86948f512ceSopenharmony_ci } else { 87048f512ceSopenharmony_ci break; 87148f512ceSopenharmony_ci } 87248f512ceSopenharmony_ci } 87348f512ceSopenharmony_ci return true; 87448f512ceSopenharmony_ci} 87548f512ceSopenharmony_ci 87648f512ceSopenharmony_cistd::map<u32, std::map<u64, ReportItemAuxRawData>> AuxRawDataMap_; 87748f512ceSopenharmony_cistd::map<u32, u64> typeCount; 87848f512ceSopenharmony_ci 87948f512ceSopenharmony_ciconst std::vector<u32> DEFAULT_SPE_EVENT_TYPE = { 88048f512ceSopenharmony_ci PERF_SPE_L1D_ACCESS, 88148f512ceSopenharmony_ci PERF_SPE_L1D_MISS, 88248f512ceSopenharmony_ci PERF_SPE_LLC_ACCESS, 88348f512ceSopenharmony_ci PERF_SPE_LLC_MISS, 88448f512ceSopenharmony_ci PERF_SPE_TLB_ACCESS, 88548f512ceSopenharmony_ci PERF_SPE_TLB_MISS, 88648f512ceSopenharmony_ci PERF_SPE_BRANCH_MISS, 88748f512ceSopenharmony_ci PERF_SPE_REMOTE_ACCESS, 88848f512ceSopenharmony_ci PERF_SPE_SVE_PARTIAL_PRED, 88948f512ceSopenharmony_ci PERF_SPE_SVE_EMPTY_PRED, 89048f512ceSopenharmony_ci}; 89148f512ceSopenharmony_ci 89248f512ceSopenharmony_ciconstexpr const int SPE_PERCENTAGE_COMM_LEN = 40; 89348f512ceSopenharmony_ciconstexpr const int SPE_PERCENTAGE_PC_LEN = 18; 89448f512ceSopenharmony_ciconstexpr const int SPE_PERCENTAGE_DSO_LEN = 50; 89548f512ceSopenharmony_ciconstexpr const int SPE_PERCENTAGE_FUNC_LEN = 60; 89648f512ceSopenharmony_ciconstexpr const int SPE_PERCENTAGE_OFFSET_LEN = 20; 89748f512ceSopenharmony_ci 89848f512ceSopenharmony_civoid AddReportItems(const std::vector<ReportItemAuxRawData>& auxRawData) 89948f512ceSopenharmony_ci{ 90048f512ceSopenharmony_ci for (const auto& data : auxRawData) { 90148f512ceSopenharmony_ci for (auto type : DEFAULT_SPE_EVENT_TYPE) { 90248f512ceSopenharmony_ci if (data.type & type) { 90348f512ceSopenharmony_ci if (typeCount.count(type) == 0) { 90448f512ceSopenharmony_ci typeCount[type] = 1; 90548f512ceSopenharmony_ci } else { 90648f512ceSopenharmony_ci typeCount[type]++; 90748f512ceSopenharmony_ci } 90848f512ceSopenharmony_ci std::map<u64, ReportItemAuxRawData>& map = AuxRawDataMap_[type]; 90948f512ceSopenharmony_ci 91048f512ceSopenharmony_ci auto data1 = map.find(data.pc); 91148f512ceSopenharmony_ci if (data1 == map.end()) { 91248f512ceSopenharmony_ci HLOGV("add %llx", data.pc); 91348f512ceSopenharmony_ci map[data.pc] = {type, 0.0f, 1, data.comm, data.pc, data.SharedObject, data.Symbol, data.offset}; 91448f512ceSopenharmony_ci } else { 91548f512ceSopenharmony_ci HLOGV("add pc: %llx", data.pc); 91648f512ceSopenharmony_ci data1->second.count++; 91748f512ceSopenharmony_ci HLOGV("add pc: %llx count: %llu", data.pc, data1->second.count); 91848f512ceSopenharmony_ci } 91948f512ceSopenharmony_ci } 92048f512ceSopenharmony_ci } 92148f512ceSopenharmony_ci } 92248f512ceSopenharmony_ci} 92348f512ceSopenharmony_ci 92448f512ceSopenharmony_civoid UpdateHeating() 92548f512ceSopenharmony_ci{ 92648f512ceSopenharmony_ci for (auto it = AuxRawDataMap_.begin(); it != AuxRawDataMap_.end(); it++) { 92748f512ceSopenharmony_ci u64 cc = typeCount[it->first]; 92848f512ceSopenharmony_ci for (auto& it2 : it->second) { 92948f512ceSopenharmony_ci float heating = (float)it2.second.count / cc * FULL_PERCENTAGE; 93048f512ceSopenharmony_ci HLOGV("heating %llu/%llu %f", it2.second.count, cc, heating); 93148f512ceSopenharmony_ci it2.second.heating = heating; 93248f512ceSopenharmony_ci } 93348f512ceSopenharmony_ci } 93448f512ceSopenharmony_ci} 93548f512ceSopenharmony_ci 93648f512ceSopenharmony_civoid GetSpeEventNameByType(uint32_t type, std::string& eventName) 93748f512ceSopenharmony_ci{ 93848f512ceSopenharmony_ci switch (type) { 93948f512ceSopenharmony_ci case PERF_SPE_L1D_ACCESS: 94048f512ceSopenharmony_ci eventName = "l1d-access"; 94148f512ceSopenharmony_ci break; 94248f512ceSopenharmony_ci case PERF_SPE_L1D_MISS: 94348f512ceSopenharmony_ci eventName = "l1d-miss"; 94448f512ceSopenharmony_ci break; 94548f512ceSopenharmony_ci case PERF_SPE_LLC_ACCESS: 94648f512ceSopenharmony_ci eventName = "llc-access"; 94748f512ceSopenharmony_ci break; 94848f512ceSopenharmony_ci case PERF_SPE_LLC_MISS: 94948f512ceSopenharmony_ci eventName = "llc-miss"; 95048f512ceSopenharmony_ci break; 95148f512ceSopenharmony_ci case PERF_SPE_TLB_ACCESS: 95248f512ceSopenharmony_ci eventName = "tlb-access"; 95348f512ceSopenharmony_ci break; 95448f512ceSopenharmony_ci case PERF_SPE_TLB_MISS: 95548f512ceSopenharmony_ci eventName = "tlb-miss"; 95648f512ceSopenharmony_ci break; 95748f512ceSopenharmony_ci case PERF_SPE_BRANCH_MISS: 95848f512ceSopenharmony_ci eventName = "branch-miss"; 95948f512ceSopenharmony_ci break; 96048f512ceSopenharmony_ci case PERF_SPE_REMOTE_ACCESS: 96148f512ceSopenharmony_ci eventName = "remote-access"; 96248f512ceSopenharmony_ci break; 96348f512ceSopenharmony_ci case PERF_SPE_SVE_PARTIAL_PRED: 96448f512ceSopenharmony_ci eventName = "paritial_read"; 96548f512ceSopenharmony_ci break; 96648f512ceSopenharmony_ci case PERF_SPE_SVE_EMPTY_PRED: 96748f512ceSopenharmony_ci eventName = "empty_read"; 96848f512ceSopenharmony_ci break; 96948f512ceSopenharmony_ci default: 97048f512ceSopenharmony_ci eventName = "unknow"; 97148f512ceSopenharmony_ci return; 97248f512ceSopenharmony_ci } 97348f512ceSopenharmony_ci} 97448f512ceSopenharmony_ci 97548f512ceSopenharmony_civoid DumpSpeReportHead(int indent, uint32_t type, uint64_t count) 97648f512ceSopenharmony_ci{ 97748f512ceSopenharmony_ci std::string eventName = ""; 97848f512ceSopenharmony_ci GetSpeEventNameByType(type, eventName); 97948f512ceSopenharmony_ci PRINT_INDENT(indent, "\nEvent :%s\n", eventName.c_str()); 98048f512ceSopenharmony_ci PRINT_INDENT(indent, "Samples Count: %" PRIu64 "\n", count); 98148f512ceSopenharmony_ci 98248f512ceSopenharmony_ci // head print 98348f512ceSopenharmony_ci const std::string head = "Heating"; 98448f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s ", FULL_PERCENTAGE_LEN, head.c_str()); 98548f512ceSopenharmony_ci const std::string eventCount = " count"; 98648f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s ", FULL_PERCENTAGE_LEN, eventCount.c_str()); 98748f512ceSopenharmony_ci const std::string comm = " comm"; 98848f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s ", SPE_PERCENTAGE_COMM_LEN, comm.c_str()); 98948f512ceSopenharmony_ci const std::string pc = " PC"; 99048f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s ", SPE_PERCENTAGE_PC_LEN, pc.c_str()); 99148f512ceSopenharmony_ci const std::string dso = " dso"; 99248f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s ", SPE_PERCENTAGE_DSO_LEN, dso.c_str()); 99348f512ceSopenharmony_ci const std::string func = " func"; 99448f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s", SPE_PERCENTAGE_FUNC_LEN, func.c_str()); 99548f512ceSopenharmony_ci const std::string offset = " offset"; 99648f512ceSopenharmony_ci PRINT_INDENT(indent, "%-*s\n", SPE_PERCENTAGE_OFFSET_LEN, offset.c_str()); 99748f512ceSopenharmony_ci return; 99848f512ceSopenharmony_ci} 99948f512ceSopenharmony_ci 100048f512ceSopenharmony_civoid DumpSpeReportData(int indent, FILE *outputDump) 100148f512ceSopenharmony_ci{ 100248f512ceSopenharmony_ci if (outputDump != nullptr) { 100348f512ceSopenharmony_ci g_outputDump = outputDump; 100448f512ceSopenharmony_ci } 100548f512ceSopenharmony_ci if (AuxRawDataMap_.empty()) { 100648f512ceSopenharmony_ci return; 100748f512ceSopenharmony_ci } 100848f512ceSopenharmony_ci PRINT_INDENT(indent, "\n ==== Spe Report Data ====\n"); 100948f512ceSopenharmony_ci for (auto it = AuxRawDataMap_.begin(); it != AuxRawDataMap_.end(); it++) { 101048f512ceSopenharmony_ci u64 count = typeCount[it->first]; 101148f512ceSopenharmony_ci DumpSpeReportHead(indent, it->first, count); 101248f512ceSopenharmony_ci for (auto& it2 : it->second) { 101348f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "%*.2f%% ", FULL_PERCENTAGE_LEN, it2.second.heating); 101448f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "%-*llu ", FULL_PERCENTAGE_LEN, it2.second.count); 101548f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "%-*s ", SPE_PERCENTAGE_COMM_LEN, it2.second.comm.c_str()); 101648f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%-*llx ", SPE_PERCENTAGE_PC_LEN, it2.second.pc); 101748f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "%-*s ", SPE_PERCENTAGE_DSO_LEN, it2.second.SharedObject.c_str()); 101848f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "%-*s", SPE_PERCENTAGE_FUNC_LEN, it2.second.Symbol.c_str()); 101948f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%llx\n", it2.second.offset); 102048f512ceSopenharmony_ci } 102148f512ceSopenharmony_ci } 102248f512ceSopenharmony_ci} 102348f512ceSopenharmony_ci} // namespace HiPerf 102448f512ceSopenharmony_ci} // namespace Developtools 102548f512ceSopenharmony_ci} // namespace OHOS 1026