1 #include <stdio.h>
2 
3 #include <analyzer/plugins/plugin.hpp>
4 #include <analyzer/ras-data/ras-data-parser.hpp>
5 #include <hei_util.hpp>
6 #include <util/pdbg.hpp>
7 #include <util/trace.hpp>
8 
9 #include "gtest/gtest.h"
10 
11 namespace analyzer
12 {
13 // Forward reference of filterRootCause
14 bool filterRootCause(AnalysisType i_type,
15                      const libhei::IsolationData& i_isoData,
16                      libhei::Signature& o_rootCause,
17                      const RasDataParser& i_rasData);
18 } // namespace analyzer
19 
20 using namespace analyzer;
21 
22 static const auto nodeId =
23     static_cast<libhei::NodeId_t>(libhei::hash<libhei::NodeId_t>("PLL_UNLOCK"));
24 
25 // Sub-test #1 - single PLL unlock attention on proc 1, clock 1
26 TEST(PllUnlock, TestSet1)
27 {
28     pdbg_targets_init(nullptr);
29 
30     libhei::Chip chip1{util::pdbg::getTrgt("/proc1"), P10_20};
31 
32     libhei::Signature sig11{chip1, nodeId, 0, 1, libhei::ATTN_TYPE_CHIP_CS};
33 
34     libhei::IsolationData isoData{};
35     isoData.addSignature(sig11);
36     ServiceData sd{sig11, AnalysisType::SYSTEM_CHECKSTOP, isoData};
37 
38     RasDataParser rasData{};
39     rasData.getResolution(sig11)->resolve(sd);
40 
41     nlohmann::json j{};
42     std::string s{};
43 
44     // Callout list
45     j = sd.getCalloutList();
46     s = R"([
47     {
48         "Deconfigured": false,
49         "Guarded": false,
50         "LocationCode": "P0",
51         "Priority": "M"
52     },
53     {
54         "Deconfigured": false,
55         "Guarded": false,
56         "LocationCode": "/proc1",
57         "Priority": "M"
58     }
59 ])";
60     EXPECT_EQ(s, j.dump(4));
61 
62     // Callout FFDC
63     j = sd.getCalloutFFDC();
64     s = R"([
65     {
66         "Callout Type": "Clock Callout",
67         "Clock Type": "OSC_REF_CLOCK_1",
68         "Priority": "medium"
69     },
70     {
71         "Callout Type": "Hardware Callout",
72         "Guard": false,
73         "Priority": "medium",
74         "Target": "/proc1"
75     }
76 ])";
77     EXPECT_EQ(s, j.dump(4));
78 }
79 
80 // Sub-test #2 - PLL unlock attention on multiple procs and clocks. Isolating
81 //               only to proc 1 clock 0 PLL unlock attentions.
82 TEST(PllUnlock, TestSet2)
83 {
84     pdbg_targets_init(nullptr);
85 
86     libhei::Chip chip0{util::pdbg::getTrgt("/proc0"), P10_20};
87     libhei::Chip chip1{util::pdbg::getTrgt("/proc1"), P10_20};
88 
89     // PLL unlock signatures for each clock per processor.
90     libhei::Signature sig00{chip0, nodeId, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
91     libhei::Signature sig01{chip0, nodeId, 0, 1, libhei::ATTN_TYPE_CHIP_CS};
92     libhei::Signature sig10{chip1, nodeId, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
93     libhei::Signature sig11{chip1, nodeId, 0, 1, libhei::ATTN_TYPE_CHIP_CS};
94 
95     // Plugins for each processor.
96     auto plugin = PluginMap::getSingleton().get(chip1.getType(), "pll_unlock");
97 
98     libhei::IsolationData isoData{};
99     isoData.addSignature(sig00);
100     isoData.addSignature(sig01);
101     isoData.addSignature(sig10);
102     isoData.addSignature(sig11);
103     ServiceData sd{sig10, AnalysisType::SYSTEM_CHECKSTOP, isoData};
104 
105     // Call the PLL unlock plugin.
106     plugin(0, chip1, sd);
107 
108     nlohmann::json j{};
109     std::string s{};
110 
111     // Callout list
112     j = sd.getCalloutList();
113     s = R"([
114     {
115         "Deconfigured": false,
116         "Guarded": false,
117         "LocationCode": "P0",
118         "Priority": "H"
119     },
120     {
121         "Deconfigured": false,
122         "Guarded": false,
123         "LocationCode": "/proc0",
124         "Priority": "M"
125     },
126     {
127         "Deconfigured": false,
128         "Guarded": false,
129         "LocationCode": "/proc1",
130         "Priority": "M"
131     }
132 ])";
133     EXPECT_EQ(s, j.dump(4));
134 
135     // Callout FFDC
136     j = sd.getCalloutFFDC();
137     s = R"([
138     {
139         "Callout Type": "Clock Callout",
140         "Clock Type": "OSC_REF_CLOCK_0",
141         "Priority": "high"
142     },
143     {
144         "Callout Type": "Hardware Callout",
145         "Guard": false,
146         "Priority": "medium",
147         "Target": "/proc0"
148     },
149     {
150         "Callout Type": "Hardware Callout",
151         "Guard": false,
152         "Priority": "medium",
153         "Target": "/proc1"
154     }
155 ])";
156     EXPECT_EQ(s, j.dump(4));
157 }
158 
159 // Sub-test #3 - PLL unlock on single OCMB.
160 TEST(PllUnlock, TestSet3)
161 {
162     pdbg_targets_init(nullptr);
163 
164     libhei::Chip ocmb0{
165         util::pdbg::getTrgt("/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"),
166         ODYSSEY_10};
167 
168     libhei::Signature sig{ocmb0, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
169 
170     libhei::IsolationData isoData{};
171     isoData.addSignature(sig);
172     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP, isoData};
173 
174     RasDataParser rasData{};
175     rasData.getResolution(sig)->resolve(sd);
176 
177     nlohmann::json j{};
178     std::string s{};
179 
180     // Callout list
181     j = sd.getCalloutList();
182     s = R"([
183     {
184         "Deconfigured": false,
185         "EntityPath": [],
186         "GuardType": "GARD_Unrecoverable",
187         "Guarded": true,
188         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
189         "Priority": "H"
190     },
191     {
192         "Deconfigured": false,
193         "Guarded": false,
194         "LocationCode": "/proc0",
195         "Priority": "L"
196     }
197 ])";
198     EXPECT_EQ(s, j.dump(4));
199 
200     // Callout FFDC
201     j = sd.getCalloutFFDC();
202     s = R"([
203     {
204         "Callout Type": "Hardware Callout",
205         "Guard": true,
206         "Priority": "high",
207         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
208     },
209     {
210         "Callout Type": "Hardware Callout",
211         "Guard": false,
212         "Priority": "low",
213         "Target": "/proc0"
214     }
215 ])";
216     EXPECT_EQ(s, j.dump(4));
217 }
218 
219 // Sub-test #4 - PLL unlock on multiple OCMBs in the same domain.
220 TEST(PllUnlock, TestSet4)
221 {
222     pdbg_targets_init(nullptr);
223 
224     libhei::Chip ocmb0{
225         util::pdbg::getTrgt("/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"),
226         ODYSSEY_10};
227 
228     libhei::Chip ocmb1{
229         util::pdbg::getTrgt("/proc0/pib/perv12/mc0/mi0/mcc0/omi1/ocmb0"),
230         ODYSSEY_10};
231 
232     libhei::Signature sig0{ocmb0, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
233     libhei::Signature sig1{ocmb1, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
234 
235     libhei::IsolationData isoData{};
236     isoData.addSignature(sig0);
237     isoData.addSignature(sig1);
238     ServiceData sd{sig0, AnalysisType::SYSTEM_CHECKSTOP, isoData};
239 
240     RasDataParser rasData{};
241     rasData.getResolution(sig0)->resolve(sd);
242 
243     nlohmann::json j{};
244     std::string s{};
245 
246     // Callout list
247     j = sd.getCalloutList();
248     s = R"([
249     {
250         "Deconfigured": false,
251         "EntityPath": [],
252         "GuardType": "GARD_Unrecoverable",
253         "Guarded": true,
254         "LocationCode": "/proc0",
255         "Priority": "H"
256     },
257     {
258         "Deconfigured": false,
259         "Guarded": false,
260         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
261         "Priority": "L"
262     },
263     {
264         "Deconfigured": false,
265         "Guarded": false,
266         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi1/ocmb0",
267         "Priority": "L"
268     }
269 ])";
270     EXPECT_EQ(s, j.dump(4));
271 
272     // Callout FFDC
273     j = sd.getCalloutFFDC();
274     s = R"([
275     {
276         "Callout Type": "Hardware Callout",
277         "Guard": true,
278         "Priority": "high",
279         "Target": "/proc0"
280     },
281     {
282         "Callout Type": "Hardware Callout",
283         "Guard": false,
284         "Priority": "low",
285         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
286     },
287     {
288         "Callout Type": "Hardware Callout",
289         "Guard": false,
290         "Priority": "low",
291         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi1/ocmb0"
292     }
293 ])";
294     EXPECT_EQ(s, j.dump(4));
295 }
296 
297 // Sub-test #5 - PLL unlock on multiple OCMBs in different domains.
298 TEST(PllUnlock, TestSet5)
299 {
300     pdbg_targets_init(nullptr);
301 
302     libhei::Chip ocmb0{
303         util::pdbg::getTrgt("/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"),
304         ODYSSEY_10};
305 
306     libhei::Chip ocmb1{
307         util::pdbg::getTrgt("/proc1/pib/perv14/mc2/mi0/mcc0/omi0/ocmb0"),
308         ODYSSEY_10};
309 
310     libhei::Signature sig0{ocmb0, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
311     libhei::Signature sig1{ocmb1, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
312 
313     libhei::IsolationData isoData{};
314     isoData.addSignature(sig0);
315     isoData.addSignature(sig1);
316     ServiceData sd{sig0, AnalysisType::SYSTEM_CHECKSTOP, isoData};
317 
318     RasDataParser rasData{};
319     rasData.getResolution(sig0)->resolve(sd);
320 
321     nlohmann::json j{};
322     std::string s{};
323 
324     // Callout list
325     j = sd.getCalloutList();
326     s = R"([
327     {
328         "Deconfigured": false,
329         "EntityPath": [],
330         "GuardType": "GARD_Unrecoverable",
331         "Guarded": true,
332         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
333         "Priority": "H"
334     },
335     {
336         "Deconfigured": false,
337         "Guarded": false,
338         "LocationCode": "/proc0",
339         "Priority": "L"
340     }
341 ])";
342     EXPECT_EQ(s, j.dump(4));
343 
344     // Callout FFDC
345     j = sd.getCalloutFFDC();
346     s = R"([
347     {
348         "Callout Type": "Hardware Callout",
349         "Guard": true,
350         "Priority": "high",
351         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
352     },
353     {
354         "Callout Type": "Hardware Callout",
355         "Guard": false,
356         "Priority": "low",
357         "Target": "/proc0"
358     }
359 ])";
360     EXPECT_EQ(s, j.dump(4));
361 }
362 
363 // Sub-test #6 - PLL unlock on mixed PROCs and OCMBs.
364 TEST(PllUnlock, TestSet6)
365 {
366     pdbg_targets_init(nullptr);
367 
368     libhei::Chip proc0{util::pdbg::getTrgt("/proc0"), P10_20};
369     libhei::Chip proc1{util::pdbg::getTrgt("/proc1"), P10_20};
370 
371     libhei::Chip ocmb0{
372         util::pdbg::getTrgt("/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"),
373         ODYSSEY_10};
374 
375     libhei::Chip ocmb1{
376         util::pdbg::getTrgt("/proc1/pib/perv14/mc2/mi0/mcc0/omi0/ocmb0"),
377         ODYSSEY_10};
378 
379     libhei::Signature sig0{ocmb1, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
380     libhei::Signature sig1{proc1, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
381     libhei::Signature sig2{ocmb0, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
382     libhei::Signature sig3{proc0, nodeId, 0, 0, libhei::ATTN_TYPE_RECOVERABLE};
383 
384     libhei::IsolationData isoData{};
385     isoData.addSignature(sig0);
386     isoData.addSignature(sig1);
387     isoData.addSignature(sig2);
388     isoData.addSignature(sig3);
389 
390     RasDataParser rasData{};
391     libhei::Signature rootCause;
392     bool attnFound = filterRootCause(AnalysisType::SYSTEM_CHECKSTOP, isoData,
393                                      rootCause, rasData);
394     EXPECT_TRUE(attnFound);
395     EXPECT_EQ(sig1.toUint32(), rootCause.toUint32());
396 }
397