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
TEST(PllUnlock,TestSet1)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.
TEST(PllUnlock,TestSet2)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.
TEST(PllUnlock,TestSet3)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.
TEST(PllUnlock,TestSet4)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.
TEST(PllUnlock,TestSet5)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.
TEST(PllUnlock,TestSet6)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