xref: /openbmc/openpower-hw-diags/test/test-resolution.cpp (revision c08f5ff77436510fe9286fa48ae5f024e0986db5)
1 #include <stdio.h>
2 
3 #include <analyzer/analyzer_main.hpp>
4 #include <analyzer/resolution.hpp>
5 #include <util/pdbg.hpp>
6 #include <util/trace.hpp>
7 
8 #include <regex>
9 
10 #include "gtest/gtest.h"
11 
12 // Chip string
13 constexpr auto chip_str = "/proc0";
14 
15 // Unit paths
16 constexpr auto proc_str = "";
17 constexpr auto iolink_str = "pib/perv26/pauc1/iohs0/smpgroup0";
18 constexpr auto omi_str = "pib/perv12/mc0/mi0/mcc0/omi0";
19 constexpr auto ocmb_str = "pib/perv12/mc0/mi0/mcc0/omi0/ocmb0";
20 constexpr auto core_str = "pib/perv39/eq7/fc1/core1";
21 
22 using namespace analyzer;
23 
TEST(Resolution,TestSet1)24 TEST(Resolution, TestSet1)
25 {
26     pdbg_targets_init(nullptr);
27 
28     // Create a few resolutions
29     auto c1 = std::make_shared<HardwareCalloutResolution>(
30         proc_str, callout::Priority::HIGH, false);
31 
32     auto c2 = std::make_shared<HardwareCalloutResolution>(
33         omi_str, callout::Priority::MED_A, true);
34 
35     auto c3 = std::make_shared<HardwareCalloutResolution>(
36         core_str, callout::Priority::MED, true);
37 
38     auto c4 = std::make_shared<ProcedureCalloutResolution>(
39         callout::Procedure::NEXTLVL, callout::Priority::LOW);
40 
41     auto c5 = std::make_shared<ClockCalloutResolution>(
42         callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::LOW, false);
43 
44     // l1 = (c1, c2, c5)
45     auto l1 = std::make_shared<ResolutionList>();
46     l1->push(c1);
47     l1->push(c2);
48     l1->push(c5);
49 
50     // l2 = (c4, c3, c1, c2, c5)
51     auto l2 = std::make_shared<ResolutionList>();
52     l2->push(c4);
53     l2->push(c3);
54     l2->push(l1);
55 
56     // Get some ServiceData objects
57     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
58     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
59     ServiceData sd1{sig, AnalysisType::SYSTEM_CHECKSTOP,
60                     libhei::IsolationData{}};
61     ServiceData sd2{sig, AnalysisType::TERMINATE_IMMEDIATE,
62                     libhei::IsolationData{}};
63 
64     // Resolve
65     l1->resolve(sd1);
66     l2->resolve(sd2);
67 
68     // Verify the subsystems
69     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
70         callout::SrcSubsystem::PROCESSOR_FRU, callout::Priority::HIGH};
71     EXPECT_EQ(sd1.getSubsys(), subsys);
72 
73     subsys = {callout::SrcSubsystem::PROCESSOR_FRU, callout::Priority::HIGH};
74     EXPECT_EQ(sd2.getSubsys(), subsys);
75 
76     // Start verifying
77     nlohmann::json j{};
78     std::string s{};
79 
80     j = sd1.getCalloutList();
81     s = R"([
82     {
83         "Deconfigured": false,
84         "Guarded": false,
85         "LocationCode": "/proc0",
86         "Priority": "H"
87     },
88     {
89         "Deconfigured": false,
90         "EntityPath": [],
91         "GuardType": "GARD_Unrecoverable",
92         "Guarded": true,
93         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
94         "Priority": "A"
95     },
96     {
97         "Deconfigured": false,
98         "Guarded": false,
99         "LocationCode": "P0",
100         "Priority": "L"
101     }
102 ])";
103     EXPECT_EQ(s, j.dump(4));
104 
105     j = sd2.getCalloutList();
106     s = R"([
107     {
108         "Priority": "L",
109         "Procedure": "next_level_support"
110     },
111     {
112         "Deconfigured": false,
113         "EntityPath": [],
114         "GuardType": "GARD_Predictive",
115         "Guarded": true,
116         "LocationCode": "/proc0/pib/perv39/eq7/fc1/core1",
117         "Priority": "M"
118     },
119     {
120         "Deconfigured": false,
121         "Guarded": false,
122         "LocationCode": "/proc0",
123         "Priority": "H"
124     },
125     {
126         "Deconfigured": false,
127         "EntityPath": [],
128         "GuardType": "GARD_Predictive",
129         "Guarded": true,
130         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
131         "Priority": "A"
132     },
133     {
134         "Deconfigured": false,
135         "Guarded": false,
136         "LocationCode": "P0",
137         "Priority": "L"
138     }
139 ])";
140     EXPECT_EQ(s, j.dump(4));
141 }
142 
TEST(Resolution,HardwareCallout)143 TEST(Resolution, HardwareCallout)
144 {
145     pdbg_targets_init(nullptr);
146 
147     auto c1 = std::make_shared<HardwareCalloutResolution>(
148         omi_str, callout::Priority::MED_A, true);
149 
150     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
151     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
152     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
153                    libhei::IsolationData{}};
154 
155     c1->resolve(sd);
156 
157     // Verify the subsystem
158     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
159         callout::SrcSubsystem::MEMORY_CTLR, callout::Priority::MED_A};
160     EXPECT_EQ(sd.getSubsys(), subsys);
161 
162     nlohmann::json j{};
163     std::string s{};
164 
165     // Callout list
166     j = sd.getCalloutList();
167     s = R"([
168     {
169         "Deconfigured": false,
170         "EntityPath": [],
171         "GuardType": "GARD_Unrecoverable",
172         "Guarded": true,
173         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
174         "Priority": "A"
175     }
176 ])";
177     EXPECT_EQ(s, j.dump(4));
178 
179     // Callout FFDC
180     j = sd.getCalloutFFDC();
181     s = R"([
182     {
183         "Callout Type": "Hardware Callout",
184         "Guard": true,
185         "Priority": "medium_group_A",
186         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
187     }
188 ])";
189     EXPECT_EQ(s, j.dump(4));
190 }
191 
TEST(Resolution,ConnectedCallout)192 TEST(Resolution, ConnectedCallout)
193 {
194     pdbg_targets_init(nullptr);
195 
196     auto c1 = std::make_shared<ConnectedCalloutResolution>(
197         callout::BusType::SMP_BUS, iolink_str, callout::Priority::MED_A, true);
198 
199     auto c2 = std::make_shared<ConnectedCalloutResolution>(
200         callout::BusType::OMI_BUS, ocmb_str, callout::Priority::MED_B, true);
201 
202     auto c3 = std::make_shared<ConnectedCalloutResolution>(
203         callout::BusType::OMI_BUS, omi_str, callout::Priority::MED_C, true);
204 
205     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
206     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
207     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
208                    libhei::IsolationData{}};
209 
210     nlohmann::json j{};
211     std::string s{};
212 
213     c1->resolve(sd);
214     c2->resolve(sd);
215     c3->resolve(sd);
216 
217     // Verify the subsystem
218     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
219         callout::SrcSubsystem::PROCESSOR_BUS, callout::Priority::MED_A};
220     EXPECT_EQ(sd.getSubsys(), subsys);
221 
222     // Callout list
223     j = sd.getCalloutList();
224     s = R"([
225     {
226         "Deconfigured": false,
227         "EntityPath": [],
228         "GuardType": "GARD_Unrecoverable",
229         "Guarded": true,
230         "LocationCode": "/proc1/pib/perv25/pauc0/iohs1/smpgroup0",
231         "Priority": "A"
232     },
233     {
234         "Deconfigured": false,
235         "EntityPath": [],
236         "GuardType": "GARD_Unrecoverable",
237         "Guarded": true,
238         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
239         "Priority": "B"
240     },
241     {
242         "Deconfigured": false,
243         "EntityPath": [],
244         "GuardType": "GARD_Unrecoverable",
245         "Guarded": true,
246         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
247         "Priority": "C"
248     }
249 ])";
250     EXPECT_EQ(s, j.dump(4));
251 
252     // Callout FFDC
253     j = sd.getCalloutFFDC();
254     s = R"([
255     {
256         "Bus Type": "SMP_BUS",
257         "Callout Type": "Connected Callout",
258         "Guard": true,
259         "Priority": "medium_group_A",
260         "RX Target": "/proc0/pib/perv26/pauc1/iohs0/smpgroup0",
261         "TX Target": "/proc1/pib/perv25/pauc0/iohs1/smpgroup0"
262     },
263     {
264         "Bus Type": "OMI_BUS",
265         "Callout Type": "Connected Callout",
266         "Guard": true,
267         "Priority": "medium_group_B",
268         "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
269         "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
270     },
271     {
272         "Bus Type": "OMI_BUS",
273         "Callout Type": "Connected Callout",
274         "Guard": true,
275         "Priority": "medium_group_C",
276         "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
277         "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
278     }
279 ])";
280     EXPECT_EQ(s, j.dump(4));
281 }
282 
TEST(Resolution,BusCallout)283 TEST(Resolution, BusCallout)
284 {
285     pdbg_targets_init(nullptr);
286 
287     auto c1 = std::make_shared<HardwareCalloutResolution>(
288         omi_str, callout::Priority::MED_A, true);
289 
290     auto c2 = std::make_shared<ConnectedCalloutResolution>(
291         callout::BusType::OMI_BUS, omi_str, callout::Priority::MED_A, true);
292 
293     auto c3 = std::make_shared<BusCalloutResolution>(
294         callout::BusType::OMI_BUS, omi_str, callout::Priority::LOW, false);
295 
296     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
297     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
298     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
299                    libhei::IsolationData{}};
300 
301     nlohmann::json j{};
302     std::string s{};
303 
304     // Special case: The bus callout will add both ends of the bus to the
305     // callout list at LOW priority with no guarding. Generally, this would be
306     // the last thing to be added to the callout list because of the priority.
307     // However, there was a field defect where a higher priority callout of one
308     // of the endpoint was added to the list (with guard action) after the bus
309     // callout. The priority of the callout was updated to match the higher
310     // priority, but the guard action was not updated. So the following are
311     // added to the callout list in a specific order:
312     //  - First, one of the endpoints with MED_A and guard.
313     //  - Then, the bus callout with LOW and no guard. This should result in
314     //    both endpoints in the list: one at MED_A (guard), the other at LOW (no
315     //    guard).
316     //  - Finally, the other endpoint with MED_A and guard. This should result
317     //    in both endpoints in the list with MED_A priority and guard actions.
318     c1->resolve(sd);
319     c3->resolve(sd);
320     c2->resolve(sd);
321 
322     // Verify the subsystem
323     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
324         callout::SrcSubsystem::MEMORY_CTLR, callout::Priority::MED_A};
325     EXPECT_EQ(sd.getSubsys(), subsys);
326 
327     // Callout list
328     j = sd.getCalloutList();
329     s = R"([
330     {
331         "Deconfigured": false,
332         "EntityPath": [],
333         "GuardType": "GARD_Unrecoverable",
334         "Guarded": true,
335         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
336         "Priority": "A"
337     },
338     {
339         "Deconfigured": false,
340         "EntityPath": [],
341         "GuardType": "GARD_Unrecoverable",
342         "Guarded": true,
343         "LocationCode": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0",
344         "Priority": "A"
345     },
346     {
347         "Deconfigured": false,
348         "Guarded": false,
349         "LocationCode": "P0",
350         "Priority": "L"
351     }
352 ])";
353     EXPECT_EQ(s, j.dump(4));
354 
355     // Callout FFDC
356     j = sd.getCalloutFFDC();
357     s = R"([
358     {
359         "Callout Type": "Hardware Callout",
360         "Guard": true,
361         "Priority": "medium_group_A",
362         "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0"
363     },
364     {
365         "Bus Type": "OMI_BUS",
366         "Callout Type": "Bus Callout",
367         "Guard": false,
368         "Priority": "low",
369         "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
370         "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
371     },
372     {
373         "Bus Type": "OMI_BUS",
374         "Callout Type": "Connected Callout",
375         "Guard": true,
376         "Priority": "medium_group_A",
377         "RX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0",
378         "TX Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0"
379     }
380 ])";
381     EXPECT_EQ(s, j.dump(4));
382 }
383 
TEST(Resolution,ClockCallout)384 TEST(Resolution, ClockCallout)
385 {
386     pdbg_targets_init(nullptr);
387 
388     auto c1 = std::make_shared<ClockCalloutResolution>(
389         callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::HIGH, false);
390 
391     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
392     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
393     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
394                    libhei::IsolationData{}};
395 
396     c1->resolve(sd);
397 
398     // Verify the subsystem
399     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
400         callout::SrcSubsystem::CEC_CLOCKS, callout::Priority::HIGH};
401     EXPECT_EQ(sd.getSubsys(), subsys);
402 
403     nlohmann::json j{};
404     std::string s{};
405 
406     // Callout list
407     j = sd.getCalloutList();
408     s = R"([
409     {
410         "Deconfigured": false,
411         "Guarded": false,
412         "LocationCode": "P0",
413         "Priority": "H"
414     }
415 ])";
416     EXPECT_EQ(s, j.dump(4));
417 
418     // Callout FFDC
419     j = sd.getCalloutFFDC();
420     s = R"([
421     {
422         "Callout Type": "Clock Callout",
423         "Clock Type": "OSC_REF_CLOCK_1",
424         "Priority": "high"
425     }
426 ])";
427     EXPECT_EQ(s, j.dump(4));
428 }
429 
TEST(Resolution,ProcedureCallout)430 TEST(Resolution, ProcedureCallout)
431 {
432     pdbg_targets_init(nullptr);
433 
434     auto c1 = std::make_shared<ProcedureCalloutResolution>(
435         callout::Procedure::NEXTLVL, callout::Priority::LOW);
436 
437     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
438     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
439     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
440                    libhei::IsolationData{}};
441 
442     c1->resolve(sd);
443 
444     // Verify the subsystem
445     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
446         callout::SrcSubsystem::OTHERS, callout::Priority::LOW};
447     EXPECT_EQ(sd.getSubsys(), subsys);
448 
449     nlohmann::json j{};
450     std::string s{};
451 
452     // Callout list
453     j = sd.getCalloutList();
454     s = R"([
455     {
456         "Priority": "L",
457         "Procedure": "next_level_support"
458     }
459 ])";
460     EXPECT_EQ(s, j.dump(4));
461 
462     // Callout FFDC
463     j = sd.getCalloutFFDC();
464     s = R"([
465     {
466         "Callout Type": "Procedure Callout",
467         "Priority": "low",
468         "Procedure": "next_level_support"
469     }
470 ])";
471     EXPECT_EQ(s, j.dump(4));
472 }
473 
TEST(Resolution,PartCallout)474 TEST(Resolution, PartCallout)
475 {
476     pdbg_targets_init(nullptr);
477 
478     auto c1 = std::make_shared<PartCalloutResolution>(callout::PartType::PNOR,
479                                                       callout::Priority::MED);
480 
481     libhei::Chip chip{util::pdbg::getTrgt(chip_str), 0xdeadbeef};
482     libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHIP_CS};
483     ServiceData sd{sig, AnalysisType::SYSTEM_CHECKSTOP,
484                    libhei::IsolationData{}};
485 
486     c1->resolve(sd);
487 
488     // Verify the subsystem
489     std::pair<callout::SrcSubsystem, callout::Priority> subsys = {
490         callout::SrcSubsystem::CEC_HARDWARE, callout::Priority::MED};
491     EXPECT_EQ(sd.getSubsys(), subsys);
492 
493     nlohmann::json j{};
494     std::string s{};
495 
496     // Callout list
497     j = sd.getCalloutList();
498     s = R"([
499     {
500         "Deconfigured": false,
501         "Guarded": false,
502         "LocationCode": "/bmc0",
503         "Priority": "M"
504     }
505 ])";
506     EXPECT_EQ(s, j.dump(4));
507 
508     // Callout FFDC
509     j = sd.getCalloutFFDC();
510     s = R"([
511     {
512         "Callout Type": "Part Callout",
513         "Part Type": "PNOR",
514         "Priority": "medium"
515     }
516 ])";
517     EXPECT_EQ(s, j.dump(4));
518 }
519