LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_device/ccu_component/ccu_channel - ccu_jetty_ctx_mgr.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.7 % 120 110
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 9 9

            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_jetty_ctx_mgr_legacy.h"
      12              : 
      13              : #include "ccu_res_specs_legacy.h"
      14              : #include "orion_adapter_hccp.h"
      15              : #include "resources_not_exist_exception.h"
      16              : #include "hccp_tlv_hdc_manager.h"
      17              : 
      18              : namespace Hccl {
      19              : 
      20              : // 对一个数求以2为底的对数,num已保证不为0
      21           28 : inline uint16_t Log2OfPowerOfTwo(uint32_t num)
      22              : {
      23           28 :     uint16_t log2 = 0;
      24          140 :     while (num > 1) {
      25          112 :         num >>= 1;
      26          112 :         log2++;
      27              :     }
      28           28 :     return log2;
      29              : }
      30              : 
      31              : union DoorbellAddr {
      32              :     uint64_t dbAddr;
      33              :     uint16_t dbAddr16[4];
      34              : };
      35              : 
      36              : LocalJettyCtxData
      37           28 : BuildJettyCtxData(const uint8_t dieId, const uint32_t pfeId, const JettyInfo& jettyInfo, const JettyCfg& jettyCfg)
      38              : {
      39           28 :     LocalJettyCtxData data{};
      40              : 
      41              :     DoorbellAddr dbAddr;
      42           28 :     dbAddr.dbAddr = jettyCfg.dbVa;
      43           28 :     data.doorbellAddr[0] = dbAddr.dbAddr16[0];
      44           28 :     data.doorbellAddr[1] = dbAddr.dbAddr16[1];
      45           28 :     data.doorbellAddr[2] = dbAddr.dbAddr16[2]; // 2: doorbell 地址访问
      46           28 :     data.doorbellAddr[3] = dbAddr.dbAddr16[3]; // 3: doorbell 地址访问
      47              : 
      48           28 :     data.pfeIdx = static_cast<uint8_t>(pfeId);
      49           28 :     data.ioDieId = dieId;
      50              : 
      51           28 :     data.doorbellAddrType = DB_ADDR_TYPE;
      52           28 :     data.tokenValueIsValid = TOKEN_VALUE_IS_VALIDE;
      53              : 
      54           28 :     data.tokenIdLow = jettyCfg.dbTokenId & MASK_TK_ID_LOW;
      55           28 :     data.tokenIdHigh = (jettyCfg.dbTokenId >> SHIFT_8BITS) & MASK_TK_ID_HIGH; // tokenId右移8位
      56              : 
      57           28 :     data.tokenValueLow = jettyCfg.dbTokenValue & MASK_TK_VALUE_LOW;
      58           28 :     data.tokenValueMiddle = (jettyCfg.dbTokenValue >> SHIFT_4BITS) & MASK_TK_VALUE_MID; // tokenValue右移4位
      59           28 :     data.tokenValueHigh = (jettyCfg.dbTokenValue >> SHIFT_20BITS) & MASK_TK_VALUE_HIGH; // tokenValue右移20位
      60              : 
      61           28 :     const uint16_t wqeBBShift = Log2OfPowerOfTwo(jettyInfo.sqDepth * CCU_WQE_NUM_PER_SQE);
      62           28 :     data.sqeBasicBlockLeftShifts = wqeBBShift;
      63              : 
      64           28 :     const uint16_t wqeBBIdx = jettyInfo.wqeBBStartId;
      65           28 :     data.startWqeBasicBlockIdxLow = wqeBBIdx & MASK_WQEBB_IDX_LOW;
      66           28 :     data.startWqeBasicBlockIdxHigh = (wqeBBIdx >> SHIFT_4BITS) & MASK_WQEBB_IDX_HIGH; // 右移4位
      67              : 
      68           28 :     data.pi = CCU_HARDWARE_DEFAULT_VALUE;
      69           28 :     data.ci = CCU_HARDWARE_DEFAULT_VALUE;
      70           28 :     data.maxCi = CCU_HARDWARE_DEFAULT_VALUE;
      71           28 :     data.oooCqeCnt = CCU_HARDWARE_DEFAULT_VALUE;
      72           28 :     data.doorbellSendState = CCU_HARDWARE_DEFAULT_VALUE;
      73              : 
      74           28 :     return data;
      75              : }
      76              : 
      77           28 : void DumpJettyCtxData(const LocalJettyCtxData& tmp)
      78              : {
      79           84 :     HCCL_RUN_INFO(
      80              :         "doorbellAddr: [3]0x%04x, [2]0x%04x, [1]0x%04x, [0]0x%04x",
      81              :         tmp.doorbellAddr[3], // 3: doorbell 地址访问
      82              :         tmp.doorbellAddr[2], // 2: doorbell 地址访问
      83              :         tmp.doorbellAddr[1], tmp.doorbellAddr[0]);
      84              : 
      85              :     // 安全问题:禁止打印token相关信息
      86           84 :     HCCL_RUN_INFO(
      87              :         "pfeIdx: 0x%04x, ioDieId: 0x%04x, doorbellAddrType: 0x%04x, "
      88              :         "tokenValueIsValid: 0x%04x",
      89              :         tmp.pfeIdx, tmp.ioDieId, tmp.doorbellAddrType, tmp.tokenValueIsValid);
      90              : 
      91           84 :     HCCL_RUN_INFO(
      92              :         "sqeBasicBlockLeftShifts: 0x%04x, pi: 0x%04x, ci: 0x%04x, "
      93              :         "maxCi: 0x%04x, oooCqeCnt: 0x%04x, startWqeBasicBlockIdxLow: 0x%04x, "
      94              :         "startWqeBasicBlockIdxHigh: 0x%04x, doorbellSendState: 0x%04x",
      95              :         tmp.sqeBasicBlockLeftShifts, tmp.pi, tmp.ci, tmp.maxCi, tmp.oooCqeCnt, tmp.startWqeBasicBlockIdxLow,
      96              :         tmp.startWqeBasicBlockIdxHigh, tmp.doorbellSendState);
      97           28 : }
      98              : 
      99           26 : void ConfigJettyCtxData(
     100              :     const int32_t devLogicId, const uint8_t dieId, const uint16_t startJettyCtxId,
     101              :     std::vector<LocalJettyCtxData>& jettyCtxData)
     102              : {
     103           26 :     const uint32_t jettyNum = jettyCtxData.size(); // 分配与配置前校验已保证不为0
     104           26 :     auto tlvHandle = HccpTlvHdcManager::GetInstance().GetTlvHandle(devLogicId);
     105           26 :     CHECK_NULLPTR(
     106           52 :         tlvHandle, StringFormat("[CcuJettyCtxMgr][%s] tlvHandle is nullptr, devLogicId[%d]", __func__, devLogicId));
     107              : 
     108           26 :     struct CustomChannelInfoIn inBuff;
     109           26 :     struct CustomChannelInfoOut outBuff;
     110              : 
     111           26 :     inBuff.op = CcuOpcodeType::CCU_U_OP_SET_JETTY_CTX;
     112           26 :     (void)memset_s(inBuff.data.raw, sizeof(inBuff.data.raw), 0, sizeof(inBuff.data.raw));
     113              : 
     114           26 :     inBuff.data.dataInfo.udieIdx = dieId;
     115           26 :     inBuff.data.dataInfo.dataArraySize = jettyNum;
     116              : 
     117              :     // 设置数据长度,目前设备管理最多使用5个JettyCtx,需要长度上限为 32 * 5 = 160B
     118           26 :     inBuff.data.dataInfo.dataLen = sizeof(struct LocalJettyCtxData) * inBuff.data.dataInfo.dataArraySize;
     119           26 :     inBuff.offsetStartIdx = startJettyCtxId; // 设置起始Jetty上下文ID,注意应从0开始,非TaJettyId
     120              : 
     121           78 :     HCCL_INFO(
     122              :         "[CcuJettyCtxMgr][%s] iodie[%u], startJettyCtxId[%u], jettyCtxData.size[%u]", __func__, dieId, startJettyCtxId,
     123              :         jettyNum);
     124              : 
     125           54 :     for (size_t i = 0; i < jettyNum; i++) {
     126           28 :         DumpJettyCtxData(jettyCtxData[i]);
     127              : 
     128           28 :         (void)memcpy_s(
     129           28 :             &inBuff.data.dataInfo.dataArray[i], sizeof(struct LocalJettyCtxData), &jettyCtxData[i],
     130              :             sizeof(struct LocalJettyCtxData));
     131              :     }
     132              : 
     133           26 :     HrtRaTlvRequestForCustomChannel(
     134              :         tlvHandle, MSG_TYPE_CCU_DISPATCH_CMD, static_cast<void*>(&inBuff), static_cast<void*>(&outBuff));
     135           26 : }
     136              : 
     137           24 : CcuJettyCtxMgr::CcuJettyCtxMgr(const int32_t devLogicId, const uint8_t dieId, const uint32_t devPhyId)
     138           24 :     : devLogicId(devLogicId),
     139           24 :       dieId(dieId),
     140           24 :       devPhyId(devPhyId),
     141           24 :       wqeBBMgr(devLogicId, dieId)
     142              : {
     143              :     // 获取失败或为0场景,分配将按资源不足操作
     144           24 :     (void)CcuResSpecifications::GetInstance(devLogicId).GetJettyNum(dieId, jettySpecNum);
     145           24 :     (void)CcuResSpecifications::GetInstance(devLogicId).GetResourceAddr(dieId, ccuResBaseVa);
     146           24 :     if (UNLIKELY(ccuResBaseVa == 0)) { // 直接抛异常终止,避免访问非法地址
     147            0 :         THROW<ResourcesNotExistException>(
     148              :             "[CcuJettyCtxMgr] init failed, ccu resource base addr is 0, "
     149              :             "devLogicId[%d] dieId[%u].",
     150              :             devLogicId, dieId);
     151              :     }
     152           24 :     pfeMgr = CcuPfeMgr(devLogicId, dieId, devPhyId);
     153           24 : }
     154              : 
     155           34 : static HcclResult GetSqeBuffVa(const uint64_t ccuResBaseVa, const uint32_t jettyCtxId, uint64_t& sqeBuffVa)
     156              : {
     157           34 :     sqeBuffVa = 0;
     158           34 :     if (UINT32_MAX / CCU_SQ_BUFFER_SIZE < jettyCtxId) {
     159            0 :         HCCL_ERROR(
     160              :             "[CcuJettyCtxMgr][%s] jetty context id[%u] is greater "
     161              :             "than expected, CCU_SQ_UBFFER_SIZE[%u], their product will exceed the "
     162              :             "range of uint32_t.",
     163              :             __func__, jettyCtxId, CCU_SQ_BUFFER_SIZE);
     164            0 :         return HcclResult::HCCL_E_INTERNAL;
     165              :     }
     166           34 :     const uint64_t jettyCtxOffset = static_cast<uint64_t>(jettyCtxId) * CCU_SQ_BUFFER_SIZE;
     167              : 
     168           34 :     if (UINT64_MAX - CCU_V1_WQE_BASIC_BLOCK_OFFSET - jettyCtxOffset < ccuResBaseVa) {
     169            0 :         HCCL_ERROR(
     170              :             "[CcuJettyCtxMgr][%s] ccu resource space base va[%llu] "
     171              :             "is greater than expected, jettyCtxId[%u], the sqe buff va exceed the "
     172              :             "range of uint64_t.",
     173              :             __func__, ccuResBaseVa, jettyCtxId);
     174            0 :         return HcclResult::HCCL_E_INTERNAL;
     175              :     }
     176              : 
     177              :     // 内部分配保证jettyCtxId 小于 jettyCtx规格数量,地址不应越界
     178           34 :     sqeBuffVa = ccuResBaseVa + CCU_V1_WQE_BASIC_BLOCK_OFFSET + jettyCtxOffset;
     179           34 :     return HcclResult::HCCL_SUCCESS;
     180              : }
     181              : 
     182           28 : HcclResult CcuJettyCtxMgr::TryAllocWqeBBResource(
     183              :     const uint32_t sqSize, const uint32_t jettyCtxStartId, const uint32_t taJettyStartId, const CcuJettyType jettyType,
     184              :     std::vector<JettyInfo>& jettyInfos)
     185              : {
     186           28 :     const uint32_t jettyNum = jettyInfos.size();
     187           28 :     if (jettyNum == 0) {
     188            0 :         HCCL_WARNING(
     189              :             "[CcuJettyCtxMgr][%s] failed, jettyInfos size is 0, "
     190              :             "devLogicId[%d], dieId[%u].",
     191              :             __func__, devLogicId, dieId);
     192            0 :         return HcclResult::HCCL_E_PARA;
     193              :     }
     194              : 
     195           62 :     for (uint32_t i = 0; i < jettyNum; i++) {
     196           34 :         ResInfo wqeBBInfo(0, 0);
     197           34 :         HcclResult ret = wqeBBMgr.Alloc(sqSize, wqeBBInfo);
     198           34 :         if (ret != HcclResult::HCCL_SUCCESS) {
     199            0 :             HCCL_WARNING(
     200              :                 "[CcuJettyCtxMgr][%s] failed to alloc wqe basic block resource, "
     201              :                 "devLogicId[%d], dieId[%u].",
     202              :                 __func__, devLogicId, dieId);
     203            0 :             return ret;
     204              :         }
     205              : 
     206           34 :         auto& jettyInfo = jettyInfos[i];
     207           34 :         jettyInfo.jettyType = jettyType;
     208           34 :         jettyInfo.jettyCtxId = static_cast<uint16_t>(jettyCtxStartId + i);
     209           34 :         jettyInfo.taJettyId = static_cast<uint16_t>(taJettyStartId + i);
     210              : 
     211           34 :         const uint32_t wqeBBReqNum = wqeBBInfo.num;
     212           34 :         jettyInfo.sqDepth = wqeBBReqNum / CCU_WQE_NUM_PER_SQE;
     213           34 :         jettyInfo.wqeBBStartId = wqeBBInfo.startId;
     214           34 :         if (jettyType == CcuJettyType::CCUM_CACHED_JETTY) {
     215           34 :             jettyInfo.sqBufSize = wqeBBReqNum * CCU_ONE_WQE_SIZE;
     216           34 :             CHK_RET(GetSqeBuffVa(
     217              :                 ccuResBaseVa, static_cast<uint32_t>(jettyInfo.jettyCtxId),
     218              :                 jettyInfo.sqBufVa)); // 检查溢出,分配成功的wqeBB资源已经记录
     219              :         }
     220              :     }
     221              : 
     222           28 :     return HcclResult::HCCL_SUCCESS;
     223              : }
     224              : 
     225            2 : HcclResult CcuJettyCtxMgr::ReleaseWqeBBResource(const std::vector<JettyInfo>& jettyInfos)
     226              : {
     227            6 :     for (const auto& jettyInfo : jettyInfos) {
     228            4 :         if (jettyInfo.sqDepth == 0) {
     229            0 :             continue; // 该jetty未分配完成,跳过wqeBB资源释放
     230              :         }
     231              : 
     232            4 :         uint32_t wqeBBIdx = static_cast<uint32_t>(jettyInfo.wqeBBStartId);
     233              :         // jettyInfo 为内部数据,分配保证不会溢出
     234            4 :         uint32_t wqeBBNum = jettyInfo.sqDepth * CCU_WQE_NUM_PER_SQE;
     235            4 :         const auto resInfo = ResInfo(wqeBBIdx, wqeBBNum);
     236            4 :         CHK_RET(wqeBBMgr.Release(resInfo));
     237              :     }
     238            2 :     return HcclResult::HCCL_SUCCESS;
     239              : }
     240              : 
     241           28 : HcclResult CcuJettyCtxMgr::CheckIfJettyCfgsValid(
     242              :     const std::vector<JettyInfo>& jettyInfos, const std::vector<JettyCfg>& jettyCfgs) const
     243              : {
     244           28 :     const uint32_t jettyNum = jettyInfos.size();
     245           28 :     const uint32_t jettyCfgNum = jettyCfgs.size();
     246           31 :     CHK_PRT_RET(
     247              :         jettyCfgNum != jettyNum,
     248              :         HCCL_ERROR(
     249              :             "[CcuJettyCtxMgr][%s] failed, jettyCfgs size[%u] is not expected, "
     250              :             "which should be equal to jettyInfo size[%u], devLogicId[%d], dieId[%u].",
     251              :             __func__, jettyCfgNum, jettyNum, devLogicId, dieId),
     252              :         HcclResult::HCCL_E_PARA);
     253              : 
     254           57 :     for (uint32_t i = 0; i < jettyNum; i++) {
     255           31 :         if (jettyInfos[i].jettyCtxId != jettyCfgs[i].jettyCtxId) {
     256            3 :             HCCL_ERROR(
     257              :                 "[CcuJettyCtxMgr][%s] failed, jettyCtxId of jettyInfo[%u] and "
     258              :                 "jettyCfg[%u] are not same, devLogicId[%d], dieId[%u].",
     259              :                 __func__, jettyInfos[i].jettyCtxId, jettyCfgs[i].jettyCtxId, devLogicId, dieId);
     260            1 :             return HcclResult::HCCL_E_PARA;
     261              :         }
     262              :     }
     263           26 :     return HcclResult::HCCL_SUCCESS;
     264              : }
     265              : 
     266              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1