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
|