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-08-31 10:09:28 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,
      44              :     std::vector<uint8_t>& data) const
      45              : {
      46        18044 :     data.resize(table.num * table.byteWidth);
      47              :     rtDebugMemoryType_t memType;
      48        18044 :     if (regType == RegisterType::AIC || regType == RegisterType::AIV) {
      49          512 :         memType = RT_MEM_TYPE_REGISTER_DIRECT;
      50        17532 :     } else if (regType == RegisterType::AIC_DBG || regType == RegisterType::AIV_DBG) {
      51        17532 :         memType = RT_MEM_TYPE_REGISTER;
      52              :     } else {
      53            0 :         IDE_LOGE("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,
      75              :     std::vector<T>& regData) const
      76              : {
      77          177 :     std::stringstream ss;
      78        36442 :     for (const RegisterTable& table : tables) {
      79        18044 :         std::vector<uint8_t> data;
      80        18044 :         bool dataValid = DumpReadDebugAICoreRegister(coreType, coreId, regType, table, data);
      81        18044 :         errno_t err = EOK;
      82        18044 :         const uint8_t* dataPtr = data.data();
      83       345915 :         for (uint32_t i = 0; i < table.num; ++i) {
      84       327871 :             T regInfo{table.startAddr + i, REG_DATA_VALID, {0}, table.byteWidth, {0}};
      85       327871 :             if (dataValid) {
      86        41375 :                 err = memcpy_s(&regInfo.value, sizeof(regInfo.value), dataPtr, table.byteWidth);
      87        41375 :                 if (err != EOK) {
      88        20464 :                     IDE_LOGE(
      89              :                         "Failed to copy debug register data from cache buffer. "
      90              :                         "coreType: %hhu, coreId: %hu, addr: 0x%llx, ret: %d",
      91              :                         coreType, coreId, regInfo.addr, err);
      92        20464 :                     regInfo.validFlag = REG_DATA_INVALID;
      93              :                 }
      94              :             } else {
      95       286496 :                 regInfo.validFlag = REG_DATA_INVALID;
      96              :             }
      97       327871 :             dataPtr += table.byteWidth;
      98       327871 :             regData.emplace_back(regInfo);
      99              :         }
     100              :     }
     101          177 :     std::string dataStr = ss.str();
     102          177 :     if (!dataStr.empty()) {
     103            0 :         IDE_LOGW(
     104              :             "Debug register data. coreType=%d, coreId=%d.%s", static_cast<int32_t>(coreType), coreId, dataStr.c_str());
     105              :     }
     106          177 : }
     107              : 
     108              : template <typename T>
     109           85 : void DumpCore::DumpErrorRegisterImpl(
     110              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables, std::vector<T>& regData) const
     111              : {
     112           85 :     std::stringstream ss;
     113           85 :     std::vector<std::string> regLogs;
     114          170 :     for (uint32_t i = 0; i < exceptionRegInfo_.coreNum; i++) {
     115           85 :         rtExceptionErrRegInfo_t core = exceptionRegInfo_.errRegInfo[i];
     116           85 :         if (coreId != core.coreId || coreType != core.coreType) {
     117           68 :             continue;
     118              :         }
     119          565 :         for (const auto& table : tables) {
     120          531 :             T regInfo{table.offsetAddr, REG_DATA_VALID, {0}, table.byteWidth, {0}};
     121              :             errno_t err =
     122          531 :                 memcpy_s(&regInfo.value, sizeof(regInfo.value), core.errReg + table.errIndex, table.byteWidth);
     123          531 :             if (err != EOK) {
     124          480 :                 IDE_LOGE(
     125              :                     "Failed to copy error register data from exception args. "
     126              :                     "coreType: %hhu, coreId: %hu, addr: 0x%llx, ret: %d",
     127              :                     coreType, coreId, regInfo.addr, err);
     128          480 :                 regInfo.validFlag = REG_DATA_INVALID;
     129              :             } else {
     130           51 :                 std::string value = FormatRegisterData(regInfo.value, regInfo.regSize);
     131           51 :                 ss << table.name << "[0x" << std::hex << regInfo.addr << "]: " << value << ",";
     132           51 :             }
     133          531 :             regData.emplace_back(regInfo);
     134              :         }
     135              :     }
     136           85 :     std::string dataStr = ss.str();
     137           85 :     if (!dataStr.empty()) {
     138            2 :         IDE_LOGW(
     139              :             "Error register data. coreType=%d, coreId=%d. %s", static_cast<int32_t>(coreType), coreId, dataStr.c_str());
     140              :     }
     141           85 : }
     142              : 
     143           80 : void DumpCore::DumpV2Register(uint8_t coreType, uint16_t coreId)
     144              : {
     145           80 :     std::vector<RegInfo> regData;
     146           80 :     std::string sectionName = ASCEND_SHNAME_REGS + "." + std::to_string(ConvertCoreId(coreType, coreId));
     147           80 :     std::shared_ptr<RegisterInterface> reg = RegisterManager::GetInstance().GetRegister();
     148           80 :     IDE_CTRL_VALUE_FAILED(reg != nullptr, return, "Get register failed, null register.");
     149          327 :     for (const auto& regType : reg->GetRegisterTypes(coreType)) {
     150          167 :         DumpV2DebugRegister(coreType, coreId, reg->GetRegisterTable(regType), regData);
     151              :     }
     152           80 :     DumpV2ErrorRegister(coreType, coreId, reg->GetErrorRegisterTable(), regData);
     153              : 
     154           80 :     size_t totalSize = regData.size() * sizeof(RegInfo);
     155           80 :     std::string data(reinterpret_cast<const char*>(regData.data()), totalSize);
     156           80 :     ELF::SectionPtr registerSection = coreFile_.AddSection(ASCEND_SHTYPE_REGS, sectionName);
     157           80 :     IDE_CTRL_VALUE_FAILED(registerSection != nullptr, return, "Create %s section failed.", sectionName.c_str());
     158           80 :     registerSection->SetData(data);
     159           80 :     registerSection->SetEntSize(sizeof(RegInfo));
     160           80 : }
     161              : 
     162          167 : void DumpCore::DumpV2DebugRegister(
     163              :     uint8_t coreType, uint16_t coreId, const std::vector<RegisterTable>& tables, std::vector<RegInfo>& regData) const
     164              : {
     165              :     RegisterType regType;
     166          167 :     if (coreType == CORE_TYPE_AIC) {
     167           68 :         regType = RegisterType::AIC_DBG;
     168              :     } else {
     169           99 :         regType = RegisterType::AIV_DBG;
     170              :     }
     171          167 :     DumpDebugRegisterImpl(coreType, coreId, regType, tables, regData);
     172          167 : }
     173              : 
     174           80 : void DumpCore::DumpV2ErrorRegister(
     175              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables,
     176              :     std::vector<RegInfo>& regData) const
     177              : {
     178           80 :     DumpErrorRegisterImpl(coreType, coreId, tables, regData);
     179           80 : }
     180              : 
     181            5 : void DumpCore::DumpV4Register(uint8_t coreType, uint16_t coreId)
     182              : {
     183            5 :     std::vector<RegInfoWide> regData;
     184            5 :     std::string sectionName = ASCEND_SHNAME_REGS + "." + std::to_string(ConvertCoreId(coreType, coreId));
     185            5 :     std::shared_ptr<RegisterInterface> reg = RegisterManager::GetInstance().GetRegister();
     186            5 :     IDE_CTRL_VALUE_FAILED(reg != nullptr, return, "Get register failed, null register.");
     187           20 :     for (const auto& regType : reg->GetRegisterTypes(coreType)) {
     188           10 :         DumpV4DebugRegister(coreType, coreId, regType, reg->GetRegisterTable(regType), regData);
     189              :     }
     190            5 :     DumpV4ErrorRegister(coreType, coreId, reg->GetErrorRegisterTable(), regData);
     191              : 
     192            5 :     size_t totalSize = regData.size() * sizeof(RegInfoWide);
     193            5 :     IDE_LOGI("coreType=%d, coreId=%d, register num=%zu", static_cast<int32_t>(coreType), coreId, regData.size());
     194            5 :     std::string data(reinterpret_cast<const char*>(regData.data()), totalSize);
     195            5 :     ELF::SectionPtr registerSection = coreFile_.AddSection(ASCEND_SHTYPE_REGS, sectionName);
     196            5 :     IDE_CTRL_VALUE_FAILED(registerSection != nullptr, return, "Create %s section failed.", sectionName.c_str());
     197            5 :     registerSection->SetData(data);
     198            5 :     registerSection->SetEntSize(sizeof(RegInfoWide));
     199            5 : }
     200              : 
     201           10 : void DumpCore::DumpV4DebugRegister(
     202              :     uint8_t coreType, uint16_t coreId, RegisterType regType, const std::vector<RegisterTable>& tables,
     203              :     std::vector<RegInfoWide>& regData) const
     204              : {
     205           10 :     DumpDebugRegisterImpl(coreType, coreId, regType, tables, regData);
     206           10 : }
     207              : 
     208            5 : void DumpCore::DumpV4ErrorRegister(
     209              :     uint8_t coreType, uint16_t coreId, const std::vector<ErrorRegisterTable>& tables,
     210              :     std::vector<RegInfoWide>& regData) const
     211              : {
     212            5 :     DumpErrorRegisterImpl(coreType, coreId, tables, regData);
     213            5 : }
     214              : 
     215          235 : uint16_t DumpCore::ConvertCoreId(uint8_t coreType, uint16_t coreId) const
     216              : {
     217          235 :     auto* plat = CoredumpManager::Get();
     218          235 :     if (plat == nullptr) {
     219           15 :         IDE_LOGW("[DumpCore] Platform unavailable, coreId not converted.");
     220           15 :         return coreId;
     221              :     }
     222          220 :     return plat->ConvertCoreId(coreType, coreId);
     223              : }
     224              : } // namespace Adx
        

Generated by: LCOV version 2.0-1