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_legacy.h"
12 :
13 : #include "hccl_common_v2.h"
14 : #include "orion_adapter_rts.h"
15 : #include "orion_adapter_hccp.h"
16 : #include "ccu_device_manager.h"
17 : #include "hccp_tlv_hdc_manager.h"
18 :
19 : namespace Hccl {
20 :
21 307 : CcuResSpecifications& CcuResSpecifications::GetInstance(const int32_t deviceLogicId)
22 : {
23 : static CcuResSpecifications ccuResSpecifications[MAX_MODULE_DEVICE_NUM + 1];
24 307 : if (deviceLogicId < 0 || static_cast<uint32_t>(deviceLogicId) > MAX_MODULE_DEVICE_NUM) {
25 0 : THROW<InvalidParamsException>(StringFormat(
26 : "[CcuResSpecifications][GetInstance] Failed to get instance. "
27 : "devLogicId should be less than %u.",
28 : MAX_MODULE_DEVICE_NUM));
29 : }
30 :
31 307 : ccuResSpecifications[deviceLogicId].devLogicId = deviceLogicId;
32 :
33 307 : return ccuResSpecifications[deviceLogicId];
34 : }
35 :
36 11 : void CcuResSpecifications::Init()
37 : {
38 11 : if (ifInit) {
39 0 : return;
40 : }
41 :
42 11 : if (Init_() != HcclResult::HCCL_SUCCESS) {
43 0 : devPhyId = MAX_MODULE_DEVICE_NUM;
44 0 : ccuVersion = CcuVersion::CCU_INVALID;
45 0 : for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
46 0 : dieEnableFlags[i] = false;
47 0 : resSpecs[i] = CcuResSpecInfo{};
48 : }
49 : }
50 :
51 11 : ifInit = true;
52 : }
53 :
54 2 : void CcuResSpecifications::Deinit()
55 : {
56 6 : for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
57 4 : dieEnableFlags[i] = false;
58 4 : resSpecs[i] = CcuResSpecInfo{};
59 : }
60 :
61 2 : ifInit = false;
62 2 : }
63 :
64 11 : static CcuVersion CheckCcuVersion()
65 : {
66 11 : return CcuVersion::CCU_V1; // CCU驱动未更新前临时使用
67 : }
68 :
69 22 : static bool CheckDieEnable(const int32_t devLogicId, const uint8_t dieId)
70 : {
71 22 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
72 22 : CHECK_NULLPTR(tlvHandle, StringFormat("[%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
73 22 : struct CustomChannelInfoIn inBuff;
74 22 : struct CustomChannelInfoOut outBuff;
75 22 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_DIE_WORKING;
76 22 : inBuff.offsetStartIdx = 0;
77 22 : inBuff.data.dataInfo.udieIdx = dieId;
78 :
79 22 : HrtRaTlvRequestForCustomChannel(
80 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
81 :
82 22 : const uint32_t enableFlag = outBuff.data.dataInfo.dataArray[0].dieinfo.enableFlag;
83 22 : return enableFlag == CCU_ENABLE_FLAG;
84 : }
85 :
86 6 : static CcuBaseInfoData ParseOutBuffToBaseInfoData(const CustomChannelInfoOut& outBuff)
87 : {
88 6 : CcuBaseInfoData baseInfoData{};
89 6 : baseInfoData.resourceAddr = outBuff.data.dataInfo.dataArray[0].baseinfo.resourceAddr;
90 6 : baseInfoData.missionKey = outBuff.data.dataInfo.dataArray[0].baseinfo.missionKey;
91 6 : baseInfoData.msId = outBuff.data.dataInfo.dataArray[0].baseinfo.msId;
92 6 : baseInfoData.caps.cap0 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap0;
93 6 : baseInfoData.caps.cap1 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap1;
94 6 : baseInfoData.caps.cap2 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap2;
95 6 : baseInfoData.caps.cap3 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap3;
96 6 : baseInfoData.caps.cap4 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap4;
97 6 : return baseInfoData;
98 : }
99 :
100 6 : static CcuResSpecInfo ParseOutBuffToResSpecInfo(const CcuVersion ccuVersion, const CustomChannelInfoOut& outBuff)
101 : {
102 6 : if (ccuVersion != CcuVersion::CCU_V1) {
103 0 : HCCL_WARNING(
104 : "[CcuResSpecifications][%s] failed to parse out buff, ccu driver "
105 : "version[%s] is not expected.",
106 : __func__, ccuVersion.Describe().c_str());
107 0 : return {};
108 : }
109 :
110 6 : const auto& baseInfoData = ParseOutBuffToBaseInfoData(outBuff);
111 :
112 6 : CcuResSpecInfo ccuResSpecInfo{};
113 6 : ccuResSpecInfo.msId = baseInfoData.msId;
114 6 : ccuResSpecInfo.resourceAddr = baseInfoData.resourceAddr;
115 6 : ccuResSpecInfo.missionKey = baseInfoData.missionKey;
116 :
117 6 : ccuResSpecInfo.instructionNum = (baseInfoData.caps.cap0 & 0x0000FFFF) + 1;
118 6 : ccuResSpecInfo.xnNum = ((baseInfoData.caps.cap1 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
119 6 : ccuResSpecInfo.msNum = ((baseInfoData.caps.cap2 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
120 6 : ccuResSpecInfo.ckeNum = (baseInfoData.caps.cap2 & 0x0000FFFF) + 1;
121 6 : ccuResSpecInfo.jettyNum = ((baseInfoData.caps.cap3 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
122 6 : ccuResSpecInfo.channelNum = (baseInfoData.caps.cap3 & 0x0000FFFF) + 1;
123 6 : ccuResSpecInfo.pfeNum = (baseInfoData.caps.cap4 & 0x000000FF) + 1;
124 :
125 6 : ccuResSpecInfo.missionNum = ((baseInfoData.caps.cap0 >> MOVE_16_BITS) & 0x000000FF) + 1;
126 6 : ccuResSpecInfo.loopEngineNum = ((baseInfoData.caps.cap0 >> MOVE_24_BITS) & 0x000000FF) + 1;
127 6 : ccuResSpecInfo.gsaNum = (baseInfoData.caps.cap1 & 0x0000FFFF) + 1;
128 6 : return ccuResSpecInfo;
129 : }
130 :
131 6 : static CcuResSpecInfo CheckResSpecifications(const int32_t devLogicId, const uint8_t dieId, const CcuVersion ccuVersion)
132 : {
133 6 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
134 6 : CHECK_NULLPTR(tlvHandle, StringFormat("[%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
135 6 : struct CustomChannelInfoIn inBuff;
136 6 : struct CustomChannelInfoOut outBuff;
137 6 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_BASIC_INFO;
138 6 : inBuff.offsetStartIdx = 0;
139 6 : inBuff.data.dataInfo.udieIdx = dieId;
140 :
141 6 : HrtRaTlvRequestForCustomChannel(
142 : tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
143 12 : return ParseOutBuffToResSpecInfo(ccuVersion, outBuff);
144 : }
145 :
146 11 : HcclResult CcuResSpecifications::Init_()
147 : {
148 66 : TRY_CATCH_RETURN(devPhyId = HrtGetDevicePhyIdByIndex(devLogicId); ccuVersion = CheckCcuVersion();
149 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
150 : auto memTypeBitmap = GetCombinedMemTypeBitmap(); auto count = GetMemTypeVector().size();
151 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
152 : dieEnableFlags[dieId] = CheckDieEnable(devLogicId, dieId);
153 : if (!dieEnableFlags[dieId]) {
154 : resSpecs[dieId] = CcuResSpecInfo{};
155 : continue;
156 : }
157 : resSpecs[dieId] = CheckResSpecifications(devLogicId, dieId, ccuVersion);
158 : HrtGetCcuMemInfo(tlvHandle, dieId, memTypeBitmap, resSpecs[dieId].memInfoList.data(), count);
159 : } HcclMainboardId hcclMainboardId;
160 : CHK_RET(HrtGetMainboardId(devLogicId, hcclMainboardId));
161 : isAX
162 : = (hcclMainboardId == HcclMainboardId::MAINBOARD_A_X_SERVER
163 : || hcclMainboardId == HcclMainboardId::MAINBOARD_PCIE_STD);
164 : HCCL_INFO(
165 : "[CcuResSpecifications]HrtGetMainboardId devLogicId[%d] hcclMainboardId[%s] isAX[%d].",
166 : devLogicId, hcclMainboardId.Describe().c_str(), static_cast<int>(isAX)););
167 :
168 11 : return HcclResult::HCCL_SUCCESS;
169 : }
170 :
171 14 : CcuVersion CcuResSpecifications::GetCcuVersion() const { return ccuVersion; }
172 :
173 14 : bool CcuResSpecifications::GetAXFlag() const { return isAX; }
174 :
175 34 : HcclResult CcuResSpecifications::GetDieEnableFlag(const uint8_t dieId, bool& dieEnableFlag) const
176 : {
177 : // 只校验dieId合法性,不校验die是否使能
178 34 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, {true, true}));
179 34 : dieEnableFlag = dieEnableFlags[dieId];
180 34 : return HcclResult::HCCL_SUCCESS;
181 : }
182 :
183 24 : HcclResult CcuResSpecifications::GetCcuMemInfoList(const uint8_t dieId, struct CcuMemInfo* memInfoList, uint32_t& count)
184 : {
185 24 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
186 24 : count = static_cast<uint32_t>(GetMemTypeVector().size());
187 : // 使用 std::copy 将 std::array 的内容拷贝到 C 风格指针数组
188 24 : std::copy_n(resSpecs[dieId].memInfoList.begin(), count, memInfoList);
189 :
190 24 : return HcclResult::HCCL_SUCCESS;
191 : }
192 :
193 51 : HcclResult CcuResSpecifications::GetResourceAddr(const uint8_t dieId, uint64_t& resourceAddr) const
194 : {
195 57 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
196 49 : resourceAddr = resSpecs[dieId].resourceAddr;
197 49 : return HcclResult::HCCL_SUCCESS;
198 : }
199 :
200 1 : HcclResult CcuResSpecifications::GetXnBaseAddr(const uint8_t dieId, uint64_t& xnBaseAddr) const
201 : {
202 1 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
203 :
204 1 : const uint64_t ccuResAddr = resSpecs[dieId].resourceAddr;
205 1 : if (ccuResAddr == 0) {
206 0 : HCCL_WARNING(
207 : "[CcuResSpecifications][%s] failed, CCU resource base address is 0, "
208 : "devLogicId[%d] dieId[%u].",
209 : __func__, devLogicId, dieId);
210 0 : return HcclResult::HCCL_E_INTERNAL;
211 : }
212 :
213 : // xn位于ins与gsa之后,xn偏移 = CCUM偏移 + 指令空间大小 + GSA大小,常量计算不会溢出
214 1 : constexpr uint64_t instrRevserveSize = CCU_RESOURCE_INS_RESERVE_SIZE;
215 1 : constexpr uint64_t gsaReserveSize = CCU_V1_RESOURCE_GSA_RESERVE_SIZE;
216 1 : constexpr uint64_t ccum_offset = CCU_V1_CCUM_OFFSET;
217 1 : constexpr uint32_t ccuXnOffset = ccum_offset + instrRevserveSize + gsaReserveSize;
218 1 : if (ccuResAddr > UINT64_MAX - ccuXnOffset) {
219 0 : HCCL_ERROR(
220 : "[CcuResSpecifications][%s] failed, CCU resource base address[%llu] is "
221 : "greater then expected, ccu xn offset[%llu], their sum will exceeds the range "
222 : "of uint64_t.",
223 : __func__, ccuResAddr, ccuXnOffset);
224 : }
225 :
226 1 : xnBaseAddr = ccuResAddr + ccuXnOffset;
227 1 : return HcclResult::HCCL_SUCCESS;
228 : }
229 :
230 25 : HcclResult CcuResSpecifications::GetMsId(const uint8_t dieId, uint32_t& msId) const
231 : {
232 25 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
233 25 : msId = resSpecs[dieId].msId;
234 25 : return HcclResult::HCCL_SUCCESS;
235 : }
236 :
237 1 : HcclResult CcuResSpecifications::GetMissionKey(const uint8_t dieId, uint32_t& missionKey) const
238 : {
239 1 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
240 1 : missionKey = resSpecs[dieId].missionKey;
241 1 : return HcclResult::HCCL_SUCCESS;
242 : }
243 :
244 25 : HcclResult CcuResSpecifications::GetInstructionNum(const uint8_t dieId, uint32_t& instrNum) const
245 : {
246 25 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
247 25 : instrNum = resSpecs[dieId].instructionNum;
248 25 : return HcclResult::HCCL_SUCCESS;
249 : }
250 :
251 29 : HcclResult CcuResSpecifications::GetMissionNum(const uint8_t dieId, uint32_t& missionNum) const
252 : {
253 29 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
254 29 : missionNum = resSpecs[dieId].missionNum;
255 29 : return HcclResult::HCCL_SUCCESS;
256 : }
257 :
258 29 : HcclResult CcuResSpecifications::GetLoopEngineNum(const uint8_t dieId, uint32_t& loopNum) const
259 : {
260 29 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
261 29 : loopNum = resSpecs[dieId].loopEngineNum;
262 29 : return HcclResult::HCCL_SUCCESS;
263 : }
264 :
265 29 : HcclResult CcuResSpecifications::GetGsaNum(const uint8_t dieId, uint32_t& gsaNum) const
266 : {
267 29 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
268 29 : gsaNum = resSpecs[dieId].gsaNum;
269 29 : return HcclResult::HCCL_SUCCESS;
270 : }
271 :
272 29 : HcclResult CcuResSpecifications::GetXnNum(const uint8_t dieId, uint32_t& xnNum) const
273 : {
274 29 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
275 29 : xnNum = resSpecs[dieId].xnNum;
276 29 : return HcclResult::HCCL_SUCCESS;
277 : }
278 :
279 54 : HcclResult CcuResSpecifications::GetCkeNum(const uint8_t dieId, uint32_t& ckeNum) const
280 : {
281 54 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
282 54 : ckeNum = resSpecs[dieId].ckeNum;
283 54 : return HcclResult::HCCL_SUCCESS;
284 : }
285 :
286 29 : HcclResult CcuResSpecifications::GetMsNum(const uint8_t dieId, uint32_t& msNum) const
287 : {
288 29 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
289 29 : msNum = resSpecs[dieId].msNum;
290 29 : return HcclResult::HCCL_SUCCESS;
291 : }
292 :
293 25 : HcclResult CcuResSpecifications::GetChannelNum(const uint8_t dieId, uint32_t& channelNum) const
294 : {
295 25 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
296 25 : channelNum = resSpecs[dieId].channelNum;
297 25 : return HcclResult::HCCL_SUCCESS;
298 : }
299 :
300 25 : HcclResult CcuResSpecifications::GetJettyNum(const uint8_t dieId, uint32_t& jettyNum) const
301 : {
302 25 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
303 25 : jettyNum = resSpecs[dieId].jettyNum;
304 25 : return HcclResult::HCCL_SUCCESS;
305 : }
306 :
307 26 : HcclResult CcuResSpecifications::GetPfeReservedNum(const uint8_t dieId, uint32_t& pfeNum) const
308 : {
309 26 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
310 26 : pfeNum = CCU_V1_PER_DIE_PFE_RESERVED_NUM;
311 26 : return HcclResult::HCCL_SUCCESS;
312 : }
313 :
314 1 : HcclResult CcuResSpecifications::GetPfeNum(const uint8_t dieId, uint32_t& pfeNum) const
315 : {
316 1 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
317 1 : pfeNum = resSpecs[dieId].pfeNum;
318 1 : return HcclResult::HCCL_SUCCESS;
319 : }
320 :
321 25 : HcclResult CcuResSpecifications::GetWqeBBNum(const uint8_t dieId, uint32_t& wqeBBNum) const
322 : {
323 25 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
324 25 : wqeBBNum = resSpecs[dieId].wqeBBNum;
325 25 : return HcclResult::HCCL_SUCCESS;
326 : }
327 :
328 : }; // namespace Hccl
|