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 "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("[CcuResSpecifications][GetInstance] Failed to get instance. "
26 : "devLogicId should be less than %u.", MAX_MODULE_DEVICE_NUM));
27 : }
28 :
29 307 : ccuResSpecifications[deviceLogicId].devLogicId = deviceLogicId;
30 :
31 307 : return ccuResSpecifications[deviceLogicId];
32 : }
33 :
34 11 : void CcuResSpecifications::Init()
35 : {
36 11 : if (ifInit) {
37 0 : return;
38 : }
39 :
40 11 : if (Init_() != HcclResult::HCCL_SUCCESS) {
41 0 : devPhyId = MAX_MODULE_DEVICE_NUM;
42 0 : ccuVersion = CcuVersion::CCU_INVALID;
43 0 : for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
44 0 : dieEnableFlags[i] = false;
45 0 : resSpecs[i] = CcuResSpecInfo{};
46 : }
47 : }
48 :
49 11 : ifInit = true;
50 : }
51 :
52 2 : void CcuResSpecifications::Deinit()
53 : {
54 6 : for (uint32_t i = 0; i < MAX_CCU_IODIE_NUM; i++) {
55 4 : dieEnableFlags[i] = false;
56 4 : resSpecs[i] = CcuResSpecInfo{};
57 : }
58 :
59 2 : ifInit = false;
60 2 : }
61 :
62 11 : static CcuVersion CheckCcuVersion()
63 : {
64 11 : return CcuVersion::CCU_V1; // CCU驱动未更新前临时使用
65 : }
66 :
67 22 : static bool CheckDieEnable(const int32_t devLogicId, const uint8_t dieId)
68 : {
69 22 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
70 22 : CHECK_NULLPTR(tlvHandle, StringFormat("[%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
71 22 : struct CustomChannelInfoIn inBuff;
72 22 : struct CustomChannelInfoOut outBuff;
73 22 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_DIE_WORKING;
74 22 : inBuff.offsetStartIdx = 0;
75 22 : inBuff.data.dataInfo.udieIdx = dieId;
76 :
77 22 : HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
78 :
79 22 : const uint32_t enableFlag = outBuff.data.dataInfo.dataArray[0].dieinfo.enableFlag;
80 22 : return enableFlag == CCU_ENABLE_FLAG;
81 : }
82 :
83 6 : static CcuBaseInfoData ParseOutBuffToBaseInfoData(const CustomChannelInfoOut &outBuff)
84 : {
85 6 : CcuBaseInfoData baseInfoData{};
86 6 : baseInfoData.resourceAddr = outBuff.data.dataInfo.dataArray[0].baseinfo.resourceAddr;
87 6 : baseInfoData.missionKey = outBuff.data.dataInfo.dataArray[0].baseinfo.missionKey;
88 6 : baseInfoData.msId = outBuff.data.dataInfo.dataArray[0].baseinfo.msId;
89 6 : baseInfoData.caps.cap0 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap0;
90 6 : baseInfoData.caps.cap1 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap1;
91 6 : baseInfoData.caps.cap2 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap2;
92 6 : baseInfoData.caps.cap3 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap3;
93 6 : baseInfoData.caps.cap4 = outBuff.data.dataInfo.dataArray[0].baseinfo.caps.cap4;
94 6 : return baseInfoData;
95 : }
96 :
97 6 : static CcuResSpecInfo ParseOutBuffToResSpecInfo(const CcuVersion ccuVersion, const CustomChannelInfoOut &outBuff)
98 : {
99 6 : if (ccuVersion != CcuVersion::CCU_V1) {
100 0 : HCCL_WARNING("[CcuResSpecifications][%s] failed to parse out buff, ccu driver "
101 : "version[%s] is not expected.", __func__, ccuVersion.Describe().c_str());
102 0 : return {};
103 : }
104 :
105 6 : const auto &baseInfoData = ParseOutBuffToBaseInfoData(outBuff);
106 :
107 6 : CcuResSpecInfo ccuResSpecInfo{};
108 6 : ccuResSpecInfo.msId = baseInfoData.msId;
109 6 : ccuResSpecInfo.resourceAddr = baseInfoData.resourceAddr;
110 6 : ccuResSpecInfo.missionKey = baseInfoData.missionKey;
111 :
112 6 : ccuResSpecInfo.instructionNum = (baseInfoData.caps.cap0 & 0x0000FFFF) + 1;
113 6 : ccuResSpecInfo.xnNum = ((baseInfoData.caps.cap1 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
114 6 : ccuResSpecInfo.msNum = ((baseInfoData.caps.cap2 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
115 6 : ccuResSpecInfo.ckeNum = (baseInfoData.caps.cap2 & 0x0000FFFF) + 1;
116 6 : ccuResSpecInfo.jettyNum = ((baseInfoData.caps.cap3 >> MOVE_16_BITS) & 0x0000FFFF) + 1;
117 6 : ccuResSpecInfo.channelNum = (baseInfoData.caps.cap3 & 0x0000FFFF) + 1;
118 6 : ccuResSpecInfo.pfeNum = (baseInfoData.caps.cap4 & 0x000000FF) + 1;
119 :
120 6 : ccuResSpecInfo.missionNum = ((baseInfoData.caps.cap0 >> MOVE_16_BITS) & 0x000000FF) + 1;
121 6 : ccuResSpecInfo.loopEngineNum = ((baseInfoData.caps.cap0 >> MOVE_24_BITS) & 0x000000FF) + 1;
122 6 : ccuResSpecInfo.gsaNum = (baseInfoData.caps.cap1 & 0x0000FFFF) + 1;
123 6 : return ccuResSpecInfo;
124 : }
125 :
126 6 : static CcuResSpecInfo CheckResSpecifications(const int32_t devLogicId,
127 : const uint8_t dieId, const CcuVersion ccuVersion)
128 : {
129 6 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
130 6 : CHECK_NULLPTR(tlvHandle, StringFormat("[%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
131 6 : struct CustomChannelInfoIn inBuff;
132 6 : struct CustomChannelInfoOut outBuff;
133 6 : inBuff.op = CcuOpcodeType::CCU_U_OP_GET_BASIC_INFO;
134 6 : inBuff.offsetStartIdx = 0;
135 6 : inBuff.data.dataInfo.udieIdx = dieId;
136 :
137 6 : HrtRaTlvRequestForCustomChannel(tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void *>(&inBuff), static_cast<void *>(&outBuff));
138 12 : return ParseOutBuffToResSpecInfo(ccuVersion, outBuff);
139 : }
140 :
141 11 : HcclResult CcuResSpecifications::Init_()
142 : {
143 66 : TRY_CATCH_RETURN(
144 : devPhyId = HrtGetDevicePhyIdByIndex(devLogicId);
145 : ccuVersion = CheckCcuVersion();
146 : auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
147 : auto memTypeBitmap = GetCombinedMemTypeBitmap();
148 : auto count = GetMemTypeVector().size();
149 : for (uint8_t dieId = 0; dieId < MAX_CCU_IODIE_NUM; dieId++) {
150 : dieEnableFlags[dieId] = CheckDieEnable(devLogicId, dieId);
151 : if (!dieEnableFlags[dieId]) {
152 : resSpecs[dieId] = CcuResSpecInfo{};
153 : continue;
154 : }
155 : resSpecs[dieId] = CheckResSpecifications(devLogicId, dieId, ccuVersion);
156 : HrtGetCcuMemInfo(tlvHandle, dieId, memTypeBitmap, resSpecs[dieId].memInfoList.data(), count);
157 : }
158 : HcclMainboardId hcclMainboardId;
159 : CHK_RET(HrtGetMainboardId(devLogicId, hcclMainboardId));
160 : isAX = (hcclMainboardId == HcclMainboardId::MAINBOARD_A_X_SERVER
161 : || hcclMainboardId == HcclMainboardId::MAINBOARD_PCIE_STD);
162 : HCCL_INFO("[CcuResSpecifications]HrtGetMainboardId devLogicId[%d] hcclMainboardId[%s] isAX[%d].",
163 : devLogicId, hcclMainboardId.Describe().c_str(), static_cast<int>(isAX));
164 : );
165 :
166 11 : return HcclResult::HCCL_SUCCESS;
167 : }
168 :
169 14 : CcuVersion CcuResSpecifications::GetCcuVersion() const
170 : {
171 14 : return ccuVersion;
172 : }
173 :
174 14 : bool CcuResSpecifications::GetAXFlag() const
175 : {
176 14 : return isAX;
177 : }
178 :
179 34 : HcclResult CcuResSpecifications::GetDieEnableFlag(const uint8_t dieId, bool &dieEnableFlag) const
180 : {
181 : // 只校验dieId合法性,不校验die是否使能
182 34 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, {true, true}));
183 34 : dieEnableFlag = dieEnableFlags[dieId];
184 34 : return HcclResult::HCCL_SUCCESS;
185 : }
186 :
187 24 : HcclResult CcuResSpecifications::GetCcuMemInfoList(const uint8_t dieId, struct CcuMemInfo *memInfoList, uint32_t &count)
188 : {
189 24 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
190 24 : count = static_cast<uint32_t>(GetMemTypeVector().size());
191 : // 使用 std::copy 将 std::array 的内容拷贝到 C 风格指针数组
192 24 : std::copy_n(resSpecs[dieId].memInfoList.begin(), count, memInfoList);
193 :
194 24 : return HcclResult::HCCL_SUCCESS;
195 : }
196 :
197 51 : HcclResult CcuResSpecifications::GetResourceAddr(const uint8_t dieId, uint64_t &resourceAddr) const
198 : {
199 57 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
200 49 : resourceAddr = resSpecs[dieId].resourceAddr;
201 49 : return HcclResult::HCCL_SUCCESS;
202 : }
203 :
204 1 : HcclResult CcuResSpecifications::GetXnBaseAddr(const uint8_t dieId, uint64_t &xnBaseAddr) const
205 : {
206 1 : CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
207 :
208 1 : const uint64_t ccuResAddr = resSpecs[dieId].resourceAddr;
209 1 : if (ccuResAddr == 0) {
210 0 : HCCL_WARNING("[CcuResSpecifications][%s] failed, CCU resource base address is 0, "
211 : "devLogicId[%d] dieId[%u].", __func__, devLogicId, dieId);
212 0 : return HcclResult::HCCL_E_INTERNAL;
213 : }
214 :
215 : // xn位于ins与gsa之后,xn偏移 = CCUM偏移 + 指令空间大小 + GSA大小,常量计算不会溢出
216 1 : constexpr uint64_t instrRevserveSize = CCU_RESOURCE_INS_RESERVE_SIZE;
217 1 : constexpr uint64_t gsaReserveSize = CCU_V1_RESOURCE_GSA_RESERVE_SIZE;
218 1 : constexpr uint64_t ccum_offset = CCU_V1_CCUM_OFFSET;
219 1 : constexpr uint32_t ccuXnOffset = ccum_offset + instrRevserveSize + gsaReserveSize;
220 1 : if (ccuResAddr > UINT64_MAX - ccuXnOffset) {
221 0 : HCCL_ERROR("[CcuResSpecifications][%s] failed, CCU resource base address[%llu] is "
222 : "greater then expected, ccu xn offset[%llu], their sum will exceeds the range "
223 : "of uint64_t.", __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
|