LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_device - ccu_res_specs.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.7 % 165 153
Test Date: 2026-07-28 12:11:00 Functions: 96.7 % 30 29

            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           25 : HcclResult CcuResSpecifications::GetGsaNum(const uint8_t dieId, uint32_t &gsaNum) const
     266              : {
     267           25 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     268           25 :     gsaNum = resSpecs[dieId].gsaNum;
     269           25 :     return HcclResult::HCCL_SUCCESS;
     270              : }
     271              : 
     272           25 : HcclResult CcuResSpecifications::GetXnNum(const uint8_t dieId, uint32_t &xnNum) const
     273              : {
     274           25 :     CHK_RET(CheckDieValid(__func__, devLogicId, dieId, dieEnableFlags));
     275           25 :     xnNum = resSpecs[dieId].xnNum;
     276           25 :     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
        

Generated by: LCOV version 2.0-1