165fefb2cSZane Shelley #include <assert.h>
265fefb2cSZane Shelley 
31a4f0e70SCaleb Palmer #include <analyzer/analyzer_main.hpp>
41a4f0e70SCaleb Palmer #include <analyzer/ras-data/ras-data-parser.hpp>
565fefb2cSZane Shelley #include <hei_main.hpp>
619df3706SZane Shelley #include <hei_util.hpp>
7f4792d68SZane Shelley #include <util/pdbg.hpp>
865fefb2cSZane Shelley 
965fefb2cSZane Shelley #include <algorithm>
1065fefb2cSZane Shelley #include <limits>
1165fefb2cSZane Shelley #include <string>
1265fefb2cSZane Shelley 
1365fefb2cSZane Shelley namespace analyzer
1465fefb2cSZane Shelley {
1565fefb2cSZane Shelley //------------------------------------------------------------------------------
1665fefb2cSZane Shelley 
__findRcsOscError(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause)17a7369f86SZane Shelley bool __findRcsOscError(const std::vector<libhei::Signature>& i_list,
18a7369f86SZane Shelley                        libhei::Signature& o_rootCause)
19a7369f86SZane Shelley {
20a7369f86SZane Shelley     // TODO: Consider returning all of them instead of one as root cause.
21a7369f86SZane Shelley     auto itr = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
2219df3706SZane Shelley         return (libhei::hash<libhei::NodeId_t>("TP_LOCAL_FIR") == t.getId() &&
23a7369f86SZane Shelley                 (42 == t.getBit() || 43 == t.getBit()));
24a7369f86SZane Shelley     });
25a7369f86SZane Shelley 
26a7369f86SZane Shelley     if (i_list.end() != itr)
27a7369f86SZane Shelley     {
28a7369f86SZane Shelley         o_rootCause = *itr;
29a7369f86SZane Shelley         return true;
30a7369f86SZane Shelley     }
31a7369f86SZane Shelley 
32a7369f86SZane Shelley     return false;
33a7369f86SZane Shelley }
34a7369f86SZane Shelley 
35a7369f86SZane Shelley //------------------------------------------------------------------------------
36a7369f86SZane Shelley 
__findPllUnlock(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause)37a7369f86SZane Shelley bool __findPllUnlock(const std::vector<libhei::Signature>& i_list,
38a7369f86SZane Shelley                      libhei::Signature& o_rootCause)
39a7369f86SZane Shelley {
40c62813d4SZane Shelley     using namespace util::pdbg;
41c62813d4SZane Shelley 
42a7369f86SZane Shelley     // TODO: Consider returning all of them instead of one as root cause.
43c62813d4SZane Shelley 
44c62813d4SZane Shelley     auto nodeId = libhei::hash<libhei::NodeId_t>("PLL_UNLOCK");
45c62813d4SZane Shelley 
46c62813d4SZane Shelley     // First, look for any PLL unlock attentions reported by a processsor chip.
47c62813d4SZane Shelley     auto itr1 = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
48c62813d4SZane Shelley         return (nodeId == t.getId() &&
49c62813d4SZane Shelley                 TYPE_PROC == getTrgtType(getTrgt(t.getChip())));
50a7369f86SZane Shelley     });
51a7369f86SZane Shelley 
52c62813d4SZane Shelley     if (i_list.end() != itr1)
53a7369f86SZane Shelley     {
54c62813d4SZane Shelley         o_rootCause = *itr1;
55c62813d4SZane Shelley         return true;
56c62813d4SZane Shelley     }
57c62813d4SZane Shelley 
58c62813d4SZane Shelley     // Then, look for any PLL unlock attentions reported by an OCMB chip. This
59c62813d4SZane Shelley     // is specifically for Odyssey, which are the only OCMBs that would report
60c62813d4SZane Shelley     // PLL unlock attentions.
61c62813d4SZane Shelley     auto itr2 = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
62c62813d4SZane Shelley         return (nodeId == t.getId() &&
63c62813d4SZane Shelley                 TYPE_OCMB == getTrgtType(getTrgt(t.getChip())));
64c62813d4SZane Shelley     });
65c62813d4SZane Shelley 
66c62813d4SZane Shelley     if (i_list.end() != itr2)
67c62813d4SZane Shelley     {
68c62813d4SZane Shelley         o_rootCause = *itr2;
69a7369f86SZane Shelley         return true;
70a7369f86SZane Shelley     }
71a7369f86SZane Shelley 
72a7369f86SZane Shelley     return false;
73a7369f86SZane Shelley }
74a7369f86SZane Shelley 
75a7369f86SZane Shelley //------------------------------------------------------------------------------
76a7369f86SZane Shelley 
__findMemoryChannelFailure(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)77f4792d68SZane Shelley bool __findMemoryChannelFailure(const std::vector<libhei::Signature>& i_list,
781a4f0e70SCaleb Palmer                                 libhei::Signature& o_rootCause,
791a4f0e70SCaleb Palmer                                 const RasDataParser& i_rasData)
80f4792d68SZane Shelley {
81f4792d68SZane Shelley     using namespace util::pdbg;
82f4792d68SZane Shelley 
8319df3706SZane Shelley     using func = libhei::NodeId_t (*)(const std::string& i_str);
8419df3706SZane Shelley     func __hash = libhei::hash<libhei::NodeId_t>;
8519df3706SZane Shelley 
86adda0540SZane Shelley     static const auto mc_dstl_fir = __hash("MC_DSTL_FIR");
87adda0540SZane Shelley     static const auto mc_ustl_fir = __hash("MC_USTL_FIR");
8819df3706SZane Shelley     static const auto mc_omi_dl_err_rpt = __hash("MC_OMI_DL_ERR_RPT");
89f4792d68SZane Shelley 
90adda0540SZane Shelley     // First, look for any chip checkstops from the connected OCMBs.
91adda0540SZane Shelley     for (const auto& s : i_list)
92f4792d68SZane Shelley     {
93adda0540SZane Shelley         if (TYPE_OCMB != getTrgtType(getTrgt(s.getChip())))
941a4f0e70SCaleb Palmer         {
95adda0540SZane Shelley             continue; // OCMBs only
96adda0540SZane Shelley         }
97adda0540SZane Shelley 
98adda0540SZane Shelley         // TODO: The chip data for Explorer chips currently report chip
99adda0540SZane Shelley         //       checkstops as unit checkstops. Once the chip data has been
100adda0540SZane Shelley         //       updated, the check for unit checkstops here will need to be
101adda0540SZane Shelley         //       removed.
102adda0540SZane Shelley         if (libhei::ATTN_TYPE_CHIP_CS == s.getAttnType() ||
103adda0540SZane Shelley             libhei::ATTN_TYPE_UNIT_CS == s.getAttnType())
104adda0540SZane Shelley         {
1051a4f0e70SCaleb Palmer             o_rootCause = s;
106adda0540SZane Shelley             return true;
1071a4f0e70SCaleb Palmer         }
108adda0540SZane Shelley     }
109adda0540SZane Shelley 
110adda0540SZane Shelley     // Now, look for any channel failure attentions on the processor side of the
111adda0540SZane Shelley     // memory bus.
112adda0540SZane Shelley     for (const auto& s : i_list)
113adda0540SZane Shelley     {
114adda0540SZane Shelley         if (TYPE_PROC != getTrgtType(getTrgt(s.getChip())))
115adda0540SZane Shelley         {
116adda0540SZane Shelley             continue; // processors only
117adda0540SZane Shelley         }
118adda0540SZane Shelley 
119adda0540SZane Shelley         // Any unit checkstop attentions that originated from the MC_DSTL_FIR or
120adda0540SZane Shelley         // MC_USTLFIR are considered a channel failure attention.
121adda0540SZane Shelley         // TODO: The "channel failure" designation is actually configurable via
122adda0540SZane Shelley         //       other registers. We just happen to expect anything that is
123adda0540SZane Shelley         //       configured to channel failure to also be configured to unit
124adda0540SZane Shelley         //       checkstop. Eventually, we will need some mechanism to check the
125adda0540SZane Shelley         //       configuration registers for a more accurate analysis.
126adda0540SZane Shelley         if (libhei::ATTN_TYPE_UNIT_CS == s.getAttnType() &&
127adda0540SZane Shelley             (mc_dstl_fir == s.getId() || mc_ustl_fir == s.getId()) &&
128adda0540SZane Shelley             !i_rasData.isFlagSet(s,
129adda0540SZane Shelley                                  RasDataParser::RasDataFlags::ATTN_FROM_OCMB))
130adda0540SZane Shelley         {
131adda0540SZane Shelley             o_rootCause = s;
132adda0540SZane Shelley             return true;
133adda0540SZane Shelley         }
134adda0540SZane Shelley         // Any signatures from MC_OMI_DL_ERR_RPT feed into the only bits in
135adda0540SZane Shelley         // MC_OMI_DL_FIR that are hardwired to channel failure.
1361a4f0e70SCaleb Palmer         else if (mc_omi_dl_err_rpt == s.getId())
1371a4f0e70SCaleb Palmer         {
1381a4f0e70SCaleb Palmer             o_rootCause = s;
1391a4f0e70SCaleb Palmer             return true;
1401a4f0e70SCaleb Palmer         }
1411a4f0e70SCaleb Palmer     }
142f4792d68SZane Shelley 
143f4792d68SZane Shelley     return false; // default, nothing found
144f4792d68SZane Shelley }
145f4792d68SZane Shelley 
146f4792d68SZane Shelley //------------------------------------------------------------------------------
147f4792d68SZane Shelley 
148f4792d68SZane Shelley // Will query if a signature is a potential system checkstop root cause.
149f4792d68SZane Shelley // attention. Note that this function excludes memory channel failure attentions
150ed3ab8f9SZane Shelley // which are checked in __findMemoryChannelFailure().
__findCsRootCause(const libhei::Signature & i_signature,const RasDataParser & i_rasData)1511a4f0e70SCaleb Palmer bool __findCsRootCause(const libhei::Signature& i_signature,
1521a4f0e70SCaleb Palmer                        const RasDataParser& i_rasData)
1531a4f0e70SCaleb Palmer {
15493b001c5SZane Shelley     // Check if the input signature has the CS_POSSIBLE or SUE_SOURCE flag set.
15593b001c5SZane Shelley     if (i_rasData.isFlagSet(i_signature,
1561a4f0e70SCaleb Palmer                             RasDataParser::RasDataFlags::CS_POSSIBLE) ||
1571a4f0e70SCaleb Palmer         i_rasData.isFlagSet(i_signature,
1581a4f0e70SCaleb Palmer                             RasDataParser::RasDataFlags::SUE_SOURCE))
1591a4f0e70SCaleb Palmer     {
1601a4f0e70SCaleb Palmer         return true;
1611a4f0e70SCaleb Palmer     }
162f4792d68SZane Shelley 
163f4792d68SZane Shelley     return false; // default, nothing found
164f4792d68SZane Shelley }
165f4792d68SZane Shelley 
166f4792d68SZane Shelley //------------------------------------------------------------------------------
167f4792d68SZane Shelley 
__findCsRootCause_RE(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)168f4792d68SZane Shelley bool __findCsRootCause_RE(const std::vector<libhei::Signature>& i_list,
1691a4f0e70SCaleb Palmer                           libhei::Signature& o_rootCause,
1701a4f0e70SCaleb Palmer                           const RasDataParser& i_rasData)
171f4792d68SZane Shelley {
172adda0540SZane Shelley     for (const auto& s : i_list)
173f4792d68SZane Shelley     {
174f4792d68SZane Shelley         // Only looking for recoverable attentions.
175f4792d68SZane Shelley         if (libhei::ATTN_TYPE_RECOVERABLE != s.getAttnType())
176f4792d68SZane Shelley         {
177f4792d68SZane Shelley             continue;
178f4792d68SZane Shelley         }
179f4792d68SZane Shelley 
1801a4f0e70SCaleb Palmer         if (__findCsRootCause(s, i_rasData))
181f4792d68SZane Shelley         {
182f4792d68SZane Shelley             o_rootCause = s;
183f4792d68SZane Shelley             return true;
184f4792d68SZane Shelley         }
185f4792d68SZane Shelley     }
186f4792d68SZane Shelley 
187f4792d68SZane Shelley     return false; // default, nothing found
188f4792d68SZane Shelley }
189f4792d68SZane Shelley 
190f4792d68SZane Shelley //------------------------------------------------------------------------------
191f4792d68SZane Shelley 
__findCsRootCause_UCS(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)192f4792d68SZane Shelley bool __findCsRootCause_UCS(const std::vector<libhei::Signature>& i_list,
1931a4f0e70SCaleb Palmer                            libhei::Signature& o_rootCause,
1941a4f0e70SCaleb Palmer                            const RasDataParser& i_rasData)
195f4792d68SZane Shelley {
196adda0540SZane Shelley     for (const auto& s : i_list)
197f4792d68SZane Shelley     {
198f4792d68SZane Shelley         // Only looking for unit checkstop attentions.
199f4792d68SZane Shelley         if (libhei::ATTN_TYPE_UNIT_CS != s.getAttnType())
200f4792d68SZane Shelley         {
201f4792d68SZane Shelley             continue;
202f4792d68SZane Shelley         }
203f4792d68SZane Shelley 
2041a4f0e70SCaleb Palmer         if (__findCsRootCause(s, i_rasData))
205f4792d68SZane Shelley         {
206f4792d68SZane Shelley             o_rootCause = s;
207f4792d68SZane Shelley             return true;
208f4792d68SZane Shelley         }
209f4792d68SZane Shelley     }
210f4792d68SZane Shelley 
211f4792d68SZane Shelley     return false; // default, nothing found
212f4792d68SZane Shelley }
213f4792d68SZane Shelley 
214f4792d68SZane Shelley //------------------------------------------------------------------------------
215f4792d68SZane Shelley 
__findOcmbAttnBits(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)21651f8202cSCaleb Palmer bool __findOcmbAttnBits(const std::vector<libhei::Signature>& i_list,
21751f8202cSCaleb Palmer                         libhei::Signature& o_rootCause,
21851f8202cSCaleb Palmer                         const RasDataParser& i_rasData)
21951f8202cSCaleb Palmer {
22051f8202cSCaleb Palmer     using namespace util::pdbg;
22151f8202cSCaleb Palmer 
22251f8202cSCaleb Palmer     // If we have any attentions from an OCMB, assume isolation to the OCMBs
22351f8202cSCaleb Palmer     // was successful and the ATTN_FROM_OCMB flag does not need to be checked.
224adda0540SZane Shelley     for (const auto& s : i_list)
22551f8202cSCaleb Palmer     {
22651f8202cSCaleb Palmer         if (TYPE_OCMB == getTrgtType(getTrgt(s.getChip())))
22751f8202cSCaleb Palmer         {
22851f8202cSCaleb Palmer             return false;
22951f8202cSCaleb Palmer         }
23051f8202cSCaleb Palmer     }
23151f8202cSCaleb Palmer 
232adda0540SZane Shelley     for (const auto& s : i_list)
23351f8202cSCaleb Palmer     {
23493b001c5SZane Shelley         if (i_rasData.isFlagSet(s, RasDataParser::RasDataFlags::ATTN_FROM_OCMB))
23551f8202cSCaleb Palmer         {
23651f8202cSCaleb Palmer             o_rootCause = s;
23751f8202cSCaleb Palmer             return true;
23851f8202cSCaleb Palmer         }
23951f8202cSCaleb Palmer     }
24051f8202cSCaleb Palmer 
24151f8202cSCaleb Palmer     return false; // default, nothing found
24251f8202cSCaleb Palmer }
24351f8202cSCaleb Palmer 
24451f8202cSCaleb Palmer //------------------------------------------------------------------------------
24551f8202cSCaleb Palmer 
__findNonExternalCs(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause)246f4792d68SZane Shelley bool __findNonExternalCs(const std::vector<libhei::Signature>& i_list,
247f4792d68SZane Shelley                          libhei::Signature& o_rootCause)
248f4792d68SZane Shelley {
249f4792d68SZane Shelley     using namespace util::pdbg;
250f4792d68SZane Shelley 
25119df3706SZane Shelley     static const auto pb_ext_fir = libhei::hash<libhei::NodeId_t>("PB_EXT_FIR");
252f4792d68SZane Shelley 
253adda0540SZane Shelley     for (const auto& s : i_list)
254f4792d68SZane Shelley     {
255f4792d68SZane Shelley         const auto targetType = getTrgtType(getTrgt(s.getChip()));
256f4792d68SZane Shelley         const auto id = s.getId();
257f4792d68SZane Shelley         const auto attnType = s.getAttnType();
258f4792d68SZane Shelley 
259adda0540SZane Shelley         // Find any processor with chip checkstop attention that did not
260f4792d68SZane Shelley         // originate from the PB_EXT_FIR.
261f4792d68SZane Shelley         if ((TYPE_PROC == targetType) &&
262adda0540SZane Shelley             (libhei::ATTN_TYPE_CHIP_CS == attnType) && (pb_ext_fir != id))
263f4792d68SZane Shelley         {
264f4792d68SZane Shelley             o_rootCause = s;
265f4792d68SZane Shelley             return true;
266f4792d68SZane Shelley         }
267f4792d68SZane Shelley     }
268f4792d68SZane Shelley 
269f4792d68SZane Shelley     return false; // default, nothing found
270f4792d68SZane Shelley }
271f4792d68SZane Shelley 
272f4792d68SZane Shelley //------------------------------------------------------------------------------
273f4792d68SZane Shelley 
__findTiRootCause(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause)274baec7c01SZane Shelley bool __findTiRootCause(const std::vector<libhei::Signature>& i_list,
275baec7c01SZane Shelley                        libhei::Signature& o_rootCause)
276baec7c01SZane Shelley {
277baec7c01SZane Shelley     using namespace util::pdbg;
278baec7c01SZane Shelley 
279baec7c01SZane Shelley     using func = libhei::NodeId_t (*)(const std::string& i_str);
280baec7c01SZane Shelley     func __hash = libhei::hash<libhei::NodeId_t>;
281baec7c01SZane Shelley 
282baec7c01SZane Shelley     // PROC registers
283baec7c01SZane Shelley     static const auto tp_local_fir = __hash("TP_LOCAL_FIR");
284baec7c01SZane Shelley     static const auto occ_fir = __hash("OCC_FIR");
285baec7c01SZane Shelley     static const auto pbao_fir = __hash("PBAO_FIR");
286baec7c01SZane Shelley     static const auto n0_local_fir = __hash("N0_LOCAL_FIR");
287baec7c01SZane Shelley     static const auto int_cq_fir = __hash("INT_CQ_FIR");
288baec7c01SZane Shelley     static const auto nx_cq_fir = __hash("NX_CQ_FIR");
289baec7c01SZane Shelley     static const auto nx_dma_eng_fir = __hash("NX_DMA_ENG_FIR");
290baec7c01SZane Shelley     static const auto vas_fir = __hash("VAS_FIR");
291baec7c01SZane Shelley     static const auto n1_local_fir = __hash("N1_LOCAL_FIR");
292baec7c01SZane Shelley     static const auto mcd_fir = __hash("MCD_FIR");
293baec7c01SZane Shelley     static const auto pb_station_fir_en_1 = __hash("PB_STATION_FIR_EN_1");
294baec7c01SZane Shelley     static const auto pb_station_fir_en_2 = __hash("PB_STATION_FIR_EN_2");
295baec7c01SZane Shelley     static const auto pb_station_fir_en_3 = __hash("PB_STATION_FIR_EN_3");
296baec7c01SZane Shelley     static const auto pb_station_fir_en_4 = __hash("PB_STATION_FIR_EN_4");
297baec7c01SZane Shelley     static const auto pb_station_fir_es_1 = __hash("PB_STATION_FIR_ES_1");
298baec7c01SZane Shelley     static const auto pb_station_fir_es_2 = __hash("PB_STATION_FIR_ES_2");
299baec7c01SZane Shelley     static const auto pb_station_fir_es_3 = __hash("PB_STATION_FIR_ES_3");
300baec7c01SZane Shelley     static const auto pb_station_fir_es_4 = __hash("PB_STATION_FIR_ES_4");
301baec7c01SZane Shelley     static const auto pb_station_fir_eq = __hash("PB_STATION_FIR_EQ");
302baec7c01SZane Shelley     static const auto psihb_fir = __hash("PSIHB_FIR");
303baec7c01SZane Shelley     static const auto pbaf_fir = __hash("PBAF_FIR");
304baec7c01SZane Shelley     static const auto lpc_fir = __hash("LPC_FIR");
305baec7c01SZane Shelley     static const auto eq_core_fir = __hash("EQ_CORE_FIR");
306baec7c01SZane Shelley     static const auto eq_l2_fir = __hash("EQ_L2_FIR");
307baec7c01SZane Shelley     static const auto eq_l3_fir = __hash("EQ_L3_FIR");
308baec7c01SZane Shelley     static const auto eq_ncu_fir = __hash("EQ_NCU_FIR");
309baec7c01SZane Shelley     static const auto eq_local_fir = __hash("EQ_LOCAL_FIR");
310baec7c01SZane Shelley     static const auto eq_qme_fir = __hash("EQ_QME_FIR");
311baec7c01SZane Shelley     static const auto iohs_local_fir = __hash("IOHS_LOCAL_FIR");
312baec7c01SZane Shelley     static const auto iohs_dlp_fir_oc = __hash("IOHS_DLP_FIR_OC");
313baec7c01SZane Shelley     static const auto iohs_dlp_fir_smp = __hash("IOHS_DLP_FIR_SMP");
314baec7c01SZane Shelley     static const auto mc_local_fir = __hash("MC_LOCAL_FIR");
315baec7c01SZane Shelley     static const auto mc_fir = __hash("MC_FIR");
316baec7c01SZane Shelley     static const auto mc_dstl_fir = __hash("MC_DSTL_FIR");
317baec7c01SZane Shelley     static const auto mc_ustl_fir = __hash("MC_USTL_FIR");
318baec7c01SZane Shelley     static const auto nmmu_cq_fir = __hash("NMMU_CQ_FIR");
319baec7c01SZane Shelley     static const auto nmmu_fir = __hash("NMMU_FIR");
320baec7c01SZane Shelley     static const auto mc_omi_dl = __hash("MC_OMI_DL");
321baec7c01SZane Shelley     static const auto pau_local_fir = __hash("PAU_LOCAL_FIR");
322baec7c01SZane Shelley     static const auto pau_ptl_fir = __hash("PAU_PTL_FIR");
323baec7c01SZane Shelley     static const auto pau_phy_fir = __hash("PAU_PHY_FIR");
324baec7c01SZane Shelley     static const auto pau_fir_0 = __hash("PAU_FIR_0");
325baec7c01SZane Shelley     static const auto pau_fir_2 = __hash("PAU_FIR_2");
326baec7c01SZane Shelley     static const auto pci_local_fir = __hash("PCI_LOCAL_FIR");
327baec7c01SZane Shelley     static const auto pci_iop_fir = __hash("PCI_IOP_FIR");
328baec7c01SZane Shelley     static const auto pci_nest_fir = __hash("PCI_NEST_FIR");
329baec7c01SZane Shelley 
330baec7c01SZane Shelley     // OCMB registers
331baec7c01SZane Shelley     static const auto ocmb_lfir = __hash("OCMB_LFIR");
332baec7c01SZane Shelley     static const auto mmiofir = __hash("MMIOFIR");
333baec7c01SZane Shelley     static const auto srqfir = __hash("SRQFIR");
334baec7c01SZane Shelley     static const auto rdffir = __hash("RDFFIR");
335baec7c01SZane Shelley     static const auto tlxfir = __hash("TLXFIR");
336baec7c01SZane Shelley     static const auto omi_dl = __hash("OMI_DL");
337baec7c01SZane Shelley 
338baec7c01SZane Shelley     for (const auto& signature : i_list)
339baec7c01SZane Shelley     {
340baec7c01SZane Shelley         const auto targetType = getTrgtType(getTrgt(signature.getChip()));
341baec7c01SZane Shelley         const auto attnType = signature.getAttnType();
342baec7c01SZane Shelley         const auto id = signature.getId();
343baec7c01SZane Shelley         const auto bit = signature.getBit();
344baec7c01SZane Shelley 
345baec7c01SZane Shelley         // Only looking for recoverable or unit checkstop attentions.
346baec7c01SZane Shelley         if (libhei::ATTN_TYPE_RECOVERABLE != attnType &&
347baec7c01SZane Shelley             libhei::ATTN_TYPE_UNIT_CS != attnType)
348baec7c01SZane Shelley         {
349baec7c01SZane Shelley             continue;
350baec7c01SZane Shelley         }
351baec7c01SZane Shelley 
352baec7c01SZane Shelley         // Ignore attentions that should not be blamed as root cause of a TI.
353baec7c01SZane Shelley         // This would include informational only FIRs or correctable errors.
354baec7c01SZane Shelley         if (TYPE_PROC == targetType)
355baec7c01SZane Shelley         {
356baec7c01SZane Shelley             if (tp_local_fir == id &&
357baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
358baec7c01SZane Shelley                  5 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
359baec7c01SZane Shelley                  11 == bit || 20 == bit || 22 == bit || 23 == bit ||
360baec7c01SZane Shelley                  24 == bit || 38 == bit || 40 == bit || 41 == bit ||
361baec7c01SZane Shelley                  46 == bit || 47 == bit || 48 == bit || 55 == bit ||
362baec7c01SZane Shelley                  56 == bit || 57 == bit || 58 == bit || 59 == bit))
363baec7c01SZane Shelley             {
364baec7c01SZane Shelley                 continue;
365baec7c01SZane Shelley             }
366baec7c01SZane Shelley 
367baec7c01SZane Shelley             if (occ_fir == id &&
368baec7c01SZane Shelley                 (9 == bit || 10 == bit || 15 == bit || 20 == bit || 21 == bit ||
369baec7c01SZane Shelley                  22 == bit || 23 == bit || 32 == bit || 33 == bit ||
370baec7c01SZane Shelley                  34 == bit || 36 == bit || 42 == bit || 43 == bit ||
371baec7c01SZane Shelley                  46 == bit || 47 == bit || 48 == bit || 51 == bit ||
372baec7c01SZane Shelley                  52 == bit || 53 == bit || 54 == bit || 57 == bit))
373baec7c01SZane Shelley             {
374baec7c01SZane Shelley                 continue;
375baec7c01SZane Shelley             }
376baec7c01SZane Shelley 
377baec7c01SZane Shelley             if (pbao_fir == id &&
378baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 8 == bit || 11 == bit ||
379baec7c01SZane Shelley                  13 == bit || 15 == bit || 16 == bit || 17 == bit))
380baec7c01SZane Shelley             {
381baec7c01SZane Shelley                 continue;
382baec7c01SZane Shelley             }
383baec7c01SZane Shelley 
384baec7c01SZane Shelley             if ((n0_local_fir == id || n1_local_fir == id ||
385baec7c01SZane Shelley                  iohs_local_fir == id || mc_local_fir == id ||
386baec7c01SZane Shelley                  pau_local_fir == id || pci_local_fir == id) &&
387baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
388baec7c01SZane Shelley                  5 == bit || 6 == bit || 7 == bit || 8 == bit || 9 == bit ||
389baec7c01SZane Shelley                  10 == bit || 11 == bit || 20 == bit || 21 == bit))
390baec7c01SZane Shelley             {
391baec7c01SZane Shelley                 continue;
392baec7c01SZane Shelley             }
393baec7c01SZane Shelley 
394baec7c01SZane Shelley             if (int_cq_fir == id &&
395baec7c01SZane Shelley                 (0 == bit || 3 == bit || 5 == bit || 7 == bit || 36 == bit ||
396ecde53fcSCaleb Palmer                  47 == bit || 48 == bit || 49 == bit || 50 == bit ||
397baec7c01SZane Shelley                  58 == bit || 59 == bit || 60 == bit))
398baec7c01SZane Shelley             {
399baec7c01SZane Shelley                 continue;
400baec7c01SZane Shelley             }
401baec7c01SZane Shelley 
402baec7c01SZane Shelley             if (nx_cq_fir == id &&
403baec7c01SZane Shelley                 (1 == bit || 4 == bit || 18 == bit || 32 == bit || 33 == bit))
404baec7c01SZane Shelley             {
405baec7c01SZane Shelley                 continue;
406baec7c01SZane Shelley             }
407baec7c01SZane Shelley 
408baec7c01SZane Shelley             if (nx_dma_eng_fir == id &&
409baec7c01SZane Shelley                 (4 == bit || 6 == bit || 9 == bit || 10 == bit || 11 == bit ||
410baec7c01SZane Shelley                  34 == bit || 35 == bit || 36 == bit || 37 == bit || 39 == bit))
411baec7c01SZane Shelley             {
412baec7c01SZane Shelley                 continue;
413baec7c01SZane Shelley             }
414baec7c01SZane Shelley 
415baec7c01SZane Shelley             if (vas_fir == id &&
416baec7c01SZane Shelley                 (8 == bit || 9 == bit || 11 == bit || 12 == bit || 13 == bit))
417baec7c01SZane Shelley             {
418baec7c01SZane Shelley                 continue;
419baec7c01SZane Shelley             }
420baec7c01SZane Shelley 
421baec7c01SZane Shelley             if (mcd_fir == id && (0 == bit))
422baec7c01SZane Shelley             {
423baec7c01SZane Shelley                 continue;
424baec7c01SZane Shelley             }
425baec7c01SZane Shelley 
426baec7c01SZane Shelley             if ((pb_station_fir_en_1 == id || pb_station_fir_en_2 == id ||
427baec7c01SZane Shelley                  pb_station_fir_en_3 == id || pb_station_fir_en_4 == id ||
428baec7c01SZane Shelley                  pb_station_fir_es_1 == id || pb_station_fir_es_2 == id ||
429baec7c01SZane Shelley                  pb_station_fir_es_3 == id || pb_station_fir_es_4 == id ||
430baec7c01SZane Shelley                  pb_station_fir_eq == id) &&
431baec7c01SZane Shelley                 (9 == bit))
432baec7c01SZane Shelley             {
433baec7c01SZane Shelley                 continue;
434baec7c01SZane Shelley             }
435baec7c01SZane Shelley 
436baec7c01SZane Shelley             if (psihb_fir == id && (0 == bit || 23 == bit))
437baec7c01SZane Shelley             {
438baec7c01SZane Shelley                 continue;
439baec7c01SZane Shelley             }
440baec7c01SZane Shelley 
441baec7c01SZane Shelley             if (pbaf_fir == id &&
442baec7c01SZane Shelley                 (0 == bit || 1 == bit || 3 == bit || 4 == bit || 5 == bit ||
443baec7c01SZane Shelley                  6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
444baec7c01SZane Shelley                  11 == bit || 19 == bit || 20 == bit || 21 == bit ||
445baec7c01SZane Shelley                  28 == bit || 29 == bit || 30 == bit || 31 == bit ||
446baec7c01SZane Shelley                  32 == bit || 33 == bit || 34 == bit || 35 == bit || 36 == bit))
447baec7c01SZane Shelley             {
448baec7c01SZane Shelley                 continue;
449baec7c01SZane Shelley             }
450baec7c01SZane Shelley 
451baec7c01SZane Shelley             if (lpc_fir == id && (5 == bit))
452baec7c01SZane Shelley             {
453baec7c01SZane Shelley                 continue;
454baec7c01SZane Shelley             }
455baec7c01SZane Shelley 
456baec7c01SZane Shelley             if (eq_core_fir == id &&
457baec7c01SZane Shelley                 (0 == bit || 2 == bit || 4 == bit || 7 == bit || 9 == bit ||
458baec7c01SZane Shelley                  11 == bit || 13 == bit || 18 == bit || 21 == bit ||
459baec7c01SZane Shelley                  24 == bit || 29 == bit || 31 == bit || 37 == bit ||
460baec7c01SZane Shelley                  43 == bit || 56 == bit || 57 == bit))
461baec7c01SZane Shelley             {
462baec7c01SZane Shelley                 continue;
463baec7c01SZane Shelley             }
464baec7c01SZane Shelley 
465baec7c01SZane Shelley             if (eq_l2_fir == id &&
466baec7c01SZane Shelley                 (0 == bit || 6 == bit || 11 == bit || 19 == bit || 36 == bit))
467baec7c01SZane Shelley             {
468baec7c01SZane Shelley                 continue;
469baec7c01SZane Shelley             }
470baec7c01SZane Shelley 
471baec7c01SZane Shelley             if (eq_l3_fir == id &&
472baec7c01SZane Shelley                 (3 == bit || 4 == bit || 7 == bit || 10 == bit || 13 == bit))
473baec7c01SZane Shelley             {
474baec7c01SZane Shelley                 continue;
475baec7c01SZane Shelley             }
476baec7c01SZane Shelley 
477baec7c01SZane Shelley             if (eq_ncu_fir == id && (9 == bit))
478baec7c01SZane Shelley             {
479baec7c01SZane Shelley                 continue;
480baec7c01SZane Shelley             }
481baec7c01SZane Shelley 
482baec7c01SZane Shelley             if (eq_local_fir == id &&
483baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 5 == bit ||
484baec7c01SZane Shelley                  6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
485baec7c01SZane Shelley                  11 == bit || 12 == bit || 13 == bit || 14 == bit ||
486baec7c01SZane Shelley                  15 == bit || 16 == bit || 20 == bit || 21 == bit ||
487baec7c01SZane Shelley                  22 == bit || 23 == bit || 24 == bit || 25 == bit ||
488baec7c01SZane Shelley                  26 == bit || 27 == bit || 28 == bit || 29 == bit ||
489baec7c01SZane Shelley                  30 == bit || 31 == bit || 32 == bit || 33 == bit ||
490baec7c01SZane Shelley                  34 == bit || 35 == bit || 36 == bit || 37 == bit ||
491baec7c01SZane Shelley                  38 == bit || 39 == bit))
492baec7c01SZane Shelley             {
493baec7c01SZane Shelley                 continue;
494baec7c01SZane Shelley             }
495baec7c01SZane Shelley 
496baec7c01SZane Shelley             if (eq_qme_fir == id && (7 == bit || 25 == bit))
497baec7c01SZane Shelley             {
498baec7c01SZane Shelley                 continue;
499baec7c01SZane Shelley             }
500baec7c01SZane Shelley 
501baec7c01SZane Shelley             if (iohs_dlp_fir_oc == id &&
502baec7c01SZane Shelley                 (6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
503baec7c01SZane Shelley                  48 == bit || 49 == bit || 52 == bit || 53 == bit))
504baec7c01SZane Shelley             {
505baec7c01SZane Shelley                 continue;
506baec7c01SZane Shelley             }
507baec7c01SZane Shelley 
508baec7c01SZane Shelley             if (iohs_dlp_fir_smp == id &&
509baec7c01SZane Shelley                 (6 == bit || 7 == bit || 14 == bit || 15 == bit || 16 == bit ||
510baec7c01SZane Shelley                  17 == bit || 38 == bit || 39 == bit || 44 == bit ||
511baec7c01SZane Shelley                  45 == bit || 50 == bit || 51 == bit))
512baec7c01SZane Shelley             {
513baec7c01SZane Shelley                 continue;
514baec7c01SZane Shelley             }
515baec7c01SZane Shelley 
516baec7c01SZane Shelley             if (mc_fir == id &&
517baec7c01SZane Shelley                 (5 == bit || 8 == bit || 15 == bit || 16 == bit))
518baec7c01SZane Shelley             {
519baec7c01SZane Shelley                 continue;
520baec7c01SZane Shelley             }
521baec7c01SZane Shelley 
522baec7c01SZane Shelley             if (mc_dstl_fir == id &&
523baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
524baec7c01SZane Shelley                  5 == bit || 6 == bit || 7 == bit || 14 == bit || 15 == bit))
525baec7c01SZane Shelley             {
526baec7c01SZane Shelley                 continue;
527baec7c01SZane Shelley             }
528baec7c01SZane Shelley 
529baec7c01SZane Shelley             if (mc_ustl_fir == id &&
530baec7c01SZane Shelley                 (6 == bit || 20 == bit || 33 == bit || 34 == bit))
531baec7c01SZane Shelley             {
532baec7c01SZane Shelley                 continue;
533baec7c01SZane Shelley             }
534baec7c01SZane Shelley 
535baec7c01SZane Shelley             if (nmmu_cq_fir == id && (8 == bit || 11 == bit || 14 == bit))
536baec7c01SZane Shelley             {
537baec7c01SZane Shelley                 continue;
538baec7c01SZane Shelley             }
539baec7c01SZane Shelley 
540baec7c01SZane Shelley             if (nmmu_fir == id &&
541baec7c01SZane Shelley                 (0 == bit || 3 == bit || 8 == bit || 9 == bit || 10 == bit ||
542baec7c01SZane Shelley                  11 == bit || 12 == bit || 13 == bit || 14 == bit ||
543baec7c01SZane Shelley                  15 == bit || 30 == bit || 31 == bit || 41 == bit))
544baec7c01SZane Shelley             {
545baec7c01SZane Shelley                 continue;
546baec7c01SZane Shelley             }
547baec7c01SZane Shelley 
548baec7c01SZane Shelley             if (mc_omi_dl == id && (2 == bit || 3 == bit || 6 == bit ||
549baec7c01SZane Shelley                                     7 == bit || 9 == bit || 10 == bit))
550baec7c01SZane Shelley             {
551baec7c01SZane Shelley                 continue;
552baec7c01SZane Shelley             }
553baec7c01SZane Shelley 
554baec7c01SZane Shelley             if (pau_ptl_fir == id && (5 == bit || 9 == bit))
555baec7c01SZane Shelley             {
556baec7c01SZane Shelley                 continue;
557baec7c01SZane Shelley             }
558baec7c01SZane Shelley 
559baec7c01SZane Shelley             if (pau_phy_fir == id &&
560baec7c01SZane Shelley                 (2 == bit || 3 == bit || 6 == bit || 7 == bit || 15 == bit))
561baec7c01SZane Shelley             {
562baec7c01SZane Shelley                 continue;
563baec7c01SZane Shelley             }
564baec7c01SZane Shelley 
565baec7c01SZane Shelley             if (pau_fir_0 == id && (13 == bit || 30 == bit || 41 == bit))
566baec7c01SZane Shelley             {
567baec7c01SZane Shelley                 continue;
568baec7c01SZane Shelley             }
569baec7c01SZane Shelley 
570baec7c01SZane Shelley             if (pau_fir_2 == id && (19 == bit || 46 == bit || 49 == bit))
571baec7c01SZane Shelley             {
572baec7c01SZane Shelley                 continue;
573baec7c01SZane Shelley             }
574baec7c01SZane Shelley 
575baec7c01SZane Shelley             if (pci_iop_fir == id &&
576baec7c01SZane Shelley                 (0 == bit || 2 == bit || 4 == bit || 6 == bit || 7 == bit ||
577baec7c01SZane Shelley                  8 == bit || 10 == bit))
578baec7c01SZane Shelley             {
579baec7c01SZane Shelley                 continue;
580baec7c01SZane Shelley             }
581baec7c01SZane Shelley 
582baec7c01SZane Shelley             if (pci_nest_fir == id && (2 == bit || 5 == bit))
583baec7c01SZane Shelley             {
584baec7c01SZane Shelley                 continue;
585baec7c01SZane Shelley             }
586baec7c01SZane Shelley         }
587baec7c01SZane Shelley         else if (TYPE_OCMB == targetType)
588baec7c01SZane Shelley         {
589baec7c01SZane Shelley             if (ocmb_lfir == id &&
590baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 8 == bit || 23 == bit ||
591baec7c01SZane Shelley                  37 == bit || 63 == bit))
592baec7c01SZane Shelley             {
593baec7c01SZane Shelley                 continue;
594baec7c01SZane Shelley             }
595baec7c01SZane Shelley 
596baec7c01SZane Shelley             if (mmiofir == id && (2 == bit))
597baec7c01SZane Shelley             {
598baec7c01SZane Shelley                 continue;
599baec7c01SZane Shelley             }
600baec7c01SZane Shelley 
601baec7c01SZane Shelley             if (srqfir == id &&
602baec7c01SZane Shelley                 (2 == bit || 4 == bit || 14 == bit || 15 == bit || 23 == bit ||
603baec7c01SZane Shelley                  25 == bit || 28 == bit))
604baec7c01SZane Shelley             {
605baec7c01SZane Shelley                 continue;
606baec7c01SZane Shelley             }
607baec7c01SZane Shelley 
608baec7c01SZane Shelley             if (rdffir == id &&
609baec7c01SZane Shelley                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
610baec7c01SZane Shelley                  5 == bit || 6 == bit || 7 == bit || 8 == bit || 9 == bit ||
611baec7c01SZane Shelley                  18 == bit || 38 == bit || 40 == bit || 41 == bit ||
612baec7c01SZane Shelley                  45 == bit || 46 == bit))
613baec7c01SZane Shelley             {
614baec7c01SZane Shelley                 continue;
615baec7c01SZane Shelley             }
616baec7c01SZane Shelley 
617baec7c01SZane Shelley             if (tlxfir == id && (0 == bit || 9 == bit || 26 == bit))
618baec7c01SZane Shelley             {
619baec7c01SZane Shelley                 continue;
620baec7c01SZane Shelley             }
621baec7c01SZane Shelley 
622baec7c01SZane Shelley             if (omi_dl == id && (2 == bit || 3 == bit || 6 == bit || 7 == bit ||
623baec7c01SZane Shelley                                  9 == bit || 10 == bit))
624baec7c01SZane Shelley             {
625baec7c01SZane Shelley                 continue;
626baec7c01SZane Shelley             }
627baec7c01SZane Shelley         }
628baec7c01SZane Shelley 
629baec7c01SZane Shelley         // At this point, the attention has not been explicitly ignored. So
630baec7c01SZane Shelley         // return this signature and exit.
631baec7c01SZane Shelley         o_rootCause = signature;
632baec7c01SZane Shelley         return true;
633baec7c01SZane Shelley     }
634baec7c01SZane Shelley 
635baec7c01SZane Shelley     return false; // default, nothing found
636baec7c01SZane Shelley }
637baec7c01SZane Shelley 
638baec7c01SZane Shelley //------------------------------------------------------------------------------
639baec7c01SZane Shelley 
findRootCause(AnalysisType i_type,const libhei::IsolationData & i_isoData,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)640c3038c03SCaleb Palmer bool findRootCause(AnalysisType i_type, const libhei::IsolationData& i_isoData,
6411a4f0e70SCaleb Palmer                    libhei::Signature& o_rootCause,
6421a4f0e70SCaleb Palmer                    const RasDataParser& i_rasData)
64365fefb2cSZane Shelley {
64465fefb2cSZane Shelley     // We'll need to make a copy of the list so that the original list is
645ec227c2cSZane Shelley     // maintained for the PEL.
64665fefb2cSZane Shelley     std::vector<libhei::Signature> list{i_isoData.getSignatureList()};
64765fefb2cSZane Shelley 
64865fefb2cSZane Shelley     // START WORKAROUND
64965fefb2cSZane Shelley     // TODO: Filtering should be data driven. Until that support is available,
65065fefb2cSZane Shelley     //       use the following isolation rules.
65165fefb2cSZane Shelley 
652ec227c2cSZane Shelley     // Ensure the list is not empty before continuing.
653f4792d68SZane Shelley     if (list.empty())
654f4792d68SZane Shelley     {
655ec227c2cSZane Shelley         return false; // nothing more to do
656f4792d68SZane Shelley     }
657f4792d68SZane Shelley 
658f4792d68SZane Shelley     // First, look for any RCS OSC errors. This must always be first because
659f4792d68SZane Shelley     // they can cause downstream PLL unlock attentions.
660f4792d68SZane Shelley     if (__findRcsOscError(list, o_rootCause))
661a7369f86SZane Shelley     {
662a7369f86SZane Shelley         return true;
663a7369f86SZane Shelley     }
664a7369f86SZane Shelley 
665f4792d68SZane Shelley     // Second, look for any PLL unlock attentions. This must always be second
666f4792d68SZane Shelley     // because PLL unlock attentions can cause any number of downstream
667f4792d68SZane Shelley     // attentions, including a system checkstop.
668f4792d68SZane Shelley     if (__findPllUnlock(list, o_rootCause))
669f4792d68SZane Shelley     {
670f4792d68SZane Shelley         return true;
671f4792d68SZane Shelley     }
672f4792d68SZane Shelley 
673ec227c2cSZane Shelley     // Regardless of the analysis type, always look for anything that could be
674ec227c2cSZane Shelley     // blamed as the root cause of a system checkstop.
675ec227c2cSZane Shelley 
676f4792d68SZane Shelley     // Memory channel failure attentions will produce SUEs and likely cause
677f4792d68SZane Shelley     // downstream attentions, including a system checkstop.
6781a4f0e70SCaleb Palmer     if (__findMemoryChannelFailure(list, o_rootCause, i_rasData))
679f4792d68SZane Shelley     {
680f4792d68SZane Shelley         return true;
681f4792d68SZane Shelley     }
682f4792d68SZane Shelley 
683f4792d68SZane Shelley     // Look for any recoverable attentions that have been identified as a
684f4792d68SZane Shelley     // potential root cause of a system checkstop attention. These would include
685f4792d68SZane Shelley     // any attention that would generate an SUE. Note that is it possible for
686f4792d68SZane Shelley     // recoverables to generate unit checkstop attentions so we must check them
687f4792d68SZane Shelley     // first.
6881a4f0e70SCaleb Palmer     if (__findCsRootCause_RE(list, o_rootCause, i_rasData))
689f4792d68SZane Shelley     {
690f4792d68SZane Shelley         return true;
691f4792d68SZane Shelley     }
692f4792d68SZane Shelley 
693f4792d68SZane Shelley     // Look for any unit checkstop attentions (other than memory channel
694f4792d68SZane Shelley     // failures) that have been identified as a potential root cause of a
695f4792d68SZane Shelley     // system checkstop attention. These would include any attention that would
696f4792d68SZane Shelley     // generate an SUE.
6971a4f0e70SCaleb Palmer     if (__findCsRootCause_UCS(list, o_rootCause, i_rasData))
698f4792d68SZane Shelley     {
699f4792d68SZane Shelley         return true;
700f4792d68SZane Shelley     }
701f4792d68SZane Shelley 
70293b001c5SZane Shelley     // If no other viable root cause has been found, check for any signatures
70393b001c5SZane Shelley     // with the ATTN_FROM_OCMB flag in case there was an attention from an
70493b001c5SZane Shelley     // inaccessible OCMB.
70551f8202cSCaleb Palmer     if (__findOcmbAttnBits(list, o_rootCause, i_rasData))
70651f8202cSCaleb Palmer     {
70751f8202cSCaleb Palmer         return true;
70851f8202cSCaleb Palmer     }
70951f8202cSCaleb Palmer 
710f4792d68SZane Shelley     // Look for any system checkstop attentions that originated from within the
711f4792d68SZane Shelley     // chip that reported the attention. In other words, no external checkstop
712f4792d68SZane Shelley     // attentions.
713f4792d68SZane Shelley     if (__findNonExternalCs(list, o_rootCause))
714f4792d68SZane Shelley     {
715f4792d68SZane Shelley         return true;
716f4792d68SZane Shelley     }
717f4792d68SZane Shelley 
718ec227c2cSZane Shelley     if (AnalysisType::SYSTEM_CHECKSTOP != i_type)
719f4792d68SZane Shelley     {
720ec227c2cSZane Shelley         // No system checkstop root cause attentions were found. Next, look for
721ec227c2cSZane Shelley         // any recoverable or unit checkstop attentions that could be associated
722baec7c01SZane Shelley         // with a TI.
723baec7c01SZane Shelley         if (__findTiRootCause(list, o_rootCause))
724ec227c2cSZane Shelley         {
725ec227c2cSZane Shelley             return true;
726ec227c2cSZane Shelley         }
727ec227c2cSZane Shelley 
728ec227c2cSZane Shelley         if (AnalysisType::TERMINATE_IMMEDIATE != i_type)
729ec227c2cSZane Shelley         {
730ec227c2cSZane Shelley             // No attentions associated with a system checkstop or TI were
731ec227c2cSZane Shelley             // found. Simply, return the first entry in the list.
73265fefb2cSZane Shelley             o_rootCause = list.front();
73365fefb2cSZane Shelley             return true;
73465fefb2cSZane Shelley         }
735ec227c2cSZane Shelley     }
73665fefb2cSZane Shelley 
73765fefb2cSZane Shelley     // END WORKAROUND
73865fefb2cSZane Shelley 
73965fefb2cSZane Shelley     return false; // default, no active attentions found.
74065fefb2cSZane Shelley }
74165fefb2cSZane Shelley 
74265fefb2cSZane Shelley //------------------------------------------------------------------------------
74365fefb2cSZane Shelley 
__findIueTh(const std::vector<libhei::Signature> & i_list,libhei::Signature & o_rootCause)744c3038c03SCaleb Palmer bool __findIueTh(const std::vector<libhei::Signature>& i_list,
745c3038c03SCaleb Palmer                  libhei::Signature& o_rootCause)
746c3038c03SCaleb Palmer {
747c3038c03SCaleb Palmer     auto itr = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
748c3038c03SCaleb Palmer         return (libhei::hash<libhei::NodeId_t>("RDFFIR") == t.getId() &&
749c3038c03SCaleb Palmer                 (17 == t.getBit() || 37 == t.getBit())) ||
750c3038c03SCaleb Palmer                (libhei::hash<libhei::NodeId_t>("RDF_FIR") == t.getId() &&
751c3038c03SCaleb Palmer                 (18 == t.getBit() || 38 == t.getBit()));
752c3038c03SCaleb Palmer     });
753c3038c03SCaleb Palmer 
754c3038c03SCaleb Palmer     if (i_list.end() != itr)
755c3038c03SCaleb Palmer     {
756c3038c03SCaleb Palmer         o_rootCause = *itr;
757c3038c03SCaleb Palmer         return true;
758c3038c03SCaleb Palmer     }
759c3038c03SCaleb Palmer 
760c3038c03SCaleb Palmer     return false;
761c3038c03SCaleb Palmer }
762c3038c03SCaleb Palmer 
763c3038c03SCaleb Palmer //------------------------------------------------------------------------------
764c3038c03SCaleb Palmer 
rootCauseSpecialCases(const libhei::IsolationData & i_isoData,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)765c3038c03SCaleb Palmer void rootCauseSpecialCases(const libhei::IsolationData& i_isoData,
766c3038c03SCaleb Palmer                            libhei::Signature& o_rootCause,
767c3038c03SCaleb Palmer                            const RasDataParser& i_rasData)
768c3038c03SCaleb Palmer {
769c3038c03SCaleb Palmer     using func = libhei::NodeId_t (*)(const std::string& i_str);
770c3038c03SCaleb Palmer     func __hash = libhei::hash<libhei::NodeId_t>;
771c3038c03SCaleb Palmer 
772c3038c03SCaleb Palmer     // Check for any special cases that exist for specific FIR bits.
773c3038c03SCaleb Palmer 
774c3038c03SCaleb Palmer     // If the channel fail was specifically a firmware initiated channel fail
775c3038c03SCaleb Palmer     // (SRQFIR[25] for Explorer OCMBs, SRQ_FIR[46] for Odyssey OCMBs) check for
776c3038c03SCaleb Palmer     // any IUE bits that are on that would have caused the channel fail
777c3038c03SCaleb Palmer     // (RDFFIR[17,37] for Explorer OCMBs, RDF_FIR_0[18,38] or RDF_FIR_1[18,38]
778c3038c03SCaleb Palmer     // for Odyssey OCMBs).
779c3038c03SCaleb Palmer 
780c3038c03SCaleb Palmer     // Explorer SRQFIR
781c3038c03SCaleb Palmer     static const auto srqfir = __hash("SRQFIR");
782c3038c03SCaleb Palmer     // Odyssey SRQ_FIR
783c3038c03SCaleb Palmer     static const auto srq_fir = __hash("SRQ_FIR");
784c3038c03SCaleb Palmer 
785c3038c03SCaleb Palmer     std::vector<libhei::Signature> list{i_isoData.getSignatureList()};
786c3038c03SCaleb Palmer 
787c3038c03SCaleb Palmer     if (((srqfir == o_rootCause.getId() && 25 == o_rootCause.getBit()) ||
788c3038c03SCaleb Palmer          (srq_fir == o_rootCause.getId() && 46 == o_rootCause.getBit())) &&
789c3038c03SCaleb Palmer         __findIueTh(list, o_rootCause))
790c3038c03SCaleb Palmer     {
791c3038c03SCaleb Palmer         // If __findIueTh returned true, o_rootCause was updated, return.
792c3038c03SCaleb Palmer         return;
793c3038c03SCaleb Palmer     }
794c3038c03SCaleb Palmer 
795c3038c03SCaleb Palmer     // Check if the root cause found was a potential side effect of an
796c3038c03SCaleb Palmer     // ODP data corruption error. If it was, check if any other signature
797c3038c03SCaleb Palmer     // in the signature list was a potential root cause.
798c3038c03SCaleb Palmer     auto OdpSide = RasDataParser::RasDataFlags::ODP_DATA_CORRUPT_SIDE_EFFECT;
799c3038c03SCaleb Palmer     auto OdpRoot = RasDataParser::RasDataFlags::ODP_DATA_CORRUPT_ROOT_CAUSE;
800c3038c03SCaleb Palmer     if (i_rasData.isFlagSet(o_rootCause, OdpSide))
801c3038c03SCaleb Palmer     {
802c3038c03SCaleb Palmer         for (const auto& s : list)
803c3038c03SCaleb Palmer         {
804c3038c03SCaleb Palmer             if (i_rasData.isFlagSet(s, OdpRoot))
805c3038c03SCaleb Palmer             {
806c3038c03SCaleb Palmer                 // ODP data corruption root cause found, return.
807c3038c03SCaleb Palmer                 o_rootCause = s;
808c3038c03SCaleb Palmer                 return;
809c3038c03SCaleb Palmer             }
810c3038c03SCaleb Palmer         }
811c3038c03SCaleb Palmer     }
812*a4424050SCaleb Palmer 
813*a4424050SCaleb Palmer     // Odyssey RDF_FIR
814*a4424050SCaleb Palmer     static const auto rdf_fir = __hash("RDF_FIR");
815*a4424050SCaleb Palmer 
816*a4424050SCaleb Palmer     // RDF_FIR[41] can be the root cause of RDF_FIR[16], so if bit 16 is on,
817*a4424050SCaleb Palmer     // check if bit 41 is also on.
818*a4424050SCaleb Palmer     if (rdf_fir == o_rootCause.getId() && 16 == o_rootCause.getBit())
819*a4424050SCaleb Palmer     {
820*a4424050SCaleb Palmer         // Look for RDF_FIR[41]
821*a4424050SCaleb Palmer         auto itr = std::find_if(list.begin(), list.end(), [&](const auto& t) {
822*a4424050SCaleb Palmer             return (rdf_fir == t.getId() && 41 == t.getBit());
823*a4424050SCaleb Palmer         });
824*a4424050SCaleb Palmer         if (list.end() != itr)
825*a4424050SCaleb Palmer         {
826*a4424050SCaleb Palmer             o_rootCause = *itr;
827*a4424050SCaleb Palmer         }
828*a4424050SCaleb Palmer     }
829c3038c03SCaleb Palmer }
830c3038c03SCaleb Palmer 
831c3038c03SCaleb Palmer //------------------------------------------------------------------------------
832c3038c03SCaleb Palmer 
filterRootCause(AnalysisType i_type,const libhei::IsolationData & i_isoData,libhei::Signature & o_rootCause,const RasDataParser & i_rasData)833c3038c03SCaleb Palmer bool filterRootCause(AnalysisType i_type,
834c3038c03SCaleb Palmer                      const libhei::IsolationData& i_isoData,
835c3038c03SCaleb Palmer                      libhei::Signature& o_rootCause,
836c3038c03SCaleb Palmer                      const RasDataParser& i_rasData)
837c3038c03SCaleb Palmer {
838c3038c03SCaleb Palmer     // Find the initial root cause attention based on common rules for FIR
839c3038c03SCaleb Palmer     // isolation.
840c3038c03SCaleb Palmer     bool rc = findRootCause(i_type, i_isoData, o_rootCause, i_rasData);
841c3038c03SCaleb Palmer 
842c3038c03SCaleb Palmer     // If some root cause was found, handle any special cases for specific FIR
843c3038c03SCaleb Palmer     // bits that require additional logic to determine the root cause.
844c3038c03SCaleb Palmer     if (true == rc)
845c3038c03SCaleb Palmer     {
846c3038c03SCaleb Palmer         rootCauseSpecialCases(i_isoData, o_rootCause, i_rasData);
847c3038c03SCaleb Palmer     }
848c3038c03SCaleb Palmer 
849c3038c03SCaleb Palmer     return rc;
850c3038c03SCaleb Palmer }
851c3038c03SCaleb Palmer 
852c3038c03SCaleb Palmer //------------------------------------------------------------------------------
853c3038c03SCaleb Palmer 
85465fefb2cSZane Shelley } // namespace analyzer
855