Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "ccu_dfx_schema.h"
12 :
13 : #include "securec.h"
14 : #include "log.h"
15 : #include "ccu_error_info_v1.h"
16 : #include "ccu_error_info_v2.h"
17 : #include "adapter_rts_common.h"
18 :
19 : namespace hcomm {
20 : namespace {
21 : struct CcumDfxCommonInfo {
22 : unsigned int ccumSqeRecvCnt;
23 : unsigned int ccumSqeSendCnt;
24 : unsigned int ccumMissionDfx;
25 : unsigned int ccumSqeDropCnt;
26 : unsigned int ccumSqeAddrLenErrDropCnt;
27 : unsigned int lqcCcuSecReg0;
28 : unsigned int ccumTifSqeCnt;
29 : unsigned int ccumTifCqeCnt;
30 : unsigned int ccumCifSqeCnt;
31 : unsigned int ccumCifCqeCnt;
32 : };
33 :
34 : struct ccumDfxInfo {
35 : unsigned int queryResult; // 0:success, 1:fail
36 : CcumDfxCommonInfo commonInfo;
37 : };
38 :
39 : struct ccumDfxInfoV2 {
40 : union {
41 : struct {
42 : unsigned int queryResult : 1; // 0:success, 1:fail
43 : unsigned int sqeRecvCnt : 1;
44 : unsigned int sqeSendCnt : 1;
45 : unsigned int missionDfx : 1;
46 : unsigned int sqeDropCnt : 1;
47 : unsigned int sqeErrDropCnt : 1;
48 : unsigned int secReg0 : 1;
49 : unsigned int tifSqeCnt : 1;
50 : unsigned int tifCqeCnt : 1;
51 : unsigned int cifSqeCnt : 1;
52 : unsigned int cifCqeCnt : 1;
53 : unsigned int mcmDfx : 1;
54 : unsigned int resv : 20;
55 : } bs;
56 : unsigned int validBits : 32;
57 : };
58 : union {
59 : struct {
60 : CcumDfxCommonInfo commonInfo;
61 : unsigned int ccumMcmDfx;
62 : unsigned int resv[20];
63 : } dfxInfo;
64 : unsigned int regVal[31];
65 : };
66 : };
67 3 : void PrintCcumDfxInfoV1(const void* rawData, std::ostringstream& oss)
68 : {
69 3 : if (rawData == nullptr) {
70 1 : oss << " [rawData is null]";
71 1 : HCCL_ERROR("[PrintCcumDfxInfoV1] rawData is null");
72 1 : return;
73 : }
74 2 : struct ccumDfxInfo info {};
75 2 : const auto copyRet = memcpy_s(&info, sizeof(info), rawData, sizeof(info));
76 2 : if (copyRet != EOK) {
77 0 : oss << " [decode failed]";
78 0 : HCCL_ERROR("[PrintCcumDfxInfoV1] memcpy_s failed, ret[%d]", copyRet);
79 0 : return;
80 : }
81 2 : if (info.queryResult != 0U) {
82 1 : HCCL_ERROR("get ccu dfx info fail, ccu dfx info not all correct");
83 : }
84 2 : oss << " SQE_RECV_CNT[" << info.commonInfo.ccumSqeRecvCnt << ']';
85 2 : oss << " SQE_SEND_CNT[" << info.commonInfo.ccumSqeSendCnt << ']';
86 2 : oss << " MISSION_DFX[" << info.commonInfo.ccumMissionDfx << ']';
87 2 : oss << " TIF_SQE_CNT[" << info.commonInfo.ccumTifSqeCnt << ']';
88 2 : oss << " TIF_CQE_CNT[" << info.commonInfo.ccumTifCqeCnt << ']';
89 2 : oss << " CIF_SQE_CNT[" << info.commonInfo.ccumCifSqeCnt << ']';
90 2 : oss << " CIF_CQE_CNT[" << info.commonInfo.ccumCifCqeCnt << ']';
91 2 : oss << " SQE_DROP_CNT[" << info.commonInfo.ccumSqeDropCnt << ']';
92 2 : oss << " SQE_ADDR_LEN_ERR_DROP_CNT[" << info.commonInfo.ccumSqeAddrLenErrDropCnt << ']';
93 2 : oss << " ccumIsEnable[" << (info.commonInfo.lqcCcuSecReg0 & 1U) << ']';
94 : }
95 :
96 5 : void PrintCcumDfxInfoV2(const void* rawData, std::ostringstream& oss)
97 : {
98 5 : if (rawData == nullptr) {
99 1 : oss << " [rawData is null]";
100 1 : HCCL_ERROR("[PrintCcumDfxInfoV2] rawData is null");
101 1 : return;
102 : }
103 4 : struct ccumDfxInfoV2 info {};
104 4 : const auto copyRet = memcpy_s(&info, sizeof(info), rawData, sizeof(info));
105 4 : if (copyRet != EOK) {
106 0 : oss << " [decode failed]";
107 0 : HCCL_ERROR("[PrintCcumDfxInfoV2] memcpy_s failed, ret[%d]", copyRet);
108 0 : return;
109 : }
110 4 : if (info.bs.queryResult != 0U) {
111 1 : HCCL_ERROR("get ccu dfx info fail, ccu dfx info not all correct");
112 : }
113 44 : auto dump = [&oss](const char* name, unsigned int value, bool hwValid) {
114 44 : oss << ' ' << name << '[';
115 44 : if (hwValid) {
116 32 : oss << value;
117 : } else {
118 12 : oss << "INVALID(hardware)";
119 12 : HCCL_WARNING("[CCU DFX][V2] %s marked invalid by hardware", name);
120 : }
121 44 : oss << ']';
122 48 : };
123 4 : dump("SQE_RECV_CNT", info.dfxInfo.commonInfo.ccumSqeRecvCnt, info.bs.sqeRecvCnt != 0U);
124 4 : dump("SQE_SEND_CNT", info.dfxInfo.commonInfo.ccumSqeSendCnt, info.bs.sqeSendCnt != 0U);
125 4 : dump("MISSION_DFX", info.dfxInfo.commonInfo.ccumMissionDfx, info.bs.missionDfx != 0U);
126 4 : dump("TIF_SQE_CNT", info.dfxInfo.commonInfo.ccumTifSqeCnt, info.bs.tifSqeCnt != 0U);
127 4 : dump("TIF_CQE_CNT", info.dfxInfo.commonInfo.ccumTifCqeCnt, info.bs.tifCqeCnt != 0U);
128 4 : dump("CIF_SQE_CNT", info.dfxInfo.commonInfo.ccumCifSqeCnt, info.bs.cifSqeCnt != 0U);
129 4 : dump("CIF_CQE_CNT", info.dfxInfo.commonInfo.ccumCifCqeCnt, info.bs.cifCqeCnt != 0U);
130 4 : dump("SQE_DROP_CNT", info.dfxInfo.commonInfo.ccumSqeDropCnt, info.bs.sqeDropCnt != 0U);
131 4 : dump(
132 4 : "SQE_ADDR_LEN_ERR_DROP_CNT", info.dfxInfo.commonInfo.ccumSqeAddrLenErrDropCnt, info.bs.sqeErrDropCnt != 0U);
133 4 : dump("ccumIsEnable", info.dfxInfo.commonInfo.lqcCcuSecReg0 & 1U, info.bs.secReg0 != 0U);
134 4 : dump("MCM_DFX", info.dfxInfo.ccumMcmDfx, info.bs.mcmDfx != 0U);
135 : }
136 :
137 3 : HcclResult GetCcuMissionInfoV1(const void* rawData, CcuMissionInfo* out)
138 : {
139 3 : if (rawData == nullptr || out == nullptr) {
140 2 : HCCL_ERROR("[GetCcuMissionInfoV1] invalid input: rawData=%p, out=%p", rawData, out);
141 2 : return HCCL_E_PARA;
142 : }
143 1 : CcuMissionContext ctx{};
144 1 : const auto copyRet = memcpy_s(&ctx, sizeof(ctx), rawData, sizeof(ctx));
145 1 : if (copyRet != EOK) {
146 0 : HCCL_ERROR("[GetCcuMissionInfoV1] memcpy_s failed, ret[%d]", copyRet);
147 0 : return HCCL_E_INTERNAL;
148 : }
149 1 : out->currentIns = ctx.GetCurrentIns();
150 1 : out->endIns = ctx.GetEndIns();
151 1 : out->startIns = ctx.GetStartIns();
152 1 : return HCCL_SUCCESS;
153 : }
154 :
155 3 : HcclResult GetCcuLoopInfoV1(const void* rawData, CcuLoopInfo* out)
156 : {
157 3 : if (rawData == nullptr || out == nullptr) {
158 2 : HCCL_ERROR("[GetCcuLoopInfoV1] invalid input: rawData=%p, out=%p", rawData, out);
159 2 : return HCCL_E_PARA;
160 : }
161 1 : CcuLoopContext ctx{};
162 1 : const auto copyRet = memcpy_s(&ctx, sizeof(ctx), rawData, sizeof(ctx));
163 1 : if (copyRet != EOK) {
164 0 : HCCL_ERROR("[GetCcuLoopInfoV1] memcpy_s failed, ret[%d]", copyRet);
165 0 : return HCCL_E_INTERNAL;
166 : }
167 1 : out->currentCnt = ctx.GetCurrentCnt();
168 1 : out->addrStride = ctx.GetAddrStride();
169 1 : return HCCL_SUCCESS;
170 : }
171 :
172 3 : HcclResult GetCcuMissionInfoV2(const void* rawData, CcuMissionInfo* out)
173 : {
174 3 : if (rawData == nullptr || out == nullptr) {
175 2 : HCCL_ERROR("[GetCcuMissionInfoV2] invalid input: rawData=%p, out=%p", rawData, out);
176 2 : return HCCL_E_PARA;
177 : }
178 :
179 1 : CcuMissionContextV2 ctx{};
180 1 : const auto copyRet = memcpy_s(&ctx, sizeof(ctx), rawData, sizeof(ctx));
181 1 : if (copyRet != EOK) {
182 0 : HCCL_ERROR("[GetCcuMissionInfoV2] memcpy_s failed, ret[%d]", copyRet);
183 0 : return HCCL_E_INTERNAL;
184 : }
185 1 : out->currentIns = ctx.GetCurrentIns();
186 1 : out->endIns = ctx.GetEndIns();
187 1 : out->startIns = ctx.GetStartIns();
188 1 : return HCCL_SUCCESS;
189 : }
190 :
191 3 : HcclResult GetCcuLoopInfoV2(const void* rawData, CcuLoopInfo* out)
192 : {
193 3 : if (rawData == nullptr || out == nullptr) {
194 2 : HCCL_ERROR("[GetCcuLoopInfoV2] invalid input: rawData=%p, out=%p", rawData, out);
195 2 : return HCCL_E_PARA;
196 : }
197 :
198 1 : CcuLoopContextV2 ctx{};
199 1 : const auto copyRet = memcpy_s(&ctx, sizeof(ctx), rawData, sizeof(ctx));
200 1 : if (copyRet != EOK) {
201 0 : HCCL_ERROR("[GetCcuLoopInfoV2] memcpy_s failed, ret[%d]", copyRet);
202 0 : return HCCL_E_INTERNAL;
203 : }
204 1 : out->currentCnt = ctx.GetCurrentCnt();
205 1 : out->addrStride = ctx.GetAddrStride();
206 :
207 1 : return HCCL_SUCCESS;
208 : }
209 :
210 : enum class CcuSchemaVersion : uint8_t { CCU_SCHEMA_V1 = 0, CCU_SCHEMA_V2 = 1, CCU_SCHEMA_COUNT = 2 };
211 :
212 : const CcuVersionOps CCU_V1_OPS = {
213 : "CCU_V1",
214 : PrintCcumDfxInfoV1,
215 : GetCcuMissionInfoV1,
216 : GetCcuLoopInfoV1,
217 : };
218 :
219 : const CcuVersionOps CCU_V2_OPS = {
220 : "CCU_V2",
221 : PrintCcumDfxInfoV2,
222 : GetCcuMissionInfoV2,
223 : GetCcuLoopInfoV2,
224 : };
225 :
226 : const CcuVersionOps* const CCU_OPS_TABLE[] = {
227 : &CCU_V1_OPS, // [0] V1
228 : &CCU_V2_OPS, // [1] V2
229 : };
230 :
231 : // 编译期校验:ops 表下标必须与 CcuSchemaVersion 枚举值一一对应,
232 : // 后续新增 schema 版本时若漏改表项会立即编译失败。
233 : static_assert(
234 : sizeof(CCU_OPS_TABLE) / sizeof(CCU_OPS_TABLE[0]) == static_cast<size_t>(CcuSchemaVersion::CCU_SCHEMA_COUNT),
235 : "CCU_OPS_TABLE size must match CcuSchemaVersion::CCU_SCHEMA_COUNT");
236 :
237 34 : HcclResult GetCcuSchemaVersion(CcuSchemaVersion& schemaVersion)
238 : {
239 34 : DevType deviceType = DevType::DEV_TYPE_COUNT;
240 34 : HcclResult ret = hrtGetDeviceType(deviceType);
241 34 : if (ret != HCCL_SUCCESS) {
242 2 : HCCL_ERROR("[GetCcuSchemaVersion] hrtGetDeviceType failed, ret[%d].", ret);
243 2 : return ret;
244 : }
245 32 : if (deviceType == DevType::DEV_TYPE_950) {
246 10 : schemaVersion = CcuSchemaVersion::CCU_SCHEMA_V1;
247 22 : } else if (deviceType == DevType::DEV_TYPE_960) {
248 12 : schemaVersion = CcuSchemaVersion::CCU_SCHEMA_V2;
249 : } else {
250 10 : HCCL_ERROR(
251 : "[GetCcuSchemaVersion] Unsupported deviceType[%u], only 950/960 supported.",
252 : static_cast<uint32_t>(deviceType));
253 10 : return HCCL_E_INTERNAL;
254 : }
255 22 : return HCCL_SUCCESS;
256 : }
257 :
258 22 : HcclResult ResolveCcuOps(CcuSchemaVersion schemaVersion, const CcuVersionOps*& ops)
259 : {
260 22 : const uint8_t versionIdx = static_cast<uint8_t>(schemaVersion);
261 22 : const size_t tableSize = sizeof(CCU_OPS_TABLE) / sizeof(CCU_OPS_TABLE[0]);
262 22 : if (versionIdx >= tableSize || CCU_OPS_TABLE[versionIdx] == nullptr) {
263 0 : HCCL_ERROR("[ResolveCcuOps] Invalid schema version[%u], table_size[%zu].", versionIdx, tableSize);
264 0 : ops = nullptr;
265 0 : return HCCL_E_INTERNAL;
266 : }
267 :
268 22 : ops = CCU_OPS_TABLE[versionIdx];
269 22 : return HCCL_SUCCESS;
270 : }
271 :
272 : } // namespace
273 :
274 34 : HcclResult GetCcuOps(const CcuVersionOps*& ops)
275 : {
276 34 : ops = nullptr;
277 34 : CcuSchemaVersion schemaVersion = CcuSchemaVersion::CCU_SCHEMA_COUNT;
278 34 : const HcclResult ret = GetCcuSchemaVersion(schemaVersion);
279 34 : if (ret != HCCL_SUCCESS) {
280 12 : HCCL_ERROR("[GetCcuOps] GetCcuSchemaVersion failed, ret[%d].", ret);
281 12 : return ret;
282 : }
283 :
284 22 : const HcclResult resolveRet = ResolveCcuOps(schemaVersion, ops);
285 22 : if (resolveRet != HCCL_SUCCESS) {
286 0 : return resolveRet;
287 : }
288 22 : return HCCL_SUCCESS;
289 : }
290 : } // namespace hcomm
|