LCOV - code coverage report
Current view: top level - adump/exception - kernel_pc_fixer.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.0 % 215 202
Test Date: 2026-07-28 10:54:24 Functions: 100.0 % 25 25

            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 <algorithm>
      11              : #include <initializer_list>
      12              : #include <mutex>
      13              : #include "securec.h"
      14              : #include "runtime/base.h"
      15              : #include "kernel_pc_fixer.h"
      16              : #include "acc_error_info.h"
      17              : #include "common/adump_dsmi.h"
      18              : #include "common/adump_platform_manager.h"
      19              : #include "log/adx_log.h"
      20              : 
      21              : namespace Adx {
      22              : namespace {
      23              : constexpr uint32_t UINT32_BIT_NUM = 32U;
      24              : constexpr uint32_t V100_AIC_ERR_NUM = 6U;
      25              : std::mutex g_pcFixerMutex;
      26              : 
      27              : // start/end 为闭区间,当前调用点均使用合法常量范围。
      28         1540 : constexpr uint64_t GenPcMask64(uint64_t start, uint64_t end)
      29              : {
      30         1540 :     return static_cast<uint64_t>(((1ULL << (end - start + 1ULL)) - 1ULL) << start);
      31              : }
      32              : 
      33           90 : constexpr uint32_t GenPcMask32(uint32_t start, uint32_t end)
      34              : {
      35           90 :     return static_cast<uint32_t>(((1ULL << (end - start + 1ULL)) - 1ULL) << start);
      36              : }
      37              : 
      38          770 : PcFixEntry MakePcFixEntry(uint32_t errInfoRegNum, uint64_t srcMask, uint64_t dstMask)
      39              : {
      40          770 :     return {errInfoRegNum, srcMask, dstMask};
      41              : }
      42              : 
      43          420 : void AddPcFixGroup(
      44              :     std::vector<PcFixGroup>& groups, uint32_t moduleId, uint32_t aicErrMask,
      45              :     std::initializer_list<PcFixEntry> entries)
      46              : {
      47          420 :     if (aicErrMask == 0) {
      48          143 :         return;
      49              :     }
      50          277 :     PcFixGroup group;
      51          277 :     group.moduleId = moduleId;
      52          277 :     group.aicErrMask = aicErrMask;
      53          277 :     group.entries.insert(group.entries.end(), entries.begin(), entries.end());
      54          277 :     groups.push_back(group);
      55          277 : }
      56              : 
      57              : } // namespace
      58              : 
      59           31 : void PcFixerInterface::ReplacePcBits(uint64_t& pc, uint32_t regValue, uint64_t srcMask, uint64_t dstMask)
      60              : {
      61           31 :     if (srcMask == 0 || dstMask == 0 || __builtin_popcountll(srcMask) != __builtin_popcountll(dstMask)) {
      62            0 :         IDE_LOGW("[Dump][Exception] Invalid PC fix mask, srcMask=%lu, dstMask=%lu.", srcMask, dstMask);
      63            0 :         return;
      64              :     }
      65           31 :     int srcShift = __builtin_ctzll(srcMask);
      66           31 :     int dstShift = __builtin_ctzll(dstMask);
      67           31 :     uint64_t extracted = (static_cast<uint64_t>(regValue) & srcMask) >> srcShift;
      68           31 :     pc = (pc & ~dstMask) | ((extracted << dstShift) & dstMask);
      69              : }
      70              : 
      71           31 : uint64_t PcFixerInterface::FixPc(uint64_t pc, const uint32_t errReg[], size_t errRegLen)
      72              : {
      73           31 :     if (errReg == nullptr || errRegLen == 0) {
      74            4 :         IDE_LOGW("[Dump][Exception] Invalid error register info, skip fix PC.");
      75            4 :         return pc;
      76              :     }
      77              : 
      78           27 :     std::vector<const PcFixGroup*> matchedGroups = GetMatchedGroups(errReg, errRegLen);
      79           27 :     if (matchedGroups.empty()) {
      80            8 :         IDE_LOGI("[Dump][Exception] No matched PC fix module, skip fix PC.");
      81            8 :         return pc;
      82              :     }
      83              : 
      84           19 :     std::vector<uint64_t> fixedPcs;
      85           19 :     fixedPcs.reserve(matchedGroups.size());
      86           40 :     for (const auto* matchedGroup : matchedGroups) {
      87           21 :         uint64_t moduleFixedPc = pc;
      88           54 :         for (const auto& entry : matchedGroup->entries) {
      89           33 :             if (entry.errInfoRegNum >= errRegLen) {
      90            2 :                 continue;
      91              :             }
      92           31 :             uint32_t regValue = errReg[entry.errInfoRegNum];
      93           31 :             ReplacePcBits(moduleFixedPc, regValue, entry.srcMask, entry.dstMask);
      94              :         }
      95           21 :         fixedPcs.push_back(moduleFixedPc);
      96           21 :         std::string moduleName = GetModuleName(matchedGroup->moduleId);
      97           21 :         IDE_LOGE("[Dump][Exception] Fix PC with module=%s, originalPC=0x%lx, fixedPC=0x%lx.",
      98              :             moduleName.c_str(), pc, fixedPcs.back());
      99           21 :     }
     100           19 :     return fixedPcs.front();
     101           27 : }
     102              : 
     103           27 : std::vector<const PcFixGroup*> PcFixerInterface::GetMatchedGroups(const uint32_t errReg[], size_t errRegLen) const
     104              : {
     105           27 :     std::vector<const PcFixGroup*> matchedGroups;
     106          237 :     for (uint32_t i = 0; i < errCount_; i++) {
     107          210 :         uint32_t errIdx = errStartIdx_ + i;
     108          210 :         if (errIdx >= errRegLen) {
     109           10 :             continue;
     110              :         }
     111          200 :         uint32_t errVal = errReg[errIdx];
     112          200 :         if (errVal == 0) {
     113          176 :             continue;
     114              :         }
     115           24 :         if (i >= table_.size() || table_[i].empty()) {
     116            1 :             continue;
     117              :         }
     118           64 :         for (const auto& group : table_[i]) {
     119           41 :             if ((errVal & group.aicErrMask) == 0) {
     120           17 :                 continue;
     121              :             }
     122           24 :             bool moduleExists = std::any_of(matchedGroups.begin(), matchedGroups.end(),
     123            5 :                 [&group](const auto* matchedGroup) {
     124            5 :                     return matchedGroup->moduleId == group.moduleId;
     125              :                 });
     126           24 :             if (moduleExists) {
     127            3 :                 continue;
     128              :             }
     129           21 :             matchedGroups.push_back(&group);
     130              :         }
     131              :     }
     132           27 :     return matchedGroups;
     133            0 : }
     134              : 
     135              : // ===== V100(CloudV2)错误位名称表 =====
     136              : 
     137              : namespace {
     138              : const char* const AIC_ERROR_0_BIT_NAMES[UINT32_BIT_NUM] = {
     139              :     "biu_l2_read_oob", "biu_l2_write_oob", "ccu_call_depth_ovrflw", "ccu_div0",
     140              :     "ccu_illegal_instr", "ccu_loop_cnt_err", "ccu_loop_err", "ccu_neg_sqrt",
     141              :     "ccu_ub_ecc", "cube_invld_input", "cube_l0a_ecc", "cube_l0a_rdwr_cflt",
     142              :     "cube_l0a_wrap_around", "cube_l0b_ecc", "cube_l0b_rdwr_cflt", "cube_l0b_wrap_around",
     143              :     "cube_l0c_ecc", "cube_l0c_rdwr_cflt", "cube_l0c_self_rdwr_cflt", "cube_l0c_wrap_around",
     144              :     "ifu_bus_err", "mte_aipp_illegal_param", "mte_bas_raddr_obound", "mte_biu_rdwr_resp",
     145              :     "mte_cidx_overflow", "mte_decomp", "mte_f1wpos_larger_fsize", "mte_fmap_less_kernel",
     146              :     "mte_fmapwh_larger_l1size", "mte_fpos_larger_fsize", "mte_gdma_illegal_burst_len", "mte_gdma_illegal_burst_num",
     147              : };
     148              : 
     149              : const char* const AIC_ERROR_1_BIT_NAMES[UINT32_BIT_NUM] = {
     150              :     "mte_gdma_read_overflow", "mte_gdma_write_overflow", "mte_comp", "mte_illegal_fm_size",
     151              :     "mte_illegal_l1_3d_size", "mte_illegal_stride", "mte_l0a_rdwr_cflt", "mte_l0b_rdwr_cflt",
     152              :     "mte_l1_ecc", "mte_padding_cfg", "mte_read_overflow", "mte_rob_ecc",
     153              :     "mte_tlu_ecc", "mte_ub_ecc", "mte_unzip", "mte_write_3d_overflow",
     154              :     "mte_write_overflow", "vec_data_excp_ccu", "vec_data_excp_mte", "vec_data_excp_vec",
     155              :     "vec_div0", "vec_illegal_mask", "vec_inf_nan", "vec_l0c_ecc",
     156              :     "vec_l0c_rdwr_cflt", "vec_neg_ln", "vec_neg_sqrt", "vec_same_blk_addr",
     157              :     "vec_ub_ecc", "vec_ub_self_rdwr_cflt", "vec_ub_wrap_around", "biu_dfx_err",
     158              : };
     159              : 
     160              : const char* const AIC_ERROR_2_BIT_NAMES[UINT32_BIT_NUM] = {
     161              :     "ccu_sbuf_ecc", "vec_col2img_rd_fm_addr_ovflow",
     162              :     "vec_col2img_rd_dfm_addr_ovfflow", "vec_col2img_illegal_fm_size",
     163              :     "vec_col2img_illegal_stride", "vec_col2img_illegal_1st_win_pos",
     164              :     "vec_col2img_illegal_fetch_pos", "vec_col2img_illegal_k_size",
     165              :     "ccu_inf_nan", "mte_illegal_schn_cfg", "mte_atm_addr_misalg",
     166              :     "vec_instr_addr_misalign", "vec_instr_illegal_cfg", "vec_instr_undef",
     167              :     "ccu_addr_err",
     168              :     "reserved_ccu_bus_err", "mte_err_addr_misalign", "mte_err_dw_pad_conf_err",
     169              :     "mte_err_dw_fmap_h_illegal", "mte_err_wino_l0b_write_overflow",
     170              :     "mte_err_wino_l0b_read_overflow", "mte_err_illegal_v_cov_pad_ctl",
     171              :     "mte_err_illegal_h_cov_pad_ctl", "mte_err_illegal_w_size",
     172              :     "mte_err_illegal_h_size", "mte_err_illegal_chn_size",
     173              :     "mte_err_illegal_k_m_ext_step", "mte_err_illegal_k_m_start_pos",
     174              :     "mte_err_illegal_smallk_cfg", "mte_err_read_3d_overflow", "ccu_veciq_ecc",
     175              :     "ccu_dc_data_ecc",
     176              : };
     177              : 
     178              : const char* const AIC_ERROR_3_BIT_NAMES[UINT32_BIT_NUM] = {
     179              :     "ccu_dc_tag_ecc", "ccu_div0_fp", "ccu_neg_sqrt_fp", "cnt_sw_bus_err",
     180              :     "fixp_err_instr_addr_misal", "fixp_err_illegal_cfg", "fixp_err_read_l0c_ovflw",
     181              :     "fixp_err_read_l1_ovflw", "fixp_err_read_ub_ovflw", "fixp_err_write_l1_ovflw",
     182              :     "fixp_err_write_ub_ovflw", "fixp_err_fbuf_write_ovflw", "fixp_err_fbuf_read_ovflw",
     183              :     "sc_reg_parity_err", "mte_err_fifo_parity", "mte_err_waitset",
     184              :     "ccu_err_parity_err", "mte_err_cache_ecc", "cube_err_hset_cnt_unf",
     185              :     "cube_err_hset_cnt_ovf", "mte_err_instr_illegal_cfg", "mte_err_hebcd",
     186              :     "mte_err_hebce", "mte_err_waipp", "ccu_seq_err", "ccu_mpu_err",
     187              :     "ccu_lsu_err", "ccu_pb_ecc_err", "mte_ub_wr_ovflw", "mte_ub_rd_ovflw",
     188              :     "cube_illegal_instr", "ccu_safety_crc_err",
     189              : };
     190              : 
     191              : const char* const AIC_ERROR_4_BIT_NAMES[UINT32_BIT_NUM] = {
     192              :     "mte_timeout", "mte_ub_rd_cflt", "mte_ub_wr_cflt", "mte_ktable_wr_addr_overflow",
     193              :     "mte_ktable_rd_addr_overflow", "ccu_ub_rd_cflt", "ccu_ub_wr_cflt", "ccu_ub_overflow_err",
     194              :     "biu_unsplit_err", "mte_stb_ecc_err", "mte_aipp_ecc_err", "ccu_lsu_atomic_err",
     195              :     "ccu_cross_core_set_ovfl_err", "fixp_err_out_write_overflow", "cube_err_pbuf_wrap_around", "fixp_l0c_ecc",
     196              :     "mte_err_l0c_rdwr_cflt", "reserved", "reserved", "reserved",
     197              :     "reserved", "reserved", "reserved", "reserved",
     198              :     "reserved", "reserved", "reserved", "reserved",
     199              :     "reserved", "reserved", "reserved", "reserved",
     200              : };
     201              : 
     202              : const char* const AIC_ERROR_5_BIT_NAMES[UINT32_BIT_NUM] = {
     203              :     "vec_data_excpt_mte", "vec_data_excpt_su", "vec_data_excpt_vec", "vec_instr_timeout",
     204              :     "vec_instrs_undef", "vec_instr_ill_cfg", "vec_instr_misalign", "vec_instr_ill_mask",
     205              :     "vec_instr_ill_sqzn", "vec_ub_addr_wrap_around", "vec_ub_ecc_mberr", "vec_idata_inf_nan",
     206              :     "vec_div_by_zero", "vec_valu_neg_ln", "vec_valu_neg_sqrt", "vec_vci_idata_out_range",
     207              :     "vec_ill_vloop_op", "vec_ill_vloop_sreg", "vec_ld_num_mismatch", "vec_st_num_mismatch",
     208              :     "vec_ex_num_mismatch", "vec_ld_num_exceed_limit", "vec_st_num_exceed_limit", "vec_ill_instr_padding",
     209              :     "vec_ill_vga_vpd_order", "vec_ic_ecc_err", "vec_biu_resp_err", "vec_pb_ecc_mberr",
     210              :     "vec_pb_read_no_resp", "vec_valu_ill_issue", "vec_err_parity_err", "reserved",
     211              : };
     212              : 
     213              : const char* const* const AIC_ERROR_BIT_NAMES[V100_AIC_ERR_NUM] = {
     214              :     AIC_ERROR_0_BIT_NAMES, AIC_ERROR_1_BIT_NAMES, AIC_ERROR_2_BIT_NAMES,
     215              :     AIC_ERROR_3_BIT_NAMES, AIC_ERROR_4_BIT_NAMES, AIC_ERROR_5_BIT_NAMES,
     216              : };
     217              : 
     218              : enum V100ModuleIdx {
     219              :     V100_CUBE_INFO_IDX,
     220              :     V100_CCU_INFO_IDX,
     221              :     V100_IFU_INFO_IDX,
     222              :     V100_MTE_INFO_IDX,
     223              :     V100_VEC_INFO_IDX,
     224              :     V100_FIXP_INFO_IDX,
     225              :     V100_MODULE_ID_NUM
     226              : };
     227              : 
     228              : enum V200ErrorIdx {
     229              :     V200_SC_ERROR_T0_IDX,
     230              :     V200_SU_ERROR_T0_IDX,
     231              :     V200_MTE_ERROR_T0_IDX,
     232              :     V200_MTE_ERROR_T1_IDX,
     233              :     V200_VEC_ERROR_T0_IDX,
     234              :     V200_VEC_ERROR_T2_IDX,
     235              :     V200_CUBE_ERROR_T0_IDX,
     236              :     V200_CUBE_ERROR_T1_IDX,
     237              :     V200_L1_ERROR_T0_IDX,
     238              :     V200_L1_ERROR_T1_IDX,
     239              :     V200_ERROR_IDX_NUM
     240              : };
     241              : 
     242              : // V100 errReg 下标对应的 RTS 寄存器枚举名称,与 rtErrRegInfoIdxV100_t 顺序一致。
     243              : const char* const V100_REG_NAMES[] = {
     244              :     "AIC_ERR_0", "AIC_ERR_1", "AIC_ERR_2", "AIC_ERR_3",
     245              :     "AIC_ERR_4", "AIC_ERR_5", "BIU_ERR_0", "BIU_ERR_1",
     246              :     "CCU_ERR_0", "CCU_ERR_1", "CUBE_ERR_0", "CUBE_ERR_1",
     247              :     "IFU_ERR_0", "IFU_ERR_1", "MTE_ERR_0", "MTE_ERR_1",
     248              :     "VEC_ERR_0", "VEC_ERR_1", "FIXP_ERR_0", "FIXP_ERR_1",
     249              :     "AIC_COND_0", "AIC_COND_1",
     250              : };
     251              : 
     252              : // V200 errReg 下标对应的 RTS 寄存器枚举名称,与 rtErrRegInfoIdxV200_t 顺序一致。
     253              : const char* const V200_REG_NAMES[] = {
     254              :     "SU_ERR_INFO_T0_0", "SU_ERR_INFO_T0_1", "SU_ERR_INFO_T0_2",
     255              :     "SU_ERR_INFO_T0_3", "MTE_ERR_INFO_T0_0", "MTE_ERR_INFO_T0_1",
     256              :     "MTE_ERR_INFO_T0_2", "MTE_ERR_INFO_T1_0", "MTE_ERR_INFO_T1_1",
     257              :     "MTE_ERR_INFO_T1_2", "VEC_ERR_INFO_T0_0", "VEC_ERR_INFO_T0_1",
     258              :     "VEC_ERR_INFO_T0_2", "VEC_ERR_INFO_T0_3", "VEC_ERR_INFO_T0_4",
     259              :     "VEC_ERR_INFO_T0_5", "CUBE_ERR_INFO_T0_0", "CUBE_ERR_INFO_T0_1",
     260              :     "L1_ERR_INFO_T0_0", "L1_ERR_INFO_T0_1", "SC_ERROR_T0_0",
     261              :     "SU_ERROR_T0_0", "MTE_ERROR_T0_0", "MTE_ERROR_T1_0",
     262              :     "VEC_ERROR_T0_0", "VEC_ERROR_T0_2", "CUBE_ERROR_T0_0",
     263              :     "CUBE_ERROR_T0_1", "L1_ERROR_T0_0", "L1_ERROR_T0_1",
     264              :     "SC_ERR_INFO_T0_0", "SC_ERR_INFO_T0_1", "SU_SPR_CONDITION_0",
     265              :     "SU_SPR_CONDITION_1",
     266              : };
     267              : 
     268         2112 : std::string GetV100BitName(uint32_t aicErrorIdx, uint32_t bit)
     269              : {
     270         2112 :     if (aicErrorIdx >= V100_AIC_ERR_NUM || bit >= UINT32_BIT_NUM) {
     271            0 :         return "";
     272              :     }
     273         4224 :     return std::string(AIC_ERROR_BIT_NAMES[aicErrorIdx][bit]);
     274              : }
     275              : 
     276         2112 : bool IsCubeErrorBitName(const std::string& bitName)
     277              : {
     278         2112 :     return bitName.find("cube_") == 0 || bitName.find("cube_err_") == 0 || bitName.find("cube_invld_") == 0;
     279              : }
     280              : 
     281         1947 : bool IsCcuErrorBitName(const std::string& bitName)
     282              : {
     283         5269 :     return bitName.find("ccu_") == 0 || bitName.find("ccu_err_") == 0 || bitName.find("ccu_inf_") == 0 ||
     284         4983 :            bitName.find("ccu_addr_") == 0 || bitName.find("ccu_div0_fp") == 0 ||
     285         4983 :            bitName.find("ccu_neg_sqrt_fp") == 0 || bitName.find("ccu_dc_") == 0 ||
     286         4983 :            bitName.find("ccu_sbuf_") == 0 || bitName.find("ccu_veciq_") == 0 ||
     287         4983 :            bitName.find("ccu_pb_ecc_err") == 0 || bitName.find("ccu_seq_") == 0 ||
     288         6930 :            bitName.find("ccu_mpu_") == 0 || bitName.find("ccu_lsu_") == 0 ||
     289         3608 :            bitName.find("ccu_safety_") == 0;
     290              : }
     291              : 
     292          990 : bool IsVecErrorBitName(const std::string& bitName)
     293              : {
     294         1760 :     return bitName.find("vec_") == 0 || bitName.find("vec_data_excp_") == 0 ||
     295         2145 :            bitName.find("vec_col2img_") == 0 || bitName.find("vec_instr_") == 0 ||
     296         1375 :            bitName.find("vec_err_parity_") == 0;
     297              : }
     298              : 
     299           66 : void BuildV100ModuleMasks(uint32_t aicErrorIdx, uint32_t moduleMasks[])
     300              : {
     301         2178 :     for (uint32_t bit = 0; bit < UINT32_BIT_NUM; bit++) {
     302         2112 :         std::string bitName = GetV100BitName(aicErrorIdx, bit);
     303         2112 :         if (IsCubeErrorBitName(bitName)) {
     304          165 :             moduleMasks[V100_CUBE_INFO_IDX] |= (1U << bit);
     305         1947 :         } else if (IsCcuErrorBitName(bitName)) {
     306          286 :             moduleMasks[V100_CCU_INFO_IDX] |= (1U << bit);
     307         1661 :         } else if (bitName.find("mte_") == 0 || bitName.find("mte_err_") == 0) {
     308          671 :             moduleMasks[V100_MTE_INFO_IDX] |= (1U << bit);
     309          990 :         } else if (IsVecErrorBitName(bitName)) {
     310          605 :             moduleMasks[V100_VEC_INFO_IDX] |= (1U << bit);
     311          385 :         } else if (bitName.find("fixp_") == 0 || bitName.find("fixp_err_") == 0) {
     312          121 :             moduleMasks[V100_FIXP_INFO_IDX] |= (1U << bit);
     313              :         }
     314         2112 :     }
     315           66 : }
     316              : 
     317           66 : void AppendV100PcFixGroups(const uint32_t moduleMasks[], std::vector<PcFixGroup>& groups)
     318              : {
     319           66 :     AddPcFixGroup(groups, V100_CUBE_INFO_IDX, moduleMasks[V100_CUBE_INFO_IDX],
     320           66 :         {MakePcFixEntry(RT_V100_CUBE_ERR_0, GenPcMask64(0, 7), GenPcMask64(2, 9)),
     321           66 :             MakePcFixEntry(RT_V100_CUBE_ERR_0, GenPcMask64(24, 31), GenPcMask64(10, 17))});
     322           66 :     AddPcFixGroup(groups, V100_CCU_INFO_IDX, moduleMasks[V100_CCU_INFO_IDX],
     323           66 :         {MakePcFixEntry(RT_V100_CCU_ERR_0, GenPcMask64(0, 7), GenPcMask64(2, 9)),
     324           66 :             MakePcFixEntry(RT_V100_CCU_ERR_0, GenPcMask64(23, 30), GenPcMask64(10, 17))});
     325           66 :     AddPcFixGroup(groups, V100_MTE_INFO_IDX, moduleMasks[V100_MTE_INFO_IDX],
     326           66 :         {MakePcFixEntry(RT_V100_MTE_ERR_0, GenPcMask64(0, 7), GenPcMask64(2, 9)),
     327           66 :             MakePcFixEntry(RT_V100_MTE_ERR_1, GenPcMask64(0, 7), GenPcMask64(10, 17))});
     328           66 :     AddPcFixGroup(groups, V100_VEC_INFO_IDX, moduleMasks[V100_VEC_INFO_IDX],
     329           66 :         {MakePcFixEntry(RT_V100_VEC_ERR_0, GenPcMask64(0, 7), GenPcMask64(2, 9)),
     330           66 :             MakePcFixEntry(RT_V100_VEC_ERR_1, GenPcMask64(0, 7), GenPcMask64(10, 17))});
     331           66 :     AddPcFixGroup(groups, V100_FIXP_INFO_IDX, moduleMasks[V100_FIXP_INFO_IDX],
     332           66 :         {MakePcFixEntry(RT_V100_FIXP_ERR_0, GenPcMask64(0, 7), GenPcMask64(2, 9)),
     333           66 :             MakePcFixEntry(RT_V100_FIXP_ERR_1, GenPcMask64(0, 7), GenPcMask64(10, 17))});
     334           66 : }
     335              : 
     336           10 : void InitV200CommonPcFixGroups(std::vector<std::vector<PcFixGroup>>& table)
     337              : {
     338           10 :     AddPcFixGroup(table[V200_SU_ERROR_T0_IDX], V200_SU_ERROR_T0_IDX, GenPcMask32(0, 31),
     339           10 :         {MakePcFixEntry(RT_V200_SU_ERR_INFO_T0_0, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     340           10 :     AddPcFixGroup(table[V200_MTE_ERROR_T0_IDX], V200_MTE_ERROR_T0_IDX, GenPcMask32(0, 31),
     341           10 :         {MakePcFixEntry(RT_V200_MTE_ERR_INFO_T0_0, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     342              :     // MTE_ERR_INFO_T1_0值废弃,使用MTE_ERR_INFO_T0_0
     343           10 :     AddPcFixGroup(table[V200_MTE_ERROR_T1_IDX], V200_MTE_ERROR_T0_IDX, GenPcMask32(0, 31),
     344           10 :         {MakePcFixEntry(RT_V200_MTE_ERR_INFO_T0_0, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     345           10 : }
     346              : 
     347           10 : void InitV200VecPcFixGroups(std::vector<std::vector<PcFixGroup>>& table)
     348              : {
     349           10 :     AddPcFixGroup(table[V200_VEC_ERROR_T0_IDX], V200_VEC_ERROR_T0_IDX, GenPcMask32(0, 25),
     350           10 :         {MakePcFixEntry(RT_V200_VEC_ERR_INFO_T0_1, GenPcMask64(0, 31), GenPcMask64(0, 31)),
     351           10 :             MakePcFixEntry(RT_V200_VEC_ERR_INFO_T0_2, GenPcMask64(0, 16), GenPcMask64(32, 48))});
     352           10 :     AddPcFixGroup(table[V200_VEC_ERROR_T2_IDX], V200_VEC_ERROR_T0_IDX, GenPcMask32(0, 1),
     353           10 :         {MakePcFixEntry(RT_V200_VEC_ERR_INFO_T0_1, GenPcMask64(0, 31), GenPcMask64(0, 31)),
     354           10 :             MakePcFixEntry(RT_V200_VEC_ERR_INFO_T0_2, GenPcMask64(0, 16), GenPcMask64(32, 48))});
     355           10 : }
     356              : 
     357           10 : void InitV200CubeAndL1PcFixGroups(std::vector<std::vector<PcFixGroup>>& table)
     358              : {
     359           10 :     AddPcFixGroup(table[V200_CUBE_ERROR_T0_IDX], V200_CUBE_ERROR_T0_IDX, GenPcMask32(0, 15),
     360           10 :         {MakePcFixEntry(RT_V200_CUBE_ERR_INFO_T0_1, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     361           10 :     AddPcFixGroup(table[V200_CUBE_ERROR_T1_IDX], V200_CUBE_ERROR_T0_IDX, GenPcMask32(0, 9),
     362           10 :         {MakePcFixEntry(RT_V200_CUBE_ERR_INFO_T0_1, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     363           10 :     AddPcFixGroup(table[V200_L1_ERROR_T0_IDX], V200_L1_ERROR_T0_IDX, GenPcMask32(0, 30),
     364           10 :         {MakePcFixEntry(RT_V200_L1_ERR_INFO_T0_1, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     365           10 :     AddPcFixGroup(table[V200_L1_ERROR_T1_IDX], V200_L1_ERROR_T0_IDX, GenPcMask32(0, 21),
     366           10 :         {MakePcFixEntry(RT_V200_L1_ERR_INFO_T0_1, GenPcMask64(0, 15), GenPcMask64(2, 17))});
     367           10 : }
     368              : 
     369            7 : std::string BuildErrorRegistersStr(
     370              :     const char* const regNames[], size_t regNameNum, const uint32_t errReg[], size_t errRegLen)
     371              : {
     372            7 :     constexpr size_t REG_ITEM_BUF_LEN = 128U;
     373            7 :     std::string result;
     374          173 :     for (size_t i = 0; i < regNameNum && i < errRegLen; i++) {
     375          166 :         char item[REG_ITEM_BUF_LEN] = {0};
     376          166 :         int len = snprintf_s(item, sizeof(item), sizeof(item) - 1, "%s=0x%x ", regNames[i], errReg[i]);
     377          166 :         if (len < 0) {
     378            0 :             continue;
     379              :         }
     380          166 :         result += item;
     381              :     }
     382            7 :     return result;
     383            0 : }
     384              : } // namespace
     385              : 
     386              : // ===== CloudV2 PC 修正 =====
     387              : 
     388           11 : CloudV2PcFixer::CloudV2PcFixer()
     389              : {
     390           11 :     errStartIdx_ = static_cast<uint32_t>(RT_V100_AIC_ERR_0);
     391           11 :     errCount_ = V100_AIC_ERR_NUM;
     392           11 :     table_.resize(V100_AIC_ERR_NUM);
     393              : 
     394           77 :     for (uint32_t i = 0; i < V100_AIC_ERR_NUM; i++) {
     395           66 :         uint32_t moduleMasks[V100_MODULE_ID_NUM] = {0};
     396           66 :         BuildV100ModuleMasks(i, moduleMasks);
     397           66 :         AppendV100PcFixGroups(moduleMasks, table_[i]);
     398              :     }
     399           11 : }
     400              : 
     401            6 : std::string CloudV2PcFixer::GetErrorRegisters(const uint32_t errReg[], size_t errRegLen) const
     402              : {
     403            6 :     if (errReg == nullptr || errRegLen == 0) {
     404            0 :         return "";
     405              :     }
     406            6 :     constexpr size_t regNameNum = sizeof(V100_REG_NAMES) / sizeof(V100_REG_NAMES[0]);
     407            6 :     return BuildErrorRegistersStr(V100_REG_NAMES, regNameNum, errReg, errRegLen);
     408              : }
     409              : 
     410           10 : std::string CloudV2PcFixer::GetModuleName(uint32_t moduleId) const
     411              : {
     412           10 :     const char* const moduleNames[V100_MODULE_ID_NUM] = {"CUBE", "CCU", "IFU", "MTE", "VEC", "FIXP"};
     413           10 :     if (moduleId >= V100_MODULE_ID_NUM) {
     414            0 :         return "UNKNOWN";
     415              :     }
     416           20 :     return moduleNames[moduleId];
     417              : }
     418              : 
     419              : // ===== CloudV4 PC 修正 =====
     420              : 
     421           10 : CloudV4PcFixer::CloudV4PcFixer()
     422              : {
     423           10 :     errStartIdx_ = static_cast<uint32_t>(RT_V200_SC_ERROR_T0_0);
     424           10 :     errCount_ = V200_ERROR_IDX_NUM;
     425           10 :     table_.resize(errCount_);
     426              : 
     427              :     // SC_ERROR_T0_0 没有 PC 映射规则。
     428           10 :     table_[V200_SC_ERROR_T0_IDX] = {};
     429           10 :     InitV200CommonPcFixGroups(table_);
     430           10 :     InitV200VecPcFixGroups(table_);
     431           10 :     InitV200CubeAndL1PcFixGroups(table_);
     432           10 : }
     433              : 
     434            1 : std::string CloudV4PcFixer::GetErrorRegisters(const uint32_t errReg[], size_t errRegLen) const
     435              : {
     436            1 :     if (errReg == nullptr || errRegLen == 0) {
     437            0 :         return "";
     438              :     }
     439            1 :     constexpr size_t regNameNum = sizeof(V200_REG_NAMES) / sizeof(V200_REG_NAMES[0]);
     440            1 :     return BuildErrorRegistersStr(V200_REG_NAMES, regNameNum, errReg, errRegLen);
     441              : }
     442              : 
     443           11 : std::string CloudV4PcFixer::GetModuleName(uint32_t moduleId) const
     444              : {
     445           11 :     switch (moduleId) {
     446            4 :         case V200_SU_ERROR_T0_IDX:
     447            8 :             return "SU";
     448            3 :         case V200_MTE_ERROR_T0_IDX:
     449            6 :             return "MTE";
     450            2 :         case V200_VEC_ERROR_T0_IDX:
     451            4 :             return "VEC";
     452            1 :         case V200_CUBE_ERROR_T0_IDX:
     453            2 :             return "CUBE";
     454            1 :         case V200_L1_ERROR_T0_IDX:
     455            2 :             return "L1";
     456            0 :         default:
     457            0 :             return "UNKNOWN";
     458              :     }
     459              : }
     460              : 
     461              : std::unique_ptr<PcFixerInterface> PcFixerFactory::instance_;
     462              : 
     463           21 : PcFixerInterface* PcFixerFactory::GetInstance()
     464              : {
     465           21 :     std::lock_guard<std::mutex> lock(g_pcFixerMutex);
     466           21 :     if (!instance_) {
     467           10 :         auto *plat = CoredumpManager::Get();
     468           10 :         if (plat == nullptr) {
     469            3 :             IDE_LOGW("[Dump][Exception] Platform unavailable, PC fix skipped.");
     470            3 :             return nullptr;
     471              :         }
     472            7 :         instance_ = plat->CreatePcFixer();
     473            7 :         if (!instance_) {
     474            0 :             IDE_LOGW("[Dump][Exception] Unsupported platform for PC fix, PC fix skipped.");
     475            0 :             return nullptr;
     476              :         }
     477              :     }
     478           18 :     return instance_.get();
     479           21 : }
     480              : 
     481              : } // namespace Adx
        

Generated by: LCOV version 2.0-1