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