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