1 #include <assert.h>
2 
3 #include <analyzer_main.hpp>
4 #include <hei_main.hpp>
5 #include <hei_util.hpp>
6 #include <util/pdbg.hpp>
7 
8 #include <algorithm>
9 #include <limits>
10 #include <string>
11 
12 namespace analyzer
13 {
14 
15 //------------------------------------------------------------------------------
16 
17 bool __findRcsOscError(const std::vector<libhei::Signature>& i_list,
18                        libhei::Signature& o_rootCause)
19 {
20     // TODO: Consider returning all of them instead of one as root cause.
21     auto itr = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
22         return (libhei::hash<libhei::NodeId_t>("TP_LOCAL_FIR") == t.getId() &&
23                 (42 == t.getBit() || 43 == t.getBit()));
24     });
25 
26     if (i_list.end() != itr)
27     {
28         o_rootCause = *itr;
29         return true;
30     }
31 
32     return false;
33 }
34 
35 //------------------------------------------------------------------------------
36 
37 bool __findPllUnlock(const std::vector<libhei::Signature>& i_list,
38                      libhei::Signature& o_rootCause)
39 {
40     // TODO: Consider returning all of them instead of one as root cause.
41     auto itr = std::find_if(i_list.begin(), i_list.end(), [&](const auto& t) {
42         return (libhei::hash<libhei::NodeId_t>("PLL_UNLOCK") == t.getId() &&
43                 (0 == t.getBit() || 1 == t.getBit()));
44     });
45 
46     if (i_list.end() != itr)
47     {
48         o_rootCause = *itr;
49         return true;
50     }
51 
52     return false;
53 }
54 
55 //------------------------------------------------------------------------------
56 
57 bool __findMemoryChannelFailure(const std::vector<libhei::Signature>& i_list,
58                                 libhei::Signature& o_rootCause)
59 {
60     using namespace util::pdbg;
61 
62     using func  = libhei::NodeId_t (*)(const std::string& i_str);
63     func __hash = libhei::hash<libhei::NodeId_t>;
64 
65     static const auto mc_dstl_fir       = __hash("MC_DSTL_FIR");
66     static const auto mc_ustl_fir       = __hash("MC_USTL_FIR");
67     static const auto mc_omi_dl_err_rpt = __hash("MC_OMI_DL_ERR_RPT");
68 
69     for (const auto s : i_list)
70     {
71         const auto targetType = getTrgtType(getTrgt(s.getChip()));
72         const auto id         = s.getId();
73         const auto bit        = s.getBit();
74         const auto attnType   = s.getAttnType();
75 
76         // Look for any unit checkstop attentions from OCMBs.
77         if (TYPE_OCMB == targetType)
78         {
79             // Any unit checkstop attentions will trigger a channel failure.
80             if (libhei::ATTN_TYPE_UNIT_CS == attnType)
81             {
82                 o_rootCause = s;
83                 return true;
84             }
85         }
86         // Look for channel failure attentions on processors.
87         else if (TYPE_PROC == targetType)
88         {
89             // TODO: All of these channel failure bits are configurable.
90             //       Eventually, we will need some mechanism to check that
91             //       config registers for a more accurate analysis. For now,
92             //       simply check for all bits that could potentially be
93             //       configured to channel failure.
94 
95             // Any unit checkstop bit in the MC_DSTL_FIR or MC_USTL_FIR could
96             // be a channel failure.
97             if (libhei::ATTN_TYPE_UNIT_CS == attnType)
98             {
99                 // Ignore bits MC_DSTL_FIR[0:7] because they simply indicate
100                 // attentions occurred on the attached OCMBs.
101                 if ((mc_dstl_fir == id && 8 <= bit) || (mc_ustl_fir == id))
102                 {
103                     o_rootCause = s;
104                     return true;
105                 }
106             }
107 
108             // All bits in MC_OMI_DL_ERR_RPT eventually feed into
109             // MC_OMI_DL_FIR[0,20] which are configurable to channel failure.
110             if (mc_omi_dl_err_rpt == id)
111             {
112                 o_rootCause = s;
113                 return true;
114             }
115         }
116     }
117 
118     return false; // default, nothing found
119 }
120 
121 //------------------------------------------------------------------------------
122 
123 // Will query if a signature is a potential system checkstop root cause.
124 // attention. Note that this function excludes memory channel failure attentions
125 // which are checked in __findMemoryChannelFailure().
126 bool __findCsRootCause(const libhei::Signature& i_signature)
127 {
128     using namespace util::pdbg;
129 
130     using func  = libhei::NodeId_t (*)(const std::string& i_str);
131     func __hash = libhei::hash<libhei::NodeId_t>;
132 
133     // PROC registers
134     static const auto eq_core_fir      = __hash("EQ_CORE_FIR");
135     static const auto eq_l2_fir        = __hash("EQ_L2_FIR");
136     static const auto eq_l3_fir        = __hash("EQ_L3_FIR");
137     static const auto eq_ncu_fir       = __hash("EQ_NCU_FIR");
138     static const auto iohs_dlp_fir_oc  = __hash("IOHS_DLP_FIR_OC");
139     static const auto iohs_dlp_fir_smp = __hash("IOHS_DLP_FIR_SMP");
140     static const auto nx_cq_fir        = __hash("NX_CQ_FIR");
141     static const auto nx_dma_eng_fir   = __hash("NX_DMA_ENG_FIR");
142     static const auto pau_fir_0        = __hash("PAU_FIR_0");
143     static const auto pau_fir_1        = __hash("PAU_FIR_1");
144     static const auto pau_fir_2        = __hash("PAU_FIR_2");
145     static const auto pau_ptl_fir      = __hash("PAU_PTL_FIR");
146 
147     // OCMB registers
148     static const auto rdffir = __hash("RDFFIR");
149 
150     const auto targetType = getTrgtType(getTrgt(i_signature.getChip()));
151     const auto id         = i_signature.getId();
152     const auto bit        = i_signature.getBit();
153 
154     if (TYPE_PROC == targetType)
155     {
156         if (eq_core_fir == id &&
157             (3 == bit || 5 == bit || 8 == bit || 12 == bit || 22 == bit ||
158              25 == bit || 32 == bit || 36 == bit || 38 == bit || 46 == bit ||
159              47 == bit))
160         {
161             return true;
162         }
163 
164         if (eq_l2_fir == id &&
165             (1 == bit || 12 == bit || 13 == bit || 17 == bit || 18 == bit ||
166              20 == bit || 27 == bit))
167         {
168             return true;
169         }
170 
171         if (eq_l3_fir == id &&
172             (2 == bit || 5 == bit || 8 == bit || 11 == bit || 17 == bit))
173         {
174             return true;
175         }
176 
177         if (eq_ncu_fir == id && (3 == bit || 4 == bit || 5 == bit || 7 == bit ||
178                                  8 == bit || 10 == bit || 17 == bit))
179         {
180             return true;
181         }
182 
183         if (iohs_dlp_fir_oc == id && (54 <= bit && bit <= 61))
184         {
185             return true;
186         }
187 
188         if (iohs_dlp_fir_smp == id && (54 <= bit && bit <= 61))
189         {
190             return true;
191         }
192 
193         if (nx_cq_fir == id && (7 == bit || 16 == bit || 21 == bit))
194         {
195             return true;
196         }
197 
198         if (nx_dma_eng_fir == id && (0 == bit))
199         {
200             return true;
201         }
202 
203         if (pau_fir_0 == id &&
204             (15 == bit || 18 == bit || 19 == bit || 25 == bit || 26 == bit ||
205              29 == bit || 33 == bit || 34 == bit || 35 == bit || 40 == bit ||
206              42 == bit || 44 == bit || 45 == bit))
207         {
208             return true;
209         }
210 
211         if (pau_fir_1 == id &&
212             (13 == bit || 14 == bit || 15 == bit || 37 == bit || 39 == bit ||
213              40 == bit || 41 == bit || 42 == bit))
214         {
215             return true;
216         }
217 
218         if (pau_fir_2 == id &&
219             ((4 <= bit && bit <= 18) || (20 <= bit && bit <= 31) ||
220              (36 <= bit && bit <= 41) || 45 == bit || 47 == bit || 48 == bit ||
221              50 == bit || 51 == bit || 52 == bit))
222         {
223             return true;
224         }
225 
226         if (pau_ptl_fir == id && (4 == bit || 8 == bit))
227         {
228             return true;
229         }
230     }
231     else if (TYPE_OCMB == targetType)
232     {
233         if (rdffir == id && (14 == bit || 15 == bit || 17 == bit || 37 == bit))
234         {
235             return true;
236         }
237     }
238 
239     return false; // default, nothing found
240 }
241 
242 //------------------------------------------------------------------------------
243 
244 bool __findCsRootCause_RE(const std::vector<libhei::Signature>& i_list,
245                           libhei::Signature& o_rootCause)
246 {
247     for (const auto s : i_list)
248     {
249         // Only looking for recoverable attentions.
250         if (libhei::ATTN_TYPE_RECOVERABLE != s.getAttnType())
251         {
252             continue;
253         }
254 
255         if (__findCsRootCause(s))
256         {
257             o_rootCause = s;
258             return true;
259         }
260     }
261 
262     return false; // default, nothing found
263 }
264 
265 //------------------------------------------------------------------------------
266 
267 bool __findCsRootCause_UCS(const std::vector<libhei::Signature>& i_list,
268                            libhei::Signature& o_rootCause)
269 {
270     for (const auto s : i_list)
271     {
272         // Only looking for unit checkstop attentions.
273         if (libhei::ATTN_TYPE_UNIT_CS != s.getAttnType())
274         {
275             continue;
276         }
277 
278         if (__findCsRootCause(s))
279         {
280             o_rootCause = s;
281             return true;
282         }
283     }
284 
285     return false; // default, nothing found
286 }
287 
288 //------------------------------------------------------------------------------
289 
290 bool __findNonExternalCs(const std::vector<libhei::Signature>& i_list,
291                          libhei::Signature& o_rootCause)
292 {
293     using namespace util::pdbg;
294 
295     static const auto pb_ext_fir = libhei::hash<libhei::NodeId_t>("PB_EXT_FIR");
296 
297     for (const auto s : i_list)
298     {
299         const auto targetType = getTrgtType(getTrgt(s.getChip()));
300         const auto id         = s.getId();
301         const auto attnType   = s.getAttnType();
302 
303         // Find any processor with system checkstop attention that did not
304         // originate from the PB_EXT_FIR.
305         if ((TYPE_PROC == targetType) &&
306             (libhei::ATTN_TYPE_CHECKSTOP == attnType) && (pb_ext_fir != id))
307         {
308             o_rootCause = s;
309             return true;
310         }
311     }
312 
313     return false; // default, nothing found
314 }
315 
316 //------------------------------------------------------------------------------
317 
318 bool __findTiRootCause(const std::vector<libhei::Signature>& i_list,
319                        libhei::Signature& o_rootCause)
320 {
321     using namespace util::pdbg;
322 
323     using func  = libhei::NodeId_t (*)(const std::string& i_str);
324     func __hash = libhei::hash<libhei::NodeId_t>;
325 
326     // PROC registers
327     static const auto tp_local_fir        = __hash("TP_LOCAL_FIR");
328     static const auto occ_fir             = __hash("OCC_FIR");
329     static const auto pbao_fir            = __hash("PBAO_FIR");
330     static const auto n0_local_fir        = __hash("N0_LOCAL_FIR");
331     static const auto int_cq_fir          = __hash("INT_CQ_FIR");
332     static const auto nx_cq_fir           = __hash("NX_CQ_FIR");
333     static const auto nx_dma_eng_fir      = __hash("NX_DMA_ENG_FIR");
334     static const auto vas_fir             = __hash("VAS_FIR");
335     static const auto n1_local_fir        = __hash("N1_LOCAL_FIR");
336     static const auto mcd_fir             = __hash("MCD_FIR");
337     static const auto pb_station_fir_en_1 = __hash("PB_STATION_FIR_EN_1");
338     static const auto pb_station_fir_en_2 = __hash("PB_STATION_FIR_EN_2");
339     static const auto pb_station_fir_en_3 = __hash("PB_STATION_FIR_EN_3");
340     static const auto pb_station_fir_en_4 = __hash("PB_STATION_FIR_EN_4");
341     static const auto pb_station_fir_es_1 = __hash("PB_STATION_FIR_ES_1");
342     static const auto pb_station_fir_es_2 = __hash("PB_STATION_FIR_ES_2");
343     static const auto pb_station_fir_es_3 = __hash("PB_STATION_FIR_ES_3");
344     static const auto pb_station_fir_es_4 = __hash("PB_STATION_FIR_ES_4");
345     static const auto pb_station_fir_eq   = __hash("PB_STATION_FIR_EQ");
346     static const auto psihb_fir           = __hash("PSIHB_FIR");
347     static const auto pbaf_fir            = __hash("PBAF_FIR");
348     static const auto lpc_fir             = __hash("LPC_FIR");
349     static const auto eq_core_fir         = __hash("EQ_CORE_FIR");
350     static const auto eq_l2_fir           = __hash("EQ_L2_FIR");
351     static const auto eq_l3_fir           = __hash("EQ_L3_FIR");
352     static const auto eq_ncu_fir          = __hash("EQ_NCU_FIR");
353     static const auto eq_local_fir        = __hash("EQ_LOCAL_FIR");
354     static const auto eq_qme_fir          = __hash("EQ_QME_FIR");
355     static const auto iohs_local_fir      = __hash("IOHS_LOCAL_FIR");
356     static const auto iohs_dlp_fir_oc     = __hash("IOHS_DLP_FIR_OC");
357     static const auto iohs_dlp_fir_smp    = __hash("IOHS_DLP_FIR_SMP");
358     static const auto mc_local_fir        = __hash("MC_LOCAL_FIR");
359     static const auto mc_fir              = __hash("MC_FIR");
360     static const auto mc_dstl_fir         = __hash("MC_DSTL_FIR");
361     static const auto mc_ustl_fir         = __hash("MC_USTL_FIR");
362     static const auto nmmu_cq_fir         = __hash("NMMU_CQ_FIR");
363     static const auto nmmu_fir            = __hash("NMMU_FIR");
364     static const auto mc_omi_dl           = __hash("MC_OMI_DL");
365     static const auto pau_local_fir       = __hash("PAU_LOCAL_FIR");
366     static const auto pau_ptl_fir         = __hash("PAU_PTL_FIR");
367     static const auto pau_phy_fir         = __hash("PAU_PHY_FIR");
368     static const auto pau_fir_0           = __hash("PAU_FIR_0");
369     static const auto pau_fir_2           = __hash("PAU_FIR_2");
370     static const auto pci_local_fir       = __hash("PCI_LOCAL_FIR");
371     static const auto pci_iop_fir         = __hash("PCI_IOP_FIR");
372     static const auto pci_nest_fir        = __hash("PCI_NEST_FIR");
373 
374     // OCMB registers
375     static const auto ocmb_lfir = __hash("OCMB_LFIR");
376     static const auto mmiofir   = __hash("MMIOFIR");
377     static const auto srqfir    = __hash("SRQFIR");
378     static const auto rdffir    = __hash("RDFFIR");
379     static const auto tlxfir    = __hash("TLXFIR");
380     static const auto omi_dl    = __hash("OMI_DL");
381 
382     for (const auto& signature : i_list)
383     {
384         const auto targetType = getTrgtType(getTrgt(signature.getChip()));
385         const auto attnType   = signature.getAttnType();
386         const auto id         = signature.getId();
387         const auto bit        = signature.getBit();
388 
389         // Only looking for recoverable or unit checkstop attentions.
390         if (libhei::ATTN_TYPE_RECOVERABLE != attnType &&
391             libhei::ATTN_TYPE_UNIT_CS != attnType)
392         {
393             continue;
394         }
395 
396         // Ignore attentions that should not be blamed as root cause of a TI.
397         // This would include informational only FIRs or correctable errors.
398         if (TYPE_PROC == targetType)
399         {
400             if (tp_local_fir == id &&
401                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
402                  5 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
403                  11 == bit || 20 == bit || 22 == bit || 23 == bit ||
404                  24 == bit || 38 == bit || 40 == bit || 41 == bit ||
405                  46 == bit || 47 == bit || 48 == bit || 55 == bit ||
406                  56 == bit || 57 == bit || 58 == bit || 59 == bit))
407             {
408                 continue;
409             }
410 
411             if (occ_fir == id &&
412                 (9 == bit || 10 == bit || 15 == bit || 20 == bit || 21 == bit ||
413                  22 == bit || 23 == bit || 32 == bit || 33 == bit ||
414                  34 == bit || 36 == bit || 42 == bit || 43 == bit ||
415                  46 == bit || 47 == bit || 48 == bit || 51 == bit ||
416                  52 == bit || 53 == bit || 54 == bit || 57 == bit))
417             {
418                 continue;
419             }
420 
421             if (pbao_fir == id &&
422                 (0 == bit || 1 == bit || 2 == bit || 8 == bit || 11 == bit ||
423                  13 == bit || 15 == bit || 16 == bit || 17 == bit))
424             {
425                 continue;
426             }
427 
428             if ((n0_local_fir == id || n1_local_fir == id ||
429                  iohs_local_fir == id || mc_local_fir == id ||
430                  pau_local_fir == id || pci_local_fir == id) &&
431                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
432                  5 == bit || 6 == bit || 7 == bit || 8 == bit || 9 == bit ||
433                  10 == bit || 11 == bit || 20 == bit || 21 == bit))
434             {
435                 continue;
436             }
437 
438             if (int_cq_fir == id &&
439                 (0 == bit || 3 == bit || 5 == bit || 7 == bit || 36 == bit ||
440                  58 == bit || 59 == bit || 60 == bit))
441             {
442                 continue;
443             }
444 
445             if (nx_cq_fir == id &&
446                 (1 == bit || 4 == bit || 18 == bit || 32 == bit || 33 == bit))
447             {
448                 continue;
449             }
450 
451             if (nx_dma_eng_fir == id &&
452                 (4 == bit || 6 == bit || 9 == bit || 10 == bit || 11 == bit ||
453                  34 == bit || 35 == bit || 36 == bit || 37 == bit || 39 == bit))
454             {
455                 continue;
456             }
457 
458             if (vas_fir == id &&
459                 (8 == bit || 9 == bit || 11 == bit || 12 == bit || 13 == bit))
460             {
461                 continue;
462             }
463 
464             if (mcd_fir == id && (0 == bit))
465             {
466                 continue;
467             }
468 
469             if ((pb_station_fir_en_1 == id || pb_station_fir_en_2 == id ||
470                  pb_station_fir_en_3 == id || pb_station_fir_en_4 == id ||
471                  pb_station_fir_es_1 == id || pb_station_fir_es_2 == id ||
472                  pb_station_fir_es_3 == id || pb_station_fir_es_4 == id ||
473                  pb_station_fir_eq == id) &&
474                 (9 == bit))
475             {
476                 continue;
477             }
478 
479             if (psihb_fir == id && (0 == bit || 23 == bit))
480             {
481                 continue;
482             }
483 
484             if (pbaf_fir == id &&
485                 (0 == bit || 1 == bit || 3 == bit || 4 == bit || 5 == bit ||
486                  6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
487                  11 == bit || 19 == bit || 20 == bit || 21 == bit ||
488                  28 == bit || 29 == bit || 30 == bit || 31 == bit ||
489                  32 == bit || 33 == bit || 34 == bit || 35 == bit || 36 == bit))
490             {
491                 continue;
492             }
493 
494             if (lpc_fir == id && (5 == bit))
495             {
496                 continue;
497             }
498 
499             if (eq_core_fir == id &&
500                 (0 == bit || 2 == bit || 4 == bit || 7 == bit || 9 == bit ||
501                  11 == bit || 13 == bit || 18 == bit || 21 == bit ||
502                  24 == bit || 29 == bit || 31 == bit || 37 == bit ||
503                  43 == bit || 56 == bit || 57 == bit))
504             {
505                 continue;
506             }
507 
508             if (eq_l2_fir == id &&
509                 (0 == bit || 6 == bit || 11 == bit || 19 == bit || 36 == bit))
510             {
511                 continue;
512             }
513 
514             if (eq_l3_fir == id &&
515                 (3 == bit || 4 == bit || 7 == bit || 10 == bit || 13 == bit))
516             {
517                 continue;
518             }
519 
520             if (eq_ncu_fir == id && (9 == bit))
521             {
522                 continue;
523             }
524 
525             if (eq_local_fir == id &&
526                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 5 == bit ||
527                  6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
528                  11 == bit || 12 == bit || 13 == bit || 14 == bit ||
529                  15 == bit || 16 == bit || 20 == bit || 21 == bit ||
530                  22 == bit || 23 == bit || 24 == bit || 25 == bit ||
531                  26 == bit || 27 == bit || 28 == bit || 29 == bit ||
532                  30 == bit || 31 == bit || 32 == bit || 33 == bit ||
533                  34 == bit || 35 == bit || 36 == bit || 37 == bit ||
534                  38 == bit || 39 == bit))
535             {
536                 continue;
537             }
538 
539             if (eq_qme_fir == id && (7 == bit || 25 == bit))
540             {
541                 continue;
542             }
543 
544             if (iohs_dlp_fir_oc == id &&
545                 (6 == bit || 7 == bit || 8 == bit || 9 == bit || 10 == bit ||
546                  48 == bit || 49 == bit || 52 == bit || 53 == bit))
547             {
548                 continue;
549             }
550 
551             if (iohs_dlp_fir_smp == id &&
552                 (6 == bit || 7 == bit || 14 == bit || 15 == bit || 16 == bit ||
553                  17 == bit || 38 == bit || 39 == bit || 44 == bit ||
554                  45 == bit || 50 == bit || 51 == bit))
555             {
556                 continue;
557             }
558 
559             if (mc_fir == id &&
560                 (5 == bit || 8 == bit || 15 == bit || 16 == bit))
561             {
562                 continue;
563             }
564 
565             if (mc_dstl_fir == id &&
566                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
567                  5 == bit || 6 == bit || 7 == bit || 14 == bit || 15 == bit))
568             {
569                 continue;
570             }
571 
572             if (mc_ustl_fir == id &&
573                 (6 == bit || 20 == bit || 33 == bit || 34 == bit))
574             {
575                 continue;
576             }
577 
578             if (nmmu_cq_fir == id && (8 == bit || 11 == bit || 14 == bit))
579             {
580                 continue;
581             }
582 
583             if (nmmu_fir == id &&
584                 (0 == bit || 3 == bit || 8 == bit || 9 == bit || 10 == bit ||
585                  11 == bit || 12 == bit || 13 == bit || 14 == bit ||
586                  15 == bit || 30 == bit || 31 == bit || 41 == bit))
587             {
588                 continue;
589             }
590 
591             if (mc_omi_dl == id && (2 == bit || 3 == bit || 6 == bit ||
592                                     7 == bit || 9 == bit || 10 == bit))
593             {
594                 continue;
595             }
596 
597             if (pau_ptl_fir == id && (5 == bit || 9 == bit))
598             {
599                 continue;
600             }
601 
602             if (pau_phy_fir == id &&
603                 (2 == bit || 3 == bit || 6 == bit || 7 == bit || 15 == bit))
604             {
605                 continue;
606             }
607 
608             if (pau_fir_0 == id && (13 == bit || 30 == bit || 41 == bit))
609             {
610                 continue;
611             }
612 
613             if (pau_fir_2 == id && (19 == bit || 46 == bit || 49 == bit))
614             {
615                 continue;
616             }
617 
618             if (pci_iop_fir == id &&
619                 (0 == bit || 2 == bit || 4 == bit || 6 == bit || 7 == bit ||
620                  8 == bit || 10 == bit))
621             {
622                 continue;
623             }
624 
625             if (pci_nest_fir == id && (2 == bit || 5 == bit))
626             {
627                 continue;
628             }
629         }
630         else if (TYPE_OCMB == targetType)
631         {
632             if (ocmb_lfir == id &&
633                 (0 == bit || 1 == bit || 2 == bit || 8 == bit || 23 == bit ||
634                  37 == bit || 63 == bit))
635             {
636                 continue;
637             }
638 
639             if (mmiofir == id && (2 == bit))
640             {
641                 continue;
642             }
643 
644             if (srqfir == id &&
645                 (2 == bit || 4 == bit || 14 == bit || 15 == bit || 23 == bit ||
646                  25 == bit || 28 == bit))
647             {
648                 continue;
649             }
650 
651             if (rdffir == id &&
652                 (0 == bit || 1 == bit || 2 == bit || 3 == bit || 4 == bit ||
653                  5 == bit || 6 == bit || 7 == bit || 8 == bit || 9 == bit ||
654                  18 == bit || 38 == bit || 40 == bit || 41 == bit ||
655                  45 == bit || 46 == bit))
656             {
657                 continue;
658             }
659 
660             if (tlxfir == id && (0 == bit || 9 == bit || 26 == bit))
661             {
662                 continue;
663             }
664 
665             if (omi_dl == id && (2 == bit || 3 == bit || 6 == bit || 7 == bit ||
666                                  9 == bit || 10 == bit))
667             {
668                 continue;
669             }
670         }
671 
672         // At this point, the attention has not been explicitly ignored. So
673         // return this signature and exit.
674         o_rootCause = signature;
675         return true;
676     }
677 
678     return false; // default, nothing found
679 }
680 
681 //------------------------------------------------------------------------------
682 
683 bool filterRootCause(AnalysisType i_type,
684                      const libhei::IsolationData& i_isoData,
685                      libhei::Signature& o_rootCause)
686 {
687     // We'll need to make a copy of the list so that the original list is
688     // maintained for the PEL.
689     std::vector<libhei::Signature> list{i_isoData.getSignatureList()};
690 
691     // START WORKAROUND
692     // TODO: Filtering should be data driven. Until that support is available,
693     //       use the following isolation rules.
694 
695     // Ensure the list is not empty before continuing.
696     if (list.empty())
697     {
698         return false; // nothing more to do
699     }
700 
701     // First, look for any RCS OSC errors. This must always be first because
702     // they can cause downstream PLL unlock attentions.
703     if (__findRcsOscError(list, o_rootCause))
704     {
705         return true;
706     }
707 
708     // Second, look for any PLL unlock attentions. This must always be second
709     // because PLL unlock attentions can cause any number of downstream
710     // attentions, including a system checkstop.
711     if (__findPllUnlock(list, o_rootCause))
712     {
713         return true;
714     }
715 
716     // Regardless of the analysis type, always look for anything that could be
717     // blamed as the root cause of a system checkstop.
718 
719     // Memory channel failure attentions will produce SUEs and likely cause
720     // downstream attentions, including a system checkstop.
721     if (__findMemoryChannelFailure(list, o_rootCause))
722     {
723         return true;
724     }
725 
726     // Look for any recoverable attentions that have been identified as a
727     // potential root cause of a system checkstop attention. These would include
728     // any attention that would generate an SUE. Note that is it possible for
729     // recoverables to generate unit checkstop attentions so we must check them
730     // first.
731     if (__findCsRootCause_RE(list, o_rootCause))
732     {
733         return true;
734     }
735 
736     // Look for any unit checkstop attentions (other than memory channel
737     // failures) that have been identified as a potential root cause of a
738     // system checkstop attention. These would include any attention that would
739     // generate an SUE.
740     if (__findCsRootCause_UCS(list, o_rootCause))
741     {
742         return true;
743     }
744 
745     // Look for any system checkstop attentions that originated from within the
746     // chip that reported the attention. In other words, no external checkstop
747     // attentions.
748     if (__findNonExternalCs(list, o_rootCause))
749     {
750         return true;
751     }
752 
753     if (AnalysisType::SYSTEM_CHECKSTOP != i_type)
754     {
755         // No system checkstop root cause attentions were found. Next, look for
756         // any recoverable or unit checkstop attentions that could be associated
757         // with a TI.
758         if (__findTiRootCause(list, o_rootCause))
759         {
760             return true;
761         }
762 
763         if (AnalysisType::TERMINATE_IMMEDIATE != i_type)
764         {
765             // No attentions associated with a system checkstop or TI were
766             // found. Simply, return the first entry in the list.
767             o_rootCause = list.front();
768             return true;
769         }
770     }
771 
772     // END WORKAROUND
773 
774     return false; // default, no active attentions found.
775 }
776 
777 //------------------------------------------------------------------------------
778 
779 } // namespace analyzer
780