LCOV - code coverage report
Current view: top level - adump/exception/dump_core - dump_core_register.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.6 % 125 122
Test Date: 2026-07-28 10:54:24 Functions: 100.0 % 14 14

            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              : #include <sstream>
      11              : #include <iomanip>
      12              : #include "log/adx_log.h"
      13              : #include "runtime/mem.h"
      14              : #include "adump_platform_manager.h"
      15              : #include "register_config.h"
      16              : #include "exception_info_common.h"
      17              : #include "dump_core.h"
      18              : 
      19              : namespace Adx {
      20              : constexpr int32_t REG_FIELD_WIDTH = 2;
      21              : 
      22           90 : void DumpCore::DumpRegister(uint8_t coreType, uint16_t coreId)
      23              : {
      24           90 :     auto *plat = CoredumpManager::Get();
      25           90 :     if (plat == nullptr) {
      26            5 :         IDE_LOGW("[DumpCore] Platform unavailable, register dump skipped.");
      27            5 :         return;
      28              :     }
      29           85 :     plat->DumpRegister(*this, coreType, coreId);
      30              : }
      31              : 
      32           51 : std::string DumpCore::FormatRegisterData(const uint8_t* valAddr, uint8_t valSize) const
      33              : {
      34           51 :     std::stringstream ss;
      35           51 :     ss << std::hex << std::setfill('0');
      36          255 :     for (uint8_t i = 0; i < valSize; ++i) {
      37          204 :         ss << std::setw(REG_FIELD_WIDTH) << static_cast<uint32_t>(valAddr[i]);
      38              :     }
      39          102 :     return ss.str();
      40           51 : }
      41              : 
      42        18044 : bool DumpCore::DumpReadDebugAICoreRegister(
      43              :     uint8_t coreType, uint16_t coreId, RegisterType regType, const RegisterTable& table, std::vector<uint8_t>& data) const
      44              : {
      45        18044 :     data.resize(table.num * table.byteWidth);
      46              :     rtDebugMemoryType_t memType;
      47        18044 :     if (regType == RegisterType::AIC || regType == RegisterType::AIV) {
      48          512 :         memType = RT_MEM_TYPE_REGISTER_DIRECT;
      49        17532 :     } else if (regType == RegisterType::AIC_DBG || regType == RegisterType::AIV_DBG) {
      50        17532 :         memType = RT_MEM_TYPE_REGISTER;
      51              :     } else {
      52            0 :         IDE_LOGE(
      53              :             "Wrong regType. regType: %d", regType);
      54            0 :         return false;
      55              :     }
      56        18044 :     rtDebugMemoryParam_t param = {coreType, 0, coreId, memType, 0, 0, 0, 0, 0};
      57        18044 :     param.srcAddr = table.startAddr;
      58        18044 :     param.dstAddr = reinterpret_cast<uint64_t>(data.data());
      59        18044 :     param.memLen = table.num * table.byteWidth;
      60        18044 :     param.elementSize = table.byteWidth;
      61        18044 :     rtError_t ret = rtDebugReadAICore(&param);
      62        18044 :     if (ret != RT_ERROR_NONE) {
      63        15750 :         IDE_LOGE(
      64              :             "Failed to read debug register data. coreType: %hhu, coreId: %hu, start addr: 0x%llx, "
      65              :             "num: %u, byteWidth: %hhu, ret: %d",
      66              :             coreType, coreId, param.srcAddr, table.num, table.byteWidth, static_cast<int32_t>(ret));
      67        15750 :         return false;
      68              :     }
      69         2294 :     return true;
      70              : }
      71              : 
      72              : template <typename T>
      73          177 : void DumpCore::DumpDebugRegisterImpl(
      74              :     uint8_t coreType, uint16_t coreId, RegisterType regType, const std::vector<RegisterTable>& tables, std::vector<T>& regData) const
      75              : {
      76          177 :     std::stringstream ss;
      77        18221 :     for (const RegisterTable& table : tables) {
      78        18044 :         std::vector<uint8_t> data;
      79        18044 :         bool dataValid = DumpReadDebugAICoreRegister(coreType, coreId, regType, table, data);
      80        18044 :         errno_t err = EOK;
      81        18044 :         const uint8_t* dataPtr = data.data();
      82       345915 :         for (uint32_t i = 0; i < table.num; ++i) {
      83       327871 :             T regInfo{table.startAddr + i, REG_DATA_VALID, {0}, table.byteWidth, {0}};
      84       327871 :             if (dataValid) {
      85        41375 :                 err = memcpy_s(&regInfo.value, sizeof(regInfo.value), dataPtr, table.byteWidth);
      86        41375 :                 if (err != EOK) {
      87        20464 :                     IDE_LOGE("Failed to copy debug register data from cache buffer. "
      88              :                         "coreType: %hhu, coreId: %hu, addr: 0x%llx, ret: %d",
      89              :                         coreType, coreId, regInfo.addr, err);
      90        20464 :                     regInfo.validFlag = REG_DATA_INVALID;
      91              :                 } 
      92              :             } else {
      93       286496 :                 regInfo.validFlag = REG_DATA_INVALID;
      94              :             }
      95       327871 :             dataPtr += table.byteWidth;
      96       327871 :             regData.emplace_back(regInfo);
      97              :         }
      98              :     }
      99          177 :     std::string dataStr = ss.str();
     100          177 :     if (!dataStr.empty()) {
     101            0 :         IDE_LOGW("Debug register data. coreType=%d, coreId=%d.%s",
     102              :             static_cast<int32_t>(coreType), coreId, dataStr.c_str());
     103              :     }
     104          177 : }
     105              : 
     106              : template <typename T>
     107           85 : void DumpCore::DumpErrorRegisterImpl(
     108              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables, std::vector<T>& regData) const
     109              : {
     110           85 :     std::stringstream ss;
     111           85 :     std::vector<std::string> regLogs;
     112          170 :     for (uint32_t i = 0; i < exceptionRegInfo_.coreNum; i++) {
     113           85 :         rtExceptionErrRegInfo_t core = exceptionRegInfo_.errRegInfo[i];
     114           85 :         if (coreId != core.coreId || coreType != core.coreType) {
     115           68 :             continue;
     116              :         }
     117          548 :         for (const auto& table : tables) {
     118          531 :             T regInfo{table.offsetAddr, REG_DATA_VALID, {0}, table.byteWidth, {0}};
     119          531 :             errno_t err = memcpy_s(&regInfo.value, sizeof(regInfo.value), core.errReg + table.errIndex, table.byteWidth);
     120          531 :             if (err != EOK) {
     121          480 :                 IDE_LOGE("Failed to copy error register data from exception args. "
     122              :                     "coreType: %hhu, coreId: %hu, addr: 0x%llx, ret: %d",
     123              :                     coreType, coreId, regInfo.addr, err);
     124          480 :                 regInfo.validFlag = REG_DATA_INVALID;
     125              :             } else {
     126           51 :                 std::string value = FormatRegisterData(regInfo.value, regInfo.regSize);
     127           51 :                 ss << table.name << "[0x" << std::hex << regInfo.addr << "]: " << value << ",";
     128           51 :             }
     129          531 :             regData.emplace_back(regInfo);
     130              :         }
     131              :     }
     132           85 :     std::string dataStr = ss.str();
     133           85 :     if (!dataStr.empty()) {
     134            2 :         IDE_LOGW("Error register data. coreType=%d, coreId=%d. %s",
     135              :             static_cast<int32_t>(coreType), coreId, dataStr.c_str());
     136              :     }
     137           85 : }
     138              : 
     139           80 : void DumpCore::DumpV2Register(uint8_t coreType, uint16_t coreId)
     140              : {
     141           80 :     std::vector<RegInfo> regData;
     142           80 :     std::string sectionName = ASCEND_SHNAME_REGS + "." + std::to_string(ConvertCoreId(coreType, coreId));
     143           80 :     std::shared_ptr<RegisterInterface> reg = RegisterManager::GetInstance().GetRegister();
     144           80 :     IDE_CTRL_VALUE_FAILED(reg != nullptr, return, "Get register failed, null register.");
     145          247 :     for (const auto& regType : reg->GetRegisterTypes(coreType)) {
     146          167 :         DumpV2DebugRegister(coreType, coreId, reg->GetRegisterTable(regType), regData);
     147              :     }
     148           80 :     DumpV2ErrorRegister(coreType, coreId, reg->GetErrorRegisterTable(), regData);
     149              : 
     150           80 :     size_t totalSize = regData.size() * sizeof(RegInfo);
     151           80 :     std::string data(reinterpret_cast<const char*>(regData.data()), totalSize);
     152           80 :     ELF::SectionPtr registerSection = coreFile_.AddSection(ASCEND_SHTYPE_REGS, sectionName);
     153           80 :     IDE_CTRL_VALUE_FAILED(registerSection != nullptr, return, "Create %s section failed.", sectionName.c_str());
     154           80 :     registerSection->SetData(data);
     155           80 :     registerSection->SetEntSize(sizeof(RegInfo));
     156           80 : }
     157              : 
     158          167 : void DumpCore::DumpV2DebugRegister(
     159              :     uint8_t coreType, uint16_t coreId, const std::vector<RegisterTable>& tables, std::vector<RegInfo>& regData) const
     160              : {
     161              :     RegisterType regType;
     162          167 :     if (coreType == CORE_TYPE_AIC) {
     163           68 :         regType = RegisterType::AIC_DBG;
     164              :     } else {
     165           99 :         regType = RegisterType::AIV_DBG;
     166              :     }
     167          167 :     DumpDebugRegisterImpl(coreType, coreId, regType, tables, regData);
     168          167 : }
     169              : 
     170           80 : void DumpCore::DumpV2ErrorRegister(
     171              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables,
     172              :     std::vector<RegInfo>& regData) const
     173              : {
     174           80 :     DumpErrorRegisterImpl(coreType, coreId, tables, regData);
     175           80 : }
     176              : 
     177            5 : void DumpCore::DumpV4Register(uint8_t coreType, uint16_t coreId)
     178              : {
     179            5 :     std::vector<RegInfoWide> regData;
     180            5 :     std::string sectionName = ASCEND_SHNAME_REGS + "." + std::to_string(ConvertCoreId(coreType, coreId));
     181            5 :     std::shared_ptr<RegisterInterface> reg = RegisterManager::GetInstance().GetRegister();
     182            5 :     IDE_CTRL_VALUE_FAILED(reg != nullptr, return, "Get register failed, null register.");
     183           15 :     for (const auto& regType : reg->GetRegisterTypes(coreType)) {
     184           10 :         DumpV4DebugRegister(coreType, coreId, regType, reg->GetRegisterTable(regType), regData);
     185              :     }
     186            5 :     DumpV4ErrorRegister(coreType, coreId, reg->GetErrorRegisterTable(), regData);
     187              : 
     188            5 :     size_t totalSize = regData.size() * sizeof(RegInfoWide);
     189            5 :     IDE_LOGI("coreType=%d, coreId=%d, register num=%zu", static_cast<int32_t>(coreType), coreId, regData.size());
     190            5 :     std::string data(reinterpret_cast<const char*>(regData.data()), totalSize);
     191            5 :     ELF::SectionPtr registerSection = coreFile_.AddSection(ASCEND_SHTYPE_REGS, sectionName);
     192            5 :     IDE_CTRL_VALUE_FAILED(registerSection != nullptr, return, "Create %s section failed.", sectionName.c_str());
     193            5 :     registerSection->SetData(data);
     194            5 :     registerSection->SetEntSize(sizeof(RegInfoWide));
     195            5 : }
     196              : 
     197           10 : void DumpCore::DumpV4DebugRegister(
     198              :     uint8_t coreType, uint16_t coreId, RegisterType regType, const std::vector<RegisterTable>& tables,
     199              :     std::vector<RegInfoWide>& regData) const
     200              : {
     201           10 :     DumpDebugRegisterImpl(coreType, coreId, regType, tables, regData);
     202           10 : }
     203              : 
     204            5 : void DumpCore::DumpV4ErrorRegister(
     205              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables,
     206              :     std::vector<RegInfoWide>& regData) const
     207              : {
     208            5 :     DumpErrorRegisterImpl(coreType, coreId, tables, regData);
     209            5 : }
     210              : 
     211          235 : uint16_t DumpCore::ConvertCoreId(uint8_t coreType, uint16_t coreId) const
     212              : {
     213          235 :     auto *plat = CoredumpManager::Get();
     214          235 :     if (plat == nullptr) {
     215           15 :         IDE_LOGW("[DumpCore] Platform unavailable, coreId not converted.");
     216           15 :         return coreId;
     217              :     }
     218          220 :     return plat->ConvertCoreId(coreType, coreId);
     219              : }
     220              : } // namespace Adx
        

Generated by: LCOV version 2.0-1