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_res_specs.h"
12 :
13 : #include "hccp_ctx.h"
14 : #include "hccl_common.h"
15 : #include "hcomm_adapter_hccp.h"
16 :
17 : namespace hcomm {
18 :
19 12685 : CcuResSpecifications& CcuResSpecifications::GetInstance(const int32_t deviceLogicId)
20 : {
21 : static CcuResSpecifications ccuResSpecifications[MAX_MODULE_DEVICE_NUM + 1];
22 12685 : int32_t devLogicId = deviceLogicId;
23 12685 : if (devLogicId < 0 || static_cast<uint32_t>(devLogicId) >= MAX_MODULE_DEVICE_NUM) {
24 0 : HCCL_WARNING(
25 : "[CcuResSpecifications][%s] use the backup device, devLogicId[%d] "
26 : "should be less than %u.",
27 : __func__, devLogicId, MAX_MODULE_DEVICE_NUM);
28 0 : devLogicId = MAX_MODULE_DEVICE_NUM; // 使用备份设备
29 : }
30 12685 : ccuResSpecifications[devLogicId].devLogicId_ = devLogicId;
31 12685 : return ccuResSpecifications[devLogicId];
32 : }
33 :
34 1 : static CcuVersion CheckCcuVersion(int32_t devLogicId)
35 : {
36 1 : CustomChannelInfoIn inBuff{};
37 1 : CustomChannelInfoOut outBuff{};
38 1 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_VERSION;
39 1 : inBuff.offsetStartIdx = 0;
40 1 : inBuff.data.dataInfo.udieIdx = 0; // 查询版本访问任意die均可
41 :
42 1 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
43 1 : if (ret != 0) {
44 0 : HCCL_ERROR(
45 : "[%s] failed to call ccu driver, "
46 : "devLogicId[%d], op[%s].",
47 : __func__, devLogicId, "GET_CCU_VERSION");
48 0 : return CcuVersion::CCU_INVALID;
49 : }
50 1 : const CcuVersionEnum ccuVersionEnum = outBuff.data.dataInfo.dataArray[0].ccuVersion;
51 :
52 : static const std::unordered_map<int, CcuVersion> ccuVersionMap
53 : = {{static_cast<int>(CcuVersionEnum::CCU_V1), CcuVersion::CCU_V1},
54 3 : {static_cast<int>(CcuVersionEnum::CCU_V2), CcuVersion::CCU_V2}};
55 :
56 1 : const auto& iter = ccuVersionMap.find(static_cast<int>(ccuVersionEnum));
57 1 : if (iter == ccuVersionMap.end()) {
58 0 : HCCL_ERROR(
59 : "[CcuResSpecifications][%s] failed, ccu driver version[%d] "
60 : "is invalid, devLogicId[%d].",
61 : __func__, static_cast<int>(ccuVersionEnum), devLogicId);
62 0 : return CcuVersion::CCU_INVALID;
63 : }
64 :
65 1 : return iter->second;
66 : }
67 :
68 2 : static bool CheckDieEnable(const uint32_t devLogicId, const uint8_t dieId)
69 : {
70 2 : CustomChannelInfoIn inBuff{};
71 2 : CustomChannelInfoOut outBuff{};
72 2 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_DIE_WORKING;
73 2 : inBuff.offsetStartIdx = 0;
74 2 : inBuff.data.dataInfo.udieIdx = dieId;
75 :
76 2 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
77 2 : if (ret != HCCL_SUCCESS) {
78 0 : HCCL_ERROR(
79 : "[CcuResSpecifications][%s] failed to call ccu driver, "
80 : "devLogicId[%d] dieId[%d] op[%s] ret[%d].",
81 : __func__, devLogicId, dieId, "GET_DIE_WORKING", ret);
82 0 : return false;
83 : }
84 :
85 2 : const uint32_t enableFlag = outBuff.data.dataInfo.dataArray[0].dieinfo.enableFlag;
86 2 : return enableFlag == Hccl::CCU_ENABLE_FLAG;
87 : }
88 :
89 0 : static CcuBaseInfoData ParseOutBuffToBaseInfoData(const CustomChannelInfoOut& outBuff)
90 : {
91 0 : CcuBaseInfoData baseInfoData{};
92 0 : baseInfoData.resourceAddr = outBuff.data.dataInfo.dataArray[0].baseinfo.resourceAddr;
93 0 : baseInfoData.missionKey = outBuff.data.dataInfo.dataArray[0].baseinfo.missionKey;
94 0 : baseInfoData.msId = outBuff.data.dataInfo.dataArray[0].baseinfo.msId;
95 0 : baseInfoData.caps.cap0 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap0;
96 0 : baseInfoData.caps.cap1 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap1;
97 0 : baseInfoData.caps.cap2 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap2;
98 0 : baseInfoData.caps.cap3 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap3;
99 0 : baseInfoData.caps.cap4 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap4;
100 0 : return baseInfoData;
101 : }
102 :
103 0 : static CcuResSpecInfo ParseOutBuffToResSpecInfo(const CcuVersion ccuVersion, const CustomChannelInfoOut& outBuff)
104 : {
105 0 : if (ccuVersion == CcuVersion::CCU_INVALID || ccuVersion == CcuVersion::INVALID) {
106 0 : HCCL_WARNING(
107 : "[CcuResSpecifications][%s] failed to parse out buff, ccu driver "
108 : "version[%s] is not expected.",
109 : __func__, ccuVersion.Describe().c_str());
110 0 : return {};
111 : }
112 :
113 0 : const auto& baseInfoData = ParseOutBuffToBaseInfoData(outBuff);
114 :
115 0 : CcuResSpecInfo ccuResSpecInfo{};
116 :
117 0 : ccuResSpecInfo.msId = baseInfoData.msId;
118 0 : ccuResSpecInfo.resourceAddr = baseInfoData.resourceAddr;
119 0 : ccuResSpecInfo.missionKey = baseInfoData.missionKey;
120 :
121 0 : ccuResSpecInfo.instructionNum = (baseInfoData.caps.cap0 & 0x0000FFFF) + 1;
122 0 : ccuResSpecInfo.xnNum = ((baseInfoData.caps.cap1 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
123 0 : ccuResSpecInfo.msNum = ((baseInfoData.caps.cap2 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
124 0 : ccuResSpecInfo.ckeNum = (baseInfoData.caps.cap2 & 0x0000FFFF) + 1;
125 0 : ccuResSpecInfo.jettyNum = ((baseInfoData.caps.cap3 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
126 0 : ccuResSpecInfo.channelNum = (baseInfoData.caps.cap3 & 0x0000FFFF) + 1;
127 0 : ccuResSpecInfo.pfeNum = (baseInfoData.caps.cap4 & 0x000000FF) + 1;
128 :
129 0 : if (ccuVersion == CcuVersion::CCU_V1) {
130 0 : ccuResSpecInfo.missionNum = ((baseInfoData.caps.cap0 >> MOVE_16_BITS) & 0x000000FF) + 1;
131 0 : ccuResSpecInfo.loopEngineNum = ((baseInfoData.caps.cap0 >> MOVE_24_BITS) & 0x000000FF) + 1;
132 0 : ccuResSpecInfo.gsaNum = (baseInfoData.caps.cap1 & 0x0000FFFF) + 1;
133 0 : return ccuResSpecInfo;
134 : }
135 :
136 0 : ccuResSpecInfo.loopEngineNum = ((baseInfoData.caps.cap0 >> MOVE_20_BITS) & 0x00000FFF) + 1;
137 0 : ccuResSpecInfo.missionNum = ((baseInfoData.caps.cap0 >> MOVE_16_BITS) & 0x0000000F) + 1;
138 0 : ccuResSpecInfo.gsaNum = 0; // v2废弃字段,固定为0;
139 :
140 : // loop cke 数量与loop一致,与cke数量寄存器隔离
141 : // loop cke 从全局 cke 划分后半部分,资源不足时cke为0
142 0 : HCCL_INFO(
143 : "ParseOutBuffToResSpecInfo, loopEngineNum[%u], ckeNum[%u]", ccuResSpecInfo.loopEngineNum,
144 : ccuResSpecInfo.ckeNum);
145 0 : if (ccuResSpecInfo.loopEngineNum < ccuResSpecInfo.ckeNum) {
146 0 : HCCL_INFO("ccuResSpecInfo.loopEngineNum < ccuResSpecInfo.ckeNum");
147 0 : ccuResSpecInfo.loopCkeNum = ccuResSpecInfo.loopEngineNum; // ccu v2 loop cke要求与loop静态对应
148 : } else {
149 0 : HCCL_INFO("ccuResSpecInfo.loopEngineNum >= ccuResSpecInfo.ckeNum");
150 0 : ccuResSpecInfo.ckeNum = 0; // cke资源信息错误
151 : }
152 :
153 : // count xn 从全局xn划分后半部分,资源不足时count xn为0
154 0 : if (ccuResSpecInfo.xnNum > CCU_V2_COUNT_XN_NUM) {
155 0 : ccuResSpecInfo.xnNum -= CCU_V2_COUNT_XN_NUM;
156 0 : ccuResSpecInfo.countXnNum = CCU_V2_COUNT_XN_NUM;
157 : }
158 :
159 0 : HCCL_INFO(
160 : "[CcuResSpecifications][%s] msId[%u] resourceAddr[%llx] channelJettyMap[%u, %u].", __func__,
161 : ccuResSpecInfo.msId, ccuResSpecInfo.resourceAddr, ccuResSpecInfo.channelJettyMap.channelNum,
162 : ccuResSpecInfo.channelJettyMap.jettyNum);
163 0 : return ccuResSpecInfo;
164 : }
165 :
166 0 : static HcclResult CheckResSpecifications(
167 : const int32_t devLogicId, const uint8_t dieId, const CcuVersion ccuVersion, CcuResSpecInfo& resSpecs)
168 : {
169 0 : CustomChannelInfoIn inBuff{};
170 0 : CustomChannelInfoOut outBuff{};
171 0 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_BASIC_INFO;
172 0 : inBuff.offsetStartIdx = 0;
173 0 : inBuff.data.dataInfo.udieIdx = dieId;
174 :
175 0 : auto ret = HccpRaTlvCcuCustomChannel(devLogicId, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
176 0 : if (ret != HCCL_SUCCESS) {
177 0 : HCCL_ERROR(
178 : "[CcuResSpecifications][%s] failed to call ccu driver, "
179 : "devLogicId[%d] dieId[%d] op[%s] ret[%d].",
180 : __func__, devLogicId, dieId, "GET_BASIC_INFO", ret);
181 0 : return ret;
182 : }
183 0 : resSpecs = ParseOutBuffToResSpecInfo(ccuVersion, outBuff);
184 0 : return HcclResult::HCCL_SUCCESS;
185 : }
186 :
187 : /*
188 : * 获取Mainboard ID 5-7位,输出整机形态枚举值
189 : * Mainboard ID描述说明
190 : * Mainboard ID采用了16bit,区分形态,主从,以及端口配置
191 : * bit[7:5] 区分整机形态(当前POD和EVB没有区分A+X或A+K)
192 : * {
193 : * 000: 天成 POD
194 : * 001: A+K Server
195 : * 010: A+X Server
196 : * 011: PCIE标卡
197 : * 100-101: RSV
198 : * 110: 装备
199 : * 111: EVB
200 : * }
201 : * bit[4:1] 整机形态细分
202 : * {
203 : * 0000-1111
204 : * }
205 : * bit[0] 主从或池化
206 : * {
207 : * 0: 主从(NPU作为某个Host的从设备,Host主控)
208 : * 1: 池化(NPU作为资源池,其它Host对等访问)
209 : * }
210 : */
211 : constexpr uint64_t POD_MAINBOARD = 0x0;
212 : constexpr uint64_t A_K_SERVER_MAINBOARD = 0x1;
213 : constexpr uint64_t A_X_SERVER_MAINBOARD = 0x2;
214 : constexpr uint64_t PCIE_STD_MAINBOARD = 0x3;
215 : constexpr uint64_t RSV1_MAINBOARD = 0x4;
216 : constexpr uint64_t RSV2_MAINBOARD = 0x5;
217 : constexpr uint64_t EQUIP_MAINBOARD = 0x6;
218 : constexpr uint64_t EVB_MAINBOARD = 0x7;
219 : const std::unordered_map<uint64_t, Hccl::HcclMainboardId> rtMainboardIdToHcclMainboardId
220 : = {{POD_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_POD},
221 : {A_K_SERVER_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_A_K_SERVER},
222 : {A_X_SERVER_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_A_X_SERVER},
223 : {PCIE_STD_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_PCIE_STD},
224 : {RSV1_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_RSV},
225 : {RSV2_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_RSV},
226 : {EQUIP_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_EQUIPMENT},
227 : {EVB_MAINBOARD, Hccl::HcclMainboardId::MAINBOARD_EVB}};
228 :
229 2 : HcclResult CcuGetMainboardId(uint32_t deviceLogicId, Hccl::HcclMainboardId& hcclMainboardId)
230 : {
231 2 : constexpr aclrtDevAttr devAttr = aclrtDevAttr::ACL_DEV_ATTR_MAINBOARD_ID;
232 2 : constexpr uint64_t BITS_5 = 5;
233 2 : constexpr uint64_t MASK_7 = 0x7;
234 2 : int64_t val = 0;
235 2 : auto ret = aclrtGetDeviceInfo(deviceLogicId, devAttr, &val);
236 2 : if (ret != RT_ERROR_NONE) {
237 0 : HCCL_ERROR(
238 : "[%s]errNo[0x%016llx] rt get device info failed, "
239 : "deviceLogicId=%u, devAttr=%d",
240 : __func__, HCCL_ERROR_CODE(HcclResult::HCCL_E_RUNTIME), deviceLogicId, devAttr);
241 0 : return HcclResult::HCCL_E_RUNTIME;
242 : }
243 :
244 2 : HCCL_INFO("[%s] deviceLogicId[%u] val[%lld].", __func__, deviceLogicId, static_cast<long long>(val));
245 2 : uint64_t mainboardId = (static_cast<uint64_t>(val) >> BITS_5) & MASK_7; // 提取val的5-7位,判断整机形态
246 2 : hcclMainboardId = Hccl::HcclMainboardId::MAINBOARD_OTHERS;
247 2 : auto it = rtMainboardIdToHcclMainboardId.find(mainboardId);
248 2 : if (it != rtMainboardIdToHcclMainboardId.end()) {
249 2 : hcclMainboardId = it->second;
250 : }
251 2 : HCCL_INFO(
252 : "[%s] deviceLogicId[%u] mainboardId[%llu] hcclMainboardId[%s].", __func__, deviceLogicId,
253 : static_cast<unsigned long long>(mainboardId), hcclMainboardId.Describe().c_str());
254 2 : return HcclResult::HCCL_SUCCESS;
255 : }
256 :
257 1 : static HcclResult CheckServeMode(int32_t devLogicId, ServeMode& serveMode)
258 : {
259 1 : Hccl::HcclMainboardId hcclMainboardId{Hccl::HcclMainboardId::MAINBOARD_RSV};
260 1 : CHK_RET(CcuGetMainboardId(devLogicId, hcclMainboardId));
261 1 : if (hcclMainboardId == Hccl::HcclMainboardId::MAINBOARD_A_X_SERVER
262 1 : || hcclMainboardId == Hccl::HcclMainboardId::MAINBOARD_PCIE_STD) {
263 0 : serveMode = ServeMode::ARMX86;
264 : } else {
265 1 : serveMode = ServeMode::NORMAL;
266 : }
267 1 : HCCL_INFO(
268 : "[CcuResSpecifications][%s] devLogicId[%d] "
269 : "hcclMainboardId[%s] serveMode_[%d].",
270 : __func__, devLogicId, hcclMainboardId.Describe().c_str(), static_cast<int>(serveMode));
271 1 : return HcclResult::HCCL_SUCCESS;
272 : }
273 :
274 69 : HcclResult CcuResSpecifications::Init()
275 : {
276 69 : if (initFlag_) {
277 68 : return HcclResult::HCCL_SUCCESS;
278 : }
279 :
280 1 : CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(devLogicId_), devPhyId_));
281 1 : CHK_RET(CheckServeMode(devLogicId_, serveMode_));
282 1 : ccuVersion_ = CheckCcuVersion(devLogicId_);
283 1 : if (ccuVersion_ == CcuVersion::CCU_INVALID) {
284 0 : HCCL_WARNING("[CcuResSpecifications][%s] check ccu version failed.", __func__);
285 0 : return HcclResult::HCCL_E_UNAVAIL;
286 : }
287 3 : for (uint8_t dieId = 0; dieId < CCU_MAX_IODIE_NUM; dieId++) {
288 2 : dieEnableFlags_[dieId] = CheckDieEnable(devLogicId_, dieId);
289 2 : if (!dieEnableFlags_[dieId]) {
290 2 : resSpecs_[dieId] = CcuResSpecInfo{};
291 2 : continue;
292 : }
293 :
294 0 : CHK_RET(CheckResSpecifications(devLogicId_, dieId, ccuVersion_, resSpecs_[dieId]));
295 : }
296 :
297 1 : initFlag_ = true;
298 1 : return HcclResult::HCCL_SUCCESS;
299 : }
300 :
301 174 : HcclResult CcuResSpecifications::Deinit()
302 : {
303 522 : for (uint32_t i = 0; i < CCU_MAX_IODIE_NUM; i++) {
304 348 : dieEnableFlags_[i] = false;
305 348 : resSpecs_[i] = CcuResSpecInfo{};
306 : }
307 :
308 174 : serveMode_ = ServeMode::ARMX86;
309 174 : initFlag_ = false;
310 174 : return HcclResult::HCCL_SUCCESS;
311 : }
312 :
313 6382 : CcuVersion CcuResSpecifications::GetCcuVersion() const { return ccuVersion_; }
314 :
315 8781 : HcclResult CcuResSpecifications::CheckDieValid(
316 : const std::string& funcName, const int32_t devLogicId, const uint8_t dieId,
317 : const std::array<bool, CCU_MAX_IODIE_NUM>& dieEnableFlags) const
318 : {
319 8781 : CHK_PRT_RET(
320 : dieId >= CCU_MAX_IODIE_NUM,
321 : HCCL_ERROR(
322 : "[%s] failed, dieId[%u] is invalid, should be in [0-%u), devLogicId[%d].", funcName.c_str(), dieId,
323 : CCU_MAX_IODIE_NUM, devLogicId),
324 : HcclResult::HCCL_E_PARA);
325 :
326 8779 : CHK_PRT_RET(
327 : !dieEnableFlags[dieId],
328 : HCCL_WARNING("[%s] failed, dieId[%u] is disable, devLogicId[%d].", funcName.c_str(), dieId, devLogicId),
329 : HcclResult::HCCL_E_PARA);
330 :
331 8778 : return HcclResult::HCCL_SUCCESS;
332 : }
333 :
334 398 : HcclResult CcuResSpecifications::GetDieEnableFlag(const uint8_t dieId, bool& dieEnableFlag) const
335 : {
336 : // 只校验dieId合法性,不校验die是否使能
337 1194 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, {true, true}));
338 397 : dieEnableFlag = dieEnableFlags_[dieId];
339 397 : return HcclResult::HCCL_SUCCESS;
340 : }
341 :
342 197 : ServeMode CcuResSpecifications::GetServeMode() const { return serveMode_; }
343 :
344 426 : HcclResult CcuResSpecifications::GetResourceAddr(const uint8_t dieId, uint64_t& resourceAddr) const
345 : {
346 1278 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
347 424 : resourceAddr = resSpecs_[dieId].resourceAddr;
348 424 : return HcclResult::HCCL_SUCCESS;
349 : }
350 :
351 3427 : HcclResult CcuResSpecifications::GetXnBaseAddr(const uint8_t dieId, uint64_t& xnBaseAddr) const
352 : {
353 : // xn位于ins与gsa之后,xn偏移 = CCUM偏移 + 指令空间大小 + GSA大小,常量计算不会溢出
354 3427 : constexpr uint64_t instrRevserveSize = CCU_RESOURCE_INS_RESERVE_SIZE;
355 3427 : constexpr uint64_t gsaReserveSize = CCU_V1_RESOURCE_GSA_RESERVE_SIZE;
356 :
357 10281 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
358 3427 : const uint64_t ccuResAddr = resSpecs_[dieId].resourceAddr;
359 3427 : if (ccuResAddr == 0) {
360 1 : HCCL_ERROR(
361 : "[CcuResSpecifications][%s] failed, CCU resource base address is 0, "
362 : "devLogicId[%d] dieId[%u].",
363 : __func__, devLogicId_, dieId);
364 1 : return HcclResult::HCCL_E_INTERNAL;
365 : }
366 :
367 3426 : uint64_t ccum_offset = 0;
368 3426 : uint32_t ccuXnOffset = 0;
369 3426 : if (ccuVersion_ == CcuVersion::CCU_V1) {
370 2465 : ccum_offset = CCU_V1_CCUM_OFFSET;
371 2465 : ccuXnOffset = ccum_offset + instrRevserveSize + gsaReserveSize;
372 961 : } else if (ccuVersion_ == CcuVersion::CCU_V2) {
373 961 : ccum_offset = CCU_V2_CCUM_OFFSET;
374 961 : ccuXnOffset = ccum_offset + instrRevserveSize;
375 : } else {
376 0 : HCCL_ERROR(
377 : "[CcuResSpecifications][%s]current version[%s] not support", __func__, ccuVersion_.Describe().c_str());
378 0 : return HcclResult::HCCL_E_INTERNAL;
379 : }
380 :
381 3426 : if (ccuResAddr > UINT64_MAX - ccuXnOffset) {
382 0 : HCCL_ERROR(
383 : "[CcuResSpecifications][%s] failed, CCU resource base address[0x%llx] is "
384 : "greater than expected, ccu xn offset[%u], their sum will exceed the range "
385 : "of uint64_t.",
386 : __func__, static_cast<unsigned long long>(ccuResAddr), ccuXnOffset);
387 0 : return HcclResult::HCCL_E_INTERNAL;
388 : }
389 :
390 3426 : xnBaseAddr = ccuResAddr + ccuXnOffset;
391 3426 : return HcclResult::HCCL_SUCCESS;
392 : }
393 :
394 2 : HcclResult CcuResSpecifications::GetCkeBaseAddr(const uint8_t dieId, uint64_t& ckeBaseAddr) const
395 : {
396 2 : constexpr uint64_t instrRevserveSize = CCU_RESOURCE_INS_RESERVE_SIZE;
397 2 : constexpr uint64_t gsaReserveSize = CCU_V1_RESOURCE_GSA_RESERVE_SIZE;
398 2 : constexpr uint64_t xnReserveSizeV1 = CCU_RESOURCE_XN_V1_RESERVE_SIZE;
399 2 : constexpr uint64_t xnReserveSizeV2 = CCU_RESOURCE_XN_V2_RESERVE_SIZE;
400 :
401 6 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
402 2 : const uint64_t ccuResAddr = resSpecs_[dieId].resourceAddr;
403 2 : if (ccuResAddr == 0) {
404 0 : HCCL_ERROR(
405 : "[CcuResSpecifications][%s] failed, CCU resource base address is 0, "
406 : "devLogicId[%d] dieId[%u].",
407 : __func__, devLogicId_, dieId);
408 0 : return HcclResult::HCCL_E_INTERNAL;
409 : }
410 :
411 2 : uint64_t ccum_offset = CCU_V1_CCUM_OFFSET;
412 2 : uint32_t ccuCkeOffset = 0;
413 : // ccuCkeOffset 为常量计算,不涉及溢出
414 2 : if (ccuVersion_ == CcuVersion::CCU_V1) {
415 1 : ccuCkeOffset = ccum_offset + instrRevserveSize + gsaReserveSize + xnReserveSizeV1;
416 1 : } else if (ccuVersion_ == CcuVersion::CCU_V2) {
417 1 : ccum_offset = CCU_V2_CCUM_OFFSET;
418 1 : ccuCkeOffset = ccum_offset + instrRevserveSize + xnReserveSizeV2;
419 : } else {
420 0 : HCCL_ERROR(
421 : "[CcuResSpecifications][%s]current version[%s] not support", __func__, ccuVersion_.Describe().c_str());
422 0 : return HcclResult::HCCL_E_INTERNAL;
423 : }
424 :
425 2 : if (ccuResAddr > UINT64_MAX - ccuCkeOffset) {
426 0 : HCCL_ERROR(
427 : "[CcuResSpecifications][%s] failed, CCU resource base address[0x%llx] is "
428 : "greater than expected, ccu cke offset[%u], their sum will exceed the range "
429 : "of uint64_t.",
430 : __func__, static_cast<unsigned long long>(ccuResAddr), ccuCkeOffset);
431 0 : return HcclResult::HCCL_E_INTERNAL;
432 : }
433 2 : ckeBaseAddr = ccuResAddr + ccuCkeOffset;
434 2 : HCCL_DEBUG(
435 : "[CcuResSpecifications][%s] devLogicId[%d], dieId[%u], ckeBaseAddr[0x%llx]", __func__, devLogicId_, dieId,
436 : ckeBaseAddr);
437 2 : return HcclResult::HCCL_SUCCESS;
438 : }
439 :
440 4 : uint64_t CcuResSpecifications::GetXnOffsetCcumBaseAddr(const uint8_t dieId) const
441 : {
442 4 : CHK_PRT_RET(
443 : dieId >= CCU_MAX_IODIE_NUM || !dieEnableFlags_[dieId],
444 : HCCL_ERROR("[CcuResSpecifications][GetCcuMBaseAddr] devLogicId[%d], dieId[%u] is invalid.", devLogicId_, dieId),
445 : INVALID_ADDR);
446 3 : uint64_t xnOffsetCcumBaseAddr{0};
447 3 : if (ccuVersion_ == CcuVersion::CCU_V1) {
448 : xnOffsetCcumBaseAddr
449 1 : = CCU_RESOURCE_INS_RESERVE_SIZE + CCU_V1_RESOURCE_GSA_RESERVE_SIZE; // CCUM + 1M Instruction + 32K GSA
450 2 : } else if (ccuVersion_ == CcuVersion::CCU_V2) {
451 2 : xnOffsetCcumBaseAddr = CCU_RESOURCE_INS_RESERVE_SIZE; // CCUM + 1M Instruction
452 : } else {
453 0 : xnOffsetCcumBaseAddr = 0;
454 : }
455 3 : HCCL_DEBUG(
456 : "[CcuResSpecifications][%s] devLogicId[%d], dieId[%u], xnOffsetCcumBaseAddr[0x%llx]", __func__, devLogicId_,
457 : dieId, xnOffsetCcumBaseAddr);
458 3 : return xnOffsetCcumBaseAddr;
459 : }
460 :
461 2 : static HcclResult CheckResOffsetAddrIsValid(uint32_t id, uint64_t baseAddr, uint32_t resoucePerSize)
462 : {
463 2 : if (baseAddr == INVALID_ADDR) {
464 0 : HCCL_ERROR("[CcuResSpecifications][%s] failed, base addr is invalid.", __func__);
465 0 : return HcclResult::HCCL_E_INTERNAL;
466 : }
467 :
468 2 : if (id > UINT32_MAX / resoucePerSize) {
469 0 : HCCL_ERROR("[CcuResSpecifications][%s] failed, id[%u] is invalid.", __func__, id);
470 0 : return HcclResult::HCCL_E_PARA;
471 : }
472 :
473 2 : return HcclResult::HCCL_SUCCESS;
474 : }
475 :
476 1 : HcclResult CcuResSpecifications::GetXnOffsetCcumAddrById(const uint8_t dieId, uint32_t id, uint64_t& xnAddr) const
477 : {
478 1 : uint64_t xnBaseAddr = GetXnOffsetCcumBaseAddr(dieId);
479 1 : CHK_RET(CheckResOffsetAddrIsValid(id, xnBaseAddr, CCU_RESOURCE_XN_PER_SIZE));
480 :
481 1 : xnAddr = xnBaseAddr + id * CCU_RESOURCE_XN_PER_SIZE;
482 1 : HCCL_DEBUG(
483 : "[CcuResSpecifications][%s] devLogicId[%d], dieId[%u], xnBaseAddr[0x%llx], xn[%d][0x%llx]", __func__,
484 : devLogicId_, dieId, xnBaseAddr, id, xnAddr);
485 1 : return HcclResult::HCCL_SUCCESS;
486 : }
487 :
488 3 : uint64_t CcuResSpecifications::GetCkeOffsetCcumBaseAddr(const uint8_t dieId) const
489 : {
490 3 : CHK_PRT_RET(
491 : dieId >= CCU_MAX_IODIE_NUM || !dieEnableFlags_[dieId],
492 : HCCL_ERROR("[CcuResSpecifications][GetCcuMBaseAddr] devLogicId[%d], dieId[%u] is invalid.", devLogicId_, dieId),
493 : INVALID_ADDR);
494 :
495 3 : uint64_t ckeBaseAddr{0};
496 3 : if (ccuVersion_ == CcuVersion::CCU_V1) {
497 1 : ckeBaseAddr = CCU_RESOURCE_INS_RESERVE_SIZE + CCU_V1_RESOURCE_GSA_RESERVE_SIZE
498 : + CCU_RESOURCE_XN_V1_RESERVE_SIZE; // CCUM + 1M Instruction + 32K GSA + 32K Xn
499 2 : } else if (ccuVersion_ == CcuVersion::CCU_V2) {
500 : ckeBaseAddr
501 2 : = CCU_RESOURCE_INS_RESERVE_SIZE + CCU_RESOURCE_XN_V2_RESERVE_SIZE; // CCUM + 1M Instruction + 256K Xn
502 : } else {
503 0 : ckeBaseAddr = INVALID_ADDR;
504 : }
505 3 : HCCL_DEBUG(
506 : "[CcuResSpecifications][%s] devLogicId[%d], dieId[%u], ckeBaseAddr[0x%llx]", __func__, devLogicId_, dieId,
507 : ckeBaseAddr);
508 3 : return ckeBaseAddr;
509 : }
510 :
511 1 : HcclResult CcuResSpecifications::GetCkeOffsetCcumAddrById(const uint8_t dieId, uint32_t id, uint64_t& ckeAddr) const
512 : {
513 1 : uint64_t ckeBaseAddr = GetCkeOffsetCcumBaseAddr(dieId);
514 1 : CHK_RET(CheckResOffsetAddrIsValid(id, ckeBaseAddr, CCU_RESOURCE_CKE_PER_SIZE));
515 :
516 1 : ckeAddr = ckeBaseAddr + id * CCU_RESOURCE_CKE_PER_SIZE;
517 1 : HCCL_DEBUG(
518 : "[CcuResSpecifications][%s] devLogicId[%d], dieId[%u], ckeBaseAddr[0x%llx], ckeAddr[%d][0x%llx]", __func__,
519 : devLogicId_, dieId, ckeBaseAddr, id, ckeAddr);
520 1 : return HcclResult::HCCL_SUCCESS;
521 : }
522 :
523 201 : HcclResult CcuResSpecifications::GetMsId(const uint8_t dieId, uint32_t& msId) const
524 : {
525 603 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
526 201 : msId = resSpecs_[dieId].msId;
527 201 : return HcclResult::HCCL_SUCCESS;
528 : }
529 :
530 45 : HcclResult CcuResSpecifications::GetMissionKey(const uint8_t dieId, uint32_t& missionKey) const
531 : {
532 135 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
533 45 : missionKey = resSpecs_[dieId].missionKey;
534 45 : return HcclResult::HCCL_SUCCESS;
535 : }
536 :
537 233 : HcclResult CcuResSpecifications::GetInstructionNum(const uint8_t dieId, uint32_t& instrNum) const
538 : {
539 699 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
540 233 : instrNum = resSpecs_[dieId].instructionNum;
541 233 : return HcclResult::HCCL_SUCCESS;
542 : }
543 :
544 405 : HcclResult CcuResSpecifications::GetMissionNum(const uint8_t dieId, uint32_t& missionNum) const
545 : {
546 1215 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
547 405 : missionNum = resSpecs_[dieId].missionNum;
548 405 : return HcclResult::HCCL_SUCCESS;
549 : }
550 :
551 403 : HcclResult CcuResSpecifications::GetLoopEngineNum(const uint8_t dieId, uint32_t& loopNum) const
552 : {
553 1209 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
554 403 : loopNum = resSpecs_[dieId].loopEngineNum;
555 403 : return HcclResult::HCCL_SUCCESS;
556 : }
557 :
558 373 : HcclResult CcuResSpecifications::GetGsaNum(const uint8_t dieId, uint32_t& gsaNum) const
559 : {
560 1119 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
561 373 : gsaNum = resSpecs_[dieId].gsaNum;
562 373 : return HcclResult::HCCL_SUCCESS;
563 : }
564 :
565 613 : HcclResult CcuResSpecifications::GetXnNum(const uint8_t dieId, uint32_t& xnNum) const
566 : {
567 1839 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
568 613 : xnNum = resSpecs_[dieId].xnNum;
569 613 : return HcclResult::HCCL_SUCCESS;
570 : }
571 :
572 421 : HcclResult CcuResSpecifications::GetCountXnNum(const uint8_t dieId, uint32_t& countXnNum) const
573 : {
574 1263 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
575 421 : countXnNum = resSpecs_[dieId].countXnNum;
576 421 : return HcclResult::HCCL_SUCCESS;
577 : }
578 :
579 403 : HcclResult CcuResSpecifications::GetCkeNum(const uint8_t dieId, uint32_t& ckeNum) const
580 : {
581 1209 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
582 403 : ckeNum = resSpecs_[dieId].ckeNum;
583 403 : return HcclResult::HCCL_SUCCESS;
584 : }
585 :
586 1 : HcclResult CcuResSpecifications::GetLoopCkeNum(const uint8_t dieId, uint32_t& loopCkeNum) const
587 : {
588 3 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
589 1 : loopCkeNum = resSpecs_[dieId].loopCkeNum;
590 1 : return HcclResult::HCCL_SUCCESS;
591 : }
592 :
593 403 : HcclResult CcuResSpecifications::GetMsNum(const uint8_t dieId, uint32_t& msNum) const
594 : {
595 1209 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
596 403 : msNum = resSpecs_[dieId].msNum;
597 403 : return HcclResult::HCCL_SUCCESS;
598 : }
599 :
600 212 : HcclResult CcuResSpecifications::GetChannelNum(const uint8_t dieId, uint32_t& channelNum) const
601 : {
602 636 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
603 212 : channelNum = resSpecs_[dieId].channelNum;
604 212 : return HcclResult::HCCL_SUCCESS;
605 : }
606 :
607 285 : HcclResult CcuResSpecifications::GetJettyNum(const uint8_t dieId, uint32_t& jettyNum) const
608 : {
609 855 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
610 285 : jettyNum = resSpecs_[dieId].jettyNum;
611 285 : return HcclResult::HCCL_SUCCESS;
612 : }
613 :
614 202 : HcclResult CcuResSpecifications::GetPfeReservedNum(const uint8_t dieId, uint32_t& pfeNum) const
615 : {
616 606 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
617 202 : if (ccuVersion_ == CcuVersion::CCU_V1) {
618 171 : pfeNum = CCU_V1_PER_DIE_PFE_RESERVED_NUM;
619 171 : return HcclResult::HCCL_SUCCESS;
620 : }
621 31 : pfeNum = CCU_V2_PER_DIE_PFE_RESERVED_NUM;
622 31 : return HcclResult::HCCL_SUCCESS;
623 : }
624 :
625 1 : HcclResult CcuResSpecifications::GetPfeNum(const uint8_t dieId, uint32_t& pfeNum) const
626 : {
627 3 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
628 1 : pfeNum = resSpecs_[dieId].pfeNum;
629 1 : return HcclResult::HCCL_SUCCESS;
630 : }
631 :
632 232 : HcclResult CcuResSpecifications::GetWqeBBNum(const uint8_t dieId, uint32_t& wqeBBNum) const
633 : {
634 696 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
635 232 : wqeBBNum = resSpecs_[dieId].wqeBBNum;
636 232 : return HcclResult::HCCL_SUCCESS;
637 : }
638 :
639 95 : HcclResult CcuResSpecifications::GetChannelJettyMap(const uint8_t dieId, CcuChannelJettyMap& channelJettyMap) const
640 : {
641 285 : CHK_RET(CheckDieValid(__func__, devLogicId_, dieId, dieEnableFlags_));
642 95 : channelJettyMap = resSpecs_[dieId].channelJettyMap;
643 95 : return HcclResult::HCCL_SUCCESS;
644 : }
645 : } // namespace hcomm
|